我在尝试通过检查每条路径的前端(移动端)所触及的颜色来实现碰撞检测系统时遇到问题。我已经尝试了数组方法但是失败了 - 我对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>
感谢
答案 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>
目前,这只是在发生碰撞时登录到控制台,但显然您可以根据需要将条件语句集成到此中。