ホームページ >ウェブフロントエンド >jsチュートリアル >ネイティブ JavaScript を使用して簡単なパズル ゲームを実装する方法

ネイティブ JavaScript を使用して簡単なパズル ゲームを実装する方法

不言
不言転載
2018-11-16 16:39:502919ブラウズ

この記事の内容は、ネイティブ JavaScript を使用して簡単なパズル ゲームを実装する方法についてです。必要な方は参考にしていただければ幸いです。 。

1. ゲームの基本ロジック

言語を使用してゲームを開発したい場合は、まずこの言語を使用して基本ロジックを実装する方法を理解する必要があります。描画、インタラクティブ処理、タイマーなど。

1. グラフィック描画

グラフィック描画はすべての基礎です。ここでは JavaScript を使用して canvas に描画します。つまり、まず htmlcanvas 要素を作成し、次に JavaScript でこの要素を id で取得し、canvas で取得します。対応するコンテキスト環境 context が後続の描画のために準備されます。

<canvas id="background" width="450px" height="450px"></canvas>
var background = document.getElementById("background");
var context = background.getContext('2d');

画像は、contextdrawImage メソッドを通じて描画できます。対応するカプセル化はここで実行されます:

注: here 描画する前に画像がロードされるのを待つには、つまり、onloaddrawImage メソッドを呼び出します。そうしないと、描画が失敗します。

var drawImageItem = function(index, position) {
    var img = new Image();
    img.src = './image/dog_0' + String(index+1) + '.jpg';
    img.onload = () => {
        var rect = rectForPosition(position);
        context.drawImage(img, rect[0], rect[1], rect[2], rect[3]);
    }
}

画像を描画した後、ビューを動的に更新する必要があります。そうしないと、canvas は単なる静的な画像になります。単純なグラフィック更新の場合は、元の位置に再描画して上書きするだけです。ただし、新しいグラフィックを描画せずに既存のグラフィックをクリアする必要がある場合もあります。たとえば、ジグソーパズルでは、ブロックを別の位置に移動した後、元の位置をクリアする必要があります。

クリアの目的は、contextclearRect メソッドを通じて実現できます。以下は、canvas の特定の領域をクリアするコードです:

var originRect = rectForPosition(origin);
context.clearRect(originRect[0], originRect[1], originRect[2], originRect[3]);

2. イベント処理

グラフィックを描画した後、プレーヤーの処理も行う必要があります。次に、入力イベントに基づいてビューを更新するタイミングを決定します。入力イベントは、携帯電話のタッチ スクリーン イベント、PC のマウスおよびキーボード イベントの 3 つのタイプに分類できます。

JavaScript でのタッチ スクリーンとマウス クリックの監視は同じであり、両方とも canvasonclick イベントを通じてコールバックされます。

// 屏幕点击
background.onclick = function(e) {
};

e.offsetXe.offsetY を通じて canvas 内のタッチ ポイントの位置を取得できます。

注: canvas の座標原点は左上隅にあります。つまり、左上隅の座標は (0, 0) です。

キーボードのキーのクリックは、documentonkeyuponkeydown などのイベントを通じてコールバックされます。 onkeyup はキーリフト イベントを指し、onkeydown はキーを押すイベントを指します。 keyCode を通じて現在どのキーが押されているかを知ることができ、次に示すように、さまざまなキーに応じてさまざまなロジックを処理します:

if (event.keyCode == '37') {  // 左
    // do something
} else if (event.keyCode == '38') { // 上
    // do something
} else if (event.keyCode == '39') { // 右
    // do something
} else if (event.keyCode == '40') { // 下
    // do something
}

Sometimes 。プレーヤーが入力したときにビューを更新する必要があるため、一定の間隔で定期的にビューを更新する必要もあります。たとえば、ヘビ ゲームでは、ヘビの位置を時々更新する必要があります。

現時点では、ビューを時々更新するコードを実行するタイマーが必要です。

setInterval

メソッドを通じてタイマー関数を実装します。 <pre class="brush:php;toolbar:false">setInterval(&quot;run()&quot;, 100);</pre> 上記のコードは、

run

メソッドが 100 ミリ秒ごとに実行されることを意味します。 2. パズルの基本ロジック

ゲームの基本ロジックとともに、パズルのロジックを実装する方法を見てみましょう。

1. ランダム シーケンスの生成

翻訳によってシーケンスを復元できるわけではないため、単純にランダム シーケンスを生成することはできません。たとえば、シーケンス

1, 0, 2, 3, 4, 5, 6, 7, 8

は、どのように翻訳しても復元できません。 ここで採用される方法は、4 つの削減可能なシーケンスをあらかじめ設定しておき、これら 4 つのシーケンスから 1 つをランダムに選択し、そのシーケンスをいくつかのステップでシミュレートおよび変換します。これは、初期シーケンスの多様性を可能な限り確保し、シーケンスの還元性を確保するために行われます。具体的なコードは次のとおりです:

var setupRandomPosition = function() {
    var list1 = [4, 3, 2, 8, 0, 7, 5, 6, 1];
    var list2 = [2, 0, 5, 6, 8, 7, 3, 1, 4];
    var list3 = [3, 7, 2, 4, 1, 6, 8, 0, 5];
    var list4 = [3, 2, 4, 1, 7, 6, 5, 0, 8];
    var lists = [list1, list2, list3, list4];

    imageIndexForPosition = lists[parseInt(Math.random() * 4)];

    // 获取空位位置
    var emptyPosition = 0;
    for (var i = imageIndexForPosition.length - 1; i >= 0; i--) {
        if (imageIndexForPosition[i] == lastIndex()) {
            emptyPosition = i;
            break;
        }
    }
    background.emptyPosition = emptyPosition;

    // 随机移动次数
    var times = 10;
    while (times--) {
        // 获取随机数,决定空位哪个位置进行移动
        var direction = parseInt(Math.random() * 4);

        var target = -1;
        if (direction == 0) {
            target = topOfPosition(emptyPosition);  // 上
        } else if (direction == 1) {
            target = leftOfPosition(emptyPosition);  // 左 
        } else if (direction == 2) {
            target = rightOfPosition(emptyPosition);  // 右
        } else if (direction == 3) {
            target = bottomOfPosition(emptyPosition);  // 下
        }
        if (target < 0 || target > lastIndex()) {  // 位置不合法,继续下一次循环
            continue;
        }
        var result = moveImageIfCanAtPosition(target);
        if (result >= 0) { // 如果移动成功,更新空位的位置
            emptyPosition = target;
        }
    }
}

2. ブロックを移動できるかどうかを決定します

注文を保存するときに、0 から 8 までの 9 つの数字と空白の四角形を使用します。は8番の場所です。したがって、移動可能かどうかを判断する唯一の条件は、ターゲット位置の値が 8 であるかどうかです。コードは次のとおりです。

var isPositionEmpty = function(position) {
    if (position < 0 || position > lastIndex()) {
        return false;
    } 
    if (imageIndexForPosition[position] == lastIndex()) {
        return true;
    } else {
        return false;
    }
}

上記の

lastIndex()

の値は 8 です。 3. ブロック移動の実装 ブロック移動の実装は非常に簡単です。最初に古い位置のグラフィックを消去し、次に新しい位置に描画します。

var refreshImagePositions = function(origin, target) {
    var originRect = rectForPosition(origin);
    context.clearRect(originRect[0], originRect[1], originRect[2], originRect[3]);
    drawImageItem(imageIndexForPosition[target], target);
}

4. 完了したかどうかを確認する

パターンが復元されたかどうかを確認するには、配列を 1 回走査するだけで、順序どおりであるかどうかを確認できます。

var checkIfFinish = function() {
    for (var index = 0; index < imageIndexForPosition.length; index++) {
        if (index != imageIndexForPosition[index]) {
            return false;
        }
    }
    return true;
}

5、交互事件屏蔽

当图案还原之后,我们不希望玩家还能通过键盘或鼠标来移动方块,这个时候就需要对交互事件进行屏蔽。

只需要一个标志位就可以达到这个目的:

// 屏幕点击
background.onclick = function(e) {
    if (isFinish) {
        return;
    }

    // do something
};

// 键盘按钮事件
document.onkeyup = function(event) {
    if (isFinish) {
        return;
    }

    // do something
}

当图案还原之后,标志位 isFinish 会被置为 true ,然后在屏幕点击和键盘按钮响应事件的开始处添加判断,如果已经结束,则不继续走方块移动的逻辑。

以上がネイティブ JavaScript を使用して簡単なパズル ゲームを実装する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はsegmentfault.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。