js實現(xiàn)飛機大戰(zhàn)游戲
更新時間:2020年08月26日 10:16:30 作者:小時俞
這篇文章主要為大家詳細介紹了js實現(xiàn)飛機大戰(zhàn)游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
本文實例為大家分享了js實現(xiàn)飛機大戰(zhàn)游戲的具體代碼,供大家參考,具體內(nèi)容如下
CSS部分的代碼:
<style>
* {
margin: 0px;
padding: 0px;
}
canvas{
border: 1px solid #000;
display: block;
margin: auto;
}
</style>
JavaScript代碼:
<!-- 先創(chuàng)建一個畫布 -->
<canvas id="canvas" width="480" height="640"></canvas>
<script>
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
// 0游戲初始化
// 0.1定義游戲開始的五個階段
var START = 0;
var STARTING = 1;
var RUNNING = 2;
var PAUSE = 3;
var GAMEOVER = 4;
// 0.2 定義一個自己的狀態(tài),時刻去和上面的五個狀態(tài)作比較
// 0.3 頁面加載時
var state = START;
// 0.4 背景圖片的寬和高
var WIDTH = 480;
var HEIGHT = 640;
// 0.5 定義分數(shù)
var score = 0;
// 0.6 定義生命條數(shù)
var life = 3;
// 1 游戲開始前
// 1.1 加載背景圖片
// 1.1.1 背景圖片的對象
var bg = new Image();// 創(chuàng)建一個背景圖片
bg.src = "images/background.png";
// 1.1.2 背景圖片的數(shù)據(jù)
var BG = {
imgs: bg,
width: 480,
height: 852
}
// 1.1.3 背景圖片的構造函數(shù)
function Bg(config) {
this.imgs = config.imgs;
this.width = config.width;
this.height = config.height;
// 繪制圖片的坐標(兩張背景圖片進行輪流滑動)
this.x1 = 0;
this.y1 = 0;
this.x2 = 0;
this.y2 = -this.height;
// 背景圖片繪制
this.paint = function () {
context.drawImage(this.imgs, this.x1, this.y1);
context.drawImage(this.imgs, this.x2, this.y2);
}
// 圖片的運動
this.step = function () {
this.y1++;
this.y2++;
// 判斷圖片的臨界點
if (this.y1 == this.height) {
this.y1 = -this.height;
}
if (this.y2 == this.height) {
this.y2 = -this.height;
}
}
}
// 1.1.4創(chuàng)建對象
var sky = new Bg(BG);
// console.log(sky);
// 1.2 創(chuàng)建頁面加載時的飛機大戰(zhàn)圖片
var logo = new Image();
logo.src = "images/start.png";
// 2.游戲開始前
// 2.1 開始前動畫的對象
var loadings = [];
loadings[0] = new Image();
loadings[0].src = "images/game_loading1.png";
loadings[1] = new Image();
loadings[1].src = "images/game_loading2.png";
loadings[2] = new Image();
loadings[2].src = "images/game_loading3.png";
loadings[3] = new Image();
loadings[3].src = "images/game_loading4.png";
// 2.2 開始前加載的動畫圖片的數(shù)據(jù)
var LOADINGS = {
imgs: loadings,
length: loadings.length,
width: 186,
height: 38
}
// 2.3 開始前動畫的構造函數(shù)
function Loading(config) {
this.imgs = config.imgs;
this.length = config.length;
this.width = config.width;
this.height = config.height;
// 定義一個索引
this.startIndex = 0;
// 繪制
this.paint = function () {
context.drawImage(this.imgs[this.startIndex], 0, HEIGHT - this.height);
}
// 定義一個速度
this.time = 0;
this.step = function () {
this.time++;
if (this.time % 3 == 0) {
// 頁面加載時下面小飛機運行的速度
this.startIndex++;
}
// 當動畫運行完成進入下一個階段
if (this.startIndex == this.length) {
state = RUNNING;
}
}
}
// 2.4創(chuàng)建對象
var loading = new Loading(LOADINGS);
// 2.5綁定時間
canvas.onclick = function () {
if (state == START) {
state = STARTING;
}
}
// 3.1.1游戲開始時的圖片
var heros = [];
heros[0] = new Image();
heros[0].src = "images/hero1.png";
heros[1] = new Image();
heros[1].src = "images/hero2.png";
heros[2] = new Image();
heros[2].src = "images/hero_blowup_n1.png";
heros[3] = new Image();
heros[3].src = "images/hero_blowup_n2.png";
heros[4] = new Image();
heros[4].src = "images/hero_blowup_n3.png";
heros[5] = new Image();
heros[5].src = "images/hero_blowup_n4.png";
// 3.1.2游戲開始時加載數(shù)據(jù)
var HEROS = {
imgs: heros,
length: heros.length,
width: 99,
height: 124,
// 我方飛機有兩種狀態(tài),增加標識
frame: 2
}
// 3.1.3我方飛機的構造器
function Hero(config) {
this.imgs = config.imgs;
this.length = config.length;
this.width = config.width;
this.height = config.height;
this.frame = config.frame;
// 定義索引
this.startIndex = 0;
// 繪制坐標
this.x = WIDTH / 2 - this.width / 2;
this.y = HEIGHT - 150;
// 增加標識符
this.down = false; //表示一直沒有撞擊
// 增加標識符
this.candel = false; //表示撞擊以后的動畫是否運行完成,完成以后的恢復運行的狀態(tài)
// 定義繪制方法
this.paint = function () {
context.drawImage(this.imgs[this.startIndex], this.x, this.y)
}
// 定義運動的方法
this.step = function () {
// 兩個狀態(tài)
// 1.正常運動狀態(tài)
// 2.碰撞以后的狀態(tài)
if (!this.down) {//正常運動狀態(tài)
// 沒有發(fā)生撞擊的時候 一直在0和1之間切換
this.startIndex++;
this.startIndex = this.startIndex % 2;
}
else {//撞擊以后的狀態(tài)
// 腳標就要不停的加1,模擬出從碰撞到爆炸完成的動畫
this.startIndex++;
// 判斷是否完成撞擊
if (this.startIndex == this.length) {
life--//爆炸一次生命值減1;
if (life == 0) {
state = GAMEOVER;
// 如果死了,動畫保存最后一張爆破的照片
this.startIndex = this.length - 1;
}
else {
hero = new Hero(HEROS);
}
}
}
}
// 我方飛機增加射擊方法
this.time = 0;
this.shoot = function () {
this.time++;
if (this.time % 2 == 0) {
bullets.push(new Bullet(BULLET));
}
}
// 撞擊以后觸發(fā)
this.bang = function () {
this.down = true;
}
}
// 3.1.4我方飛機的對象
var hero = new Hero(HEROS);
// 3.1.5綁定鼠標移動事件
canvas.onmousemove = function (e) {
if (state == RUNNING) {
var x = e.offsetX;
var y = e.offsetY;
hero.x = x - hero.width / 2;
hero.y = y - hero.height / 2;
}
}
// 3.2 繪制子彈
// 3.2.1 圖片
var bullet = new Image();
bullet.src = "images/bullet1.png";
// 3.2.2數(shù)據(jù)
var BULLET = {
imgs: bullet,
width: 9,
height: 21
}
// 3.2.3 子彈的構造函數(shù)
function Bullet(config) {
this.imgs = config.imgs;
this.width = config.width;
this.height = config.height;
// 子彈坐標
this.x = hero.x + hero.width / 2 - this.width / 2;
this.y = hero.y - this.height;
// 繪制
this.paint = function () {
context.drawImage(this.imgs, this.x, this.y);
}
// 運動 往上運動
this.step = function () {
this.y -= 10;
}
this.candel = false;//表示撞擊以后的動畫是否運行完成,完成以后的恢復運行的狀態(tài)
this.bang = function () {
this.candel = true;
}
}
// 3.2.4 存放所有子彈
var bullets = [];
// 3.2.5 繪制所有子彈
function bulletsPaint() {
for (var i = 0; i < bullets.length; i++) {
bullets[i].paint();
}
}
// 3.2.6 繪制所有子彈的運動
function bulletsStep() {
for (var i = 0; i < bullets.length; i++) {
bullets[i].step();
}
}
// 3.2.7 刪除子彈
function bulletsDel(){
for(var i = 0; i < bullets.length;i++){
if(bullets[i].y < -bullets[i].height || bullets[i].candel){
bullets.splice(i,1)
}
}
// console.log(bullets)
}
// 3.3 敵方飛機
// 3.3.1 敵方飛機的圖片(3種)
// 小號
var enemy1 = [];
enemy1[0] = new Image();
enemy1[0].src = "images/enemy1.png";
enemy1[1] = new Image();
enemy1[1].src = "images/enemy1_down1.png";
enemy1[2] = new Image();
enemy1[2].src = "images/enemy1_down2.png";
enemy1[3] = new Image();
enemy1[3].src = "images/enemy1_down3.png";
enemy1[4] = new Image();
enemy1[4].src = "images/enemy1_down4.png";
// 中號
var enemy2 = [];
enemy2[0] = new Image();
enemy2[0].src = "images/enemy2.png";
enemy2[1] = new Image();
enemy2[1].src = "images/enemy2_down1.png";
enemy2[2] = new Image();
enemy2[2].src = "images/enemy2_down2.png";
enemy2[3] = new Image();
enemy2[3].src = "images/enemy2_down3.png";
enemy2[4] = new Image();
enemy2[4].src = "images/enemy2_down4.png";
// 大號
var enemy3 = [];
enemy3[0] = new Image();
enemy3[0].src = "images/enemy3_n1.png";
enemy3[1] = new Image();
enemy3[1].src = "images/enemy3_n2.png";
enemy3[2] = new Image();
enemy3[2].src = "images/enemy3_down1.png";
enemy3[3] = new Image();
enemy3[3].src = "images/enemy3_down2.png";
enemy3[4] = new Image();
enemy3[4].src = "images/enemy3_down3.png";
enemy3[5] = new Image();
enemy3[5].src = "images/enemy3_down4.png";
enemy3[6] = new Image();
enemy3[6].src = "images/enemy3_down5.png";
enemy3[7] = new Image();
enemy3[7].src = "images/enemy3_down6.png";
// 3.2.2 數(shù)據(jù)
var ENEMY1 = {
imgs: enemy1,
length: enemy1.length,
width: 57,
height: 51,
type: 1, //增加標識符,區(qū)分飛機的種類。小號的設置成1
frame: 1, //增加標識符,1種狀態(tài)就為1,2種狀態(tài)就為2
life: 1, //增加標識符,被子彈打擊的次數(shù)
score: 1 //打倒一只的得分
}
var ENEMY2 = {
imgs: enemy2,
length: enemy2.length,
width: 69,
height: 95,
type: 2, //增加標識符,區(qū)分飛機的種類。中號的設置成2
frame: 1, //增加標識符,1種狀態(tài)就為1,2種狀態(tài)就為2
life: 3, //增加標識符,被子彈打擊的次數(shù)
score: 5 //打倒一只的得分
}
var ENEMY3 = {
imgs: enemy3,
length: enemy3.length,
width: 169,
height: 258,
type: 3, //增加標識符,區(qū)分飛機的種類。大號的設置成3
frame: 2, //增加標識符,,1種狀態(tài)就為1,2種狀態(tài)就為2
life: 10, //增加標識符,被子彈打擊的次數(shù)
score: 15 //打倒一只的得分
}
// 3.3.3 構造函數(shù)
function Enemy(config) {
this.imgs = config.imgs;
this.length = config.length;
this.width = config.width;
this.height = config.height;
this.type = config.type;
this.frame = config.frame;
this.life = config.life;
this.score = config.score;
// 圖片的索引
this.startIndex = 0
this.down = false; //表示一直沒有撞擊
this.candel = false; //表示撞擊以后的動畫是否運行完成,完成以后的恢復運行的狀態(tài)
// 繪制坐標
this.x = Math.random() * (WIDTH - this.width);
this.y = -this.height;
// 繪制的方法
this.paint = function () {
context.drawImage(this.imgs[this.startIndex], this.x, this.y);
}
// 運動方法
this.step = function(){
if(!this.down){ //正常
// 小號的,中號 角標始終是0
// 大號的是在0和1之間切換
this.startIndex ++;
this.startIndex = this.startIndex % this.frame;
this.y += 2;
}else { //爆炸
this.startIndex ++;
if(this.startIndex == this.length){
this.candel = true;
this.startIndex = this.length - 1;
}
}
}
// 爆炸的方法
this.bang = function(){
this.life -- ;
if(this.life == 0){
this.down = true;
score += this.score;
}
}
// 檢測是否撞擊
this.checkHit = function(wo){
// 1.撞擊到子彈
// 2.撞擊到我方飛機
return wo.y + wo.height > this.y
&& wo.x + wo.width > this.x
&& wo.y < this.y + this.height
&& wo.x < this.x + this.width;
}
}
// 3.3.4 創(chuàng)建數(shù)組 存儲敵方飛機
var enemies = [];
// 3.3.5 創(chuàng)建飛機
function enterEnemies() {
var num = Math.random();
if (num < 0.1) {
enemies.push(new Enemy(ENEMY1))
} else if (num < 0.15) {
enemies.push(new Enemy(ENEMY2))
} else if (num < 0.16) {
enemies.push(new Enemy(ENEMY3))
}
}
// 3.3.6 繪制
function paintEnemies() {
for (var i = 0; i < enemies.length; i++) {
enemies[i].paint();
}
}
// 3.3.7 運動
function stepEnemies() {
for (var i = 0; i < enemies.length; i++) {
enemies[i].step();
}
}
// 3.3.8 刪除
function delEnemies(){
for(var i = 0;i < enemies.length;i++){
if(enemies[i].y > HEIGHT || enemies[i].candel){
enemies.splice(i,1)
}
}
}
// 3.4 檢測撞擊
function hitEnemies() {
for (var i = 0; i < enemies.length; i++) {
if (enemies[i].checkHit(hero)) {
enemies[i].bang();
hero.bang();
}
for (var j = 0; j < bullets.length; j++) {
if (enemies[i].checkHit(bullets[j])) {
enemies[i].bang();
bullets[j].bang();
}
}
}
}
// 3.5 我方飛機的生命和得分
function paintText(){
context.font = "bold 30px 微軟雅黑";
context.fillText("SCORE:" + score,10,30);
context.fillText("LIFE:" + life,380,30)
}
// 4.暫停階段
canvas.onmouseover=function(){
if(state==PAUSE){
state=RUNNING;
}
}
canvas.onmouseout=function(){
if(state==RUNNING){
state=PAUSE;
}
}
var pause=new Image();
pause.src="images/game_pause_nor.png"
function paintdown(){
context.drawImage(pause,220,300)
}
// 5.gameover階段
function paintOver(){
context.font="bold 50px 微軟雅黑";
context.fillText("GAME OVER",110,300);
}
// 定時器加載,使圖片緩慢往下面移動
setInterval(function () {
sky.paint();
sky.step();
if (state == START) {
context.drawImage(logo, 40, 0);//繪制在正中間
} else if (state == STARTING) {
loading.paint();
loading.step();
} else if (state == RUNNING) {
hero.paint();
hero.step();
hero.shoot();
bulletsPaint();
bulletsStep();
bulletsDel();
enterEnemies();
paintEnemies();
stepEnemies();
delEnemies();
hitEnemies();
paintText();
}else if(state==PAUSE){
hero.paint();
bulletsPaint();
paintEnemies();
paintText();
paintdown();
}else if(state==GAMEOVER){
hero.paint();
bulletsPaint();
paintEnemies();
paintText();
paintdown();
paintOver();
}
}, 100)
</script>
更多有趣的經(jīng)典小游戲?qū)崿F(xiàn)專題,分享給大家:
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
javascript中將Object轉(zhuǎn)換為String函數(shù)代碼 (json str)
下面的代碼就是想將Object轉(zhuǎn)換為String函數(shù),需要的朋友可以參考下2012-04-04
javascript 獲取url參數(shù)和script標簽中獲取url參數(shù)函數(shù)代碼
不要在方法中調(diào)用方法,否則可能始終獲取的是最后一個js的文件的參數(shù),要在方法中使用,請先用變量保存,在方法中直接獲取2010-01-01
微信小程序通過點擊事件跨頁面?zhèn)鲄⒓癲ata-方法傳參(data-)的示例詳解
在?vue?中,我們可以直接在點擊事件中放入傳遞的參數(shù)進行傳參;然而微信小程序中并不適用這樣的寫法,但是微信小程序可以通過自定義屬性從而綁定參數(shù)使用,這篇文章主要介紹了微信小程序通過點擊事件跨頁面?zhèn)鲄⒁约癲ata-方法傳參(data-),需要的朋友可以參考下2023-12-12

