当前位置: 首页 > 知识库问答 >
问题:

玩家角色移动错误LibGDX RPG

裴华荣
2023-03-14

我正在做一个RPG游戏,但是,我现在有一个错误。玩家的角色可以在所有四个基本方向上移动,但如果你向右、向上或向下移动,玩家就会被卡住。

此外,这个错误似乎有一定的逻辑性:

如果向下移动,角色将卡在向下移动的循环中

除非按下向上箭头,否则玩家将开始一个新的向上无限循环

除非按下向右箭头,否则玩家将开始一个新的向右无限循环

所以权利似乎优先于上,而上优先于下。

奇怪的是,向左移动工作得很完美,即使当角色卡在无限循环中时,向左箭头键也总是会导致玩家以正确的方式向左移动。

我不明白代码中的错误在哪里。我不知道为什么向左运动有效,而其他三个方向无效。我不明白为什么其他三个方向之间似乎也有某种优先顺序。

我已经看了这个程序,我不认为我对待向左运动不同于任何其他方向。然而,考虑到这个错误,我可能错了。

由于30k字数限制,我没有足够的空间来包含这里的所有代码。因此,我包含了一个到我的github的链接,所以你可以在那里看到代码。

https://github.com/davey67/bludbourne

我认为这些课程可能是最重要的课程:

package com.bludbourne.game.desktop;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Application;
import com.badlogic.gdx.backends.lwjgl.LwjglApplication;
import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration;
import com.bludbourne.game.BludBourne;

public class DesktopLauncher {
    public static void main (String[] arg) {
        LwjglApplicationConfiguration config = new LwjglApplicationConfiguration();



        config.title="BludBourne";
        config.useGL30=false;
        config.width =480;
        config.height=480;

        Application app = new LwjglApplication(new BludBourne(),config);

        Gdx.app=app;
        Gdx.app.setLogLevel(Application.LOG_DEBUG);


    }
}

/

package com.bludbourne.game;

import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;


import com.bludbourne.game.screens.MainGameScreen;
import com.badlogic.gdx.Game;

public class BludBourne extends Game {

    public static final MainGameScreen _mainGameScreen = new MainGameScreen();


    @Override
    public void create () {
        setScreen(_mainGameScreen);
    }

    @Override
    public void dispose () {
        _mainGameScreen.dispose();
    }
}

/

package com.bludbourne.game;

import java.util.HashMap;
import java.util.Map;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input;
import com.badlogic.gdx.InputProcessor;
import com.badlogic.gdx.math.Vector3;


public class PlayerController implements InputProcessor
{

    private final static String TAG = PlayerController.class.getSimpleName();

    enum Keys{
        LEFT,RIGHT,UP,DOWN,QUIT
    }

    enum Mouse{

        SELECT,DOACTION
    }

    private static Map<Keys,Boolean> keys=new HashMap<PlayerController.Keys,Boolean>();
    private static Map<Mouse,Boolean> mouseButtons = new HashMap<PlayerController.Mouse,Boolean>();
    private Vector3 lastMouseCoordinates;

    static {
        keys.put(Keys.LEFT,false);
        keys.put(Keys.RIGHT,false);
        keys.put(Keys.UP,false);
        keys.put(Keys.DOWN, false);
        keys.put(Keys.QUIT, false);

    }


    static {

        mouseButtons.put(Mouse.SELECT, false);
        mouseButtons.put(Mouse.DOACTION, false);

    }


    private Entity _player;

    public PlayerController(Entity player) {

        this.lastMouseCoordinates=new Vector3();
        this._player=player;

    }



    @Override
    public boolean keyDown(int keycode)
    {
        if(keycode ==Input.Keys.LEFT||keycode==Input.Keys.A) {
            this.leftPressed();
        }
        if(keycode ==Input.Keys.RIGHT||keycode==Input.Keys.D) {
            this.rightPressed();
        }
        if(keycode ==Input.Keys.UP||keycode==Input.Keys.W) {
            this.upPressed();
        }
        if(keycode ==Input.Keys.DOWN||keycode==Input.Keys.S) {
            this.downPressed();
        }
        if(keycode==Input.Keys.Q) {
            this.quitPressed();
        }
        return true;
    }

    @Override
    public boolean keyUp(int keycode)
    {
        if(keycode ==Input.Keys.LEFT||keycode==Input.Keys.A) {
            this.leftReleased();
        }
        if(keycode ==Input.Keys.RIGHT||keycode==Input.Keys.D) {
            this.rightReleased();
        }
        if(keycode ==Input.Keys.UP||keycode==Input.Keys.W) {
            this.upReleased();
        }
        if(keycode ==Input.Keys.DOWN||keycode==Input.Keys.S) {
            this.downReleased();
        }
        if(keycode==Input.Keys.Q) {
            this.quitReleased();
        }
        return true;
    }

    @Override
    public boolean keyTyped(char character)
    {
        // TODO Auto-generated method stub
        return false;
    }

    @Override
    public boolean touchDown(int screenX, int screenY, int pointer, int button)
    {
        if(button==Input.Buttons.LEFT||button==Input.Buttons.RIGHT) {
            this.setClickedMouseCoordinates(screenX,screenY);
        }
        if(button==Input.Buttons.LEFT) {
            this.selectMouseButtonPressed(screenX,screenY);

        }

        if(button==Input.Buttons.RIGHT) {
            this.doActionMouseButtonPressed(screenX,screenY);
        }
        return true;
    }

    @Override
    public boolean touchUp(int screenX, int screenY, int pointer, int button)
    {
        if(button==Input.Buttons.LEFT) {
            this.selectMouseButtonReleased(screenX,screenY);
        }
        if(button==Input.Buttons.RIGHT) {
            this.doActionMouseButtonReleased(screenX,screenY);
        }
        return true;
    }

    @Override
    public boolean touchDragged(int screenX, int screenY, int pointer)
    {
        // TODO Auto-generated method stub
        return false;
    }

    @Override
    public boolean mouseMoved(int screenX, int screenY)
    {
        // TODO Auto-generated method stub
        return false;
    }

    @Override
    public boolean scrolled(int amount)
    {
        // TODO Auto-generated method stub
        return false;
    }

    public void dispose() {



    }

    public void leftPressed() {
        keys.put(Keys.LEFT,true);

    }

    public void rightPressed() {
        keys.put(Keys.RIGHT,true);

    }

    public void upPressed() {
        keys.put(Keys.UP,true);

    }

    public void downPressed() {
        keys.put(Keys.DOWN,true);

    }

    public void quitPressed() {

        keys.put(Keys.QUIT, true);
    }


    public void setClickedMouseCoordinates(int x,int y) {

        lastMouseCoordinates.set(x,y,0);

    }

    public void selectMouseButtonPressed(int x,int y) {

        mouseButtons.put(Mouse.SELECT,true);
    }

    public void doActionMouseButtonPressed(int x,int y) {

        mouseButtons.put(Mouse.DOACTION, true);
    }

    public void leftReleased() {
        keys.put(Keys.LEFT,false);

    }

    public void rightReleased() {
        keys.put(Keys.RIGHT,true);

    }

    public void upReleased() {
        keys.put(Keys.UP,true);

    }

    public void downReleased() {
        keys.put(Keys.DOWN,true);

    }

    public void quitReleased() {

        keys.put(Keys.QUIT, true);
    }


    public void selectMouseButtonReleased(int x,int y) {
        mouseButtons.put(Mouse.SELECT, false);
    }

    public void doActionMouseButtonReleased(int x ,int y) {

        mouseButtons.put(Mouse.DOACTION, false);
    }


    public void update(float delta) {

        processInput(delta);
    }

    public static void hide() {

        keys.put(Keys.LEFT, false);
        keys.put(Keys.RIGHT, false);
        keys.put(Keys.UP, false);
        keys.put(Keys.DOWN, false);
        keys.put(Keys.QUIT, false);

    }

    private void processInput(float delta) {

        if(keys.get(Keys.LEFT)) {
            _player.calculateNextPosition(Entity.Direction.LEFT,delta);
            _player.setState(Entity.State.WALKING);
            _player.setDirection(Entity.Direction.LEFT,delta);

        }

        else if(keys.get(Keys.RIGHT)) {
            _player.calculateNextPosition(Entity.Direction.RIGHT,delta);
            _player.setState(Entity.State.WALKING);
            _player.setDirection(Entity.Direction.RIGHT,delta);

        }

        else if(keys.get(Keys.UP)) {
            _player.calculateNextPosition(Entity.Direction.UP,delta);
            _player.setState(Entity.State.WALKING);
            _player.setDirection(Entity.Direction.UP,delta);

        }

        else if(keys.get(Keys.DOWN)) {
            _player.calculateNextPosition(Entity.Direction.DOWN,delta);
            _player.setState(Entity.State.WALKING);
            _player.setDirection(Entity.Direction.DOWN,delta);

        }
        else if(keys.get(Keys.QUIT)) {
            Gdx.app.exit();


        }

        else {

            _player.setState(Entity.State.IDLE);
        }


        if(mouseButtons.get(Mouse.SELECT)) {

            mouseButtons.put(Mouse.SELECT, false);
        }
    }
}

/

package com.bludbourne.game;

import java.util.UUID;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Animation;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.Array;

public class Entity
{

    private static final String     TAG                 = Entity.class.getSimpleName();
    private static final String _defaultSpritePath = "sprites/characters/Warrior.png";

    private Vector2                 _velocity;
    private String                  _entityID;

    private Direction               _currentDirection   = Direction.LEFT;
    private Direction               _previousDirection  = Direction.UP;

    private Animation               _walkLeftAnimation;
    private Animation               _walkRightAnimation;
    private Animation               _walkUpAnimation;
    private Animation               _walkDownAnimation;

    private Array<TextureRegion>    _walkLeftFrames;
    private Array<TextureRegion>    _walkRightFrames;
    private Array<TextureRegion>    _walkUpFrames;
    private Array<TextureRegion>    _walkDownFrames;

    protected Vector2               _nextPlayerPosition;
    protected Vector2               _currentPlayerPosition;
    protected State                 _state              = State.IDLE;
    protected float                 _frameTime          = 0f;
    protected Sprite                _frameSprite        = null;
    protected TextureRegion         _currentFrame       = null;

    public final int                FRAME_WIDTH         = 16;
    public final int                FRAME_HEIGHT        = 16;
    public static Rectangle         boundingBox;

    public enum State
    {

        IDLE, WALKING
    }

    public enum Direction
    {
        UP, RIGHT, DOWN, LEFT
    }

    public Entity() {

        initEntity();
    }

    public void initEntity()
    {
        this._entityID = UUID.randomUUID().toString();
        this._nextPlayerPosition = new Vector2();
        this._currentPlayerPosition = new Vector2();
        this.boundingBox = new Rectangle();
        this._velocity = new Vector2(2f, 2f);
        Utility.loadTextureAsset(_defaultSpritePath);
        loadDefaultSprite();
        loadAllAnimations();

    }

    public void update(float delta)
    {

        _frameTime = (_frameTime + delta) % 5;

        setBoundingBoxSize(0f, 0.5f);

    }

    public void init(float startX, float startY)
    {

        this._currentPlayerPosition.x = startX;
        this._currentPlayerPosition.y = startY;
        this._nextPlayerPosition.x = startX;
        this._nextPlayerPosition.y = startY;

    }

    public void setBoundingBoxSize(float percentageWidthReduced, float percentageHeightReduced)
    {

        float width;
        float height;

        float widthReductionAmount = 1.0f - percentageWidthReduced;
        float heightReductionAmount = 1.0f - percentageHeightReduced;

        if (widthReductionAmount > 0 && widthReductionAmount < 1)
        {
            width = FRAME_WIDTH * widthReductionAmount;
        }
        else
        {
            width = FRAME_WIDTH;
        }

        if (heightReductionAmount > 0 && heightReductionAmount < 1)
        {
            height = FRAME_HEIGHT * heightReductionAmount;
        }
        else
        {
            height = FRAME_HEIGHT;
        }

        if (width == 0 || height == 0)
        {
            Gdx.app.debug(TAG, "Width and Height are 0!! " + width + ":" + height);
        }

        float minX;
        float minY;

        if (MapManager.UNIT_SCALE > 0)
        {

            minX = _nextPlayerPosition.x / MapManager.UNIT_SCALE;
            minY = _nextPlayerPosition.y / MapManager.UNIT_SCALE;

        }

        else
        {

            minX = _nextPlayerPosition.x;
            minY = _nextPlayerPosition.y;
        }

        boundingBox.set(minX, minY, width, height);

    }

    private void loadDefaultSprite()
    {

        Texture texture = Utility.getTextureAsset(_defaultSpritePath);
        TextureRegion[][] textureFrames = TextureRegion.split(texture, FRAME_WIDTH, FRAME_HEIGHT);
        _frameSprite = new Sprite(textureFrames[0][0].getTexture(), 0, 0, FRAME_WIDTH, FRAME_HEIGHT);
        _currentFrame = textureFrames[0][0];

    }

    public void loadAllAnimations()
    {

        Texture texture = Utility.getTextureAsset(_defaultSpritePath);
        TextureRegion[][] textureFrames = TextureRegion.split(texture, FRAME_WIDTH, FRAME_HEIGHT);

        _walkDownFrames = new Array<TextureRegion>(4);
        _walkLeftFrames = new Array<TextureRegion>(4);
        _walkRightFrames = new Array<TextureRegion>(4);
        _walkUpFrames = new Array<TextureRegion>(4);

        for (int i = 0; i < 4; i++)
        {

            for (int j = 0; j < 4; j++)
            {
                TextureRegion region=textureFrames[i][j];

                if(region==null) {
                    Gdx.app.debug(TAG, "Got null animation frame "+i+","+j);
                }

                switch(i) {


                case 0:
                    _walkDownFrames.insert(j,region);
                    break;
                case 1:
                    _walkLeftFrames.insert(j,region);
                    break;
                case 2:
                    _walkRightFrames.insert(j,region);
                    break;
                case 3:
                    _walkUpFrames.insert(j,region);
                    break;

                }


            }

        }

        _walkDownAnimation = new Animation(0.25f,_walkDownFrames,Animation.PlayMode.LOOP);
        _walkLeftAnimation = new Animation(0.25f,_walkLeftFrames,Animation.PlayMode.LOOP);
        _walkRightAnimation = new Animation(0.25f,_walkRightFrames,Animation.PlayMode.LOOP);
        _walkUpAnimation = new Animation(0.25f,_walkUpFrames,Animation.PlayMode.LOOP);



    }


    public void dispose() {

        Utility.unloadAsset(_defaultSpritePath);

    }

    public void setState(State state) {

        this._state = state;
    }

    public Sprite getFrameSprite() {

        return _frameSprite;
    }

    public TextureRegion getFrame() {

        return _currentFrame;
    }

    public Vector2 getCurrentPosition() {
        return _currentPlayerPosition;
    }

    public void setCurrentPosition(float currentPositionX,float currentPositionY) {

        _frameSprite.setX(currentPositionX);
        _frameSprite.setY(currentPositionY);
        this._currentPlayerPosition.x=currentPositionX;
        this._currentPlayerPosition.y=currentPositionY;
    }

    public void setDirection(Direction direction,float deltaTime) {


        this._previousDirection=this._currentDirection;
        this._currentDirection=direction;

        switch(_currentDirection) {
        //not sure about this
        case DOWN:
            _currentFrame=(TextureRegion) _walkDownAnimation.getKeyFrame(_frameTime);
            break;
        case LEFT:
            _currentFrame=(TextureRegion) _walkLeftAnimation.getKeyFrame(_frameTime);
            break;
        case RIGHT:
            _currentFrame=(TextureRegion) _walkRightAnimation.getKeyFrame(_frameTime);
            break;
        case UP:
            _currentFrame=(TextureRegion) _walkUpAnimation.getKeyFrame(_frameTime);
            break;

        default:
            break;



        }

    }

    public void setNextPositionToCurrent() {

        setCurrentPosition(_nextPlayerPosition.x,_nextPlayerPosition.y);

    }

    public void calculateNextPosition(Direction currentDirection,float deltaTime) {

        float testX=_currentPlayerPosition.x;
        float testY=_currentPlayerPosition.y;

        _velocity.scl(deltaTime);

        switch(currentDirection) {

        case LEFT:
            testX-=_velocity.x;
            break;
        case RIGHT:
            testX+=_velocity.x;
            break;
        case UP:
            testY+=_velocity.y;
            break;
        case DOWN:
            testY-=_velocity.y;
            break;
        default:
            break;


        }

        _nextPlayerPosition.x=testX;
        _nextPlayerPosition.y=testY;

        _velocity.scl(1/deltaTime);


    }
}

我觉得我可能遗漏了一些明显的东西,但是,我仍然看不到错误。非常感谢帮助。谢谢你。

我的github还包含精灵表和三个地图,所有这些都将存储在我项目的资产文件夹中。

共有1个答案

长孙玉泽
2023-03-14

请注意PlayerInput

    public void leftReleased() {
        keys.put(Keys.LEFT,false);

    }

    public void rightReleased() {
        keys.put(Keys.RIGHT,true);

    }

    public void upReleased() {
        keys.put(Keys.UP,true);

    }

    public void downReleased() {
        keys.put(Keys.DOWN,true);

    }

我相信当密钥被释放时,它应该是false,而不是true。我已经验证了这可以防止无限循环。

右,上,然后下的优先级顺序是由于在处理输入中检查键的顺序。

 类似资料:
  • 我在使用我创建的bot为服务器中的不协调用户分配角色时遇到问题。 我编写的代码是用于与FaceIT交互的,它工作得很好,但我希望能够根据一个用户进行了多少次匹配来分配角色。 通过我的代码,我知道discord用户的ID,因为它们存储在配置文件中,配置被加载到一个名为 运行代码时,出现以下错误: 不一致外部命令。错误。CommandInvokeError:命令引发异常:AttributeError:

  • 我是一个业余程序员,在Pyplay非常新。这是我用Pyplay编写的程序,类似于我的世界。在过去的一个小时里,我一直在尝试设置一个代码,让我的玩家在按下X键时移动到随机瓦片。我已经耗尽了大部分如果不是所有的网站和搜索引擎寻找。我已经设法完成了一半的任务;当按下X键时,化身会移动到随机磁贴,但它会移出窗口/显示器。拜托,你能看看我的代码,看看我能做些什么来改进它吗?

  • 我对Android/Java编程比较陌生。我正在创建一个基于文本的社交游戏,并创建了一个包含ID、名称和角色的SQLite数据库。 角色将由应用程序分配并存储在相关的SQLite表中。 由于角色是随机的,我想也许一个随机数生成器从1-7(2个独特的角色,2个相同的角色和3个相同的角色) 我被困在哪里开始和如何实现此功能,任何帮助/建议将不胜感激。

  • 我在libgdx中使用tiled。我正在做一个自上而下的rpg,类似于《最终幻想1》、《2》等等。 我使用setX(getX()速度)。x*delta);和setY(getY()速度)。y*delta);在地图上移动玩家。我怎样才能让玩家一块一块地移动呢。我该如何检查玩家在哪个磁贴中?谁能帮帮我吗。谢谢你。 我发现: } 来自:libGDX:如何实现基于平滑瓷砖/网格的游戏角色移动? 但是我似乎可

  • 刚开始使用pygame,当你按住箭头键时,试图让一个简单的点在屏幕上移动。目前,它只在你按键时移动,但你必须重复按键。 此外,我很感激你对我目前的代码有任何建议,可以改进或改变,使之更有效。

  • 由于列表中最高角色的位置等于角色的数量,所以创建的每个角色都应该移动到完全相同的位置,从而将其下面的每个角色都低一个位置。 但这不是正在发生的事情。 在执行这些代码行并降低进程速度时(通过使用和/或),我看到了以下情况: null 如果您怀疑这是我的代码中根深蒂固的,请让我知道,因为我可以为您提供更多的细节。