1

たくさんのテキストを読みたくない人のためにこれを追加するだけで、少なくともこれを読んで写真を見て私の質問を理解してください。
「プレイヤー」と「オブジェクト」の間に衝突を設定したので、「プレイヤー」が「オブジェクト」の「左」に当たると、「プレイヤー」は「オブジェクト」の「左」に置かれます。(これは私が欲しいものです)。しかし、プレイヤーがオブジェクトの任意の側面 (「上」、「左」、「右」、「下」) を叩いて適切に配置できるようにしたいと考えています。 ブロック衝突の例の画像 上の画像を見ると、基本的には黒い四角と残りのオブジェクトの間に衝突を作成しようとしています。黒い四角は「プレイヤー」オブジェクト、灰色の四角は番号付きの「壁」オブジェクト、赤い四角は「次のレベル」のオブジェクトです。私はこれを達成しましたが、それはちょっと厄介で、壁オブジェクトを動かすことになると、プレイヤーの衝突も私が望むように機能しなくなりました. とにかく、ここに私の「壁」コードがあります:

var canvasWalls1 = document.getElementById('canvasWalls');
var ctxWalls1 = canvasWalls.getContext('2d');
var walls1 = new Walls1();
var imgSprite = new Image();
imgSprite.src = 'sprite.png';
imgSprite.addEventListener('load',init,false);

WallLeft.prototype.draw = function (){
    ctxWalls1.drawImage(imgSprite,this.srcX,this.srcY,this.width,this.height,this.drawX,this.drawY,this.width,this.height);
this.checkHitPlayer();
};
WallLeft.prototype.checkHitPlayer = function() {
if (this.drawX > player1.drawX &&
this.drawX <= player1.drawX + player1.width &&
this.drawY >= player1.drawY &&
this.drawY < player1.drawY + player1.height) {
player1.isUpKey = false;
player1.isDownKey = false;
player1.isRightKey = false;
player1.isLeftKey = false;
player1.drawX = this.drawX - player1.width - 0.05;
player1.drawY = this.drawY - 0.05;      }
}; 

wall1、2、3などに同じコードをコピーしたところです。誰かがより良い方法を提案できる場合は、これを行うより良い方法があると確信していますか? 同じスプライトを 2 つの異なる場所に描画しようとしましたが、これを適切に実現する方法がわかりません。「壁」オブジェクトが異なる主な理由は、「プレイヤー」オブジェクトが「壁」オブジェクトと衝突する場所に応じて、異なる位置に「プレイヤー」オブジェクトを描画する必要があるためです。プレーヤーが左から飛んできた場合、player1.drawX = walls1.drawX - player width. でもプレイヤーが上から飛んでくると、player1.drawY = walls1.drawY + player1.height. 「壁」オブジェクトですべての衝突を発生させる必要がある理由は、「プレイヤー」オブジェクトが「フィニッシュ」に達するたびにすべての「壁」オブジェクトを再利用するためです。より良いシステムを知っていれば、私が持っているコリジョン システムを使い続けることができるかもしれません。とにかく、「プレイヤー」が「フィニッシュ」オブジェクトに当たったときに何が起こるかを次に示します。

Finish.prototype.checkHitPlayer = function() {
if (this.drawX >= player1.drawX &&
this.drawX <= player1.drawX + player1.width &&
this.drawY >= player1.drawY &&
this.drawY <= player1.drawY + player1.height) {
increaseLevel();
} };
function increaseLevel() {
Level+=1;
if (Level===2) {
drawlevel2(); }
function drawlevel2()
{
player1.drawX = 288;
player1.drawY = 160;
walls1.drawX = 448;
walls1.drawY = 160;
walls2.drawX = 416;
walls2.drawY = 320;
walls3.drawX = 192;
walls3.drawY = 288;
finish1.drawX = 224
finish1.drawY = 96;
}

繰り返しますが、「プレーヤー」と「壁」の間の衝突を達成しましたが、「壁」ごとに個別の関数を作成するだけで、「壁」を別の場所に描画したい場合には機能しません。読みにくいと思われる場合は申し訳ありませんが、関連するコードのみを含めようとしました。どんな助け/提案も大歓迎です。

4

3 に答える 3

2

4 辺すべてからの長方形の衝突の検出

ここに画像の説明を入力

次のように定義された矩形オブジェクトが与えられた場合:

var player={x:0,y:0, w:20,h:20};

var barrier={x:100,y:100, w:50,h:50};

この関数を使用して、2 つの長方形がいずれかの側から衝突しているかどうかをテストできます。

// return true if the 2 rectangles are colliding

function RectsColliding(r1,r2){
        return !(r1.x>r2.x+r2.w || r1.x+r1.w<r2.x || r1.y>r2.y+r2.h || r1.y+r1.h<r2.y);
}

そして、次のように関数を呼び出します。

// test if the player and barrier are colliding

if( RectsColliding(player,barrier){
       console.log(‘BANG’);
}else{
       console.log(‘Congrats…No collision’);
}

多くのバリア オブジェクトがある場合でも、衝突を簡単に確認できます。

var CollisionOccured=false;

for(var i=0;i<barriers.length;i++){
    if(RectsColliding(desiredPlayer,barriers[i])){
        CollisionOccured=true;
    }
} 

return(CollisionOccured);

ここにコードとフィドルがあります: http://jsfiddle.net/m1erickson/sJfbd/

<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>

<style>
    body{ background-color: ivory; padding:20px; }
    canvas{border:1px solid red;}
</style>

<script>
    $(function(){

        var canvas=document.getElementById("canvas");
        var ctx=canvas.getContext("2d");

        var defaultFill="lightgray";
        var defaultStroke="skyblue";

        ctx.fillStyle=defaultFill;
        ctx.strokeStyle=defaultStroke;

        var player={x:0,y:0, w:20,h:20, fill:"black",stroke:"black"};

        console.log(player.fill);

        var barriers=[];
        barriers.push({x:50 ,y:100, w:40,h:30});
        barriers.push({x:200,y:230, w:20,h:20});
        barriers.push({x:150,y:100, w:20,h:20});
        barriers.push({x:150,y:200, w:20,h:20});
        barriers.push({x:240,y:25,  w:10,h:150});

        drawAll();


        function drawAll(){
            ctx.clearRect(0,0,canvas.width,canvas.height);
            for(var i=0;i<barriers.length;i++){
                drawRect(barriers[i]);
            }
            drawRect(player,player.fill,player.stroke);
        }


        function drawRect(r,fill,stroke){
            ctx.beginPath();
            ctx.rect(r.x,r.y,r.w,r.h);
            ctx.closePath();
            ctx.fillStyle=fill||defaultFill;
            ctx.fill();
            ctx.strokeStyle=stroke||defaultStroke;
            ctx.stroke();
        }


        function movePlayer(desiredMoveX,desiredMoveY){

            // calculate where the player would like to be
            var desiredPlayer={
                x:player.x+desiredMoveX,
                y:player.y+desiredMoveY,
                w:player.w,
                h:player.h,
                fill:"black",
                stroke:"black"
            }

            // to start, set the move to be allowed
            var allowMove=true;

            // check every barrier for collisions
            for(var i=0;i<barriers.length;i++){
                // if the desiredPlayer has collided with a barrier
                // set the allowMove flag to false
                if(RectsColliding(desiredPlayer,barriers[i])){
                    allowMove=false;
                }
            }

            // if the move is allowed, return the desiredPlayer position
            // if the move is not allowed, return the old player position
            if(allowMove){
                player=desiredPlayer;
                player.stroke="black";
            }else{
                player.stroke="red";
            }

            // redraw the screen
            drawAll();

        }


        // return true if the 2 rectangles are colliding
        function RectsColliding(r1,r2){
            return !(r1.x>r2.x+r2.w || r1.x+r1.w<r2.x || r1.y>r2.y+r2.h || r1.y+r1.h<r2.y);
        }


        $(document).bind("keydown",function(event) {

            switch(event.which){
                case 37:
                    movePlayer(-1,0);
                    break;
                case 39:
                    movePlayer(1,0);
                    break;
                case 38:
                    movePlayer(0,-1);
                    break;
                case 40:
                    movePlayer(0,1);
                    break;
                default:
                    break;
            }

        });


    }); // end $(function(){});
</script>

</head>

<body>
    <p>Use arrowkeys to move player (black box)</p>
    <p>Player's outline will become red if hitting barrier</p>
    <canvas id="canvas" width=300 height=300></canvas>
</body>
</html>
于 2013-07-30T06:27:20.120 に答える
0

画面の x/y 座標と、衝突可能な各オブジェクトの高さと幅を確認できます。

コライダー x/y が特定の範囲内にある場合、衝突がトリガーされます。

(ただし、それはブロックに対してのみ機能します)

役立つかもしれないフィドルを見つけました:

http://jsbin.com/imofat/660/edit

于 2013-07-29T20:24:25.090 に答える
0

そこで、私がやろうとしていることに対して機能する方法を見つけました。(player1.x >= wall1.x && player1.Y===walls1.Y)プレイヤーのさまざまな側面に 4 つのオブジェクトを配置することになったとき、プレイヤーの X 値は壁よりも高く、別の壁よりも低くする必要があるため、または似たようなものを使用することはできません 。Y 値と同じです。(これも途切れ途切れになります。)とにかく、私が使用したものは次のとおりです。

Player.prototype.checkHitWall = function() {
this.TopY = this.drawY; this.BottomY = this.drawY + this.height; this.LeftX = this.drawX; this.RightX = this.drawX + this.width;
if (this.LeftX===walls1.x + walls1.width - 16 && this.drawY===walls1.y) //If player  flys in from the RIGHT of wall1
{
player1.isUpKey = false; player1.isDownKey = false; player1.isRightKey = false; player1.isLeftKey = false;
upkey = false;
rightkey = false;
downkey = false;
leftkey = true;
this.drawX = walls1.x + walls1.width;
this.drawY = walls1.y;

次に、プレイヤーが壁にぶつかったとき、またはゲームが再起動したときに leftkey = false にする関数を追加しました。-16について疑問に思っている人のために、それは壁の幅の半分なので、私が持っているfpsのために、プレーヤーは壁の隣に配置するために壁の中心にぶつかる必要があります(とにかく推測しています)プレイヤーが壁のオブジェクトの中に入るのを見ると、実際にプレイヤーが完全に壁にぶつかったように見えます。-16 の理由は、プレイヤーがプレイヤーの真上に壁がある状態で左右に移動しようとすると、壁が衝突を検出しないためです。

于 2013-07-31T05:48:25.883 に答える