我出于学习目的而制作2D塔防游戏,并且在移动时无法使敌人(精灵)面对正确的方向。

以下是地图的构建方式,以进行澄清:

http://i.imgur.com/ivO8kWe.png

这是我用来测试的Sprite工作表:

http://i.imgur.com/2h4fSL3.png

左上方的第一个子画面是第0帧,右侧的下一个子画面是第1帧,依此类推。 如您所见,精灵已经朝错误的方向前进。 该地图具有起点(顶部的第一个棕色瓷砖)和终点(终点的最后一个棕色瓷砖),并且只有棕色瓷砖是可步行的,因此有了起点和终点,它将计算出精灵走到终点的最短有效路径。

就是说,每一个生成的精灵都会有一个预定的行走路径,从中我尝试通过检查最后的X或Y位置以及X或Y当前位置来找到精灵所面对的方向,并选择哪条线我将用于行走动画的Sprite表的。 例如,假设小精灵正在向南移动,它应该使用小精灵表格底部(第15到19帧)的小精灵,但它不起作用。

这是我用于敌人的动画课:

 public class AnimatedSprite : Sprite
    {
        public int Lines { get; set; }
        public int Columns { get; set; }
        protected int currentFrame;
        protected int totalFrames;
        protected int timeSinceLastFrame = 0;
        protected int milisecondsPerFrame = 50;


        public AnimatedSprite(Texture2D texture, int lines, int columns, Vector2 position)
            : base ( texture, position)
        {
            this.texture = texture;
            this.position = position;
            Lines = lines;
            Columns = columns;
            totalFrames = Lines * Columns;
        }

        public override void Update(GameTime gameTime)
        {
            base.Update(gameTime);

           //Here i check if the sprite sheet have more than 1 line because if it have, 
           //it must use a different update method.
            if (Lines > 1)
            {
                // Down
                if (lastPostion.Y < position.Y)
                {
                    AnimateDown(gameTime);
                }
                // Up
                if (position.Y < lastPosition.Y)
                {
                    AnimateUp(gameTime);
                }

                // Right
                if (position.X > lastPosition.X)
                {
                    AnimateRight(gameTime);
                }

                // Left
                if (position.X < lastPosition.X)
                {
                    AnimateLeft(gameTime);
                }
            }

            if (Lines == 1) {
            timeSinceLastFrame += gameTime.ElapsedGameTime.Milliseconds;
            if (timeSinceLastFrame > milisecondsPerFrame)
            {
                timeSinceLastFrame -= milisecondsPerFrame;
                currentFrame++;
                if (currentFrame == totalFrames)
                {
                    currentFrame = 0;
                }
            }
        }                        
           center = new Vector2(position.X + texture.Width / Columns, position.Y + texture.Height / Lines);
        }

        public void AnimateUp(GameTime gameTime)
        {
            timeSinceLastFrame += gameTime.ElapsedGameTime.Milliseconds;
            if (timeSinceLastFrame > milisecondsPerFrame)
            {
                timeSinceLastFrame -= milisecondsPerFrame;
                currentFrame++;
                if (currentFrame > 14)
                    currentFrame = 10;
            }
        }

        public void AnimateDown(GameTime gameTime)
        {
            timeSinceLastFrame += gameTime.ElapsedGameTime.Milliseconds;
            if (timeSinceLastFrame > milisecondsPerFrame)
            {
                timeSinceLastFrame -= milisecondsPerFrame;
                currentFrame++;
                if (currentFrame > 19)
                    currentFrame = 15;
            }
        }           

        public void AnimateLeft(GameTime gameTime)
        {
            timeSinceLastFrame += gameTime.ElapsedGameTime.Milliseconds;
                if (timeSinceLastFrame > milisecondsPerFrame)
            {
                timeSinceLastFrame -= milisecondsPerFrame;
                currentFrame++;
                if (currentFrame > 4)
                    currentFrame = 0;
            }
        }

     public void AnimateRight(GameTime gameTime)
        {
            timeSinceLastFrame += gameTime.ElapsedGameTime.Milliseconds;
                if (timeSinceLastFrame > milisecondsPerFrame)
            {
                timeSinceLastFrame -= milisecondsPerFrame;
                currentFrame++;
                if (currentFrame > 9)
                    currentFrame = 5;
            }
        }


        public override void Draw(SpriteBatch spriteBatch)
        {
            int width = texture.Width / Columns;
            int height = texture.Height / Lines;
            int line = (int)((float)currentFrame / (float)Columns);
            int column = currentFrame % Columns;

            Rectangle originRectangle = new Rectangle(width * column, height * line, width, height);
            Rectangle destinationRectangle = new Rectangle((int)position.X, (int)position.Y, width, height);          

            spriteBatch.Draw(texture, destinationRectangle, originRectangle, Color.White);
        }
    }
}

编辑:我在一条直线水平上进行了测试(起点在左侧),它开始朝左(第0帧),但是当它到达第三个棕色瓷砖时,它固定并面向正确的方向:

i.imgur.com/3FsGhuY.png

Edit2:我在所有四个方向(上下移动,向右移动和向左移动,反之亦然)上使用直线水平进行了测试,并且在所有这些方向上,它都从第0帧开始,并在到达第三个图块时开始修复并面对正确的方向。

#1楼 票数:1 已采纳

您无需检查当前帧是否低于所需动画循环的最小值; 您只需要对照最大值进行检查即可。 另外,您的代码中有一些重复可能应该被考虑在内,以使其更易于阅读和使用。

我将用单个方法替换所有AnimateXXXX方法:

public void AnimateLoop(GameTime gameTime, int loopFirstFrame, int loopLastFrame)
{
    timeSinceLastFrame += gameTime.ElapsedGameTime.Milliseconds;
    if (timeSinceLastFrame > milisecondsPerFrame)
    {
        timeSinceLastFrame -= milisecondsPerFrame;
        currentFrame++;
    }
    if (currentFrame > loopLastFrame || currentFrame < loopFirstFrame)
        currentFrame = loopFirstFrame;
}

然后像这样称呼他们:

// Down
if (lastPostion.Y < position.Y)
    AnimateLoop(gameTime, 15, 19);
// Up
if (position.Y < lastPosition.Y)
    AnimateLoop(gameTime, 10, 14);
// Right
if (lastPosition.X < position.X)
    AnimateLoop(gameTime, 5, 9);
// Left
if (position.X < lastPosition.X)
    AnimateLoop(gameTime, 0, 4);

  ask by ViNi translate from so

未解决问题?本站智能推荐:

3回复

二维C#XNA游戏中的动画

我想使用XNA在C#中创建2D游戏。 应该有火柴人可以穿着不同的武器,例如手枪,手榴弹或火箭发射器。 而且那些火柴人还应该能够做其他事情,例如喝一瓶啤酒和其他东西。.那么如何创建和存储这些动画(喝一瓶啤酒,走路,扔手榴弹)以及如何告诉他们如何握持武器(手枪:手中,手榴弹:手中,但握在武器身后
1回复

XNA-如何计算二维圆相互碰撞后的速度?

我一直在研究使圆圈相互碰撞,这就是我到目前为止想到的: 当圆圈碰撞时代码确实有效,但是最终速度的方程似乎使圆圈在屏幕上跳跃或缓慢地相互穿过,我尝试在网上找到解决方案,但我无法让它工作. 关于我可以做些什么来解决它的任何建议? 新的代码和 GIF 来展示它的作用:
2回复

二维碰撞检测不起作用XNAC#

我是XNA和C#的新手(我是2天前开始的,所以请原谅草率的编程),并且我在制作一个简单的游戏时遇到了问题。 我似乎在任何在线教程中都找不到解决方案。 我正在尝试利用矩形碰撞检测,但无法使其正常工作。 角色完全掉落在地板上,似乎在任何地方都没有碰撞发生。 我在这里找不到逻辑错误。 在下面
1回复

碰撞块运动

我在阻止运动方面有问题,我已经阅读了关于在碰撞中阻止运动的问题,但是我对自己的问题一无所知。 如果您能给我逻辑,我将尝试解决自己的问题。 我希望你能帮我这个我的球员更新 :EDIT:感谢Kai Hartmann的回复我的问题是2D图形,我想知道当object1与object2碰撞时如何停
1回复

XNASprite运动出错

大家好,首先,这是我的精灵图片: 我在游戏中按比例缩小了比例,因此游戏中的比例不是很大。 所以无论如何我想要的下面的代码结果: 然后是Draw方法: 是当我按下“向上”箭头时,这个小火箭应该朝它指向的方向(因为我可以用向左和向右箭头旋转它以使其指向所需的位置),但是这段代码的结
1回复

简单的2D运动[关闭]

我最近开始使用XNA进行开发。 我可以说我拥有更多的基本编程语言,但是没什么特别的。 作为我在XNA的第一个项目。 我想创建一个简单的2D平台游戏,但是目前,我正在尝试简单的移动。 我有3个向量(位置,速度,加速度)和一个简单的整数(最大速度): 然后,我在XNA框架的Updat
1回复

如何在2DXNA游戏中使用路径动画?

我希望我的2D精灵沿着某些给定的路径(同时提供位置和旋转数据)移动,这些路径可以从单独的文件中读取,这些文件最好可以由一些外部编辑器进行编辑,或者可以轻松地手动修改。 在XNA游戏中有什么方法可以做到这一点? 我已经阅读了此存储矢量XNA动画 它说要做到这一点,我必须首先为矢量动画实现
1回复

带有移动平台的瓷砖系统

使用基于图块的系统时,我需要将平台块与其余部分分开,然后允许它们以恒定速度上下移动。 我如何使标有“ =”(垂直移动平台)的磁贴向上或向下移动,直到碰到“#”(墙)或终点“ +”(垂直移动平台移动区域)? 在播放器之后有一个摄影机类,一个控制移动的播放器类,一个控制块碰撞的Block类。