2

私のウェブプログラミングコースには、JavaScriptで小さなゲームを作ることになっている小さなプロジェクトがあります。これがゲームです。2 つの大砲がゲーム空間の両端に固定されています。大砲は交互に互いに発砲し、プレイヤーは大砲をある程度傾けて、砲弾を発射する力を選択します。他にも色々考えているので、時間があれば追記します。

http://www.rodedev.com/tutorials/gamephysics/という素敵なサイトを見つけて、2D 物理学に取り掛かり、いくつかのテストを行いました。以下のコードを参照してください。ただし、2 つの大きな問題があります。

  1. 平らでない床/地面。
  2. 回転!

現在、スクリプトは floorDiv の style.top 値のみをチェックしているため、ボックスは常にこのピクセル行に「着陸」します。高さが可変の地形が必要な場合、これでは十分ではありません。これをどのように達成できるかについて、皆さんからのアイデアはありますか? 特定のピクセルの色を確認する方法はありますか? もしそうなら、空や地面以外の色のピクセルをチェックして、これを着陸基準にすることができます。

プレイヤーが照準を調整できるように、大砲を回転させる必要があります。大砲の「ベース」と大砲のバレルという 2 つの異なる大砲オブジェクトを作成しようと考えています。次に、プレイヤーがキーを押したときに大砲のバレルを回転させるだけです。残念ながら、ウェブプログラミングではローテーションは難しいようです。http://code.google.com/p/jquery-rotate/で、この jquery プラグインを見つけました。、しかし、私はそれをうまく機能させていません。砲弾が写真の中心にあることを確認しましたが、回転だけでなく、移動もいくつかあります。これは、画像が中心を中心に回転していないためではないでしょうか。以下のローテーション テスト コードを参照してください (コードを試してみたい場合は、ローテーション プラグインをダウンロードする必要があります)。角度ごとに写真を撮ればいいと思いますが、そうしないと大砲に実際の視覚的な変化がないので、それはちょっと無駄に思えます。

また、複数のオブジェクトを同時にアニメートしたい場合、同じゲームループ関数内のすべてのオブジェクトを変更するだけでよいと思いますか? これに関するアイデアはありますか?

以下は、物理テストのコードです

CSSファイル

#moveDiv {
    position:absolute;
    width:100px;
    height:100px;
    background-color:#000;
}

#floorDiv {
    position:absolute;
    width:800px;
    height:1px;
    background-color:#2E2;
}

table {
text-align:right;

}
table input {
    width:35px;
}

HTMLファイル

<script type="text/javascript">
//global vars
var gravity = 0.5;
var friction = 0.5;
var moving = false;
var moveDiv;
var floorDiv;
var yPos;
var xPos;
var floorPos;
var velocity_y = 0;
var velocity_x = 0;
</script>
</head>

<body onload="initialize();">
<input type="button" value="fall" onclick="fall();"></button>
<input type="button" value="Push" onclick="push();"></button>
<input type="button" value="reset" onclick="reset();"></button>

<table>
<tr>
<td>Angle: <input type="text" value="45" id="angle" /></td>
<td>Speed: <input type="text" value="10" id="speed"/></td>
</tr>
<tr>
<td>Gravity: <input type="text" value="0.5" id="gravity" /></td>
<td>Friction: <input type="text" value="0.5" id="friction" /></td>
</table>

<div id="moveDiv"></div>
<div id="floorDiv"></div>
</body>
</html>

jsファイル

function initialize() {
    moveDiv = document.getElementById('moveDiv');
    floorDiv = document.getElementById('floorDiv'); 

    moveDiv.style.left=400;
    moveDiv.style.top=50;

    floorDiv.style.left=200;
    floorDiv.style.top=400;
}//end initialize

function fall() 
{
    moving=true;
    var angle = 275;
    var rad = angle / (Math.pi * 2);
    var scale_x = Math.cos(rad);
    var scale_y = Math.sin(rad);

    var moveDivSpeed = 0;

    gameLoop();

}//end fall

function push() 
{
    moving=true;
    var angle = document.getElementById('angle').value;
    var rad = angle / (Math.PI * 2);
    var scale_x = Math.cos(rad);
    var scale_y = Math.sin(rad);
    var moveDivSpeed = document.getElementById('speed').value;
    friction = document.getElementById('friction').value;
    gravity = document.getElementById('gravity').value;
    velocity_x = moveDivSpeed*scale_x;
    console.log("original velocity_x is " + velocity_x);
    velocity_y = moveDivSpeed*scale_y;
    gameLoop();
}

function gameLoop () {
    //console.log("gameLoop start");
    var len = moveDiv.style.top.length;
    var presentTop = parseInt(moveDiv.style.top.substr(0, len-2));

    var lenX = moveDiv.style.left.length;
    var presentLeft = parseInt(moveDiv.style.left.substr(0, lenX-2));

    var len2 = floorDiv.style.top.length;
    var floorTop = parseInt(floorDiv.style.top.substr(0, len2-2));

    if (moving == true) 
    {
        velocity_y -= gravity;

        if ((presentTop+100) - velocity_y < floorTop) 
        { //if moveDiv hasn't hit the floor yet...
            moveDiv.style.top = presentTop - velocity_y;
            moveDiv.style.left = presentLeft + velocity_x;
        }
        else if (presentTop + 100 == floorTop) //if moveDiv is ON the floor
        {
            velocity_x = velocity_x*(1-friction);
            moveDiv.style.left = presentLeft + velocity_x;
            console.log("on the floor");
            console.log("friction is " + friction);
            console.log(" and velocity_x is " + velocity_x);
            console.log("moveDiv.style.left is " +moveDiv.style.left);

            if (velocity_x <= 1)
            {
                console.log("stopped moving");
                moving = false;
            }

        }
        else //if moveDiv will hit the floor/go through the floor this time
        {
            var diff = floorTop - (presentTop + 100);
            moveDiv.style.top = presentTop + diff;
            moveDiv.style.left = presentLeft + velocity_x;
        }
    }
    else if (moving == false) 
    {
        clearTimeout(runAgain);
        console.log("else if moving == false");
        return false;
    }

    var runAgain = setTimeout("gameLoop()", 5);
    //console.log("end of gameLoop");
    return false;
}//end gameLoop

function reset () {
    moving = false;

    moveDiv.style.left=400;
    moveDiv.style.top=50;

    floorDiv.style.left=200;
    floorDiv.style.top=400;
}//end reset

ローテーション テストのコード (html ファイルとローテーション プラグインのみ)

<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script type="text/javascript" src="jquery.rotate.1-1.js"></script>
<script type="text/javascript">
    $(document).ready(function() {

        $("#hide").click(function() {
            $("p").hide(500);
            $(".box").animate({height:300, opacity:0}, 1000);
        });

        $("#show").click(function() {
            $("p").show(500);
            $(".box").animate({height:100, opacity:100}, 1000);
        });

        $(".box").mouseenter(function() {
            $(".box").animate({height:300, opacity:0}, 500);
        });

        $(".box").mouseleave(function() {
            $(".box").animate({height:100, opacity:10}, 1000);
        });

        $("#move").click(function() {
            $("#grey").animate({left: -300, top: -100}, 1000)
            .animate({left: -600, top: 200}, 1000);
        });

        $("#cannonball").click(function() {
            $("#cannonball").animate({"left": "+=300", "top": "-=100"}, 500)
            .animate({"left": "+=300", "top": "+=100"}, 500);

        });

        $("p.fading").css("opacity","0.3");
        $("p.fading").hover(function() {
            $(this).stop().animate({opacity: 1.0}, "slow");}, 
                function () {
                $(this).stop().animate({opacity: 0.3}, "slow");
            });

        $("#rotateRight").click(function() {
            $("#cannonball").rotate(10);
        });

    }); //end jquery document.ready scripts

function initialize () {
    document.getElementById('box').style.top = 250;
}
</script>

<style type="text/css">
body {
    background-color: #ccc;
}

.box {
    background-color: #000;
    width:100px;
    height:100px;
    margin-left:300px;
}

.divMove {
    position:relative;
    top:350px;
    float:right;
    background-color: #ddd;
    width:100px;
    height:100px;
    margin-right:100px;
}   

#cannonball {
    position: relative;
}
</style>
</head>
<body onload="initialize();">
<p>Let's make this disappear and appear.</p>

<button id="hide">Hide</button>
<button id="show">Show</button>
<button id="move">Move</button>
<button id="rotateRight">Rotate+</button>

<div id="box" class="box">
</div>


<div class="divMove" id="grey">
</div>

<img src="http://dl.dropbox.com/u/18833130/Webprogrammering/test/cannonball.png" id="cannonball" border="1" />
<p class="fading">This is a paragraph that fades. Let's see how it looks.</p>
</body>
</html> 

長文でコード量が多くて申し訳ありませんが、やってみたい方は基本的にコピペでいいので、こちらの方が議論しやすいと思いました!

4

1 に答える 1

0

大砲の「ベース」と大砲のバレルという 2 つの異なる大砲オブジェクトを作成しようと考えています。次に、プレイヤーがキーを押したときに大砲のバレルを回転させるだけです。残念ながら、ウェブプログラミングではローテーションは難しいようです。

最も簡単な (現在) のは、CSStransformプロパティを使用することです。

const angleInputElement = document.getElementById('angle');
const degrees = angleInputElement.value;
const barrelElement = document.getElementById('barrel'); // I don't see this in your sample though
barrelElement.style.transform = `rotate(${degrees}deg)`;

また、複数のオブジェクトを同時にアニメートしたい場合、同じゲームループ関数内のすべてのオブジェクトを変更するだけでよいと思いますか? これに関するアイデアはありますか?

この単純な実装では、正常に機能するはずです。

于 2020-05-15T15:35:47.013 に答える