- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
由于我的其他错误已解决,我针对此错误发布了一个新问题。
我制作了一个贪吃蛇 Canvas 游戏,但是当您同时按下两个按钮时我的蛇往往会吃掉自己。我不确定如何正确解释它,但事情就是这样:
假设我的蛇向左移动,我按下 + 右,它会吃掉自己并触发游戏结束。当它向右移动时也是如此:向下 + 向左,砰的一声,死了。不过,当蛇上下移动时,我似乎无法重现该错误。
这是改变方向的代码:
bindEvents = ->
keysToDirections =
37 : LEFT
38 : UP
39 : RIGHT
40 : DOWN
$(document).keydown (e) ->
key = e.which
newDirection = keysToDirections[key]
if newDirection
setDirection newDirection
e.preventDefault()
setDirection = (newDirection) ->
# TODO: there's some bug here; try pressing two buttons at the same time..
switch Snake.direction
when UP, DOWN
allowedDirections = [LEFT, RIGHT]
when LEFT, RIGHT
allowedDirections = [UP, DOWN]
if allowedDirections.indexOf(newDirection) > -1
Snake.direction = newDirection
我认为编译后的 JS 有问题,因为我的 switch 语句在最后一个 case
上没有 break
;但是,我尝试将 else return
添加到 CoffeeScript 文件中,但这并没有改变任何东西。我完全迷失在这里所以我希望有人能够发现我哪里出错了。
它似乎正确处理了按键事件,但是当您按下得太快时它们会被覆盖。如果这有意义?就像.. 当蛇向右走时你会向上按,但是在它实际上有机会向上然后它就向左走之前你向左按。乱七八糟的句子,我建议你玩一会儿,如果你和我一样感兴趣的话,试着重现一下:(
我不知道如何正确调试它。当我执行 console.log
时,游戏循环往往会向我发送垃圾邮件。
可以找到现场演示和指向我的 github 存储库的链接 here
提前致谢。
最佳答案
问题在于,如果您按键的速度足够快,则可能会在一帧内多次触发事件回调。因此,如果蛇向下走,它可以在同一帧中向右转然后向上转,从而反转方向吃掉自己。我会建议两种方法来解决这个问题:
首先是在方向改变的时候设置一个flag,即:
if allowedDirections.indexOf(newDirection) > -1 and !turnedThisFrame
Snake.direction = newDirection
turnedThisFrame = true
然后,在运行每一帧的代码中,将 turnedThisFrame
设置为 false
。
第二个是重新设计您处理按键的方式。这通常是我采用的方法。保留按下哪些键的映射(例如,keysDown
),并绑定(bind)一个将 keysDown[e.which] = true
设置为 keydown 的函数和另一个设置 keysDown[e.which] = false
到 keyup。然后,您可以检查在运行每一帧的代码中按下了哪些键,并采取相应的行动。
以下是我如何在当前项目中实现第二个解决方案的一些详细信息。以下代码出现在我的 onload 处理程序中:
do ->
keysDown = []
$(document).keydown (e) ->
keysDown.push e.which
$(document).keyup (e) ->
keysDown = _.without keysDown, e.which
window.isPressed = (keyCode) -> keyCode in keysDown
do ->
构造用于创建一个函数并立即调用它,这具有将 keysDown
保持在处理程序和 闭包中的有益效果isPressed
,同时避免污染 onload
回调的主要范围。
然后,在我的 tick
函数(每帧运行一次并处理游戏逻辑、绘制屏幕等)的开头,我会有这样的东西:
switch Snake.direction
when UP, DOWN
allowedDirections = [LEFT, RIGHT]
when LEFT, RIGHT
allowedDirections = [UP, DOWN]
for direction in allowedDirections
if isPressed(directionToKey[direction])
Snake.direction = newDirection
break
map directionToKey
正好与您的 keysToDirections
相反。
请注意,这意味着 allowedDirections
中首先列出的键将具有优先权,即如果您向右走并在同一帧中同时按下向上键和向下键,则无论先按下哪个键,都会出现向上键.
第二种方法的优势在于:在菜单屏幕和游戏之间切换时,您不必更改按键处理程序回调。您只是有一个不同的 tick
函数来检查按下的内容。
关于javascript - Canvas 游戏 : My snake eats itself,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8012063/
我是一名优秀的程序员,十分优秀!