2

HTML5 と JavaScript で Windows 8 用のゲームに取り組んでいます。「ゴキブリ」オブジェクトを配列に格納するゲームの作業バージョンがあります。私が持っているゲーム コードを Microsoft のサンプル (ここにリンク) に入れようとしています。この例では、保存され、さまざまなクラスで使用されるゲーム状態のオブジェクト リテラルのセットを宣言します。

internal: {
    gamePaused: false,
    gamePhase: "ready",
    speed: 5,
    score: 0,
}

そこにゴキブリ オブジェクトの配列を配置したいと思います。私はできると思った:

roaches: [],

しかし、私が電話すると:

this.state.roaches.push(new Roach());
this.state.roaches.length;

私は得る:

JavaScript runtime error: Unable to get property 'length' of undefined or null reference

私は何を間違っていますか?どうすれば修正できますか?

ナット

追加情報:

さて、ここに私のゴキブリのクラスがあります:

var Roach = WinJS.Class.define( function () {
    this.position.x = Math.random() * gameCanvas.width + 1;
    this.position.y = Math.random() * gameCanvas.height + 1;
    this.squished = false;
    this.image = GameManager.assetManager.assets.roachImage;
},
{
    move: function (speed) {
        // changes position
    },
    squish: function() {

    }
});

これは、別のクラスを含む game.js というファイルにあります。

var Game = WinJS.Class.define(
    null,
{
// other functions
// Called when the game is being prepared to start
    ready: function () {
        // TODO: Replace with your own new game initialization logic
        if (this.isSnapped()) {
            this.state.gamePaused = true;
        } else {
            this.state.gamePaused = false;
        }
        this.state.gamePhase = "ready";
        switch (this.settings.skillLevel) {
            case 0:
                this.state.speed = 3;
                break;
            case 1:
                this.state.speed = 5;
                break;
            case 2:
                this.state.speed = 10;
                break;
        }
        this.state.roaches.push(new Roach());
        this.state.score = 0;
    },
// Main game render loop
    draw: function () {
        this.gameContext.clearRect(0, 0, gameCanvas.width, gameCanvas.height);

        // TODO: Sample game rendering to be replaced

        // Draw the current score
        this.gameContext.fillStyle = "#FFFF99";
        this.gameContext.font = "bold 48px Segoe UI";
        this.gameContext.textBaseline = "middle";
        this.gameContext.textAlign = "right";
        this.gameContext.fillText(this.state.score, gameCanvas.width - 5, 20);

        // update image positions
        // THROWS ERROR HERE
        for (var i = 0; i < this.state.roaches.length; i++) {
            if (!this.state.roaches[i].squished) {

            }
        }

        // Draw a ready or game over or paused indicator
        if (this.state.gamePhase === "ready") {
            this.gameContext.textAlign = "center";
            this.gameContext.fillText("READY", gameCanvas.width / 2, gameCanvas.height / 2);
        } else if (this.state.gamePhase === "ended") {
            this.gameContext.textAlign = "center";
            this.gameContext.fillText("GAME OVER", gameCanvas.width / 2, gameCanvas.height / 2);
        } else if (this.state.gamePaused) {
            this.gameContext.textAlign = "center";
            this.gameContext.fillText("PAUSED", gameCanvas.width / 2, gameCanvas.height / 2);
        }
    }

ここで、gameState.js というファイルで、前に参照した変数を保持する gameState クラスが定義されます。

var GameState = WinJS.Class.define(
    null,
{
    config: {
    // TODO: Adjust these values to configure the template itself
        frameRate: 20, // Set to 0 to have no update loop at all
        minSquished: 20,
        currentPage: "/html/homePage.html",
        gameName: "SDK Game Sample", // Used by share contract on scores page
    },

    // TODO: Replace these public settings exposed on the settings panel
    external: {
        playerName: "Player",
        soundVolume: 100,
        skillLevel: 0,
    },

    // TODO: Replace these values with state variables relevant for your game
    internal: {
        gamePaused: false,
        gamePhase: "ready",
        roaches: [],
        speed: 5,
        score: 0,
    },

これらのファイルは、ファイルから各クラスを呼び出し、その名前空間の下にそれらを作成する GameManager 名前空間の下で組み立てられます。したがって、ユーザーがゲームを開始すると、GameManager によって ready 関数が呼び出され、次に draw 関数が呼び出されて画面が更新されます。うまくいけば、これが明確にするのに役立ちます。

名前空間は次のように定義されています。

 var game = new Game();
 var touchPanel = new TouchPanel();
 var state = new GameState();
 state.load();

WinJS.Namespace.define("GameManager", {
        navigateHome: navigateHome,
        navigateGame: navigateGame,
        navigateRules: navigateRules,
        navigateScores: navigateScores,
        navigateCredits: navigateCredits,
        showPreferences: showPreferences,
        onBeforeShow: onBeforeShow,
        onAfterHide: onAfterHide,
        game: game,
        state: state,
        assetManager: assetManager,
        scoreHelper: scoreHelper,
        gameId: gameId,
        touchPanel: touchPanel
    });
4

1 に答える 1

0

オブジェクトリテラルに書き込んでからデータを読み返し、エラーが発生するという同様の問題がありました。どうやら、これは 2 つの例で灰色の領域です。

  1. キー/値のペアは、ドット表記を使用して追加されます
  2. オブジェクトリテラルは非同期でアクセスされます

最初のケースでは、仕様は読み取り操作が機能することを保証していません。2 番目のケースでは、次の方法でアクセスを処理する必要があります。

  • 複数のコールバック
  • 複数のデータ型を処理するコールバック

シンプルなワンライナーでテストできます:

 var foo = {}; foo["bar"] = []; setTimeout(function(){foo.bar.push(new Date); console.log('Hi ' + foo.bar.length)}, 5000);

参考文献

于 2014-05-05T21:49:39.193 に答える