2D HTML5 Canvas 游戏:特定的宽度/高度限制了玩家的移动(未实现碰撞)

2D HTML5 Canvas Game: Specific width/height restricts player movement (No collision implemented)

提问人:Undwell 提问时间:11/17/2023 最后编辑:Undwell 更新时间:11/18/2023 访问量:56

问:

问:为什么根据画布的宽度/高度 + 玩家位置,在这些方向上的移动受到限制,我该如何解决这个问题?

正如标题中提到的,我一直在构建一个 2D 画布游戏(一个像神奇宝贝一样的自上而下的生物收集器),在没有实现任何碰撞的情况下,有一个神秘的错误。

该错误阻止我的角色在两个方向上移动,具体取决于角色的起始位置和画布的宽度/高度,即使我能够在被阻止之前移动到这些方向上的某些图块:

  • 上/右

  • 左/下

只有当画布的宽度/高度设置为特定值时,才会发生这种情况,并且我仍然能够在不受影响的两个方向上随心所欲地移动。

我想要的宽度和高度是 360x240,以显示地图的 24x24 像素图块,宽度为 15,高度为 10。尝试使用 720x480(所需尺寸的 2 倍)和 300x200 时,移动不受限制

如果您想测试该 bug,这里有一个指向 bug 存储库的链接: https://github.com/LateSupper/CreatureCollectorBug

我提供了两个不同大小的地图,以在“engine.js”文件中测试此问题。只需切换您要测试的那个。

这是我在 repo 中的示例中不可见的对角线障碍似乎在哪里的图像: Invisible Barrier Visual(玩家从黄色方块开始

我尝试过的事情包括:

  • 控制台记录移动逻辑,以查看它是否仍然触发(确实触发,但没有移动)
  • 将画布的宽度/高度设置为不同的尺寸,结果各不相同,并且大多数具有 3:2 的纵横比尺寸,无法允许在这些方向上移动
  • 创建了不同的地图,根据我的代码逻辑,这些地图会改变玩家的起始位置,并改变哪个方向被阻挡
  • 谷歌搜索。当然,我今天在谷歌上搜索了一下,因为为什么会发生这种情况?我在 HTML Canvas 游戏中遇到的最奇怪的错误。

编辑:根据添加代码的建议,我认为可能会给我带来麻烦:

// "main.js" -> line 1
const game = new GameEngine(
  { width: 24 * 16, height: 24 * 10 }, // Dimensions
  24, // Tile Size
  18 // Camera Offset
)

在上面的代码中,当宽度和/或高度乘以奇数时,移动受到限制,但如果两个数字都是 24 * 偶数,则效果很好。

这可能是我如何将背景/玩家精灵绘制到画布上的问题吗?

// "engine.js" -> GameEngine.determineSpriteProperties()
determineSpriteProperties = (image) => {
  const properties = {
    type: 0,
    position: { x: 0, y: 0 },
    image: image
  }
  if (image.currentSrc.indexOf("map_") > -1) {
    properties.position.x = ((this.canvas.width / 2) - (image.width / 2)) + (this.tileSize / 2),
    properties.position.y = ((this.canvas.height / 2) - (image.height / 2))
  } else {
    properties.type = 1
    properties.position.x = (this.canvas.width / 2 - (image.width / 3)) + ((image.width / 3) / 2)
    properties.position.y = this.canvas.height / 2 - (image.height / 4) + this.cameraOffset
  }
  return properties
}
JavaScript HTML5-Canvas 游戏开发

评论

0赞 Kokodoko 11/17/2023
为了在这里得到一个好的答案,如果你在这里粘贴给你带来问题的确切代码,而不是指向整个项目的链接,那将会有所帮助。代码中的问题之一似乎是移动控制器中嵌套语句的复杂列表。这变成了一个意大利面条代码,通常是导致意外结果的原因。一旦你发现了你的错误到底在哪里,你就可以更好地集中你的问题。if
0赞 Undwell 11/18/2023
@Kokodoko好的,我添加了一些我认为可能是罪魁祸首的代码。
1赞 Helder Sepulveda 11/18/2023
我在 github 上给你发了一个 PR:github.com/LateSupper/CreatureCollectorBug/pull/1/files

答:

1赞 Helder Sepulveda 11/18/2023 #1

问题出在停止运动的条件下......
你有一个声明:
if

this.mapSprite.position.x !== this.targetPosition.position && 
this.mapSprite.position.y !== this.targetPosition.position

...但 也有一个 axis 属性,您没有将其包含在该条件中targetPosition

(targetPosition.axis == "x" && mapSprite.position.x !== targetPosition.position) ||
(targetPosition.axis == "y" && mapSprite.position.y !== targetPosition.position)

(我删除了一些代码以使此示例变小)


有关详细信息,请参阅我的 PR:
https://github.com/LateSupper/CreatureCollectorBug/pull/1

评论

0赞 Undwell 11/18/2023
我感谢帮助和公关!关于我如何重构代码并使其不那么混乱,您有什么建议吗?
1赞 Helder Sepulveda 11/18/2023
@Undwell对未来问题的建议...您需要减少示例代码中的代码,例如,在这个问题上,精灵不是问题,只是分散了对真正问题的注意力,请阅读以下内容: stackoverflow.com/help/minimal-reproducible-example 即使在减少代码的过程中,我们也经常会发现问题
0赞 Undwell 11/18/2023
很好的建议。我会在以后的问题中考虑到这一点。
1赞 Helder Sepulveda 11/18/2023
@Undwell让它不那么混乱?!?也许采用真正的游戏引擎:github.com/collections/javascript-game-engines
1赞 Helder Sepulveda 11/18/2023
有优点也有缺点,100%由你决定......看看每个游戏都是用什么游戏构建的,看看你是否能找到类似的东西