【问题标题】:Javascript canvas "game". Hero mooves only one timeJavascript 画布“游戏”。英雄只移动一次
【发布时间】:2018-10-10 21:03:35
【问题描述】:

我正在尝试在画布中制作简单的游戏。我使用 setTimeout() 函数为英雄制作了动画。我用函数 moove(e) 检查按下的键:

当我第一次按左箭头或右箭头时,一切正常,但随后英雄不动。对代码的任何建议表示赞赏。

var cns = document.getElementById("can");
cns.height = 600;
cns.width = 300;
var ctx = cns.getContext("2d");
var hero = new Image();
hero.src = "images/hero.png";
hero.onload = function() {
  ctx.drawImage(hero, 120, 570);
  hero.xx = 120;
  hero.yy = 570;
};

var intervalL, intervalR, intervalLL, intervalRR;
var keys = [];

function moove(e) {
  keys[e.keyCode] = (e.type == "keydown");
  if (keys[37]) {
    clearTimeout(intervalR);
    clearTimeout(intervalRR);
    goLeft(hero);
  } else {
    clearTimeout(intervalL);
    clearTimeout(intervalLL);
  }
  if (keys[39]) {
    clearTimeout(intervalL);
    clearTimeout(intervalLL);
    goRight(hero);
  } else {
    clearTimeout(intervalR);
    clearTimeout(intervalRR);
  }
}

function goLeft(img) {
  var x = img.xx,
    y = img.yy;

  function f() {
    ctx.clearRect(img.xx, img.yy, img.width, img.height);
    ctx.drawImage(img, x, y);
    img.xx = x;
    img.yy = y;
    x -= 1.2;
    if (x < -35) {
      x = cns.width;
    }
  }
  if (!intervalL) {
    intervalL = setTimeout(function run() {
      f();
      intervalLL = setTimeout(run, 5);
    }, 5);
  }
}

函数 goRight 与 goLeft 类似。

函数 moove 在标记体中调用 onkeydown='moove(event)' onkeyup='moove(event)'。

您可以在这里查看项目:https://github.com/Fabulotus/Fabu/tree/master/Canvas%20game%20-%20dodge%20and%20jump

【问题讨论】:

  • 什么叫moove函数?在您的代码示例中看到这一点会很有帮助。什么时候向keys 数组添加值?
  • 在正文中调用。已编辑。

标签: javascript canvas


【解决方案1】:

它第一次不起作用的原因是因为第一次通过您将位置设置为之前的位置 (x = image.xx),然后在绘制后更新 x。你应该在调用drawImage之前更新x值x -= 1.2

【讨论】:

  • 这个函数每5ms调用一次,所以我什至没有注意到,对吧。我的意思是,这个代码只有在我第一次按右箭头或左箭头时才有效,但当我第二次按它时,英雄就站着。我认为问题在于我在 keyup 和 keydown 事件上调用了相同的函数。
  • 哦,是的,这是真的。
【解决方案2】:

这是您的代码的“工作”版本:

var cns = document.getElementById("can");
cns.height = 170;
cns.width = 600;
var ctx = cns.getContext("2d");
var hero = new Image();
hero.src = "http://swagger-net-test.azurewebsites.net/api/Image";
hero.onload = function() {
  ctx.drawImage(hero, cns.width-10, cns.height/2);
  hero.xx = cns.width-10;
  hero.yy = cns.height/2;
};

var intervalL, intervalR, intervalLL, intervalRR;
var keys = [];


function goLeft(img) {
  function f() {
    ctx.beginPath()
    ctx.clearRect(0, 0, cns.width, cns.height);
    ctx.drawImage(img, img.xx, img.yy);
    img.xx--;      
    if (img.xx < -img.width) {
      img.xx = cns.width;
    }
  }
  if (!intervalL) {
    intervalL = setTimeout(function run() {
      f();
      intervalLL = setTimeout(run, 5);
    }, 5);
  }
}

goLeft(hero)
&lt;canvas id="can"&gt;

如您所见,function goLeft 已大大简化。

一个建议:避免使用许多setTimeoutclearTimeout,而是使用一个 setInterval 来调用绘制函数,该函数负责绘制游戏中的所有内容,所有其他函数应该只更新游戏对象的位置。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-06-06
    • 1970-01-01
    • 2016-03-11
    • 2015-09-30
    • 1970-01-01
    • 1970-01-01
    • 2013-07-02
    • 2013-03-26
    相关资源
    最近更新 更多