如何使用数组协调基于2D平铺的游戏中的图形和逻辑位置?

时间:2011-08-10 07:18:45

标签: java multidimensional-array 2d sprite

我正在使用像Bomberman(我的第一个游戏)的Java编程基于2D平铺的游戏。

我使用2D数组来表示我跟踪墙壁,步行空间等的地图。到现在为止,我能够让玩家顺利地移动精灵,取决于他按下的方向键(但不能与之交互)背景/地图,它可以随机走动并离开屏幕。)

当我想跟踪玩家在阵列中的位置时,我的问题就出现了。从逻辑上讲,角色总是只属于一个瓷砖,但在图形上它可以在两个瓷砖之间。我该如何解决这个问题?

  

我已经尝试过了:

     

currentTileArrayX = x / tileWidth;

     

currentTileArrayY = y / tileHeight;

     

其中x和y是精灵的左上角坐标。   但是一切都变得非常错误,因为玩家的精灵与瓷砖的尺寸不同。

我有另一个选项可以解决上一个问题:当玩家按下一个方向键时,将该角色移动到下一个方块,就像动画一样。这不会让玩家停在两块瓷砖的中间......但是如果他用另一台按键打断它呢?如何在动画执行时停止用户的操作?我认为这是最简单的解决方案,但我不知道如何实现它。

我已经尝试在其他问题中找到解决方案,但我没有运气。我希望你能帮助我。

非常感谢。

3 个答案:

答案 0 :(得分:2)

Aaaaaaaaaaaaaaah!遇到'离散空间问题':)你的逻辑映射是离散的,但你的UI运动是在连续的空间。我不是用户实际上可以“同时”在两个区块中 - 视觉上是,但从不'内部'。现在你正在获得玩家的位置,这可以是在瓷砖内的“任何地方”或2个瓷砖的“边界”,可以这么说......

你有两个解决这个问题的方法,IMO:

  1. 使用简单的舍入:如果玩家位置是&lt;瓷砖边界只是让他在前一个瓷砖上。如果下一个更大。现在边界的问题 - 你可以使用启发式,因为你不应该相信浮点比较的准确性(即,比较0不是一件好事)。所以你可以试试这样的if(currentPosition - boundary <= 0.000000001)然后假设它是下一个瓷砖留在同一个。
  2. 好吧@Jay打败了我。所以第二个实际上是一个 定义移动速度并移动每步多步的角色 'click'/'button press' - 但你说你有钥匙的问题 按在“之间”。我猜你的代码是不是这样设计的 那应该不是问题:
  3.     update()
            {
               calculate(); //update all datastructures/calculations
               draw(); //update the visual representation based on calculations
            }
    

    update()是a.k.a,gameLoop。我认为这应该可以解决你的问题...

答案 1 :(得分:1)

我会尽量保持逻辑部分(玩家所属的图块)和可视化部分(图块之间的动画)尽可能分开。我的方法是拥有一个逻辑位置(设置播放器的平铺)和移动速度(这实际上意味着移动到平铺后玩家不被允许移动到下一个平铺的时间量)。然后从一个瓷砖到另一个瓷砖的动画意味着你的精灵总是朝着你的瓷砖的屏幕坐标移动 - 这个时间可以很容易地由移动速度决定(只要玩家必须使用一个完整的瓷砖移动在当前的瓷砖上休息。)

唯一的特殊情况是这种“转身”,你可以让玩家随时返回他来自的牌,只需(timeToRecoverOnTile - (timeToRecoverOnTile - timeSinceMovementStarted))

答案 2 :(得分:1)

我曾经在AS3中做过基本相同的事情,但这个概念转移到了Java。我决定创建两个主要值来帮助跟踪移动,一个Point包含玩家的x / y值(通过tile),以及一个方向Point指向运动的方向。这是一些伪代码:

if(direction.x == 0 && direction.x == 0) {
    if (up) direction.y = -1;
    else if (down) direction.y = 1;
    else if (left) direction.x = -1;
    else if (right) direction.x = 1;
} else {
    player.x += direction.x;
    player.y += direction.y;
    distance--;
    if(distance == 0) {
        direction.x = direction.y = 0;
        distance = tileWidth;
    }
}

显然,你必须调整它以满足你的需求,但这是基础知识。此外,tileWidth可以替换为整数文字,该文字只等于单个图块的宽度。