角色的更新

角色对象的update方法接受时间步长、状态对象和keys对象作为参数。Lava角色类型忽略keys对象。

  1. Lava.prototype.update = function(time, state) {
  2. let newPos = this.pos.plus(this.speed.times(time));
  3. if (!state.level.touches(newPos, this.size, "wall")) {
  4. return new Lava(newPos, this.speed, this.reset);
  5. } else if (this.reset) {
  6. return new Lava(this.reset, this.speed, this.reset);
  7. } else {
  8. return new Lava(this.pos, this.speed.times(-1));
  9. }
  10. };

它通过将时间步长乘上当前速度,并将其加到其旧位置,来计算新的位置。如果新的位置上没有障碍,它移动到那里。如果有障碍物,其行为取决于岩浆块的类型:滴落岩浆具有reset位置,当它碰到某物时,它会跳回去。跳跃岩浆将其速度乘以-1,从而开始向相反的方向移动。

硬币使用它们的act方法来晃动。他们忽略了网格的碰撞,因为它们只是在它们自己的方块内部晃动。

  1. const wobbleSpeed = 8, wobbleDist = 0.07;
  2. Coin.prototype.update = function(time) {
  3. let wobble = this.wobble + time * wobbleSpeed;
  4. let wobblePos = Math.sin(wobble) * wobbleDist;
  5. return new Coin(this.basePos.plus(new Vec(0, wobblePos)),
  6. this.basePos, wobble);
  7. };

递增wobble属性来跟踪时间,然后用作Math.sin的参数,来找到波上的新位置。然后,根据其基本位置和基于波的偏移,计算硬币的当前位置。

还剩下玩家本身。玩家的运动对于每和轴单独处理,因为碰到地板不应阻止水平运动,碰到墙壁不应停止下降或跳跃运动。

  1. const playerXSpeed = 7;
  2. const gravity = 30;
  3. const jumpSpeed = 17;
  4. Player.prototype.update = function(time, state, keys) {
  5. let xSpeed = 0;
  6. if (keys.ArrowLeft) xSpeed -= playerXSpeed;
  7. if (keys.ArrowRight) xSpeed += playerXSpeed;
  8. let pos = this.pos;
  9. let movedX = pos.plus(new Vec(xSpeed * time, 0));
  10. if (!state.level.touches(movedX, this.size, "wall")) {
  11. pos = movedX;
  12. }
  13. let ySpeed = this.speed.y + time * gravity;
  14. let movedY = pos.plus(new Vec(0, ySpeed * time));
  15. if (!state.level.touches(movedY, this.size, "wall")) {
  16. pos = movedY;
  17. } else if (keys.ArrowUp && ySpeed > 0) {
  18. ySpeed = -jumpSpeed;
  19. } else {
  20. ySpeed = 0;
  21. }
  22. return new Player(pos, new Vec(xSpeed, ySpeed));
  23. };

水平运动根据左右箭头键的状态计算。当没有墙壁阻挡由这个运动产生的新位置时,就使用它。否则,保留旧位置。

垂直运动的原理类似,但必须模拟跳跃和重力。玩家的垂直速度(ySpeed)首先考虑重力而加速。

我们再次检查墙壁。如果我们不碰到任何一个,使用新的位置。如果存在一面墙,就有两种可能的结果。当按下向上的箭头,并且我们向下移动时(意味着我们碰到的东西在我们下面),将速度设置成一个相对大的负值。这导致玩家跳跃。否则,玩家只是撞到某物上,速度就被设定为零。

重力、跳跃速度和几乎所有其他常数,在游戏中都是通过反复试验来设定的。我测试了值,直到我找到了我喜欢的组合。