通过颜色在吨游戏中进行碰撞检测

时间:2016-09-09 08:20:15

标签: javascript canvas colors collision-detection

我在尝试通过检查每条路径的前端(移动端)所触及的颜色来实现碰撞检测系统时遇到问题。我已经尝试了数组方法但是失败了 - 我对javascript很新。

我想实现一个检查

的碰撞检测方法
grid("cyan",cyan_x,cyan_y)
grid("red",red_x,red_y)
每个框架内的

都会触摸除灰色(背景颜色)以外的任何颜色。如果它触及任何其他颜色,游戏应该调用

if (cyan_x == 0 || cyan_x == 159 || cyan_y == 0 ||cyan_y == 159) {
            red_x = 130;
            red_y = 80;

            cyan_x = 30;
            cyan_y = 80;

            dx = 1;
            dy = 1;

            directionr = "l";
            directionc = "r";

            context.clearRect(0,0,canvas.width,canvas.height);
            redscore = redscore + 1;
        }

或红色小道的等效物。 我的所有代码:

<script>

    //variables
    var canvas, context;
    //current x,y coordinates of each trail within a frame
    var red_x, red_y, cyan_x, cyan_y;
    //how much coordinates change within each frame
    var dx, dy;
    //the direction of each trail
    var directionr;
    var directionc;
    //trail scores
    var redscore, cyanscore;


    //this function is used to draw the individual squares to make a trail
    function grid(color,c,u){
        context.beginPath();
        //note that the 800x800 canvas is broken into 160x160 by multiplying the
        //x,y, values of context.rect by 5
        context.rect(c*5,u*5,5,5);
        context.fillStyle = color;
        context.fill();
        context.closePath();
    }


    function start() {
        startGame();
    }

   //this function runs all the other functions and properly starts the game
    function startGame(){
        setupGame();
        setInterval(playGame,45);
        context.clearRect(0,0,canvas.width,canvas.height);

        redscore = 0;
        cyanscore = 0;
   };

   //when one of the trails score reaches 3 then the game should stop
    function stopGame(){
        context.clearRect(0,0,canvas.width,canvas.height);
   };

   //this function sets uo the games by initialising starting positions etc
    function setupGame() {
        canvas = document.getElementById("canvas");
        context = canvas.getContext("2d");

        red_x = 130;
        red_y = 80;

        cyan_x = 30;
        cyan_y = 80;

        dx = 1;
        dy = 1;

        directionr = "l";
        directionc = "r";

        window.addEventListener("keydown", onKeyDown, true);
    };

    //movement controls
    function onKeyDown(e){

        if (e.keyCode == 37 && directionr != "r") { directionr = "l";} // left arrow pressed
        if (e.keyCode == 38 && directionr != "d") { directionr = "u";} // up arrow pressed
        if (e.keyCode == 39 && directionr != "l") { directionr = "r";} // right arrow pressed
        if (e.keyCode == 40 && directionr != "u") { directionr = "d";} // down arrow pressed

        if (e.keyCode == 65 && directionc != "r") { directionc = "l";} // left arrow pressed
        if (e.keyCode == 87 && directionc != "d") { directionc = "u";} // up arrow pressed
        if (e.keyCode == 68 && directionc != "l") { directionc = "r";} // right arrow pressed
        if (e.keyCode == 83 && directionc != "u") { directionc = "d";} // down arrow pressed

    }


    function playGame(){
        drawCycles();  
    };

    //this function manages each frame - keeping track of score, and ideally would
    //check if collisions occur
    function drawCycles(){

        //draw trails
        grid("red",red_x,red_y);
        grid("cyan",cyan_x,cyan_y);

        //display score
        document.getElementById("redscore").innerHTML = "Red's score: " + redscore;
        document.getElementById("cyanscore").innerHTML = "Cyan's score: " + cyanscore;

        //reset positions when trails hit the edge
        if (red_x == 0 || red_x == 159 || red_y == 0 || red_y == 159) {
            red_x = 130;
            red_y = 80;

            cyan_x = 30;
            cyan_y = 80;

            dx = 1;
            dy = 1;

            directionr = "l";
            directionc = "r";

            context.clearRect(0,0,canvas.width,canvas.height);
            cyanscore = cyanscore + 1;
        }

        if (cyan_x == 0 || cyan_x == 159 || cyan_y == 0 ||cyan_y == 159) {
            red_x = 130;
            red_y = 80;

            cyan_x = 30;
            cyan_y = 80;

            dx = 1;
            dy = 1;

            directionr = "l";
            directionc = "r";

            context.clearRect(0,0,canvas.width,canvas.height);
            redscore = redscore + 1;
        }


        //check if its hitting the edges
        if (directionr == "l" && red_x != 0) { red_x -= dx; };
        if (directionr == "r" && red_x != 159) { red_x += dx; };
        if (directionr == "u" && red_y != 0) { red_y -= dy; };
        if (directionr == "d" && red_y != 159) { red_y += dy; };

        if (directionc == "l" && cyan_x != 0) { cyan_x -= dx; };
        if (directionc == "r" && cyan_x != 159) { cyan_x += dx; };
        if (directionc == "u" && cyan_y != 0) { cyan_y -= dy; };
        if (directionc == "d" && cyan_y != 159) { cyan_y += dy; };

        //scoring system
        if (cyanscore >= 3) {
            document.getElementById("redscore").innerHTML = "Red loses";
            document.getElementById("cyanscore").innerHTML = "Cyan wins";
            stopGame();
        }

        if (redscore >= 3) {
            document.getElementById("redscore").innerHTML = "Red wins";
            document.getElementById("cyanscore").innerHTML = "Cyan loses";
            stopGame();
        }
   }; 


</script>

感谢

1 个答案:

答案 0 :(得分:0)

您可以使用轴对齐的边界框方法在此场景中检测到碰撞 - 详见:https://developer.mozilla.org/en-US/docs/Games/Techniques/2D_collision_detection

以下是一个例子:

if (rect1.x < rect2.x + rect2.width &&
    rect1.x + rect1.width > rect2.x &&
    rect1.y < rect2.y + rect2.height &&
    rect1.height + rect1.y > rect2.y) {
    // Collision detected!
}

值得注意的是,这种方法仅限于同一轴上的矩形 - 它们无法旋转。

以下是集成到代码中的简单示例:

<!DOCTYPE html>
<html>
<head>
	<title>CC</title>
	<style type="text/css">
		#canvas {
			border:  1px solid #ccc;
            background-color: #ccc;
		}
	</style>
</head>
<body>

<div><span id="redscore"></span> | <span id="cyanscore"></span></div>
<canvas id="canvas"></div>

<script>
    //variables
    var canvas, context;
    //current x,y coordinates of each trail within a frame
    var red_x, red_y, cyan_x, cyan_y;
    //dimensions of the rectangles
    var red_width, red_height, cyan_width, cyan_height;
    //how much coordinates change within each frame
    var dx, dy;
    //the direction of each trail
    var directionr;
    var directionc;
    //trail scores
    var redscore, cyanscore;



    //this function is used to draw the individual squares to make a trail
    function grid(color,c,u){
        //note that the 800x800 canvas is broken into 160x160 by multiplying the
        //x,y, values of context.rect by 5
        context.fillStyle = color;
        context.fillRect(c*5,u*5,10,10);
    }


    function start() {
        startGame();
    }

   //this function runs all the other functions and properly starts the game
    function startGame(){
        setupGame();
        setInterval(playGame,45);
        context.clearRect(0,0,canvas.width,canvas.height);

        redscore = 0;
        cyanscore = 0;
   };

   //when one of the trails score reaches 3 then the game should stop
    function stopGame(){
        context.clearRect(0,0,canvas.width,canvas.height);
   };

   //this function sets uo the games by initialising starting positions etc
    function setupGame() {
        canvas = document.getElementById("canvas");
        context = canvas.getContext("2d");

        context.canvas.width  = 800;
        context.canvas.height = 800;

        red_x = 130;
        red_y = 80;

        cyan_x = 30;
        cyan_y = 80;

        red_width = 10;
        red_height = 10;

        cyan_width = 10;
        cyan_height = 10;

        dx = 1;
        dy = 1;

        directionr = "l";
        directionc = "r";

        window.addEventListener("keydown", onKeyDown, true);
    };

    //movement controls
    function onKeyDown(e){

        if (e.keyCode == 37 && directionr != "r") { directionr = "l";} // left arrow pressed
        if (e.keyCode == 38 && directionr != "d") { directionr = "u";} // up arrow pressed
        if (e.keyCode == 39 && directionr != "l") { directionr = "r";} // right arrow pressed
        if (e.keyCode == 40 && directionr != "u") { directionr = "d";} // down arrow pressed

        if (e.keyCode == 65 && directionc != "r") { directionc = "l";} // left arrow pressed
        if (e.keyCode == 87 && directionc != "d") { directionc = "u";} // up arrow pressed
        if (e.keyCode == 68 && directionc != "l") { directionc = "r";} // right arrow pressed
        if (e.keyCode == 83 && directionc != "u") { directionc = "d";} // down arrow pressed

    }

    function playGame(){
        drawCycles();  
    };

    //this function manages each frame - keeping track of score, and ideally would
    //check if collisions occur
    function drawCycles(){
        //draw trails
        grid("red",red_x,red_y);
        grid("cyan",cyan_x,cyan_y);

        //display score
        document.getElementById("redscore").innerHTML = "Red's score: " + redscore;
        document.getElementById("cyanscore").innerHTML = "Cyan's score: " + cyanscore;

        // Check for collision
        if (red_x < cyan_x + cyan_width &&
            red_x + red_width > cyan_x &&
            red_y < cyan_y + cyan_height &&
            red_height + red_y > cyan_y) {
            
            console.log('Collision detected!');
        }

        if (cyan_x == 0 || cyan_x == 159 || cyan_y == 0 ||cyan_y == 159) {
            red_x = 130;
            red_y = 80;
        
            cyan_x = 30;
            cyan_y = 80;
        
            dx = 1;
            dy = 1;
        
            directionr = "l";
            directionc = "r";
        
            context.clearRect(0,0,canvas.width,canvas.height);
            redscore = redscore + 1;
        }

        //reset positions when trails hit the edge
        if (red_x == 0 || red_x == 159 || red_y == 0 || red_y == 159) {
            red_x = 130;
            red_y = 80;
        
            cyan_x = 30;
            cyan_y = 80;
        
            dx = 1;
            dy = 1;
        
            directionr = "l";
            directionc = "r";
        
            context.clearRect(0,0,canvas.width,canvas.height);
            cyanscore = cyanscore + 1;
        }

        //check if its hitting the edges
        if (directionr == "l" && red_x != 0) { red_x -= dx; };
        if (directionr == "r" && red_x != 159) { red_x += dx; };
        if (directionr == "u" && red_y != 0) { red_y -= dy; };
        if (directionr == "d" && red_y != 159) { red_y += dy; };

        if (directionc == "l" && cyan_x != 0) { cyan_x -= dx; };
        if (directionc == "r" && cyan_x != 159) { cyan_x += dx; };
        if (directionc == "u" && cyan_y != 0) { cyan_y -= dy; };
        if (directionc == "d" && cyan_y != 159) { cyan_y += dy; };

        //scoring system
        if (cyanscore >= 3) {
            document.getElementById("redscore").innerHTML = "Red loses";
            document.getElementById("cyanscore").innerHTML = "Cyan wins";
            stopGame();
        }

        if (redscore >= 3) {
            document.getElementById("redscore").innerHTML = "Red wins";
            document.getElementById("cyanscore").innerHTML = "Cyan loses";
            stopGame();
        }
   }; 

   start();
</script>
</body>
</html>

目前,这只是在发生碰撞时登录到控制台,但显然您可以根据需要将条件语句集成到此中。