我正在创建一个游戏,黄色方块必须穿过所有其他方块才能到达屏幕顶部。我无法测试方块是否重叠以重置黄色方块。我尝试过在这个网站上找到其他方法,但似乎都没有用,除非我错误地实现它们。
现在,在方法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>
答案 0 :(得分:0)
胜利的问题在于你每隔30秒就调用一次checkWin
函数,在这个函数中你什么都不做,只是在一秒钟内安排一次胜利检查。我必须运行它来查看到底发生了什么,但更好的解决方案是执行以下操作
// 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');
您可以通过阵列访问方块。例如测试玩家命中
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()
,但这可以在您获得基本对象时保留。