Что мне нужно изменить, чтобы я мог вызывать свою функцию в JS? - PullRequest
0 голосов
/ 10 января 2020

Я играю в игру «Птица с нестабильной птицей» и пытаюсь изменить скорость птицы с определенным интервалом, но, похоже, моя функция не будет вызвана, и я не понимаю почему, потому что я использовал тот же синтаксис что я использовал для других функций. Функция speedChange не работает, а updateDx перемещает каналы быстрее в зависимости от выбранного уровня. Заранее большое спасибо.

   const canvas=document.getElementById("bird");
const ctx=canvas.getContext("2d");

let frames=0;
const DEGREE=Math.PI/180;//transforms radians in degrees

const sprite=new Image();
sprite.src="img/sprite.png";

//sounds
const SCORE_S=new Audio();
SCORE_S.src="audio/sfx_point.wav";
const FLAP=new Audio();
FLAP.src="audio/sfx_flap.wav";
const HIT=new Audio();
HIT.src="audio/sfx_hit.wav";
const SWOOSH=new Audio();
SWOOSH.src="audio/sfx_swooshing.wav";
const DIE=new Audio();
DIE.src="audio/sfx_die.wav";

//game state
const state=
{
	current:0,
	getReady:0,
	game:1,
	over:2
}

//start button
const start=
{
	x:120,
	y:263,
	w:83,
	h:29
}

canvas.addEventListener("click", function(evt)
{
	switch (state.current) {
		case state.getReady:
			state.current=state.game;
			SWOOSH.play();
			break;
		case state.game:
		  bird.flap();
			FLAP.play();
		  break;
		case state.over:
			let rect=canvas.getBoundingClientRect();
			let clickX=evt.clientX-rect.left;
			let clickY=evt.clientY-rect.top;

			//check if we click on the start button
			if(clickX>=start.x&&clickX<=start.x+start.w&&
				clickY>=start.y&&clickY<=start.y+start.h)
				{
					pipes.reset();
					bird.speedReset();
					score.reset();
					state.current=state.getReady;
				}
			break;
		}
});

const city=
{
	sX:0,
	sY:0,
	w:275,
	h:226,
	x:0,
	y:canvas.height-226,
	draw:function()
	{
		ctx.drawImage(sprite,this.sX,this.sY,this.w,this.h,this.x,this.y,this.w,this.h)
		ctx.drawImage(sprite,this.sX,this.sY,this.w,this.h,this.x+this.w,this.y,this.w,this.h)

	}
}
const foreground=
{
	sX:276,
	sY:0,
	w:224,
	h:112,
	x:0,
	y:canvas.height-112,
	dx:2,
	draw:function()
	{
		ctx.drawImage(sprite,this.sX,this.sY,this.w,this.h,this.x,this.y,this.w,this.h)
		ctx.drawImage(sprite,this.sX,this.sY,this.w,this.h,this.x+this.w,this.y,this.w,this.h)
	},
	update:function()
	{
		if(state.current==state.game)
		{
			this.x=(this.x-this.dx)%(this.w/2);//sensation that the bird is moving forward
		}
	}
}

const bird=
{
	animation:[
		{sX:276, sY:112},
		{sX:276, sY:139},
		{sX:276, sY:164},
		{sX:276, sY:139}
	],
	x:50,
	y:150,
	w:34,
	h:26,
	radius:12,
	frame:0,
	gravity:0.1,
	jump:3,
	speed:0,
  rotation:0,
	draw:function()
	{
		let bird=this.animation[this.frame];
		ctx.save();
		ctx.translate(this.x,this.y);
		ctx.rotate(this.rotation);
		ctx.drawImage(sprite,bird.sX,bird.sY,this.w,this.h, -this.w/2, -this.h/2,this.w, this.h);
		ctx.restore();
	},

	flap:function()
	{
		this.speed=-this.jump;
	},
	update:function()
	{
		//if the game is in the get ready state the bird must flap slowly
		this.period=state.current==state.getReady ? 10:5;
		//we increase the frame by 1 each period
		this.frame+=frames%this.period==0?1:0;
		//frame goes from 0 to 4 then again to 0
		this.frame=this.frame%this.animation.length;

		if(state.current==state.getReady)
		{
			this.y=150; //reset the pos of the bird after game over
			this.rotation=0*DEGREE;
		}
		else {
			this.speed+=this.gravity;
			this.y+=this.speed;

			if(this.y+this.h/2>=canvas.height-foreground.h)
			{
				this.y=canvas.height-foreground.h-this.h/2;
				if(state.current==state.game)
				{
					state.current=state.over;
					DIE.play();
				}
			}
			//if the speed is greater than the jump, it means the bird is falling
			 if(this.speed>=this.jump)
			 {
				 this.rotation=90*DEGREE;
				 this.frame=1;//if the bird fell, it must stop flapping
			 }
			 else {
				 this.rotation=-25*DEGREE;
			 }
		}
	},
	speedReset:function()
{
	this.speed=0;
}

}

const getReady=
{
	sX:0,
	sY:228,
	w:173,
	h:152,
	x:canvas.width/2-173/2,
	y:80,

	draw:function()
	{
		if(state.current==state.getReady)
		{
		ctx.drawImage(sprite,this.sX,this.sY,this.w,this.h,this.x,this.y,this.w,this.h)
		}
	}
}

const gameOver=
{
	sX:175,
	sY:228,
	w:225,
	h:202,
	x:canvas.width/2-225/2,
	y:90,

	draw:function()
	{
		if(state.current==state.over)
		{
		ctx.drawImage(sprite,this.sX,this.sY,this.w,this.h,this.x,this.y,this.w,this.h)
	  }
	}
}

const pipes=
{
	position:[],
	top:
	{
		sX:553,
		sY:0
	},
	bottom:
	{
		sX:502,
		sY:0
	},
	w:53,
	h:400,
	gap:90,
	maxYPos:-180,
	dx:2,
	updateDx : function updateDx(value)
	{
		console.log(this);
		this.dx=value;
	},
	speedChange : function speedChange(vall){
  //console.log("Am intrat");
		setInterval(
			function ()
			{this.dx+=vall;},3000);
 },
	draw:function()
	{
		for(let i=0;i<this.position.length;i++)
		{
			let p=this.position[i];

			let topYPos=p.y;
			let bottomYPos=p.y+this.h+this.gap;

			//top pipe
			ctx.drawImage(sprite,this.top.sX,this.top.sY,this.w,this.h,p.x,topYPos,this.w,this.h)
			//bottom pipe
			ctx.drawImage(sprite,this.bottom.sX,this.bottom.sY,this.w,this.h,p.x,bottomYPos,this.w,this.h)
		}
	},
	update:function()
	{

		if(state.current!==state.game) return;
		if(frames%100==0)
		 {
			 this.position.push({
				 x:canvas.width,
				 y:this.maxYPos*(Math.random()+1)
			 });
		 }
		 for(let i=0;i<this.position.length;i++)
		 {
			 let p=this.position[i];

			 let bottomPipeYPos=p.y+this.h+this.gap;

			 //collision top
			 if(bird.x+bird.radius>p.x&&bird.x-bird.radius<p.x+this.w&&
				 bird.y+bird.radius>p.y&&bird.y-bird.radius<p.y+this.h)
			 {
				 state.current=state.over;
				 HIT.play();
			 }
			 //collision bottom
			 if(bird.x+bird.radius>p.x&&bird.x-bird.radius<p.x+this.w&&
				 bird.y+bird.radius>bottomPipeYPos&&
				 bird.y-bird.radius<bottomPipeYPos+this.h)
			 {
				 state.current=state.over;
				 HIT.play();
			 }
			 //move pipes to the left
			 			 p.x -=this.dx;
			 //if the pipes go beyond canvas, we delete them from the array
			 if(p.x+this.w<=0)
			 {
				 this.position.shift();
				 score.value+=1;
				 SCORE_S.play();
				 score.best=Math.max(score.value, score.best);
				 localStorage.setItem("best", score.best);
			 }
		 }
	},
	reset:function()
	{
	this.position=[];
}
}

//score
const score=
{
	best:parseInt(localStorage.getItem("best")) || 0,
	value:0,

	draw:function()
	{
		ctx.fillStyle="#FFF";
		ctx.strokeStyle="#000";
		if(state.current==state.game)
		{
			ctx.lineWidth=2;
			ctx.font="35px Teko";
			ctx.fillText(this.value, canvas.width/2, 50);
			ctx.strokeText(this.value, canvas.width/2, 50);
		}
		else if(state.current==state.over){
			//score value
			ctx.font="25px Teko";
			ctx.fillText(this.value, 225, 186);
			ctx.strokeText(this.value, 225, 186);

			//best score
			ctx.fillText(this.best, 225, 228);
			ctx.strokeText(this.best, 225, 228);
		}
	},
	reset:function()
	{
		this.value=0;
	}
}

function draw()
{
  ctx.fillStyle="#70c5ce"; //culoare fundal
  ctx.fillRect(0,0,canvas.width,canvas.height); //x=0, y=0
  city.draw();
  pipes.draw();
 	foreground.draw();
 	bird.draw();
 	getReady.draw();
	gameOver.draw();
	score.draw();
}

function update()
{
 bird.update();
 foreground.update();
 pipes.update();
}


function loop()
{
 update();
 draw();
 frames++;
 requestAnimationFrame(loop);
}
 loop();


var button=document.createElement("button");
var button2=document.createElement("button")
var button3=document.createElement("button")

button.innerHTML="Easy"
button.type=button;
document.body.appendChild(button);

button2.innerHTML="Medium"
button.type=button;
document.body.appendChild(button2);

button3.innerHTML="Hard"
button.type=button;
document.body.appendChild(button3);

button.onclick=function(){level("first-button");}
button2.onclick=function(){level("second-button");}
button3.onclick=function(){level("third-button");}

function level(buttonTitle)
{
	if(buttonTitle=="first-button")
	{
		pipes.updateDx(2);
		this.state=state.game;
	}
	else if(buttonTitle=="second-button")
  {
		pipes.updateDx(3);
  }
	else {
		{
pipes.updateDx(20);
		}
	}
}

function Chspeed(buttonTitle){
	if(buttonTitle=="first-button")
	{
		pipes.speedChange(3);
		this.state=state.game;
	}
	else if(buttonTitle=="second-button")
  {
		pipes.speedChange(1);
  }
	else {
		{
    pipes.speedChange(3);
		}
	}
}

Ответы [ 2 ]

0 голосов
/ 10 января 2020

dx будет undefined внутри интервала в вашей функции speedChange (), потому что внутри обратного вызова setInterval на него не ссылаются каналы. Вместо доступа this.dx вы можете использовать pipes.dx

0 голосов
/ 10 января 2020

Кажется, вам не хватает двух закрывающих скобок, я думаю, после этой строки:

{ this.dx += vall; }, 3000);

РЕДАКТИРОВАТЬ:

this в обратном вызове setInterval будет быть неопределенным. Вам нужно сохранить его снаружи как локальную переменную, а затем использовать это:

speedChange: function speedChange(vall)
{
   var localthis = this;

   setInterval(
       function()
       {
           localthis.dx += vall;
       }, 3000);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...