神秘的打字稿错误

时间:2012-12-28 16:53:35

标签: javascript visual-studio graphics raphael typescript

我正在尝试使用Typescript和RaphaelJs进行一场小游戏。到目前为止,代码很短:

/// <reference path="raphael-2.1.d.ts"/>
window.onload = () => {
    var paper: RaphaelPaper = Raphael(10, 50, 500, 500);
    var time: Date =new Date();
    var now = time.getTime();
    var elapsedTime = time.getTime() - now;
    var gameObjects = new GameObject[];
    var robot =new Robot( paper.rect(10, 10, 100, 100));
    robot.elem.attr("fill", "green");
    gameObjects.push(robot);
    while (true) {

        elapsedTime = time.getTime() - now;
        gameObjects.forEach((object) => object.update(elapsedTime));
        //gameObjects.forEach((object) => object.draw(paper));
    }
}

interface GameObject{
    update(time:number);
}

class Robot implements GameObject{
    public x: number;
    public y: number;
    public elem: RaphaelElement;
    constructor(element: RaphaelElement) { 
        this.elem = element;
        this.x = this.elem.attr("x");
        this.y = this.elem.attr("y");
    }
    public update(time: number) {
        this.x += 1;
        this.y += 1;
        this.elem.attr("x", this.x);
        this.elem.attr("x", this.y);
    }
}

当页面加载完新的RaphaelPaper后,会创建一个GameObjects列表。每个GameObject都需要实现一个方法:update。这个想法是在游戏过程中创建的每个RaphaelElement都存储在GameObject的具体实现中,并根据其规格进行更新。

让我们假设敌人是小蓝色矩形。为了将这些敌人添加到我的游戏中,我会添加一个实现GameObject的类Enemy,并且有一个特殊的更新方法,可以将敌人移向玩家并检查交叉点。机器人对象只是一个非常简单的例子。

代码对我来说似乎很好,VisualStudio标记没有错,但当我尝试运行游戏时,会弹出一条错误消息并通知我:

  

错误1命令“tsc --sourcemap”... strategy go \ game.ts“   “...策略go \ raphael-2.1.d.ts”“...策略go \ app.ts”“退出代码   1. ...策略go \ strategy go.csproj 85 5策略go

我确信这与我的IDE设置无关,因为另一个打字稿/ raphaelJs项目效果很好。不幸的是,我无法从错误消息中获取任何有用的信息。

更新: 注释掉gameObjects.forEach((object) => object.update(elapsedTime));之后,项目编译没有错误。 VisualStudio说“构建成功”并且Chrome打开了。但页面从未完成加载。即使我输入此内容,我甚至都没有看到html文件中的文字。

更新2: 我用window.setInterval交换了while循环,现在错误消失了,页面加载了。但这不是经典的游戏循环。我想知道为什么一个简单的while循环阻止我的页面加载。这似乎是矛盾的,因为while循环是在window.onload中执行的。

1 个答案:

答案 0 :(得分:3)

我不确定您的原始TypeScript错误(您通常可以通过在Visual Studio中构建项目时查看“输出”窗口来查看错误本身),但是为什么您的页面会在一段时间内冻结(true) {}循环是因为你创建了一个无限的阻塞循环。 JavaScript在单线程进程中运行,因此原始循环所做的是阻止窗口中发生的任何其他事情。

JavaScript还在基于队列的系统上执行代码,setInterval(fn,delay)所做的实际上是将函数添加到队列中,以便在命中延迟时执行(这也是我们实现异步编程的方式) JavaScript的)。因此,setInterval(fn,0)实际上不会立即执行代码(虽然它似乎可以这样做),但会将函数添加到队列的顶部,执行队列中的其他代码,然后执行您的函数当它到达它时(所以如果你正在评估执行时间,取决于你的代码中发生的一切,你的代码可能不会像你指定的那样在0ms执行)。

同样正因为如此,如果你想要实现具有一致帧速率的游戏循环,你不应该依赖setInterval函数的'delay'参数,因为这甚至可能因浏览器而异。如果帧率一致性在游戏中很重要,您应该跟踪自己的时间间隔和缩短时间。