打飞机html + js + canvas

xiaoxiao2021-02-28  92

原文:http://blog.csdn.net/vivian_shuang/article/details/52159584

loading.js文件

// 三个参数:

// 1. 所有要加载的图片对象

// 2.加载进度函数

// 3.加载完成函数

function loading(imgsObjhandleObj) {

// 遍历对象,得到对象中属性的个数,即有多少张图片

var count 0;

var currentIndex 0;

for(prop in imgsObj) {

count++;

}

// 图片全部加载完成之后传出的对象

var imgObj {};

for(prop in imgsObj) {

var img = new Image();

img.src imgsObj[prop];

img.onload (function(prop) {

return function() {

currentIndex++;

var scale currentIndex count 100;

if(handleObj.progress) {

handleObj.progress(scale); 

}

imgObj[prop] this;

if(handleObj.complete) {

if(currentIndex == count) {

handleObj.complete(imgObj);

}

}

}

})(prop)

}

}

HTML文件

<!DOCTYPE html>

<html>

<head>

<meta charset="UTF-8">

<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no"/>

<title></title>

<style type="text/css">

* {

margin: 0;

padding: 0;

}

#gameOver {

width: 80px;

height: 35px;

border: 1px solid #000;

border-radius: 8px;

position: absolute;

top: 400px;

left: 50%;

transform: translateX(-40px);

text-align: center;    

display: none;

}

</style>

</head>

<body>

<div id="gameOver">游戏结束<button id="reStart">再来一次</button></div>

<canvas id="canvas" width="500" height="500"></canvas>

<script src="js/loading.js" type="text/JavaScript" charset="utf-8"></script>

<script type="text/javascript">

var gameOver document.getElementById("gameOver");

var reStart document.getElementById("reStart");

// 用来标记动画是否执行

var start true;

var canvas document.getElementById("canvas");

var ctx canvas.getContext("2d");

// 屏幕宽高

var SCREEN_WIDTH document.documentElement.clientWidth;

var SCREEN_HEIGHT document.documentElement.clientHeight;

canvas.width SCREEN_WIDTH;

canvas.height SCREEN_HEIGHT;

loading({

background_2"img/background_2.png",

hero_fly_1"img/hero_fly_1.png",

hero_fly_2"img/hero_fly_2.png",

bullet1"img/bullet1.png",

enemy1_fly_1"img/enemy1_fly_1.png",

enemy2_fly_1"img/enemy2_fly_1.png",

enemy3_fly_1"img/enemy3_fly_1.png",

enemy4_fly_1"img/enemy4_fly_1.png",

enemy5_fly_1"img/enemy5_fly_1.png",

enemy1_blowup_1"img/enemy1_blowup_2.png",

enemy1_blowup_2"img/enemy1_blowup_2.png",

enemy1_blowup_3"img/enemy1_blowup_3.png",

enemy1_blowup_4"img/enemy1_blowup_4.png",

enemy2_blowup_1"img/enemy2_blowup_2.png",

enemy2_blowup_2"img/enemy2_blowup_2.png",

enemy2_blowup_3"img/enemy2_blowup_3.png",

enemy2_blowup_4"img/enemy2_blowup_4.png",

enemy2_blowup_5"img/enemy2_blowup_5.png",

enemy2_blowup_6"img/enemy2_blowup_6.png",

enemy2_blowup_7"img/enemy2_blowup_7.png",

enemy3_blowup_1"img/enemy2_blowup_2.png",

enemy3_blowup_2"img/enemy3_blowup_2.png",

enemy3_blowup_3"img/enemy3_blowup_3.png",

enemy3_blowup_4"img/enemy3_blowup_4.png"

}, {

completemain

});

function rand(minmax) {

return Math.floor(Math.random() (max min 1min);

}

function checkP(obj1obj2) {

if(Math.abs(obj1.x obj1.w (obj2.x obj2.w 2)) <= obj1.w / 2 + obj2.w / && Math.abs(obj1.y obj1.h (obj2.y +obj2.h 2)) <= obj1.h / 2 + obj2.h / 2) {

return true;

else {

return false;

}

}

// 图片加载完成之后执行的函数

function main(obj) {

planeImg obj.hero_fly_1;

var plane {

imgplaneImg,

wplaneImg.width,

hplaneImg.height,

xSCREEN_WIDTH / 2 - planeImg.width / 2,

ySCREEN_HEIGHT planeImg.height 20

}

// 数组用来装子弹

var bullets [];

// 子弹

function Bullet() {

this.img obj.bullet1;

this.w this.img.width;

this.h this.img.height;

this.x plane.x plane.w / 2 - this.w / 2;

this.y plane.y this.h;

this.speed 1;

}

// 画子弹

Bullet.prototype.draw function() {

ctx.drawImage(this.img, this.x, this.y, this.w, this.h);

}

Bullet.prototype.move function() {

this.y -= this.speed;

}

// 判断子弹是否应该被清除

Bullet.prototype.canClear function() {

if(this.y <= -this.h) {

return true;

else {

return false;

}

}

// 敌机

function Enemy() {

this.img obj.enemy1_fly_1;

this.w this.img.width;

this.h this.img.height;

this.x rand(0, SCREEN_WIDTH this.w);

this.y = -this.h;

this.speed 2;

this.blood 1;

this.type 2;

// 图片的个数

this.length 4;

// 播放第几张,当这个值等于图片个数时,播放完成,应该把敌机删掉

this.playIndex 1;

}

Enemy.prototype.draw function() {

ctx.drawImage(this.img, this.x, this.y, this.w, this.h);

}

Enemy.prototype.move function() {

this.y += this.speed;

}

// 判断敌机是否应该被清除

Enemy.prototype.canClear function() {

if(this.y >= SCREEN_HEIGHT) {

return true;

else {

return false;

}

}

Enemy.prototype.changeType function(type) {

this.type type;

switch(this.type) {

case 1:

break;

case 2:

this.img obj.enemy2_fly_1;

this.w this.img.width;

this.h this.img.height;

this.x rand(0, SCREEN_WIDTH this.w);

this.y = -this.h;

this.blood 3;

this.speed 1;

break;

case 3:

this.img obj.enemy3_fly_1;

this.w this.img.width;

this.h this.img.height;

this.x rand(0, SCREEN_WIDTH this.w);

this.y = -this.h;

this.blood 2;

this.speed 1.5;

break;

default:

break;

}

}

// 爆炸动画

Enemy.prototype.play function() {

this.img obj["enemy1_blowup_" this.playIndex]

}

// 用来保存被击中的飞机的下标

var removeIndex [];

var enemys [];

var scrollY 0;

function drawAll() {

ctx.clearRect(00, SCREEN_WIDTH, SCREEN_HEIGHT);

scrollY++;

if(scrollY >= SCREEN_HEIGHT) {

scrollY 0;

}

// 给飞机换图片,模拟动态的效果

if(scrollY 10 == 0) {

plane.img obj.hero_fly_1;

else {

plane.img obj.hero_fly_2;

}

// 创建子弹

if(scrollY 20 == 0) {

var bullet = new Bullet();

bullets.push(bullet);

}

// 创建敌机

if(scrollY 40 == 0) {

var enemy = new Enemy(obj.enemy1_fly_1);

if(scrollY 299 == 0) {

enemy.changeType(2);

else if(scrollY == 0) {

enemy.changeType(3);

}

enemys.push(enemy);

}

// 画背景

ctx.drawImage(obj.background_2, 0, scrollY, SCREEN_WIDTH, SCREEN_HEIGHT);

ctx.drawImage(obj.background_2, 0, scrollY SCREEN_HEIGHT, SCREEN_WIDTH, SCREEN_HEIGHT);

// 画子弹

for(var 0; i bullets.length; i++) {

var bullet bullets[i];

bullet.draw();

bullet.move();

if(bullet.canClear()) {

bullets.splice(i, 1);

i--;

}

}

// 画敌机

for(var 0; i enemys.length; i++) {

var enemy enemys[i];

if(enemy.canClear()) {

enemys.splice(i, 1);

i--;

}

enemy.draw();

enemy.move();

}

// 画飞机

ctx.drawImage(plane.img, plane.x, plane.y /*, plane.w, plane.h*/ );

// 检测碰撞

for(var 0; i bullets.length; i++) {

for(var 0; j enemys.length; j++) {

if(checkP(bullets[i], enemys[j])) {

enemys[j].blood--;

if(enemys[j].blood == 0) {

// 先删飞机,后删子弹

// enemys.splice(j, 1);

// 记录下被击中敌机

removeIndex.push(enemys[j]);

}

bullets.splice(i, 1);

// 在当前这一帧画面内,只要判断一次碰撞,只要有碰撞,后面的就不需要再判断了,新的碰撞会产生在之后的画面里

break;

}

}

}

// 处理敌机爆炸的动画

// 不等于-1表示,某个敌机被击中,需要动画

if(removeIndex.length 0) {

for(var 0; i removeIndex.length; i++) {

var enemy removeIndex[i];

// 图片改变

enemy.playIndex++;

enemy.play();

// 如果图片换完

if(enemy.playIndex == enemy.length) {

// 删掉

for (var 0; j enemys.length; j++) {

if (enemy === enemys[j]) {

enemys.splice(j,1);

}

}

// removeIndex改为-1,等待接收之后的值

removeIndex.splice(i, 1);

if(i removeIndex.length) {

i--;

}

}

}

}

// 检测飞机碰撞

for(var 0; i enemys.length; i++) {

if(checkP(plane, enemys[i])) {

gameOver.style.display "block";

start false;

}

}

if(start) {

window.requestAnimationFrame(drawAll);

}

}

drawAll();

reStart.onclick function() {

// 防止之前的敌机爆炸未完成,开始新游戏时清空

removeIndex [];

// 调整飞机位置

plane.x SCREEN_WIDTH / 2 - planeImg.width / 2;

plane.y SCREEN_HEIGHT planeImg.height 20;

// 清空子弹和敌机

bullets [];

enemys [];

// 重新开始绘制

gameOver.style.display "none";

start true;

drawAll();

}

canvas.addEventListener("touchstart"function() {

var event.touches[0].clientX;

var event.touches[0].clientY;

// 判断有没有点到飞机

if(x >= plane.x && <= plane.x plane.w && >= plane.y && <= plane.y plane.h) {

// 绑定手势移动事件

var disX plane.x;

var disY plane.y;

canvas.addEventListener("touchmove"function() {

var event.touches[0].clientX;

var event.touches[0].clientY;

plane.x disX;

plane.y disY;

}, false);

}

}, false);

canvas.addEventListener("touchstart"function() {

canvas.addEventListener("touchmove"function() {

event.preventDefault();

}, false);

}, false);

}

</script>

</body>

</html>

转载请注明原文地址: https://www.6miu.com/read-55809.html

最新回复(0)