【问题标题】:HTML5 Canvas game optimizationHTML5 Canvas 游戏优化
【发布时间】:2016-11-23 00:35:50
【问题描述】:

以下是我编写的示例代码,只是为了说明我在游戏中处理某些事情:

https://jsfiddle.net/qk7ayx7n/25/

<canvas id = "canvas"></canvas>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>

JS:

var canvas = document.getElementById("canvas");
var ctx=canvas.getContext("2d");
canvas.width = 750; //keeping ratio
canvas.height = 587; //keeping ratio

$('#canvas').css("height", window.innerHeight);
$('#canvas').css("width",  window.innerHeight * 1.277); //keeping the ratio
//and also resizing according to the window(not to overflow)

var board = new Image();
board.src = "https://s21.postimg.org/ko999yaaf/circ.png";
var circle = new Image();
circle.src = "https://s21.postimg.org/4zigxdh7r/circ.png";
ctx.drawImage(board, 0, 0);

var x = 10, y = 10;
ctx.drawImage(circle, x, y);
startMoving();

function startMoving(){
      if(y > 310) return;
    y+=3;
    ctx.clearRect(0,0,750,587);
    ctx.drawImage(board, 0, 0);
      ctx.drawImage(circle, x, y);
    setTimeout(function(){startMoving()}, 30);
}

一点解释:这是一个简单的棋盘游戏。首先,画布本身设置为棋盘尺寸,以便正确获取坐标 X Y(这在这里没有用,但在我的实际游戏中是的)。

然后根据玩家的窗口调整大小,相对于原始棋盘图像的实际比例。保持比例对于图像质量很重要。 现在运动是通过函数中的一个简单计时器完成的,一旦到达某个 X 和 Y,运动就会停止。

在某些浏览器和设备(例如在 Cordova 应用程序上)中,我无法让圆圈的运动在没有中断/滞后的情况下移动,尽管它通常可以正常工作。我知道滞后是由我处理事情的方式造成的,但为什么呢? 另外,我无法保持移动速度恒定 - +3 在每个浏览器中的移动似乎都不一样。

【问题讨论】:

  • 也许看看 requestAnimationFrame(),而不是使用 setTimeout()
  • 介意展示如何使用我的示例集成它?
  • 查看如何节流(每秒 60 帧是一个不错的目标):stackoverflow.com/questions/19764018/… 这是我发现使用画布的随机非节流 jsFiddle,但当然使用您的代码:@987654323 @
  • 与您的问题无关,但不要忘记在对其进行任何操作之前预加载您的图像。

标签: javascript html canvas


【解决方案1】:

在大多数情况下,您应该为基于 JavaScript 的动画使用 requestAnimationFrame 以避免不稳定。使用这种技术,位置是时间的函数,而不是发生了多少执行帧。这样,快速计算机将比慢速计算机拥有更多的动画帧,但您仍会感知到相同的动画速度。例如:

var x = 10, y = 10;

var startPos = 10;
var destPos = 310;
var startTime = Date.now();
var velocity = 0.1; // pixels per millisecond
var distance = destPos - startPos;
var duration = Math.abs(distance) / velocity;

requestAnimationFrame(startMoving);

function startMoving(now) {
  var elapsedTime = Math.min(now - startTime, duration);
  y = startPos + (elapsedTime * velocity);
  ctx.clearRect(0,0,750,587);
  ctx.drawImage(board, 0, 0);
  ctx.drawImage(circle, x, y);

  if (elapsedTime < duration)
    requestAnimationFrame(startMoving);
}

【讨论】:

  • 也许我错了,但是如果我需要图像移动一定距离并且持续时间结束,由于浏览器速度慢,图像只会传送到那里而不是完成它的路线,不是吗?
  • 是的,没错。换句话说,您可以设置动画的长度或速度。如果计算机的速度只够制作 1 个动画帧,那么您将看到的就是这些。不过,这不太可能。
  • 这可能是个问题,因为我需要玩家实际看到他移动到新位置。不过我不介意他有更大的跳跃,每次跳跃都会移动一个 x 像素,慢速浏览器的跳跃会更少。有可能吗?
  • 这正是这段代码的作用。传送只是一个非常慢的浏览器的情况,它只是一个跳跃。我不会被那种边缘条件挂断的。
  • 因为我太累了,无法尝试将它与我的真实代码集成(它很大),我明天会简单地告诉你,不过还是谢谢!
猜你喜欢
  • 2011-12-02
  • 2015-08-05
  • 2013-01-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-04
  • 2011-09-04
  • 2022-01-13
相关资源
最近更新 更多