【问题标题】:Collision detection for diagonal movement对角线运动的碰撞检测
【发布时间】:2016-04-17 17:17:57
【问题描述】:

我为我的小型游戏工作所使用的碰撞检测系统。它能够判断玩家何时直接撞墙。但是,当玩家对角线时,它会穿过墙壁。我真的不明白问题出在哪里。

以下代码来自处理播放器的类:

public void run()
    {
        running = true;

        while(running)
        {

            //Get the key/s pressed
            controls.update();


            //Move down
            if (controls.down)
            {
                movePlayerDown(this.thisPlayer.getSpeed());
            }
            //Move up
            if (controls.up)
            {
                movePlayerUp(this.thisPlayer.getSpeed());
            }

            //Move right
            if (controls.right)
            {
                movePlayerRight(this.thisPlayer.getSpeed());
            }
            //Move left
            else if (controls.left)
            {
                movePlayerLeft(this.thisPlayer.getSpeed());
            }



            try
            {
                Thread.sleep(this.sleep);
            }
            catch (InterruptedException e)
            {
                e.printStackTrace();
            }

        }
    }


    public void movePlayerRight(int dx)
    {
        //Gets the tile at what would be the new coordinates of the player
        Tile tile  = currentLevel.getTile(this.thisPlayer.getX() + dx + this.thisPlayer.getWidth(), this.thisPlayer.getY());
        //IF the tile is null or not solid then the player is actually moved
        if (tile == null || !tile.isSolid())
        {
            this.thisPlayer.setX(this.thisPlayer.getX() + dx);
        }
    }


    public void movePlayerLeft(int dx)
    {
        //Gets the tile at what would be the new coordinates of the player
        Tile tile = currentLevel.getTile(this.thisPlayer.getX() - dx, this.thisPlayer.getY());
        //IF the tile is null or not solid then the player is actually moved
        if (tile == null || !tile.isSolid())
        {
            this.thisPlayer.setX(this.thisPlayer.getX() - dx);
        }
    }


    public void movePlayerDown(int dy)
    {
        //Gets the tile at what would be the new coordinates of the player
        Tile tile = currentLevel.getTile(this.thisPlayer.getX(), this.thisPlayer.getY() + dy + this.thisPlayer.getHeight());
        //IF the tile is null or not solid then the player is actually moved
        if (tile == null || !tile.isSolid())
        {
            this.thisPlayer.setY(this.thisPlayer.getY() + dy);
        }
    }


    public void movePlayerUp(int dy)
    {
        //Gets the tile at what would be the new coordinates of the player
        Tile tile = currentLevel.getTile(this.thisPlayer.getX(), this.thisPlayer.getY() - dy);
        //IF the tile is null or not solid then the player is actually moved
        if (tile == null || !tile.isSolid())
        {
            this.thisPlayer.setY(this.thisPlayer.getY() - dy);
        }
    }

下一段代码是 getTile() 方法:

public Tile getTile(int x, int y)
    {
        for (int r = 0; r < worldTiles.length; r++)
        {
            for (int c = 0; c < worldTiles[r].length; c++)
            {
                if (worldTiles[r][c] != null)
                {
                    int right = worldTiles[r][c].getX() + worldTiles[r][c].getWidth();
                    int bottom = worldTiles[r][c].getY() + worldTiles[r][c].getHeight();

                    if (x > worldTiles[r][c].getX() && x < right && y > worldTiles[r][c].getY() && y < bottom)
                    {
                        return worldTiles[r][c];
                    }
                }
            }
        }

【问题讨论】:

  • 您忘记添加碰撞检测代码,问题出在此处,请发布。另外你是如何沿对角线移动的?如上代码仅列出上下左右控件。
  • 如果用户按住向上和向右键,则玩家会沿对角线运动。
  • 从程序的角度来看,它仍然是upright 键的组合。在您看来,它只是在对角线移动,因为它很快,但它对 CPU 无关紧要,因为它的速度更快。这意味着错误在您的碰撞检测代码中。不能处理 up 后跟 right 键,反之亦然。

标签: java collision-detection


【解决方案1】:

a) 您没有定义 tile==null 的条件 - 这是为了进一步考虑

b) 测试每个事件的逻辑如下 - 一次一个键

        //Move down
        if (down)
        {
            movePlayerDown(this.thisPlayer.getSpeed());
        }
        //Move up
        else if (up)
        {
            movePlayerUp(this.thisPlayer.getSpeed());
        }

        //Move right
        else if (right)
        {
            movePlayerRight(this.thisPlayer.getSpeed());
        }
        //Move left
        else if (left)
        {
            movePlayerLeft(this.thisPlayer.getSpeed());
        }

应该从那里删除睡眠,因为它会束缚程序并可能丢失事件。

c) 事件应该从关键事件处理程序中触发,并且没有人可以去那里获取它们。

其实我会把整个逻辑颠倒如下:

void keyPressed(event) {
  sendEvent(event)
}

在哪里

void sendEvent(event) {
  if(event==down) ......


.......

}

替换你的while循环。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-10
    • 1970-01-01
    • 1970-01-01
    • 2013-03-22
    相关资源
    最近更新 更多