通过单击移动更改精灵表的 Y 轴

Posted

技术标签:

【中文标题】通过单击移动更改精灵表的 Y 轴【英文标题】:Changing Y-axis of spritesheet with click to move 【发布时间】:2013-01-12 16:36:22 【问题描述】:

我是新来的编程新手。我已经搜索了一段时间,但找不到任何可以帮助解决问题的方法。

我正在尝试让我的 spritesheet 在我的 spritesheet 的不同行走框架中循环,我已经使用 IsKeyDown 轻松完成了它,但是当涉及到使用鼠标走到某个地方时,我花了一段时间才弄清楚“不好” ' 解决方案:

if (destination.X > position.X)                
                currentFrame.Y = 6;
            if (destination.X > position.X && destination.Y >= position.Y + 35)
                currentFrame.Y = 7;
            if (destination.X > position.X && destination.Y <= position.Y - 35)
                currentFrame.Y = 5;

它有点工作,但想知道是否有更好的解决方法。 我想要的是能够点击游戏屏幕并选择适当的精灵行,相对于精灵当前位置和目的地,使其以正确的方式动画。

对不起,如果之前有人问过这个问题,但我在发布这个之前已经搜索了几个小时,但什么也没找到。

【问题讨论】:

【参考方案1】:

我有点不清楚你在做什么。您是否只有 2 个精灵,一个用于左侧,一个用于右侧?这就是我在您当前代码中看到的全部内容,但您指的是动画。我将假设您有一套完整的精灵来动画行走,在这种情况下,我认为本教程将涵盖您需要的内容:

http://coderplex.blogspot.ca/2010/04/2d-animation-part-1-basics.html

(更具体地说,教程的第 4 部分:http://coderplex.blogspot.ca/2010/04/2d-animation-part-4-sprite-animation.html)

基本上,您将需要设置计时器来控制精灵动画,因为这种类型的鼠标移动在您单击鼠标和对象到达的时间之间没有更多的输入(与移动相关)目的地。因此,您需要使用计时器来确定何时调用行走动画中的下一个精灵。

或者,您可以进一步详细说明您的 if 语句(如果 currentFrame = 1 则 currentFrame = 2,如果 currentFrame = 2 则 currentFrame = 3 等),但如果您进行更改,它将变得混乱且难以维护到图形或精灵从精灵表中拉出的方式。它也很可能动画太快,无论如何您都必须使用计时器来减慢它的速度。

【讨论】:

是的,我不太确定如何准确地表达它。我的精灵表是 [9,8],有 8 个运动方向和 9 帧动画。这是我的键盘之一; 错过了 5 分钟编辑规则并稍微改变了我的解释。是的,我不太确定如何真正措辞。我的精灵表是 [9,8],有 8 个运动方向和 9 帧动画。我想要找到的是,如果我单击我的精灵的北,如何使我的精灵表更改为北行,我让它在 9 个不同的精灵中循环,只是发现改变精灵的行来循环并不容易通过鼠标坐标。我会查看链接并感谢您的回复。【参考方案2】:

我想明白了。这是我的代码(希望它的格式正确。对不起,如果我不打算回答我自己的问题,认为这可能对其他人有帮助):

public Vector2 position = new Vector2(200, 200);
    Point frameSize = new Point(48, 92);
    Point currentFrame = new Point(0, 0);
    Point sheetSize = new Point(9, 8);
    float speed = 10;
    Vector2 direction;
    Vector2 destination;
    bool mousePressed = false;
    float difference;


    KeyboardState currentState;
    KeyboardState theKeyboardState;
    KeyboardState oldKeyboardState;

    enum State
    
        Walking
    

    State mcurrentState = State.Walking;

    TimeSpan nextFrameInterval =
        TimeSpan.FromSeconds((float)1 / 16);
    TimeSpan nextFrame;
    MouseState mouseState;
    MouseState oldState;

    public void Move()
    
        direction = destination - position;
        direction.Normalize();
        position += direction * speed;

        float Xdistance = destination.X - position.X;
        float Ydistance = destination.Y - position.Y;

        difference = (float)Math.Atan2(Ydistance, Xdistance);

        float differ;
        differ = MathHelper.ToDegrees(difference);

        if (destination.X >= position.X || destination.X <= position.X)
                        
            currentFrame.X++;
            if (currentFrame.X >= 9)
                currentFrame.X = 0;

            //down = 90dg
            if (differ >= 67.6 && differ <= 112.5)
                currentFrame.Y = 0;
            if (differ >= 112.6 && differ <= 157.5)
                currentFrame.Y = 1;
            if (differ >= 157.6 && differ <= 180 || differ >= -180 && differ <= -157.5)
                currentFrame.Y = 2;
            if (differ >= -157.4 && differ <= -112.5)
                currentFrame.Y = 3;
            if (differ >= -112.4 && differ <= -67.5)
                currentFrame.Y = 4;
            if (differ >= -67.4 && differ <= -22.5)
                currentFrame.Y = 5;
            if (differ >= -22.4 && differ <= 22.5)
                currentFrame.Y = 6;
            if (differ >= 22.6 && differ <= 67.5)
                currentFrame.Y = 7;
        
    

    public void Update()
    
        mouseState = Mouse.GetState();
        currentState = Keyboard.GetState();
        theKeyboardState = Keyboard.GetState();

        if (mousePressed == true)
        
            if (Vector2.DistanceSquared(destination, position) >= speed * speed)
            
                Move();
            
        

        if (mouseState.LeftButton == ButtonState.Pressed && oldState.LeftButton == ButtonState.Released)
        
            int mouseY = mouseState.Y;
            int mouseX = mouseState.X;

            destination = new Vector2(mouseX, mouseY);
            mousePressed = true;
        

        oldState = mouseState;           

        if (mcurrentState == State.Walking)
        
            #region KB animation

            if (currentState.IsKeyDown(Keys.Down))
            
                mousePressed = false;
                currentFrame.X++;
                currentFrame.Y = 0;
                if (currentFrame.X >= 9)
                    currentFrame.X = 0;
                position.Y += speed;
            

            if (currentState.IsKeyDown(Keys.Up))
            
                mousePressed = false;
                currentFrame.X++;
                currentFrame.Y = 4;
                if (currentFrame.X >= 9)
                    currentFrame.X = 0;
                position.Y -= speed;
            

            if (currentState.IsKeyDown(Keys.Right))
            
                mousePressed = false;
                currentFrame.X++;
                currentFrame.Y = 6;
                if (currentState.IsKeyDown(Keys.Down))
                    currentFrame.Y = 7;
                if (currentState.IsKeyDown(Keys.Up))
                    currentFrame.Y = 5;
                if (currentFrame.X >= 9)
                    currentFrame.X = 0;
                position.X += speed;
            

            if (currentState.IsKeyDown(Keys.Left))
            
                mousePressed = false;
                currentFrame.X++;
                currentFrame.Y = 2;
                if (currentState.IsKeyDown(Keys.Down))
                    currentFrame.Y = 1;
                if (currentState.IsKeyDown(Keys.Up))
                    currentFrame.Y = 3;
                if (currentFrame.X >= 9)
                    currentFrame.X = 0;
                position.X -= speed;
            
        
        oldKeyboardState = theKeyboardState;
            #endregion

    

    public void Draw(SpriteBatch spriteBatch, Texture2D character)
    
        spriteBatch.Begin();

        spriteBatch.Draw(character, position, new Rectangle(frameSize.X * currentFrame.X,
            frameSize.Y * currentFrame.Y, frameSize.X, frameSize.Y), Color.White, 0, new Vector2(frameSize.X / 2, frameSize.Y / 2), 1, SpriteEffects.None, 0);

        spriteBatch.End();
    

【讨论】:

以上是关于通过单击移动更改精灵表的 Y 轴的主要内容,如果未能解决你的问题,请参考以下文章

Cocos2d V3 - 获取当前精灵位置?

如何在three.js对象渲染中从中心向左更改轴(x,y,z)位置?

在 Plotly Python 中移动 x 轴和 y 轴刻度

键盘出现时如何移动视图Y轴变化

cocos2d js-触摸一起向上移动的叠加精灵

Matlab移动图像