>웹 프론트엔드 >JS 튜토리얼 >Flappy Bird 게임의 간단한 버전을 작성하기 위한 JavaScript 및 HTML5

Flappy Bird 게임의 간단한 버전을 작성하기 위한 JavaScript 및 HTML5

小云云
小云云원래의
2018-03-17 16:27:492583검색

이전 기사에서는 JS 및 H5를 사용하여 상자 밀기 게임을 작성하는 방법을 공유했습니다. 이 기사에서는 주로 js 및 H55ba626b379994d53f7acf72a64f9b697 태그를 사용하는 Flappy Bird 간단한 버전을 작성하는 방법을 공유하겠습니다. 그것은 모두에게 도움이 될 수 있습니다.

진술: 저는 JS 및 H5를 처음 사용합니다. 이 문서에는 작성 방법과 알고리즘이 포함되어 있습니다. 더 나은 개선 사항이 있으면 제안해 주세요~

1 능력 요구 사항:
JavaScript 관련 지식, HTML5, json, 객체지향적 사고 등
2. 다음 작업을 완료해야 합니다.

1. 게임(새, 기둥 등 포함)을 디자인합니다. 명확한 논리를 따라야 합니다. 새는 수직으로 위쪽으로 던지고 자유 낙하하는 동작을 합니다. 기둥이 계속 생성되고 왼쪽으로 이동하면 기둥에서 새가 분리됩니다. 각각 독립됩니다.)

2. 날개를 펄럭일 수 없는 새를 그립니다.

3. 새가 날아가도록 합니다(자유 낙하). 마우스로 수직으로 던지기)

4 .논리적인 부분 (기둥이 왼쪽으로 움직이고, 새가 기둥에 부딪혀 게임이 종료되는 등)

5. 점수 계산 (기둥마다 점수가 1씩 추가됩니다) 통과)

6. 배경 추가(그림, 음악, 음향 효과 등)

Three. 쓰기 시작:

먼저 4개의 클래스를 만들어야 합니다: game.html(게임 실행에 사용됨), game. js(로직 부분 작성에 사용), Paint.js(객체 그리기에 사용), pojo.js(객체 생성 및 캡슐화에 사용)

game.html 클래스:

HTML5로 작성되었습니다. fef50554eca1a427827adaa329da8122을 추가해야 하는데 저는 여백을 0으로 설정하는 데 익숙합니다.

<!DOCTYPE HTML>
<html>
	<head>
		<meta charset="utf-8" />
		<title>flappy bird</title>
		
		<style>
		/*设置边距为0*/
			body{
				margin:0px;
				overflow:hidden;
			}
		/*加背景*/
			#can1{
				background-image: url(背景.jpg);
				background-size:100%100%;
			}
		</style>
		<script type="text/javascript" src="pojo.js"></script>
		<script type="text/javascript" src="game.js"></script>
		<script type="text/javascript" src="paint.js"></script>
		<!--调用run()-->
		<script>
		    window.onload = function (){
			run();
		    };
		</script>
	</head>
	<body>
		<!--画布标签,设置长宽像素-->
		<canvas id="can1" width="1536" height="733"></canvas>
		<!--加入背景音乐-->
		<audio src="bgm.mp3" autoplay loop></audio>
		<!--加入点击鼠标触发的音效-->
		<audio id="audio1" autoplay></audio>
	</body>
</html>

사실 run() 메서드는 html 파일에서 호출되며 5ba626b379994d53f7acf72a64f9b697 태그와 b97864c2e0ef2353a16c4d64c7734e92 ; 오디오 파일을 로드하기 위해 6c04bd5ca3fcae76e30b72ad730ca86d에 기록됩니다.

pojo.js 클래스: 클래스를 저장하는 데 사용되며 두 개의 Category: Bird's Pillar가 필요합니다. 여기서는 간단한 버전을 수행하므로 새가 원 근사값으로 대체되어 후속 충돌 감지를 더 쉽게 작성할 수 있습니다. 그 중 결정된 값을 직접 쓰고, 변수값을 할당하지 않습니다.

작성 형식은 다음과 같습니다.

//鸟类(圆代替)
function Bird(color){
	//鸟的颜色
	this.color = color;
	//鸟巩膜的颜色
	this.eyeColor = &#39;white&#39;;
	//鸟巩膜的半径
	this.eyeRadius = 10;
	//鸟瞳孔的颜色
	this.eyeInsideColor = &#39;black&#39;;
	//鸟瞳孔的半径
	this.eyeInsideRadius = &#39;2.5&#39;;
	//鸟初始位置
	this.left = 100;
	this.top = 300;
	//鸟身体半径
	this.size = 25;
	//鸟的速度
	this.v = 0;		//向下为+	向上为-
	//分数计算
	this.score = 0;
	//是否存活
	this.isLive = true;
}

참고: 새의 모든 속성을 고려하여 캡슐화하고 game.js에서 사용해야 합니다

그런 다음 기둥 클래스:

//柱子类
//上面下面各一个,在一个竖直线上;
//上下柱子的间隔固定;
//左右两列柱子间隔固定;
//柱子的粗细固定;
//柱子相对鸟的速度
function Pillar(position, length){
	//柱子颜色
	this.color = &#39;lime&#39;;
	//柱子向左移动速度
	this.v = 8;
	//柱子宽度
	this.width = 80;
	//柱子位置,是每个柱子左上角的位置
	this.position = position;
	//柱子长度
	this.length = length;
	//柱子是否存在,意思一会解释
	this.isLive = true;
	//鸟是否通过当前柱子
	this.isPass = false;
}

다음으로 Paint.js 클래스를 작성해야 합니다. 이 클래스도 그리기 위해서는 5ba626b379994d53f7acf72a64f9b697를 사용해야 합니다.

먼저, 페인트를 작성하는 것이 좋습니다. .js 매번 맨 앞에 배치: 화면을 지웁니다(깨끗하지 않으면 마지막 그림이 그대로 남아 "움직임 트랙"이 됩니다).

//清屏
function clearScreen(ctx){
	ctx.clearRect(0, 0, 1536, 750);
}

그런 다음 새를 그립니다. 새 그리기, 나중에 코드로 그릴 수 있도록 새의 전체적인 모양을 그릴 때 그리기 도구를 사용하는 것이 좋습니다. 이것이 제가 디자인한 새의 패턴입니다. (날개가 좀 복잡해서 그렇지 않습니다.) 아직 어떻게 그리는지 몰라서 프로그램에서는 그리지 못했습니다 죄송합니다)


디자인이 완성되면 Paint.js에서 그리기 시작합니다. Paint.js 대신 game.js에서 캔버스 및 브러시 생성):

//画鸟,同样,所有的变量属性都要考虑到,并且在画巩膜,瞳孔,嘴唇时候都要以变量作为基准!里面的参数需要耐下心来调整。
function paintBird(ctx, left, top, size, color){
	ctx.beginPath();
	ctx.fillStyle = color;
	ctx.arc(left, top, size, 0, 2*Math.PI);//left:100	top:300		size:25
	ctx.fill();
	//画巩膜
	ctx.beginPath();
	ctx.fillStyle = bird.eyeColor;
	ctx.arc(left+13,top-8,bird.eyeRadius,0,2*Math.PI);
	ctx.fill();
	//画瞳孔
	ctx.beginPath();
	ctx.fillStyle = bird.eyeInsideColor;
	ctx.arc(left+18,top-8,bird.eyeInsideRadius,0,2*Math.PI);
	ctx.fill();
	//画嘴唇
	ctx.beginPath();
	ctx.strokeStyle = &#39;black&#39;;
	ctx.fillStyle = &#39;#FC6747&#39;;
	ctx.moveTo(left+4, top+3);
	ctx.lineTo(left+29, top+3);
	ctx.lineTo(left+33, top+6);
	ctx.lineTo(left+29, top+9);
	ctx.lineTo(left+32, top+12);
	ctx.lineTo(left+29, top+15);
	ctx.lineTo(left+4, top+15);
	ctx.lineTo(left+1, top+9);
	ctx.closePath();
	ctx.stroke();
	ctx.fill();
	ctx.beginPath();
	ctx.strokeStyle = &#39;black&#39;;
	ctx.moveTo(left+1,top+9);
	ctx.lineTo(left+29,top+9);
	ctx.stroke();
	//画翅膀,简易版先不画
}

이게 제가 그린 것입니다. (보고 있으면 웃고 싶어요 :) )


그런 다음 기둥을 그립니다.

//画柱子,我用了渐变色,虽然调整的并不是很好,但是还能看
function paintPillar(ctx, left, top, width, height){
	ctx.beginPath();
	var grd=ctx.createLinearGradient(left,top,left+height,top);
	grd.addColorStop(0,"green");
	grd.addColorStop(0.45,"white");
	grd.addColorStop(1,"green");
	ctx.fillStyle = grd;
	ctx.fillRect(left, top, width, height);
}

그리고 점수도 표시해야 합니다.

//计分
function paintScore(ctx, score){
	ctx.fillStyle = &#39;red&#39;;
	ctx.font = &#39;40px 黑体&#39;;
	ctx.fillText(&#39;分数:&#39;+score, 1320, 40);
}

이 시점에서 작업은 절반 정도 완료되었으며 다음 단계는 가장 어려운 부분인 game.js입니다. , 논리, 충돌, 이동, 득점 및 기타 여러 문제를 고려해야 합니다.

먼저 새의 자유낙하를 디자인하는 방법을 소개합니다.


위 방법에 따라 프로그램을 다음과 같이 작성합니다.

//点击鼠标事件
document.onmousedown = function (ev){
	//每点击一下出来音效
	var oAudio = document.getElementById(&#39;audio1&#39;);
	oAudio.src = &#39;扇翅膀emm.wav&#39;;
	//每点击一下做一次竖直上抛
	jump(bird);
}

//鸟自由落体
function drop(bird){
	bird.top = bird.top+bird.v;
	bird.v++;
}

//设置竖直上抛,直接将速度修改为负数即可
function jump(bird){
	bird.v = -13;
}

다음은 game.js입니다. 설명은 코드에 직접 넣어서 작성하면서 설명 :

//游戏逻辑中枢
//创建鸟的对象
var bird = new Bird('#FBEE30');
//创建柱子对象,把20个柱子放到数组中
var pillar = new Array(20);
var count = 0;
function run(){
	//获取画布
	var oCan = document.getElementById('can1');
	//创建画笔,2d
	var ctx = oCan.getContext('2d');
	//这timer1是游戏页面显示的东西的线程,每25毫秒刷新一次
	var timer1 = setInterval(function (){
		//每次画之前先清屏
		clearScreen(ctx);
		//判断鸟是否碰上柱子(是否死亡),死亡则弹框,结束线程
		if(!bird.isLive){
			alert('游戏结束!你的分数是'+bird.score+'!你好菜啊!')
			clearInterval(timer1);
			clearInterval(timer2);
		}
		//降落一下
		drop(bird);
		//判断鸟是否通过柱子
		for(var i = 0; i < pillar.length; i++){
			if(pillar[i] != null && pillar[i].isLive){
				//移动柱子
				movePillar(pillar[i]);
				//画柱子
				paintPillar(ctx, pillar[i].position.x, pillar[i].position.y, pillar[i].width, pillar[i].length);
				//计分,如果每个鸟的身体(圆)的左边通过一个柱子的最右边时,加一分
				if(pillar[i].position.x+pillar[i].width <= bird.left-bird.size && !pillar[i].isPass){
					//这里是因为每次通过上下两个柱子,如果是++的话就会每次加2,所以用+=0.5
					bird.score += 0.5;
					//通过的柱子将isPass设置为true,否则程序将默认鸟通过了所有柱子,就会加每次21
					pillar[i].isPass = true;
				}
			}
		}
		//检验鸟碰到柱子
		for(var i = 0; i < pillar.length; i++){
			if(pillar[i] != null && pillar[i].isLive){
				judgeImpact(bird, pillar[i]);
			}
		}
		//死亡后执行
		//画鸟
		paintBird(ctx, bird.left, bird.top, bird.size, bird.color);
		paintScore(ctx, bird.score);
	}, 25);

	//这个timer2是创建柱子的线程
	var timer2 = setInterval(function (){
		//上面的柱子的长度
		var l = Math.random()*330+100;
		//上面柱子,用json传变量
		pillar[count++] = new Pillar({x:1536, y:0}, l);
		//下面柱子
		pillar[count++] = new Pillar({x:1536, y:l+200}, 733-l-200);
		//如果柱子达到20个,自动将第20个设置为第0个,节省了内存,属于算法优化
		if(count == 20){
			count = 0;
		}
	}, 1100);
}

//点击鼠标事件
document.onmousedown = function (ev){
	//每点击一下出来音效
	var oAudio = document.getElementById(&#39;audio1&#39;);
	oAudio.src = &#39;扇翅膀emm.wav&#39;;
	//每点击一下做一次竖直上抛
	jump(bird);
}

//鸟自由落体
function drop(bird){
	bird.top = bird.top+bird.v;
	bird.v++;
}

//设置竖直上抛,直接将速度修改为负数即可
function jump(bird){
	bird.v = -13;
}

//移动柱子
function movePillar(pillar){
	pillar.position.x -= pillar.v;
	//如果柱子移动出画布,将isLive设置为false
	if(pillar.position.x < -80){
		pillar.isLive = false;
	}
}

//检测鸟和柱子碰撞
function judgeImpact(bird, pillar){
	//碰到上边框,死亡
	if(bird.top < bird.size){
		bird.isLive = false;
		bird.top = bird.size;
	}
	//碰到下边框,死亡
	else if(bird.top > 733-bird.size){
		bird.isLive = false;
		bird.top = 733-bird.size;
	}
	//当小鸟嵌入上下柱子的左边时(检验鸟是否碰到柱子的左边)
	if(Math.abs(bird.left-pillar.position.x) <= bird.size){
		//碰到上面柱子的左边
		if(pillar.position.y == 0){
			if(bird.top < pillar.length){
				bird.isLive = false;
				bird.left = pillar.position.x-bird.size;
			}
		}
		//碰到下面柱子的左边
		else{
			if(bird.top > pillar.position.y){
				bird.isLive = false;
				bird.left = pillar.position.x-bird.size;
			}
		}
	}
	//如果是上面柱子
	if(pillar.position.y == 0){
		//如果小鸟高度小于上面柱子
		if(Math.abs(bird.top-pillar.length) <= bird.size){
			//并且小鸟在两个柱子之间,死亡
			if(bird.left+bird.size > pillar.position.x && bird.left+bird.size < pillar.position.x+pillar.width+30){
				bird.isLive = false;
				bird.top = pillar.length+bird.size;
			}
		}
	}
	//如果是下面柱子
	else{
		//如果小鸟高度大于 下面柱子上方距离顶部的高度
		if(Math.abs(bird.top-pillar.position.y) <= bird.size){
			//并且小鸟在两个柱子之间,死亡
			if(bird.left+bird.size > pillar.position.x && bird.left+bird.size < pillar.position.x+pillar.width+30){
				bird.isLive = false;
				bird.top = pillar.position.y-bird.size;
			}
		}
	}
}
IV. 요약 :

1. Canvas나 js로 만들 때는 위의 클래스가 꼭 필요합니다(물론 결합해서 사용할 수도 있습니다). 각 클래스의 기능을 4가지 클래스로 나누었습니다. 그림을 그릴 때 개체의 매개변수를 사용하여 그려야 합니다. 예:

paintPillar(ctx, pillar[i].position.x, pillar[i].position.y, pillar[i].width, pillar[i].length);

2.关于柱子,我们必须符合这一条逻辑:先创建柱子数组(array),然后创建每个柱子,再画柱子,再移动,四个步骤缺一不可。

3.其中有对于算法的优化:在创建柱子的数组中,我们没有设置很多个柱子(比如说10000,虽然也不可能达到那么高的分),因为这样每25毫秒就要创建那么多柱子,再画和移动,内存占用很高,我们只用建立一个能存放20个柱子的数组,出屏幕的清掉,位置由新的代替,这样就极大程度减少了对内存的需要。

4.关于调试参数(比如说画鸟),要耐心调整,直到满意为止。

5.在检测鸟和柱子的碰幢时候,需要在逻辑上下功夫,建议先在稿纸上画出碰撞条件,再编写程序。

위 내용은 Flappy Bird 게임의 간단한 버전을 작성하기 위한 JavaScript 및 HTML5의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.