以一定间隔在 canvas 范围内绘制和移动形状
Draw and move shapes across canvas with an interval
我试图在业余时间制作自己的 "Flappy Bird" 克隆,但我无法让 "pipes" 以设定的时间间隔进行绘制和滚动。我能够绘制一组并移动它,但是让它在一定间隔内重复绘制和移动它让我难以接受。
任何关于我需要做什么的见解都将不胜感激。
$(document).ready(function(){
//global vars
var world = document.getElementById('gameWorld');
var startScreen = document.getElementById('startScreen');
var context = world.getContext('2d');
window.requestAnimFrame = (function(callback) {
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame ||
function(callback) {
window.setTimeout(callback, 1000 / 60);
};
})()
//bord constructor
function bordBuilder(){
this.radius = 10;
this.x = world.width / 2;
this.y = world.height / 2;
this.vy = -20;
this.gravity = 0.8;
}
function pipesBuilder(){
this.width = 50;
this.x = world.width;
}
// draw the Bord on the stage
function drawBord(bord, context){
context.beginPath();
context.arc(bord.x, bord.y, bord.radius, 0, 2 * Math.PI, false);
context.fillStyle = 'blue';
context.fill();
context.lineWidth = 1;
context.strokeStyle = 'navyblue';
context.stroke();
}
//function to check whether or not the bord is hitting the top or bottom of the stage
function fallingBord(bord){
bord.y += bord.gravity;
if(bord.y < 0 + bord.radius){
bord.y = bord.radius;
}else if(bord.y + bord.radius > world.height){
bord.y = world.height - bord.radius;
}
}
//animation function always running
function startAnimation(bord, context, pipes){
context.clearRect(0, 0, world.width, world.height);
drawBord(bord, context);
fallingBord(bord);
setInterval(function(){
drawPipes(pipes, context);
}, 3000);
movePipes(pipes);
requestAnimFrame(function(){
startAnimation(bord, context, pipes);
});
}
//make the bird fly higher every click
function flyHigher(bord){
console.log('higher');
bord.y += bord.vy;
}
//pipe function/hitboxes
function drawPipes(pipes, context){
context.beginPath();
context.rect(pipes.x, world.height-50, pipes.width,50);
context.fillStyle = 'green';
context.fill();
context.beginPath();
context.rect(pipes.x, 0, pipes.width, 50);
context.fillStyle = 'green';
context.fill();
}
//function to move the pipes from the left to right
function movePipes(pipes){
pipes.x -= 1;
}
var pipes = new pipesBuilder();
var bord = new bordBuilder();
//add the fly event listener to the stage
world.addEventListener("click", function(){
flyHigher(bord);
}, false);
startScreen.addEventListener("click", function(){
startScreen.style.display = 'none';
startAnimation(bord, context, pipes);
}, false);
});
#gameWorld{
height: 50%;
width: 50%;
border: 1px solid black;
}
#startScreen{
position: absolute;
z-index: 5;
top: 0;
left: 0;
height: 50%;
width: 50%;
}
#startScreen h1{
text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="startScreen"><h1>START</h1></div>
<canvas id="gameWorld"></canvas>
您只是错过了多个管道的概念。我已经修改了你的代码,所以 pipes
现在是一个管道数组,它们的 draw/move 函数适用于每个单独的管道。我还添加了一个在间隔中调用的 newPipe
函数(我已将其移出渲染循环)。
由于管道堆积 - 我添加了一个删除功能,用于删除那些通过左 canvas 边缘的管道。
开始吧:
$(document).ready(function(){
//global vars
var world = document.getElementById('gameWorld');
var startScreen = document.getElementById('startScreen');
var context = world.getContext('2d');
window.requestAnimFrame = (function(callback) {
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame ||
function(callback) {
window.setTimeout(callback, 1000 / 60);
};
})()
//bord constructor
function bordBuilder(){
this.radius = 10;
this.x = world.width / 2;
this.y = world.height / 2;
this.vy = -20;
this.gravity = 0.8;
}
function pipesBuilder(){
this.width = 50;
this.x = world.width;
}
// draw the Bord on the stage
function drawBord(bord, context){
context.beginPath();
context.arc(bord.x, bord.y, bord.radius, 0, 2 * Math.PI, false);
context.fillStyle = 'blue';
context.fill();
context.lineWidth = 1;
context.strokeStyle = 'navyblue';
context.stroke();
}
//function to check whether or not the bord is hitting the top or bottom of the stage
function fallingBord(bord){
bord.y += bord.gravity;
if(bord.y < 0 + bord.radius){
bord.y = bord.radius;
}else if(bord.y + bord.radius > world.height){
bord.y = world.height - bord.radius;
}
}
//animation function always running
function startAnimation(bord, context, pipes){
context.clearRect(0, 0, world.width, world.height);
drawBord(bord, context);
fallingBord(bord);
drawPipes(pipes, context);
movePipes(pipes);
requestAnimFrame(function(){
startAnimation(bord, context, pipes);
});
}
//make the bird fly higher every click
function flyHigher(bord){
console.log('higher');
bord.y += bord.vy;
}
//pipe function/hitboxes
function drawPipes(pipes, context){
for(var i = 0; i < pipes.length; i++){
context.beginPath();
context.rect(pipes[i].x, world.height-50, pipes[i].width,50);
context.fillStyle = 'green';
context.fill();
context.beginPath();
context.rect(pipes[i].x, 0, pipes[i].width, 50);
context.fillStyle = 'green';
context.fill();
}
}
//function to move the pipes from the left to right
function movePipes(pipes){
for(var i = 0; i < pipes.length; i++){
pipes[i].x -= 1;
if (i == 0 && pipes[i].x < -pipes[i].width) {
console.log('deleting pipe');
pipes.splice(i, 1);
}
}
}
function newPipe(pipes){
pipes.push(new pipesBuilder());
}
var pipes = [new pipesBuilder()];
var bord = new bordBuilder();
//add the fly event listener to the stage
world.addEventListener("click", function(){
flyHigher(bord);
drawPipes(pipes, context);
}, false);
startScreen.addEventListener("click", function(){
startScreen.style.display = 'none';
startAnimation(bord, context, pipes);
setInterval(function(){
console.log('new pipe', pipes);
newPipe(pipes);
}, 3000);
}, false);
});
#gameWorld{
height: 50%;
width: 50%;
border: 1px solid black;
}
#startScreen{
position: absolute;
z-index: 5;
top: 0;
left: 0;
height: 50%;
width: 50%;
}
#startScreen h1{
text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="startScreen"><h1>START</h1></div>
<canvas id="gameWorld"></canvas>
我试图在业余时间制作自己的 "Flappy Bird" 克隆,但我无法让 "pipes" 以设定的时间间隔进行绘制和滚动。我能够绘制一组并移动它,但是让它在一定间隔内重复绘制和移动它让我难以接受。
任何关于我需要做什么的见解都将不胜感激。
$(document).ready(function(){
//global vars
var world = document.getElementById('gameWorld');
var startScreen = document.getElementById('startScreen');
var context = world.getContext('2d');
window.requestAnimFrame = (function(callback) {
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame ||
function(callback) {
window.setTimeout(callback, 1000 / 60);
};
})()
//bord constructor
function bordBuilder(){
this.radius = 10;
this.x = world.width / 2;
this.y = world.height / 2;
this.vy = -20;
this.gravity = 0.8;
}
function pipesBuilder(){
this.width = 50;
this.x = world.width;
}
// draw the Bord on the stage
function drawBord(bord, context){
context.beginPath();
context.arc(bord.x, bord.y, bord.radius, 0, 2 * Math.PI, false);
context.fillStyle = 'blue';
context.fill();
context.lineWidth = 1;
context.strokeStyle = 'navyblue';
context.stroke();
}
//function to check whether or not the bord is hitting the top or bottom of the stage
function fallingBord(bord){
bord.y += bord.gravity;
if(bord.y < 0 + bord.radius){
bord.y = bord.radius;
}else if(bord.y + bord.radius > world.height){
bord.y = world.height - bord.radius;
}
}
//animation function always running
function startAnimation(bord, context, pipes){
context.clearRect(0, 0, world.width, world.height);
drawBord(bord, context);
fallingBord(bord);
setInterval(function(){
drawPipes(pipes, context);
}, 3000);
movePipes(pipes);
requestAnimFrame(function(){
startAnimation(bord, context, pipes);
});
}
//make the bird fly higher every click
function flyHigher(bord){
console.log('higher');
bord.y += bord.vy;
}
//pipe function/hitboxes
function drawPipes(pipes, context){
context.beginPath();
context.rect(pipes.x, world.height-50, pipes.width,50);
context.fillStyle = 'green';
context.fill();
context.beginPath();
context.rect(pipes.x, 0, pipes.width, 50);
context.fillStyle = 'green';
context.fill();
}
//function to move the pipes from the left to right
function movePipes(pipes){
pipes.x -= 1;
}
var pipes = new pipesBuilder();
var bord = new bordBuilder();
//add the fly event listener to the stage
world.addEventListener("click", function(){
flyHigher(bord);
}, false);
startScreen.addEventListener("click", function(){
startScreen.style.display = 'none';
startAnimation(bord, context, pipes);
}, false);
});
#gameWorld{
height: 50%;
width: 50%;
border: 1px solid black;
}
#startScreen{
position: absolute;
z-index: 5;
top: 0;
left: 0;
height: 50%;
width: 50%;
}
#startScreen h1{
text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="startScreen"><h1>START</h1></div>
<canvas id="gameWorld"></canvas>
您只是错过了多个管道的概念。我已经修改了你的代码,所以 pipes
现在是一个管道数组,它们的 draw/move 函数适用于每个单独的管道。我还添加了一个在间隔中调用的 newPipe
函数(我已将其移出渲染循环)。
由于管道堆积 - 我添加了一个删除功能,用于删除那些通过左 canvas 边缘的管道。
开始吧:
$(document).ready(function(){
//global vars
var world = document.getElementById('gameWorld');
var startScreen = document.getElementById('startScreen');
var context = world.getContext('2d');
window.requestAnimFrame = (function(callback) {
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame ||
function(callback) {
window.setTimeout(callback, 1000 / 60);
};
})()
//bord constructor
function bordBuilder(){
this.radius = 10;
this.x = world.width / 2;
this.y = world.height / 2;
this.vy = -20;
this.gravity = 0.8;
}
function pipesBuilder(){
this.width = 50;
this.x = world.width;
}
// draw the Bord on the stage
function drawBord(bord, context){
context.beginPath();
context.arc(bord.x, bord.y, bord.radius, 0, 2 * Math.PI, false);
context.fillStyle = 'blue';
context.fill();
context.lineWidth = 1;
context.strokeStyle = 'navyblue';
context.stroke();
}
//function to check whether or not the bord is hitting the top or bottom of the stage
function fallingBord(bord){
bord.y += bord.gravity;
if(bord.y < 0 + bord.radius){
bord.y = bord.radius;
}else if(bord.y + bord.radius > world.height){
bord.y = world.height - bord.radius;
}
}
//animation function always running
function startAnimation(bord, context, pipes){
context.clearRect(0, 0, world.width, world.height);
drawBord(bord, context);
fallingBord(bord);
drawPipes(pipes, context);
movePipes(pipes);
requestAnimFrame(function(){
startAnimation(bord, context, pipes);
});
}
//make the bird fly higher every click
function flyHigher(bord){
console.log('higher');
bord.y += bord.vy;
}
//pipe function/hitboxes
function drawPipes(pipes, context){
for(var i = 0; i < pipes.length; i++){
context.beginPath();
context.rect(pipes[i].x, world.height-50, pipes[i].width,50);
context.fillStyle = 'green';
context.fill();
context.beginPath();
context.rect(pipes[i].x, 0, pipes[i].width, 50);
context.fillStyle = 'green';
context.fill();
}
}
//function to move the pipes from the left to right
function movePipes(pipes){
for(var i = 0; i < pipes.length; i++){
pipes[i].x -= 1;
if (i == 0 && pipes[i].x < -pipes[i].width) {
console.log('deleting pipe');
pipes.splice(i, 1);
}
}
}
function newPipe(pipes){
pipes.push(new pipesBuilder());
}
var pipes = [new pipesBuilder()];
var bord = new bordBuilder();
//add the fly event listener to the stage
world.addEventListener("click", function(){
flyHigher(bord);
drawPipes(pipes, context);
}, false);
startScreen.addEventListener("click", function(){
startScreen.style.display = 'none';
startAnimation(bord, context, pipes);
setInterval(function(){
console.log('new pipe', pipes);
newPipe(pipes);
}, 3000);
}, false);
});
#gameWorld{
height: 50%;
width: 50%;
border: 1px solid black;
}
#startScreen{
position: absolute;
z-index: 5;
top: 0;
left: 0;
height: 50%;
width: 50%;
}
#startScreen h1{
text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="startScreen"><h1>START</h1></div>
<canvas id="gameWorld"></canvas>