【问题标题】:Mysterious Typescript error神秘的打字稿错误
【发布时间】:2012-12-13 22:03:33
【问题描述】:

我正在尝试用 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 的具体实现中,并根据其规范进行更新。

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

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

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

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

更新: 注释掉gameObjects.forEach((object) =&gt; object.update(elapsedTime)); 后,项目编译没有错误。 VisualStudio 说“构建成功”并打开 Chrome。但页面从未完成加载。即使我输入了这个,我什至看不到 html 文件中的文本。

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

【问题讨论】:

  • 我会修剪一下,谢谢提示
  • 我已将长文件路径替换为 ...
  • 我的意思是命令被截断导致编译器混乱。
  • 嗯,如果我注释掉对 gameObjects.forEach(...) 的调用,它编译时不会出错,但页面永远不会加载
  • Jan Dvorak,没有冒犯的意思,但我认为你错了。只需在 while 循环中注释掉该行即可消除编译器错误。现在页面没有加载。为了听从您的建议,我删除了项目中不需要的 app.ts。更少的文件根本没有效果

标签: javascript visual-studio graphics raphael typescript


【解决方案1】:

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

JavaScript 也在基于队列的系统上执行代码,setInterval(fn, delay) 所做的实际上是将函数添加到队列中,以便在遇到延迟时执行(这也是我们在JavaScript)。因此, setInterval(fn, 0) 实际上并没有立即执行代码(尽管它可能看起来这样做),而是将函数添加到队列的顶部,执行队列中的其他代码,然后执行您的函数当它到达时(因此,如果您正在评估执行时间,取决于代码中发生的所有事情,您的代码可能不会像您指定的那样在 0 毫秒执行)。

也正因为如此,如果您试图以一致的帧速率实现游戏循环,则不应依赖 setInterval 函数的“延迟”参数,因为这甚至可能因浏览器而异。如果帧速率一致性在您的游戏中很重要,您应该跟踪自己的时间间隔和已用时间。

【讨论】:

  • 感谢有关 setInterval 的提示。我将 elapsedTime 传递给每个更新调用。但我不明白 window.onload 中的无限循环如何阻止页面加载。如果我没记错的话,window.onload 在页面加载完成后就被调用了,那么为什么没有显示 html 文本呢?
  • 我对 jQuery 进行了同样的尝试,它运行良好。用 $ 替换 window.onload 后,即使循环加载了页面。我猜这个问题只是javascript的怪癖之一。这样问题就完全解决了,我很乐意接受你的回答
猜你喜欢
  • 2018-04-21
  • 2014-12-14
  • 2015-03-13
  • 2017-04-20
  • 2014-06-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多