构建HTML5 Canvas / JS游戏

时间:2012-08-21 03:08:17

标签: javascript html5 canvas scroll

我是HTML5 / Canvas / Game编程的新手,但在阅读了几本书之后一直在修补它。我认为我对事情的运作方式有了很好的了解。这个问题提出了几个较小的问题,但总的来说基本上是一个“结构方法”的问题。我不期待详细的回复,但希望这里和那里的小指针:)这里是一个非滚动的链接,目前相当无聊的超级马里奥世界。

Super Mario World Test

注意:控件是左/右和空格键可以跳转。这只是为我刚刚学习的Firefox设置。


我在这一点上做错了吗?

目前我只专注于马里奥如何跑步和跳跃,并认为我已经把它弄得相当不错。硬币盒没有做任何事情,背景只是一个装入外观的图像。这是我的方法,请告诉我这是否有任何完全错误:

  • 允许Mario通过制定2个Y速度(重力和跳跃变量)来跳跃
  • 允许Mario通过1速度(左或右“摩擦力”+加速度)来运行
  • 根据keypress / keydown
  • 使用和定位精灵
  • 我不确定这是否正确,但我正在使用构造函数来构建一个对象,然后在主动画循环中我调用该对象的prototype.draw函数来更新所有变量并重绘对象。
  • 我正在清除每个画布的整个画布
  • 我应该把它分成不仅仅是一个绘制函数,比如Mario.move()吗?
  • 我设置了GroundLevel和JumpLevel变量来创建2个游戏平面。 JumpLevel设置为允许控制Mario可以在飞行中跳跃的高度。这两个地方将允许地面像山一样上升 - 保持重力压倒马里奥的跳跃力与地面相同的距离。
  • 为了清楚起见,所有内容都被分成不同的JS文件,但显然会合并。

前进:

现在我已经完成了马里奥如何移动的设置(我认为还有一些其他的小事我可能会像上升/下降和射击火球一样)。我想我可以解决这个问题,但是当我想到以下内容以及HTML5 / Canvas如何轻松处理这个问题时,我真的很遗憾:

  • 滚动背景(我已尝试设置地面平铺并使用屏幕环绕,但这似乎会导致很多不均匀的问题,因为我在相反的方向移动瓷砖。不幸的是,因为我正在尝试考虑到加速度,这会导致数量下降,导致地面出现间隙。我放弃了这个想法。画布下方的DIV是否是最佳解决方案?

  • 敌人:我会以同样的方式制造敌人并在每个帧中对每个敌人进行碰撞侦测循环吗?

  • 背景框:我试图让马里奥站在后台的盒子上,但我不确定如何处理这个问题。我目前有Mario的边界设置留在画布上,我是否继续扩展这些条件以根据框设置不同的边界?我可以看到屏幕上有几个方框并且这样做会有点疯狂,特别是如果我会对敌人做同样的命中测试?我知道我在这里错过了一些东西......

  • 等级移动:这有点相关。按下右键时,基本上所有级别都需要向左移动。在每个动画帧中,我是否需要跟踪所有可能触及马里奥的位置(让他站在一起的盒子和让他碰撞的敌人)?这似乎会变得有点低效?

感谢大家!我会用结果/解决方案更新这个:)

1 个答案:

答案 0 :(得分:7)

哇,好的。我真的很喜欢你的问题,因为你显然已经对此做了很多思考,但部分因为这是非常宽泛和对话的。你最好找一个论坛来提问这个问题。

......话虽如此,我会按照一点点的顺序回答我有资格获得的几点。 :)

  • 等级移动:这是一种奇怪的(读取:低效)方式。我不会根据屏幕位置进行任何计算:跟踪您的关卡中所有内容的规范的,与相机无关的坐标集,并更新要匹配的视觉效果。这将阻止你遇到奇怪的琐碎问题,其中帧率影响你可以和不能穿过的东西,或导致更慢的计算机让马里奥穿过敌人而不会有时受损。以这种方式跟踪位置将偶然解决许多其他问题。

  • 你绝对应该把它分成多个功能。将移动代码和渲染代码放在同一个地方会让你感到烦恼,特别是通过恶意与你的更新/刷新率进行交互。这基本上意味着每次玩家进行一次棘手的跳跃时,游戏会进行比平时更多的更新,这会使得动画/命中检测等不太可能是均匀的。

  • 敌人:我建议将其与其他所有内容联系起来。对所有事情进行一次命中检测,如果你点击某事,请检查它是什么。您可以尝试通过仅针对自身100像素内的对象检查任何给定实体来优化此操作,但如果您这样做,则需要为每个敌人运行单独的碰撞检测事件。让敌人相互扣通将在计算上更便宜。

编辑:我想澄清关于'水平运动'的第一点。基本上,您想要做的是每次相机都在屏幕上移动每个实体,将所有实体位置存储为相机位置的偏移量(其中)如果相机移动,你仍然有效地移动所有东西。)

你理想的方法是用X / Y坐标存储你的敌人,阻挡,地形位置,这些坐标偏离关卡的绝对左上角(从一开始)。为了渲染一个框架,你需要基本上这样做:(伪代码,因为我们正在讨论一种假设的级别格式!)

function GetVisible(x,width,level_entities_array) {
  for (i = 0; i < count(level_array); i++){
    if (level_entities_array[i][x] > x && level_entities_array[i][x] < x+width) {
      visible_elements[] = level_entities_array[i][x];
    }
  }
return visible_elements;
}
砰的一声,你已经拥有应该在窗口内的所有东西。现在,您从实体的x位置和ZAP中减去相机的x偏移量,您已在画布上找到它的位置。作为一个团队,“因为事情变得真实。”

你会注意到我不打算在Y轴上剔除。这可以通过外推来纠正,我猜你可以处理,因为你已经做到了这一点。如果您想进行任何马里奥式的垂直探索,这将是必要的。

是的,我知道我的伪代码看起来像C#和JavaScript的邪恶爱情。对不起,那就是我晚上11点30分的比赛。 ;)