2

2 年前からブラウザで戦略ゲームを構築しています。少数の人々によってすでに活発にプレイされているため、実用的なゲームです。私たちの問題は、リソースが不足していることです。基本的にオペラかクロムが欲しい。IE9 は多かれ少なかれプレイできず、Firefox は一部のマップで非常に遅くなる可能性があります。

このゲームは、マップに 64x64 ピクセルの DIV を使用するタイル ベースのトップダウン ゲームです。

現在、最終段階にあり、最適化に注力しています。資源を消費するものの 1 つは、アニメーション化された水です。32 種類の水のタイルがそれぞれ 15 フレームに分割されています。したがって、1.1 MB の 1 つの .gif ファイルに 480 個の 64x64 画像が含まれます。

ここに水へのリンクがあります: http://www.warbarons.com/beta5/terrain/water/water2.gif

私たちのゲームは Fog of War を使用して、RTS ゲームのように見えない敵のユニットや城を隠します。そのため、通常、.gif の上に透明な PNG のレイヤーがあります。

このソリューションは、ブラウザに対して非常に要求が厳しいようです。マップをスクロールして FireFox で水を表示すると、CPU は 25% まで上昇しますが、水が見えないときは約 4 ~ 5% になります。

私は数日間、より良いテクニックのアイデアを得るためにグーグルで検索してきました. これを行うには、スプレッドシートを反復処理するキャンバス タグを使用するか、CSS を使用してスプレッドシートをループする方法が 2 つあります。

これら 2 つのオプションで私が目にする問題は、すべての水のタイルを同期させておく必要があることです。ある波が別の波の前に再生を開始すると、波が同期しなくなり、シームレスな外観が壊れます。

誰かがこれを解決するアイデアを持っているのだろうか?複数の gif アニメーションを使用すると、非同期の問題が発生することはわかっています。

これを行うためにキャンバスを使用するクリーバーの方法はありますか? キャンバスと div を混在させることは可能ですか?それともマップ エンジン全体を変更する必要がありますか?

どんな助けでも大歓迎です。

4

1 に答える 1

1

ちょっとした初心者の回避策と大穴ですが: 準備として、さまざまな種類の水タイルすべてのスプライト シートを作成します。最初のフレームが左側にあり、種類ごとに新しい行が下に下がります。

  • <div>キャンバスの後ろに 'hidden' の 'overflow' 属性を持つ を作成します
  • キャンバスの背景を透明にする
  • div 内では<div>、水タイルに s を使用し、「マージン」属性を調整してマップの位置に一致させることができます
  • それらすべてに「水」というクラス指定と、水タイルのタイプに一致するクラス (「dockleft」、「beachtop」など) を与えます。
  • あなたの<style>要素で、クラスルール「.water」を作ります
  • ルールに 'background-image' 属性を指定し、スプライト シートがどこにあるかにリンクします。
  • 水のタイルの種類ごとに、各タイルの種類に対応するクラス ルールを作成し、スプライト シートの一致する y 位置を指定します。
  • <style>すべてのフレームの背景位置を含む id を持つ新しい要素を作成します
  • すべての背景の x 位置を含む JavaScript 変数を作成します。
  • ゲーム ループ内で、スプライトを変更するたびに変数を 64 ずつ減らします (960 になるまで変数を 0 に設定します)。
  • 変数が変更されたら、変数を使用して、新しい要素のコンテンツを<style>「background-position-x」の新しい CSS ルールに設定します。

うーん。少しはわかっていますが、配列をループしてシステムリソースを使い果たし、各要素を個別に変更するよりはましです (少なくとも私はそう思います)。簡略化されたコード サンプルを次に示します。

<script type="text/javascript">
    var pos = 0; // background-position-x variable

    function loop() {
        document.getElementById('changeMe').innerHTML = ".water{background-position-x:" + pos + "px;}"; //changes the contents of the <style> with the id 'changeMe'
        //changes the <style> with id 'Change'
        pos -= (pos == 960) ? -960 : 64; //assuming your sprite-sheet is oriented horizontally
        setTimeout('loop();', 100);
    }
</script>


<style type="text/css">
    /* Remains unchanged */
    .water {
        width: 64px;
        height: 64px;
    background-image: url('spriteSheet.png');
    }
    .dockleft{
        background-position-y: 420px;

        /* If all of your sprites are on one sheet, you can set the
        'background-position-y' attribute for each type of water tile and 
        give the 'water' class one sprite-sheet url for all of the types */
    }
</style>


<style id="changeMe" type="text/css">
    /* Changed by 'loop()' */
</style>


<body onload="loop();">
    <div class="water dockleft"></div>
</body>
于 2012-01-01T21:46:04.613 に答える