0

我正在使用 JavaScript 开发一个非常小的项目,只是为了帮助我从下往上理解画布。我现在尽量避免使用框架之类的东西,这样我才能理解 HTML5 游戏的基本功能。

这是一个相当基本的“光标移动器”,带有一条褪色的尾巴。而已。只是一种颜色的形状,根据玩家的输入四处移动,尾巴逐渐消失。我建议你试试看;它实际上很漂亮。

无论如何,显然我更喜欢光标是一个圆圈,因为它看起来更平滑。但是,每当我这样做时,浏览器几乎完全锁定了我。它显然有效,至少在很大程度上有效,但它比一只乌龟跑过冷冻花生酱要慢。

我知道我不应该只包含JSFiddle,但它的代码量很大,而且整个事情运行缓慢。

问题很可能出在绘图功能中:

Game.draw = function() {
    for (var sn = 0; sn < this.strokes.length; sn++) {
        var s = this.strokes[sn];
/*1*/   this.context.arc(s.x, s.y, this.cursorRadius, 0, 2 * Math.PI);
        this.context.fillStyle = this.bgColor;
/*2*/   //this.context.fillRect(s.x, s.y, this.cursorWidth, this.cursorHeight);
/*1*/   //this.context.fill();
        this.context.fillStyle = s.getColor();
/*2*/   //this.context.fillRect(s.x, s.y, this.cursorWidth, this.cursorHeight);
/*1*/   this.context.fill();
    }
};

这些线由方法标记。1 对应于圆形,而 2 对应于矩形。

这是整个项目:http: //jsfiddle.net/w4Rg3/3/

我只是觉得很难相信有圈子会慢得多(在看到 JS可以做的所有项目之后),而且我可能做错了什么。

4

2 回答 2

1

只是一些观察(哦,不!与正方形相比,绘制圆圈并不是“效率低下”,当然更慢 - 但仍然相当快)不幸的是,你的问题比那个更深。

看来您需要重新考虑计划实施游戏的方式。正如你所说的那样,它运行得比乌龟在冷冻花生酱中运行的速度还要慢。(呵呵,好样的!)

我怀疑这与您设置请求动画帧的方式有关,但真的无法深入调试而不担心我的笔记本电脑会融化并散发出神奇的蓝烟。

我从一个副本中修剪了所有的 js,除了 Key 变量和 2 次调用来为 keyup 和 keydown 添加事件侦听器。这给我留下了以下信息:

<!DOCTYPE HTML>
<html>
<head>
<title>flowing</title>
<script>

var Key = 
{
    _pressed: {},

    SPACE: 32,
    LEFT: 37,
    UP: 38,
    RIGHT: 39,
    DOWN: 40,

    isDown: function(keyCode) {
        return this._pressed[keyCode];
    },

    onKeydown: function(event) {
        this._pressed[event.keyCode] = true;
        console.log(this._pressed[event.keyCode]);
    },

    onKeyup: function(event) {
        delete this._pressed[event.keyCode];
        console.log(this._pressed[event.keyCode]);
    }
};
window.addEventListener('keyup', Key.onKeyup, false);
window.addEventListener('keydown', Key.onKeydown, false);

</script>
<style>
</style>
</head>
 <!-- canvas gets inserted here by js -->
<body >
</body>    
</html>

它爆炸了,大时代!

你看,事情是——当你像这样附加一个事件监听器时,只要你在处理程序中,'this'关键字实际上对应于触发事件的 HTML 元素。那么,这到底是什么意思呢?

里面的3个函数可以扩展为:

  1. 返回窗口._pressed[keyCode];
  2. window._pressed[event.keyCode] = true;
  3. 删除 window._pressed[event.keyCode];

唯一的问题是,窗口对象没有 _pressed 变量。变量 Key 有。

您应该打开您正在使用的任何浏览器的开发者工具控制台。在 Chrome、FF 和 Opera 中是 Ctrl-Shift-I,在 IE 中是 F12。

这将立即突出显示诸如此类的错误。

我会看看我是否找不到冰山,这样我就可以继续测试,而不必担心不得不购买新的 lappy。

[编辑:] Game.draw 的新代码

Game.draw = function() 
{
    for (var sn = 0; sn < this.strokes.length; sn++) 
    {
        var s = this.strokes[sn]; /*1*/
        this.context.beginPath();
        this.context.arc(s.x, s.y, this.cursorRadius, 0, 2 * Math.PI);
        this.context.fillStyle = s.getColor(); //.bgColor; /*2*/
        this.context.closePath();
        this.context.fill();
    }
};

绘制圆弧涉及路径。要正确使用路径,您需要在开始定义路径时告知 canvas 元素,并在完成定义路径时再次告知。我猜浏览器只是以“所有路径之母”结束,这很自然地花了很长时间才能绘制出来。当然,您的路径非常简单,只是简单的圆圈。随着画布的状态机根据我们的意图正确更新,无论我们绘制圆形还是正方形,代码的响应能力似乎没有什么不同。希望这是你问题的根源。:)

于 2012-11-08T05:05:34.240 回答
1

每个人!我发现了问题!这与我的游戏结构或任何特别挑剔的东西无关。只是一个 API 问题!

问题确实存在于我在第一篇文章中的问题中的代码示例中。

Game.draw = function() {
    for (var sn = 0; sn < this.strokes.length; sn++) {
        var s = this.strokes[sn];
/*1*/   this.context.beginPath();  /*THIS IS FIXED*/
/*1*/   this.context.arc(s.x, s.y, this.cursorRadius, 0, 2 * Math.PI);
/*1*/   this.context.closePath();  /*THIS IS FIXED*/
        this.context.fillStyle = this.bgColor;
/*2*/   //this.context.fillRect(s.x, s.y, this.cursorWidth, this.cursorHeight);
/*1*/   this.context.fill();
        this.context.fillStyle = s.getColor();
/*2*/   //this.context.fillRect(s.x, s.y, this.cursorWidth, this.cursorHeight);
/*1*/   this.context.fill();
    }
};

我确保用“这是固定的”注释标记我添加的行。我假设它以前只是创建一个非常非常长的弧线并一遍又一遍地绘制它,但谁知道呢?无论如何,问题解决了,它看起来很漂亮。

于 2012-11-10T09:25:03.093 回答