0

我正在尝试为 SpriteAnimation 类实现自动旋转方法(尝试移植SpriteAnimation)。

一切正常,精灵绘制正确(它使用正确的动画)它只是没有正确旋转,如果它根本没有正确旋转,通常它似乎只在它的目标与其位置匹配而我想要它的位置后指向原点 (0, 0)旋转以在移动时更新,我尝试了度数和弧度,但都不起作用。它应该旋转以匹配它的当前方向。我已经为此苦苦挣扎了大约一个星期,但仍然没有得到预期的结果。

完整代码在这里

相关代码:

来自 SpriteAnimation

// The x position of the sprite's upper left corner pixel.
public int getX() { return (int)position.x; }
public void setX(int value)
{
    prevPosition.x = position.x;
    position.x = value;
    updateRotation();
}

// The y position of the sprite's upper left corner pixel.
public int getY() { return (int)position.y; }
public void setY(int value)
{
    prevPosition.y = position.y;
    position.y = value;
    updateRotation();
}

void updateRotation()
{
    if (rotateByPosition)
    {
        Vector2 rotationVector = new Vector2(position.x - prevPosition.x, position.y - prevPosition.y);
        rotationRad = rotationVector.angle();
        rotationDeg = rotationRad * MathUtils.radiansToDegrees;
    }
}

public void MoveBy(int x, int y)
{
    prevPosition = new Vector2(position);
    position.x += x;
    position.y += y;
    updateRotation();
}

public void Update(float deltaTime)
{
    // Don't do anything if the sprite is not animating
    if (animating)
    {
        // If there is not a currently active animation
        if (getCurrentFrameAnimation() == null)
        {
            // Make sure we have an animation associated with this sprite
            if (animations.size() > 0)
            {
                // Set the active animation to the first animation
                // associated with this sprite
                String[] sKeys = new String[animations.size()];
                int index = 0;
                for (Entry<String, FrameAnimation> mapEntry : animations.entrySet()) {
                    sKeys[index] = mapEntry.getKey();
                    index++;
                }
                setCurrentAnimation(sKeys[0]);
            }
            else
            {
                return;
            }
        }

        // Run the Animation's update method
        getCurrentFrameAnimation().Update(deltaTime);

        // Check to see if there is a "follow-up" animation named for this animation
        if (getCurrentFrameAnimation().getNextAnimation() != null && !getCurrentFrameAnimation().getNextAnimation().isEmpty())
        {
            // If there is, see if the currently playing animation has
            // completed a full animation loop
            if (getCurrentFrameAnimation().getPlayCount() > 0)
            {
                // If it has, set up the next animation
                setCurrentAnimation(getCurrentFrameAnimation().getNextAnimation());
            }
        }
    }
}

public void Draw(SpriteBatch spriteBatch, int xOffset, int yOffset)
{
    updateRotation();   // Calling this while testing to make sure that it is being called
    spriteBatch.draw(getCurrentTextureRegion(), getPosition().x + xOffset - center.x, getPosition().y + yOffset - center.y, center.x, center.y, getCurrentFrameAnimation().getFrameWidth(), getCurrentFrameAnimation().getFrameHeight(), 1.0f, 1.0f, rotationRad);
}

测试屏幕类

package com.darkstudio.darkisle.screens;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.math.Vector3;
import com.darkstudio.darkisle.DarkIsle;
import com.delib.engine.sprite.MobileSprite;

/**
 * Created by DarkEnder on 2017/06/27.
 */

public class TestScreen implements Screen {
    final DarkIsle game;
    OrthographicCamera camera;
    Texture tankTexture;

    MobileSprite mouseTank;

    public TestScreen(final DarkIsle game)
    {
        this.game = game;

        camera = new OrthographicCamera();
        configureCamera();

        tankTexture = new Texture(Gdx.files.internal("MulticolorTanks.png"));

        mouseTank = new MobileSprite(tankTexture, 32, 32);
        mouseTank.getSprite().AddAnimation("red", 0, 32, 32, 32, 8, 0.1f);
        mouseTank.getSprite().AddAnimation("purple", 0, 128, 32, 32, 8, 0.1f, "red");
        mouseTank.getSprite().AddAnimation("yellow", 0, 64, 32, 32, 8, 0.1f);
        mouseTank.getSprite().setAutoRotate(true);
        mouseTank.setPosition(new Vector2(100, 100));
        mouseTank.setTarget(new Vector2(mouseTank.getPosition()));
        mouseTank.setIsPathing(true);
        mouseTank.setEndPathAnimation("yellow");
        mouseTank.setLoopPath(false);
        mouseTank.setSpeed(2);
    }

    @Override
    public void show() {

    }

    @Override
    public void render(float delta) {
        Gdx.gl.glClearColor(0, 0, 0, 1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);

        update();

        game.batch.begin();

        mouseTank.draw(game.batch);

        game.batch.end();
    }

    @Override
    public void resize(int width, int height) {

    }

    @Override
    public void pause() {

    }

    @Override
    public void resume() {

    }

    @Override
    public void hide() {

    }

    @Override
    public void dispose() {

    }

    private void configureCamera()
    {
        Vector3 camPos = new Vector3(camera.position);

        float size = 800;
        float cameraWidth = 0;
        float cameraHeight = 0;

        if (Gdx.graphics.getHeight() < Gdx.graphics.getWidth())
        {
            cameraWidth = size;
            cameraHeight = size * Gdx.graphics.getHeight() / Gdx.graphics.getWidth();
        }
        else
        {
            cameraWidth = size * Gdx.graphics.getWidth() / Gdx.graphics.getHeight();
            cameraHeight = size;
        }

        camera.setToOrtho(true, cameraWidth, cameraHeight);
        camera.position.set(camPos.x + camera.viewportWidth / 2f, camPos.y + camera.viewportHeight / 2f, 0);
    }

    private void update() {
        int xTouch = Gdx.input.getX(0);
        int yTouch = Gdx.input.getY(0);
        mouseTank.setTarget(xTouch, yTouch);
        mouseTank.update(Gdx.graphics.getDeltaTime());
    }
}

编辑:现在只是说我已经尝试在 MathUtils 中使用 atan2 并且它给出了相同的结果。

MobileSprite 更新方法

public void update(float deltaTime)
{
    if (active && movingTowardsTarget)
    {
        if ((target != null))
        {
            // Get a vector pointing from the current location of the sprite
            // to the destination.
            Vector2 Delta = new Vector2(target.x - sprite.getX(), target.y - sprite.getY());

            if (Delta.len() > getSpeed())
            {
                Delta.nor();
                Delta.scl(getSpeed());
                getPosition().add(Delta);
            }
            else
            {
                if (target == sprite.getPosition())
                {
                    if (pathing)
                    {
                        if (queuePath.size() > 0)
                        {
                            target = queuePath.remove();
                            if (loopPath)
                            {
                                queuePath.remove(target);
                            }
                        }
                        else
                        {
                            if (!(endPathAnimation == null))
                            {
                                if (!(getSprite().getCurrentAnimation() == endPathAnimation))
                                {
                                    getSprite().setCurrentAnimation(endPathAnimation);
                                }
                            }

                            if (deactivateAtEndOfPath)
                            {
                                setIsActive(false);
                            }

                            if (hideAtEndOfPath)
                            {
                                setIsVisible(false);
                            }
                        }
                    }
                }
                else
                {
                    sprite.setPosition(target);
                }
            }
        }
    }
    if (active)
        sprite.Update(deltaTime);
}
4

1 回答 1

0

要获得弧度角:

void updateRotation()
{
    if (rotateByPosition)
    {
        Vector2 rotationVector = new Vector2(position.x - prevPosition.x, position.y - prevPosition.y);
        rotationRad = rotationVector.angleRad();
        rotationDeg = rotationRad * MathUtils.radiansToDegrees;
    }
}

并且draw方法需要角度:

spriteBatch.draw(
            getCurrentTextureRegion(),
            getPosition().x + xOffset - center.x,
            getPosition().y + yOffset - center.y,
            center.x, center.y,
            getCurrentFrameAnimation().getFrameWidth(), getCurrentFrameAnimation().getFrameHeight(),
            1.0f, 1.0f,
            rotationDeg
    );

屏幕鼠标位置从左上角开始,渲染器需要从左下角开始:

int xTouch = Gdx.input.getX(0);
int yTouch = Gdx.graphics.getHeight() - Gdx.input.getY(0);
于 2017-07-05T09:35:51.410 回答