碰撞检测在一个吨游戏通过颜色

Collision detection in a ton game via colour

本文关键字:游戏 颜色 一个 碰撞检测      更新时间:2023-09-26

我在尝试通过检查每个轨迹的前端(移动端)撞击的颜色来实现碰撞检测系统时遇到了问题。我尝试过数组方法,但失败了-我对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>

谢谢

在这种情况下,您可以使用与轴对齐的边界框方法检测碰撞-详细信息请参见: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>

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