如何检查 Javascript 中方形画布是否重叠?
How to check if square canvases are overlapping in Javascript?
我正在创建一个游戏,其中黄色方块必须穿过所有其他方块才能到达屏幕顶部。我无法测试方块是否重叠以重置黄色方块。我已经尝试实施在该网站上找到的其他方法,但 none 似乎有效,除非我实施错误。
现在,在方法 intersectRect(i) 中,我正在检查方块的边缘到玩家方块的边缘。
我遇到的另一个错误,虽然不是最重要但值得一提的是,当黄色方块到达屏幕顶部时,分数会上升很多值,而不仅仅是 1。
谢谢。
<html>
<canvas id="gameCanvas" width="800" height="600">
</canvas>
<script>
var canvas;
var canvasContext;
//square variables
var squares = [];
var squareX = [50, 0, 640, 400, 575, 300, 373];
var squareY = [100, 150,200, 250, 300, 350, 400];
var forward = [true, true, true, true, true, true, true];
var interval = [15, 15, 15, 15, 15, 15];
const SQUARE_SIZE = 50;
//player variables
var player;
var playerX = 0;
var playerY = 0;
var intervalPlayer = 0;
const PLAYER_SIZE = 50;
var score = 0;
window.onload = function(){
canvas=document.getElementById('gameCanvas');
canvasContext = canvas.getContext('2d');
function calcMousePos(evt){
var rect = canvas.getBoundingClientRect();
var root = document.documentElement;
var mouseX = evt.clientX - rect.left - root.scrollLeft;
var mouseY = evt.clientY - rect.top - root.scrollTop;
return{
x:mouseX,
y:mouseY
};
}
//get mouse movement
canvas.addEventListener('mousemove', function(evt){
var mousePos = calcMousePos(evt);
playerX = mousePos.x;
playerY = mousePos.y;
});
//update screen
var framesPerSecond = 30;
setInterval(function(){
moveEverything();
drawEverything();
},1000/framesPerSecond);
}
//moves each square based on the interval
function moveEverything(){
for(var i = 0; i < squareX.length; i++){
if(!forward[i]){
forward[i] = false;
if(interval[i] > 0){
interval[i] *= -1;
}
if(squareX[i] < 0){
forward[i] = true;
}
}else if(forward[i]){
if(interval[i] < 0){
interval[i] *= -1;
}
if(squareX[i] > canvas.width - 50)
{
forward[i] = false;
}
}else{
console.log("Error ball " + i);
}
}
}
//draws each square on the background canvas
function drawEverything(){
for(var i = 0; i < squareX.length; i++){
squareX[i] += interval[i];
}
//background
colorRect(0,0,canvas.width,canvas.height, 'salmon');
//score
canvasContext.fillStyle = 'black';
canvasContext.fillText(score, 10, 10);
//red square
squares[0] = colorRect(squareX[0],squareY[0],SQUARE_SIZE,SQUARE_SIZE, 'red');
//blue square
squares[1] = colorRect(squareX[1],squareY[1],SQUARE_SIZE,SQUARE_SIZE, 'blue');
//green square
squares[2] = colorRect(squareX[2],squareY[2],SQUARE_SIZE,SQUARE_SIZE, 'green');
//white square
squares[3] = colorRect(squareX[3],squareY[3],SQUARE_SIZE,SQUARE_SIZE, 'white');
//black square
squares[4] = colorRect(squareX[4],squareY[4],SQUARE_SIZE,SQUARE_SIZE, 'black');
//orange square
squares[5] = colorRect(squareX[5],squareY[5],SQUARE_SIZE,SQUARE_SIZE, 'orange');
//purple square
squares[6] = colorRect(squareX[6],squareY[6],SQUARE_SIZE,SQUARE_SIZE, 'mediumPurple');
//player
player = colorRect(playerX,playerY,PLAYER_SIZE,PLAYER_SIZE,'yellow');
checkContact();
checkWin();
}
//functions to reate rects
function colorRect(leftX, topY, width, height, drawColor){
canvasContext.fillStyle = drawColor;
canvasContext.fillRect(leftX,topY,width,height);
}
function colorCircle(centerX, centerY, radius, color){
//draws ball
canvasContext.fillStyle=color;
canvasContext.beginPath();
canvasContext.arc(centerX,centerY,radius,0,Math.PI * 2, true);
canvasContext.fill();
}
//check for contact between the squares
function checkContact(){
for(var i = 0; i < squareX.length; i++){
if(intersectRect(i))
{
console.log("Overlap");
playerReset();
}
else
{
//none
}
}
//while(playerY < squareY[i] )
}
//check the borders of the squares for contact
function intersectRect(i){
return !(playerX > squareX[i] + 50 ||
playerX + 50 < squareY[i] ||
playerY > squareY[i] + 50 ||
playerY + 50 < squareY[i]);
}
//check if yellow square is at top of square
function checkWin(){
window.setTimeout(function(){
if(playerY < PLAYER_SIZE){
playerReset();
for(var i = 0; i < squareX.length; i++)
{
interval[i] += score/2;
}
score++;
}
},1000);
}
//reset the player to original position
function playerReset(){
playerX = canvas.width/2;
playerY = canvas.height - 50;
}
</script>
感谢您修复我的主要错误。我现在唯一看不到的是创建的暂停方法。这是我修改后的代码的样子。这是一个问题的主要原因是当它重置时,它没有给玩家时间将鼠标移回原处,它只是在鼠标移动后立即转到鼠标。谢谢。
<script>
var canvas;
var canvasContext;
var gamePaused = false;
//square variables
var squares = [];
var squareX = [50, 0, 640, 400, 575, 300, 373];
var squareY = [100, 150,200, 250, 300, 350, 400];
var forward = [true, true, true, true, true, true, true];
var interval = [15, 15, 15, 15, 15, 15, 15];
const SQUARE_SIZE = 50;
//player variables
var player;
var playerX = 0;
var playerY = 0;
var intervalPlayer = 0;
const PLAYER_SIZE = 50;
var score = 0;
//pause game
function unpause() { gamePaused = false } // un pause game
function pauseFor(time = 1000){ // defaults to 1 second
pauseGame = true;
setTimeout(unpause,time);
}
window.onload = function(){
canvas=document.getElementById('gameCanvas');
canvasContext = canvas.getContext('2d');
function calcMousePos(evt){
var rect = canvas.getBoundingClientRect();
var root = document.documentElement;
var mouseX = evt.clientX - rect.left - root.scrollLeft;
var mouseY = evt.clientY - rect.top - root.scrollTop;
return{
x:mouseX,
y:mouseY
};
}
//get mouse movement
canvas.addEventListener('mousemove', function(evt){
var mousePos = calcMousePos(evt);
playerX = mousePos.x;
playerY = mousePos.y;
});
//update screen
var framesPerSecond = 30;
function mainLoop(){
moveEverything();
drawEverything();
requestAnimationFrame(mainLoop); // request the next frame
}
requestAnimationFrame(mainLoop);
}
//moves each square based on the interval
function moveEverything(){
for(var i = 0; i < squareX.length; i++){
if(!forward[i]){
forward[i] = false;
if(interval[i] > 0){
interval[i] *= -1;
}
if(squareX[i] < 0){
forward[i] = true;
}
}else if(forward[i]){
if(interval[i] < 0){
interval[i] *= -1;
}
if(squareX[i] > canvas.width - 50)
{
forward[i] = false;
}
}else{
console.log("Error ball " + i);
}
}
}
//draws each square on the background canvas
function drawEverything(){
for(var i = 0; i < squareX.length; i++){
squareX[i] += interval[i];
}
//background
colorRect(0,0,canvas.width,canvas.height, 'salmon');
//score
canvasContext.fillStyle = 'black';
canvasContext.fillText(score, 10, 10);
//red square
squares[0] = colorRect(squareX[0],squareY[0],SQUARE_SIZE,SQUARE_SIZE, 'red');
//blue square
squares[1] = colorRect(squareX[1],squareY[1],SQUARE_SIZE,SQUARE_SIZE, 'blue');
//green square
squares[2] = colorRect(squareX[2],squareY[2],SQUARE_SIZE,SQUARE_SIZE, 'green');
//white square
squares[3] = colorRect(squareX[3],squareY[3],SQUARE_SIZE,SQUARE_SIZE, 'white');
//black square
squares[4] = colorRect(squareX[4],squareY[4],SQUARE_SIZE,SQUARE_SIZE, 'black');
//orange square
squares[5] = colorRect(squareX[5],squareY[5],SQUARE_SIZE,SQUARE_SIZE, 'orange');
//purple square
squares[6] = colorRect(squareX[6],squareY[6],SQUARE_SIZE,SQUARE_SIZE, 'purple');
//player
player = colorRect(playerX,playerY,PLAYER_SIZE,PLAYER_SIZE,'yellow');
if(! gamePaused ) { // if not pause
// do everything that should not be done during paused game
checkContact();
checkWin();
} else {
// you may want to show that you are waiting from the next round
canvasContext.fillStyle = "black";
canvasContext.textAlign = "center";
canvasContext.fillText("Get ready",canvas.width / 2, canvas.height / 4);
}
}
//functions to reate rects
function colorRect(leftX, topY, width, height, drawColor){
canvasContext.fillStyle = drawColor;
canvasContext.fillRect(leftX,topY,width,height);
}
function colorCircle(centerX, centerY, radius, color){
//draws ball
canvasContext.fillStyle=color;
canvasContext.beginPath();
canvasContext.arc(centerX,centerY,radius,0,Math.PI * 2, true);
canvasContext.fill();
}
//check for contact between the squares
function checkContact(){
for(var i = 0; i < squareX.length; i++){
if(intersectRect(i)){
resetPlayer();
pauseFor(); // pause for default 1 second
break; // this breaks out of the for loop
// no point checking for other hits
// once you found one.
}
}
}
//check the borders of the squares for contact
function intersectRect(i){
return !(playerX > squareX[i] + 50 ||
playerX + 50 < squareX[i] ||
playerY > squareY[i] + 50 ||
playerY + 50 < squareY[i]);
}
//check if yellow square is at top of square
function checkWin(){
if(playerY < PLAYER_SIZE){
gamePaused = true;
score += 1;
resetPlayer(); // reset the player
speedUpSquare(); // create a function that speeds up the squares
pauseFor(); // pause for default 1 second
}
}
function speedUpSquare(){
for(var i = 0; i < squareX.length; i++)
{
interval[i] += score/2;
}
}
//reset the player to original position
function resetPlayer(){
playerX = canvas.width/2;
playerY = canvas.height - 50;
pauseFor();
}
</script>
加分多少?
win 的问题在于您每 30 秒调用一次函数 checkWin
,而在该函数中您除了安排在一秒钟内检查 win 之外什么都不做。我必须 运行 它才能确切地看到发生了什么,但更好的解决方案是执行以下操作
// create a global that pauses the game
// when this is true then you are waiting to start the next play
var gamePaused = false;
function unpause() { gamePaused = false } // un pause game
function pauseFor(time = 1000){ // defaults to 1 second
pauseGame = true;
setTimeout(unpause,time);
}
function checkWin(){
if(playerY < PLAYER_SIZE){
gamePaused = true;
score += 1;
resetPlayer(); // reset the player
speedUpSquare(); // create a function that speeds up the squares
pauseFor(); // pause for default 1 second
}
}
主循环
你的主循环也有点问题,用requestAnimationFrame
会好很多
// where you had
setInterval(function(){ ...
// replace that interval function with
// create a mainloop function
function mainLoop(){
moveEverything();
drawEverything();
requestAnimationFrame(mainLoop); // request the next frame
}
requestAnimationFrame(mainLoop); // this will start the me main loop
这将为您提供更好的帧速率 (60fps),因此您需要降低速度(interval
您用于速度的变量)
暂停游戏
在函数 drawEverything
中,您需要确保在等待下一轮开始时不检查是否获胜。正如 gamePaused
标志
if(! gamePaused ) { // if not pause
// do everything that should not be done during paused game
checkContact();
checkWin();
} else {
// you may want to show that you are waiting from the next round
ctx.fillStyle = "black";
ctx.textAlign = "center";
ctx.fillText("Get ready",c.width / 2, c.height / 4);
}
击中正方形的测试很好,但有一个错字
function intersectRect(i){
return !(playerX > squareX[i] + 50 ||
playerX + 50 < squareY[i] ||
//...................^........ Should be squareX[i]
playerY > squareY[i] + 50 ||
playerY + 50 < squareY[i]);
}
使用该固定更改 checkContact 函数
// modify the to pause the game on hit
function checkContact(){
for(var i = 0; i < squareX.length; i++){
if(intersectRect(i)){
playerReset();
pauseFor(500); // pause for default 1/2 second
break; // this breaks out of the for loop
// no point checking for other hits
// once you found one.
}
}
}
认为这涵盖了大部分内容。
一些小技巧
奇数位代码
// you do this ?? colorRect does not return anything so dont know why
// you do this. Same for the squares
player = colorRect(playerX,playerY,PLAYER_SIZE,PLAYER_SIZE,'yellow');
// would be better as
colorRect(playerX,playerY,PLAYER_SIZE,PLAYER_SIZE,'yellow');
使用对象
使用对象可以节省您的输入时间并使游戏更易于管理。
你有以下内容,这使得添加、修改、访问方块变得困难,而且很乱
var squareX = [50, 0, 640, 400, 575, 300, 373];
var squareY = [100, 150,200, 250, 300, 350, 400];
var forward = [true, true, true, true, true, true, true];
var interval = [15, 15, 15, 15, 15, 15];
const SQUARE_SIZE = 50;
您可以为每个方块创建一个对象并将它们添加到数组中
var squares = [{
x : 50,
y : 100,
forward : true,
interval : 15,
size : 50,
color : "blue"
},{
x : 0,
y : 150,
forward : true,
interval : 15,
size : 50,
color : "Green"
},
// and so on
]
或者如果你有信心
const SQUARE_SPEED = 15 / 2; // frame rate now 60 so half speed
const SQUARE_SIZE = 50;
const squares = [];
// when you create a function with arguments you can set defaults with
// the equal eg function blah(data = 1). If I call blah() without the
// argument it will default to 1. If I call with the argumen blah(2) data
// will be set to the argument 2
const addSquare = (x,y,color,forward = true,interval = SQUARE_SPEED,size = SQUARE_SIZE) => {
squares.push({ x, y, color, forward, interval, size, });
}
addSquare(50, 100, 'red');
addSquare(0, 150, 'blue');
addSquare(640, 200, 'green');
addSquare(400, 250, 'white');
addSquare(575, 300, 'black');
addSquare(300, 350, 'orange');
addSquare(373, 400, 'mediumPurple');
您可以通过数组访问一个正方形。例如测试 player hit
function testForHit(){
var i;
for(i = 0; i < squares.length; i++){
var s = squares[i]; // get a square from the array
if( !(playerX > s.x + s.size || playerX + 50 < s.x ||
playerY > s.y + s.size || playerY + 50 < s.y){
playerReset();
pauseFor(500);
break;
}
}
}
并绘制它们
function drawSquares(){
var i;
for(i = 0; i < squares.length; i++){
var s = squares[i]; // get a square from the array
colorRect(s.x,s.y,s.size,s.size,s.color);
}
}
您甚至可以将绘制功能添加到方形对象 squares[i].draw()
但这是当您掌握基本对象时的一些东西。
我正在创建一个游戏,其中黄色方块必须穿过所有其他方块才能到达屏幕顶部。我无法测试方块是否重叠以重置黄色方块。我已经尝试实施在该网站上找到的其他方法,但 none 似乎有效,除非我实施错误。
现在,在方法 intersectRect(i) 中,我正在检查方块的边缘到玩家方块的边缘。
我遇到的另一个错误,虽然不是最重要但值得一提的是,当黄色方块到达屏幕顶部时,分数会上升很多值,而不仅仅是 1。
谢谢。
<html>
<canvas id="gameCanvas" width="800" height="600">
</canvas>
<script>
var canvas;
var canvasContext;
//square variables
var squares = [];
var squareX = [50, 0, 640, 400, 575, 300, 373];
var squareY = [100, 150,200, 250, 300, 350, 400];
var forward = [true, true, true, true, true, true, true];
var interval = [15, 15, 15, 15, 15, 15];
const SQUARE_SIZE = 50;
//player variables
var player;
var playerX = 0;
var playerY = 0;
var intervalPlayer = 0;
const PLAYER_SIZE = 50;
var score = 0;
window.onload = function(){
canvas=document.getElementById('gameCanvas');
canvasContext = canvas.getContext('2d');
function calcMousePos(evt){
var rect = canvas.getBoundingClientRect();
var root = document.documentElement;
var mouseX = evt.clientX - rect.left - root.scrollLeft;
var mouseY = evt.clientY - rect.top - root.scrollTop;
return{
x:mouseX,
y:mouseY
};
}
//get mouse movement
canvas.addEventListener('mousemove', function(evt){
var mousePos = calcMousePos(evt);
playerX = mousePos.x;
playerY = mousePos.y;
});
//update screen
var framesPerSecond = 30;
setInterval(function(){
moveEverything();
drawEverything();
},1000/framesPerSecond);
}
//moves each square based on the interval
function moveEverything(){
for(var i = 0; i < squareX.length; i++){
if(!forward[i]){
forward[i] = false;
if(interval[i] > 0){
interval[i] *= -1;
}
if(squareX[i] < 0){
forward[i] = true;
}
}else if(forward[i]){
if(interval[i] < 0){
interval[i] *= -1;
}
if(squareX[i] > canvas.width - 50)
{
forward[i] = false;
}
}else{
console.log("Error ball " + i);
}
}
}
//draws each square on the background canvas
function drawEverything(){
for(var i = 0; i < squareX.length; i++){
squareX[i] += interval[i];
}
//background
colorRect(0,0,canvas.width,canvas.height, 'salmon');
//score
canvasContext.fillStyle = 'black';
canvasContext.fillText(score, 10, 10);
//red square
squares[0] = colorRect(squareX[0],squareY[0],SQUARE_SIZE,SQUARE_SIZE, 'red');
//blue square
squares[1] = colorRect(squareX[1],squareY[1],SQUARE_SIZE,SQUARE_SIZE, 'blue');
//green square
squares[2] = colorRect(squareX[2],squareY[2],SQUARE_SIZE,SQUARE_SIZE, 'green');
//white square
squares[3] = colorRect(squareX[3],squareY[3],SQUARE_SIZE,SQUARE_SIZE, 'white');
//black square
squares[4] = colorRect(squareX[4],squareY[4],SQUARE_SIZE,SQUARE_SIZE, 'black');
//orange square
squares[5] = colorRect(squareX[5],squareY[5],SQUARE_SIZE,SQUARE_SIZE, 'orange');
//purple square
squares[6] = colorRect(squareX[6],squareY[6],SQUARE_SIZE,SQUARE_SIZE, 'mediumPurple');
//player
player = colorRect(playerX,playerY,PLAYER_SIZE,PLAYER_SIZE,'yellow');
checkContact();
checkWin();
}
//functions to reate rects
function colorRect(leftX, topY, width, height, drawColor){
canvasContext.fillStyle = drawColor;
canvasContext.fillRect(leftX,topY,width,height);
}
function colorCircle(centerX, centerY, radius, color){
//draws ball
canvasContext.fillStyle=color;
canvasContext.beginPath();
canvasContext.arc(centerX,centerY,radius,0,Math.PI * 2, true);
canvasContext.fill();
}
//check for contact between the squares
function checkContact(){
for(var i = 0; i < squareX.length; i++){
if(intersectRect(i))
{
console.log("Overlap");
playerReset();
}
else
{
//none
}
}
//while(playerY < squareY[i] )
}
//check the borders of the squares for contact
function intersectRect(i){
return !(playerX > squareX[i] + 50 ||
playerX + 50 < squareY[i] ||
playerY > squareY[i] + 50 ||
playerY + 50 < squareY[i]);
}
//check if yellow square is at top of square
function checkWin(){
window.setTimeout(function(){
if(playerY < PLAYER_SIZE){
playerReset();
for(var i = 0; i < squareX.length; i++)
{
interval[i] += score/2;
}
score++;
}
},1000);
}
//reset the player to original position
function playerReset(){
playerX = canvas.width/2;
playerY = canvas.height - 50;
}
</script>
感谢您修复我的主要错误。我现在唯一看不到的是创建的暂停方法。这是我修改后的代码的样子。这是一个问题的主要原因是当它重置时,它没有给玩家时间将鼠标移回原处,它只是在鼠标移动后立即转到鼠标。谢谢。
<script>
var canvas;
var canvasContext;
var gamePaused = false;
//square variables
var squares = [];
var squareX = [50, 0, 640, 400, 575, 300, 373];
var squareY = [100, 150,200, 250, 300, 350, 400];
var forward = [true, true, true, true, true, true, true];
var interval = [15, 15, 15, 15, 15, 15, 15];
const SQUARE_SIZE = 50;
//player variables
var player;
var playerX = 0;
var playerY = 0;
var intervalPlayer = 0;
const PLAYER_SIZE = 50;
var score = 0;
//pause game
function unpause() { gamePaused = false } // un pause game
function pauseFor(time = 1000){ // defaults to 1 second
pauseGame = true;
setTimeout(unpause,time);
}
window.onload = function(){
canvas=document.getElementById('gameCanvas');
canvasContext = canvas.getContext('2d');
function calcMousePos(evt){
var rect = canvas.getBoundingClientRect();
var root = document.documentElement;
var mouseX = evt.clientX - rect.left - root.scrollLeft;
var mouseY = evt.clientY - rect.top - root.scrollTop;
return{
x:mouseX,
y:mouseY
};
}
//get mouse movement
canvas.addEventListener('mousemove', function(evt){
var mousePos = calcMousePos(evt);
playerX = mousePos.x;
playerY = mousePos.y;
});
//update screen
var framesPerSecond = 30;
function mainLoop(){
moveEverything();
drawEverything();
requestAnimationFrame(mainLoop); // request the next frame
}
requestAnimationFrame(mainLoop);
}
//moves each square based on the interval
function moveEverything(){
for(var i = 0; i < squareX.length; i++){
if(!forward[i]){
forward[i] = false;
if(interval[i] > 0){
interval[i] *= -1;
}
if(squareX[i] < 0){
forward[i] = true;
}
}else if(forward[i]){
if(interval[i] < 0){
interval[i] *= -1;
}
if(squareX[i] > canvas.width - 50)
{
forward[i] = false;
}
}else{
console.log("Error ball " + i);
}
}
}
//draws each square on the background canvas
function drawEverything(){
for(var i = 0; i < squareX.length; i++){
squareX[i] += interval[i];
}
//background
colorRect(0,0,canvas.width,canvas.height, 'salmon');
//score
canvasContext.fillStyle = 'black';
canvasContext.fillText(score, 10, 10);
//red square
squares[0] = colorRect(squareX[0],squareY[0],SQUARE_SIZE,SQUARE_SIZE, 'red');
//blue square
squares[1] = colorRect(squareX[1],squareY[1],SQUARE_SIZE,SQUARE_SIZE, 'blue');
//green square
squares[2] = colorRect(squareX[2],squareY[2],SQUARE_SIZE,SQUARE_SIZE, 'green');
//white square
squares[3] = colorRect(squareX[3],squareY[3],SQUARE_SIZE,SQUARE_SIZE, 'white');
//black square
squares[4] = colorRect(squareX[4],squareY[4],SQUARE_SIZE,SQUARE_SIZE, 'black');
//orange square
squares[5] = colorRect(squareX[5],squareY[5],SQUARE_SIZE,SQUARE_SIZE, 'orange');
//purple square
squares[6] = colorRect(squareX[6],squareY[6],SQUARE_SIZE,SQUARE_SIZE, 'purple');
//player
player = colorRect(playerX,playerY,PLAYER_SIZE,PLAYER_SIZE,'yellow');
if(! gamePaused ) { // if not pause
// do everything that should not be done during paused game
checkContact();
checkWin();
} else {
// you may want to show that you are waiting from the next round
canvasContext.fillStyle = "black";
canvasContext.textAlign = "center";
canvasContext.fillText("Get ready",canvas.width / 2, canvas.height / 4);
}
}
//functions to reate rects
function colorRect(leftX, topY, width, height, drawColor){
canvasContext.fillStyle = drawColor;
canvasContext.fillRect(leftX,topY,width,height);
}
function colorCircle(centerX, centerY, radius, color){
//draws ball
canvasContext.fillStyle=color;
canvasContext.beginPath();
canvasContext.arc(centerX,centerY,radius,0,Math.PI * 2, true);
canvasContext.fill();
}
//check for contact between the squares
function checkContact(){
for(var i = 0; i < squareX.length; i++){
if(intersectRect(i)){
resetPlayer();
pauseFor(); // pause for default 1 second
break; // this breaks out of the for loop
// no point checking for other hits
// once you found one.
}
}
}
//check the borders of the squares for contact
function intersectRect(i){
return !(playerX > squareX[i] + 50 ||
playerX + 50 < squareX[i] ||
playerY > squareY[i] + 50 ||
playerY + 50 < squareY[i]);
}
//check if yellow square is at top of square
function checkWin(){
if(playerY < PLAYER_SIZE){
gamePaused = true;
score += 1;
resetPlayer(); // reset the player
speedUpSquare(); // create a function that speeds up the squares
pauseFor(); // pause for default 1 second
}
}
function speedUpSquare(){
for(var i = 0; i < squareX.length; i++)
{
interval[i] += score/2;
}
}
//reset the player to original position
function resetPlayer(){
playerX = canvas.width/2;
playerY = canvas.height - 50;
pauseFor();
}
</script>
加分多少?
win 的问题在于您每 30 秒调用一次函数 checkWin
,而在该函数中您除了安排在一秒钟内检查 win 之外什么都不做。我必须 运行 它才能确切地看到发生了什么,但更好的解决方案是执行以下操作
// create a global that pauses the game
// when this is true then you are waiting to start the next play
var gamePaused = false;
function unpause() { gamePaused = false } // un pause game
function pauseFor(time = 1000){ // defaults to 1 second
pauseGame = true;
setTimeout(unpause,time);
}
function checkWin(){
if(playerY < PLAYER_SIZE){
gamePaused = true;
score += 1;
resetPlayer(); // reset the player
speedUpSquare(); // create a function that speeds up the squares
pauseFor(); // pause for default 1 second
}
}
主循环
你的主循环也有点问题,用requestAnimationFrame
// where you had
setInterval(function(){ ...
// replace that interval function with
// create a mainloop function
function mainLoop(){
moveEverything();
drawEverything();
requestAnimationFrame(mainLoop); // request the next frame
}
requestAnimationFrame(mainLoop); // this will start the me main loop
这将为您提供更好的帧速率 (60fps),因此您需要降低速度(interval
您用于速度的变量)
暂停游戏
在函数 drawEverything
中,您需要确保在等待下一轮开始时不检查是否获胜。正如 gamePaused
标志
if(! gamePaused ) { // if not pause
// do everything that should not be done during paused game
checkContact();
checkWin();
} else {
// you may want to show that you are waiting from the next round
ctx.fillStyle = "black";
ctx.textAlign = "center";
ctx.fillText("Get ready",c.width / 2, c.height / 4);
}
击中正方形的测试很好,但有一个错字
function intersectRect(i){
return !(playerX > squareX[i] + 50 ||
playerX + 50 < squareY[i] ||
//...................^........ Should be squareX[i]
playerY > squareY[i] + 50 ||
playerY + 50 < squareY[i]);
}
使用该固定更改 checkContact 函数
// modify the to pause the game on hit
function checkContact(){
for(var i = 0; i < squareX.length; i++){
if(intersectRect(i)){
playerReset();
pauseFor(500); // pause for default 1/2 second
break; // this breaks out of the for loop
// no point checking for other hits
// once you found one.
}
}
}
认为这涵盖了大部分内容。
一些小技巧
奇数位代码
// you do this ?? colorRect does not return anything so dont know why
// you do this. Same for the squares
player = colorRect(playerX,playerY,PLAYER_SIZE,PLAYER_SIZE,'yellow');
// would be better as
colorRect(playerX,playerY,PLAYER_SIZE,PLAYER_SIZE,'yellow');
使用对象
使用对象可以节省您的输入时间并使游戏更易于管理。
你有以下内容,这使得添加、修改、访问方块变得困难,而且很乱
var squareX = [50, 0, 640, 400, 575, 300, 373];
var squareY = [100, 150,200, 250, 300, 350, 400];
var forward = [true, true, true, true, true, true, true];
var interval = [15, 15, 15, 15, 15, 15];
const SQUARE_SIZE = 50;
您可以为每个方块创建一个对象并将它们添加到数组中
var squares = [{
x : 50,
y : 100,
forward : true,
interval : 15,
size : 50,
color : "blue"
},{
x : 0,
y : 150,
forward : true,
interval : 15,
size : 50,
color : "Green"
},
// and so on
]
或者如果你有信心
const SQUARE_SPEED = 15 / 2; // frame rate now 60 so half speed
const SQUARE_SIZE = 50;
const squares = [];
// when you create a function with arguments you can set defaults with
// the equal eg function blah(data = 1). If I call blah() without the
// argument it will default to 1. If I call with the argumen blah(2) data
// will be set to the argument 2
const addSquare = (x,y,color,forward = true,interval = SQUARE_SPEED,size = SQUARE_SIZE) => {
squares.push({ x, y, color, forward, interval, size, });
}
addSquare(50, 100, 'red');
addSquare(0, 150, 'blue');
addSquare(640, 200, 'green');
addSquare(400, 250, 'white');
addSquare(575, 300, 'black');
addSquare(300, 350, 'orange');
addSquare(373, 400, 'mediumPurple');
您可以通过数组访问一个正方形。例如测试 player hit
function testForHit(){
var i;
for(i = 0; i < squares.length; i++){
var s = squares[i]; // get a square from the array
if( !(playerX > s.x + s.size || playerX + 50 < s.x ||
playerY > s.y + s.size || playerY + 50 < s.y){
playerReset();
pauseFor(500);
break;
}
}
}
并绘制它们
function drawSquares(){
var i;
for(i = 0; i < squares.length; i++){
var s = squares[i]; // get a square from the array
colorRect(s.x,s.y,s.size,s.size,s.color);
}
}
您甚至可以将绘制功能添加到方形对象 squares[i].draw()
但这是当您掌握基本对象时的一些东西。