前言:
很早就想写一个休闲小游戏了,今天突然心血来潮,所以写了一个飞机大战的小游戏,代码很简单,接下来就开始上代码了.
我们首先来看一下我们的层级结构:
如图所示:
audio文件下面的是我们所需要的游戏音频,可以自行添加,也可不添加。
main.css
代码如下:
/*
* @Author: Marte
* @Date: 2018-06-07 11:33:08
* @Last Modified by: Marte
* @Last Modified time: 2018-06-11 15:41:20
*/
'use strict';
window.onload = function(){
myGame.init();
}
var myGame = {
data : { //飞机数据
BULLET : {
p:{name:'b1',speed:30},
e:{name:'b2',speed:30}
},
PLANE : {},
eArr : [2,1,1,3,3,1,1,3,3,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,1,2,0,0,0,0,
3,3,2,3,3,1,1,3,3,2],
ENEMY : {
blood : [2,20,50,10],
score : [2,20,50,10],
speed : [1,3,1,2],
bullet : [false,false,false,true],
_width : [126,108,126,120],
_height : [81,81,87,101]
}
},
init : function(){ //初始化
var layout = document.getElementById('layout'),
mystart = document.getElementById('start'),
score = document.getElementById('score'),
That = this;
this.layout = layout;
this.mystart = mystart;
this.score = score;
document.getElementById('startBtn').onclick = function() {
mystart.style.display = 'none';
That.createPlane();
document.getElementsByClassName('score')[0].style.display = 'block';
document.getElementById("fire").play();
};
},
createPlane : function(){ //创建飞机
var That = this;
var plane = document.createElement('div');
plane.className = 'plane';
plane.style.width = '110px';
plane.style.left = (this.layout.offsetWidth - plane.offsetWidth) / 2 + 'px';
this.layout.append( plane );
this.plane = plane;
plane.itimer1 = setInterval(function(){
That.createBullet(That.data.BULLET.p.name,plane, 0, 1);
},150);
this.bindPlane(plane);
plane.itimer2 = setInterval(function(){
That.createEnemy();
},1000)
},
createEnemy : function(){ //创建敌机
var e = this.data.eArr[~~(Math.random()*60)];
var ey = document.createElement('div');
ey.className = 'enemy enemy' + e;
ey.style.cssText = 'width:' + this.data.ENEMY._width[e] + 'px; height:' + this.data.ENEMY._height[e] + 'px';
ey.style.left = ~~(Math.random()*(this.layout.offsetWidth - this.data.ENEMY._width[e])) + 'px';
ey.setAttribute('blood', this.data.ENEMY.blood[e]);
ey.setAttribute('score', this.data.ENEMY.score[e]);
ey.setAttribute('speed', this.data.ENEMY.speed[e]);
ey.setAttribute('bullet', this.data.ENEMY.bullet[e]);
this.layout.append(ey);
//子弹碰撞
if(this.data.ENEMY.bullet[e]){
var That = this;
ey.timer1 = setInterval(function(){
That.createBullet(That.data.BULLET.e.name,ey, ey.offsetHeight, -1);
},2000);
}
this.runEnemy(ey);
},
runEnemy : function(obj){ //敌机运动
var That = this;
obj.timer = setInterval(function(){
obj.style.top = (obj.offsetTop + parseInt(obj.getAttribute('speed'))) + 'px';
if(obj.offsetTop > That.layout.offsetHeight){
clearInterval(obj.timer);
obj.parentNode.removeChild(obj);
};
for(var i = 0, e = document.getElementsByClassName('enemy') ,len = e.length; i<len; i++){
if(That.TC(e[i],That.plane) ){ //与敌机碰撞]
clearInterval(obj.timer);
That.gameOver();
That.plane.parentNode.removeChild(That.plane);
That.plane = null;
e[i].parentNode.removeChild(e);
}
}
},30)
},
createBullet : function(name, obj, h, direction){ //创建子弹
var bt = document.createElement('div');
bt.className = name;
var _p = obj;
bt.style.top = (_p.offsetTop + h - bt.offsetHeight * direction) - 10 + 'px';
bt.style.left = (_p.offsetLeft + _p.offsetWidth/2) - 4 + 'px';
this.layout.append(bt);
if(bt.classList.contains('b1')){
this.runBullet(bt,0,-30);
}else{
this.speedDecomposition(this.plane,bt);
this.runBullet(bt,this.vx,this.vy);
}
},
speedDecomposition : function(pl,bt){ //计算敌机子弹方向,击向飞机
var plleft = pl.offsetLeft,
pltop = pl.offsetTop,
btleft = bt.offsetLeft,
bttop = bt.offsetTop,
s = Math.sqrt((plleft - btleft)*(plleft - btleft) + (pltop - bttop)*(pltop - bttop)),
sin = (pltop - bttop) / s,
vy = 5*sin,
vx = Math.sqrt(5*5 - vy * vy);
this.vy = vy;
plleft > btleft ? this.vx = vx : this.vx = -vx;
},
runBullet : function(b,x,y){ //子弹运动
var That = this;
b.timer = setInterval(function(){
if(b.offsetTop <= 30 || b.offsetTop >= That.layout.offsetHeight || b.offsetLeft <= 0 || b.offsetLeft >= That.layout.offsetWidth){ //边界判断
clearInterval(b.timer);
That.layout.removeChild(b);
}else{
b.style.cssText = 'top : ' + (b.offsetTop + y) + 'px; left : ' + (b.offsetLeft + x) + 'px';
}
for(var i = 0, EN = document.getElementsByClassName('enemy'), len = EN.length ; i < len ; i++ ){
if(That.TC(EN[i],b) && b.classList.contains('b1')){
clearInterval(b.timer);
That.layout.removeChild(b);
var Blood = EN[i].getAttribute('blood') - 1;
if(Blood){
EN[i].setAttribute('blood',Blood);
}else{
document.getElementById("boom").play();
That.score.innerHTML = (parseInt(That.score.innerHTML) + parseInt(EN[i].getAttribute('score')));
EN[i].style.background = 'url(img/qw.png) center no-repeat / cover';
var pare = EN[i];
EN[i].classList.remove("enemy");
EN[i].timer = setTimeout(function(){That.layout.removeChild(pare)},400);
}
}
}
if(That.TC(That.plane,b) && b.classList.contains('b2')){
clearInterval(b.timer);
That.layout.removeChild(b);
That.layout.removeChild(That.plane);
That.gameOver();
}
},30)
},
bindPlane : function(p){ //控制飞机鼠标事件
var lagoutx = this.layout.offsetLeft,
lagouty = this.layout.offsetTop,
lagoutw = this.layout.offsetWidth,
lagouth = this.layout.offsetHeight;
p.onmousedown = function(event){
var px = p.offsetLeft,
py = p.offsetTop,
dx = event.clientX - lagoutx - p.offsetWidth/2,
dy = event.clientY - lagouty - p.offsetHeight/2;
document.onmousemove = function(event){
dx = event.clientX - lagoutx - p.offsetWidth / 2;
dy = event.clientY - lagouty - p.offsetHeight / 2;
if( dx <= 0 ){
dx = 0 ;
}else if( dx >= lagoutw - p.offsetWidth){
dx = lagoutw - p.offsetWidth;
}
if( dy <= 0 ){
dy = 0;
}else if( dy >= lagouth - p.offsetHeight){
dy = lagouth - p.offsetHeight;
}
p.style.cssText = 'left :' + dx +'px; top :' + dy + 'px';
}
document.onmouseup = function(event){
document.onmousemove = null;
}
}
},
gameOver : function(){
document.getElementById("fire").pause();
document.getElementById('bigboom').play();
clearInterval(this.plane.itimer2);
clearInterval(this.plane.itimer1);
this.mystart.style.display = 'block';
document.getElementsByClassName('score')[0].style.display = 'none';
document.getElementById('name-over').getElementsByTagName('i')[0].innerHTML = 'GAME OVER!';
document.getElementById('name-over').getElementsByTagName('p')[0].innerHTML = this.score.innerHTML;
document.getElementById('startBtn').value = 'AGAIN';
while(this.layout.hasChildNodes()){
this.layout.removeChild(this.layout.firstChild);
};
this.score.innerHTML = '0';
},
TC : function(obj1,obj2){ //碰撞检测
var t1 = obj1.offsetTop, //上
r1 = obj1.offsetLeft + obj1.offsetWidth, //右
b1 = obj1.offsetTop + obj1.offsetHeight, //下
l1 = obj1.offsetLeft, //左
t2 = obj2.offsetTop, //上
r2 = obj2.offsetLeft + obj2.offsetWidth, //右
b2 = obj2.offsetTop + obj2.offsetHeight, //下
l2 = obj2.offsetLeft; //左
if(t1 > b2 || b1 < t2 || r1 < l2 || l1 > r2){
return false;
}else{
return true;
}
},
}
img下方使我们所需要的图片,图片可自行修改
接下来是我们最重要的一个东西,也就是我们的main.js
main.js
代码如下:
/*
* @Author: Marte
* @Date: 2018-06-07 11:33:08
* @Last Modified by: Marte
* @Last Modified time: 2018-06-11 15:41:20
*/
'use strict';
window.onload = function(){
myGame.init();
}
var myGame = {
data : { //飞机数据
BULLET : {
p:{name:'b1',speed:30},
e:{name:'b2',speed:30}
},
PLANE : {},
eArr : [2,1,1,3,3,1,1,3,3,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,1,2,0,0,0,0,
3,3,2,3,3,1,1,3,3,2],
ENEMY : {
blood : [2,20,50,10],
score : [2,20,50,10],
speed : [1,3,1,2],
bullet : [false,false,false,true],
_width : [126,108,126,120],
_height : [81,81,87,101]
}
},
init : function(){ //初始化
var layout = document.getElementById('layout'),
mystart = document.getElementById('start'),
score = document.getElementById('score'),
That = this;
this.layout = layout;
this.mystart = mystart;
this.score = score;
document.getElementById('startBtn').onclick = function() {
mystart.style.display = 'none';
That.createPlane();
document.getElementsByClassName('score')[0].style.display = 'block';
document.getElementById("fire").play();
};
},
createPlane : function(){ //创建飞机
var That = this;
var plane = document.createElement('div');
plane.className = 'plane';
plane.style.width = '110px';
plane.style.left = (this.layout.offsetWidth - plane.offsetWidth) / 2 + 'px';
this.layout.append( plane );
this.plane = plane;
plane.itimer1 = setInterval(function(){
That.createBullet(That.data.BULLET.p.name,plane, 0, 1);
},150);
this.bindPlane(plane);
plane.itimer2 = setInterval(function(){
That.createEnemy();
},1000)
},
createEnemy : function(){ //创建敌机
var e = this.data.eArr[~~(Math.random()*60)];
var ey = document.createElement('div');
ey.className = 'enemy enemy' + e;
ey.style.cssText = 'width:' + this.data.ENEMY._width[e] + 'px; height:' + this.data.ENEMY._height[e] + 'px';
ey.style.left = ~~(Math.random()*(this.layout.offsetWidth - this.data.ENEMY._width[e])) + 'px';
ey.setAttribute('blood', this.data.ENEMY.blood[e]);
ey.setAttribute('score', this.data.ENEMY.score[e]);
ey.setAttribute('speed', this.data.ENEMY.speed[e]);
ey.setAttribute('bullet', this.data.ENEMY.bullet[e]);
this.layout.append(ey);
//子弹碰撞
if(this.data.ENEMY.bullet[e]){
var That = this;
ey.timer1 = setInterval(function(){
That.createBullet(That.data.BULLET.e.name,ey, ey.offsetHeight, -1);
},2000);
}
this.runEnemy(ey);
},
runEnemy : function(obj){ //敌机运动
var That = this;
obj.timer = setInterval(function(){
obj.style.top = (obj.offsetTop + parseInt(obj.getAttribute('speed'))) + 'px';
if(obj.offsetTop > That.layout.offsetHeight){
clearInterval(obj.timer);
obj.parentNode.removeChild(obj);
};
for(var i = 0, e = document.getElementsByClassName('enemy') ,len = e.length; i<len; i++){
if(That.TC(e[i],That.plane) ){ //与敌机碰撞]
clearInterval(obj.timer);
That.gameOver();
That.plane.parentNode.removeChild(That.plane);
That.plane = null;
e[i].parentNode.removeChild(e);
}
}
},30)
},
createBullet : function(name, obj, h, direction){ //创建子弹
var bt = document.createElement('div');
bt.className = name;
var _p = obj;
bt.style.top = (_p.offsetTop + h - bt.offsetHeight * direction) - 10 + 'px';
bt.style.left = (_p.offsetLeft + _p.offsetWidth/2) - 4 + 'px';
this.layout.append(bt);
if(bt.classList.contains('b1')){
this.runBullet(bt,0,-30);
}else{
this.speedDecomposition(this.plane,bt);
this.runBullet(bt,this.vx,this.vy);
}
},
speedDecomposition : function(pl,bt){ //计算敌机子弹方向,击向飞机
var plleft = pl.offsetLeft,
pltop = pl.offsetTop,
btleft = bt.offsetLeft,
bttop = bt.offsetTop,
s = Math.sqrt((plleft - btleft)*(plleft - btleft) + (pltop - bttop)*(pltop - bttop)),
sin = (pltop - bttop) / s,
vy = 5*sin,
vx = Math.sqrt(5*5 - vy * vy);
this.vy = vy;
plleft > btleft ? this.vx = vx : this.vx = -vx;
},
runBullet : function(b,x,y){ //子弹运动
var That = this;
b.timer = setInterval(function(){
if(b.offsetTop <= 30 || b.offsetTop >= That.layout.offsetHeight || b.offsetLeft <= 0 || b.offsetLeft >= That.layout.offsetWidth){ //边界判断
clearInterval(b.timer);
That.layout.removeChild(b);
}else{
b.style.cssText = 'top : ' + (b.offsetTop + y) + 'px; left : ' + (b.offsetLeft + x) + 'px';
}
for(var i = 0, EN = document.getElementsByClassName('enemy'), len = EN.length ; i < len ; i++ ){
if(That.TC(EN[i],b) && b.classList.contains('b1')){
clearInterval(b.timer);
That.layout.removeChild(b);
var Blood = EN[i].getAttribute('blood') - 1;
if(Blood){
EN[i].setAttribute('blood',Blood);
}else{
document.getElementById("boom").play();
That.score.innerHTML = (parseInt(That.score.innerHTML) + parseInt(EN[i].getAttribute('score')));
EN[i].style.background = 'url(img/qw.png) center no-repeat / cover';
var pare = EN[i];
EN[i].classList.remove("enemy");
EN[i].timer = setTimeout(function(){That.layout.removeChild(pare)},400);
}
}
}
if(That.TC(That.plane,b) && b.classList.contains('b2')){
clearInterval(b.timer);
That.layout.removeChild(b);
That.layout.removeChild(That.plane);
That.gameOver();
}
},30)
},
bindPlane : function(p){ //控制飞机鼠标事件
var lagoutx = this.layout.offsetLeft,
lagouty = this.layout.offsetTop,
lagoutw = this.layout.offsetWidth,
lagouth = this.layout.offsetHeight;
p.onmousedown = function(event){
var px = p.offsetLeft,
py = p.offsetTop,
dx = event.clientX - lagoutx - p.offsetWidth/2,
dy = event.clientY - lagouty - p.offsetHeight/2;
document.onmousemove = function(event){
dx = event.clientX - lagoutx - p.offsetWidth / 2;
dy = event.clientY - lagouty - p.offsetHeight / 2;
if( dx <= 0 ){
dx = 0 ;
}else if( dx >= lagoutw - p.offsetWidth){
dx = lagoutw - p.offsetWidth;
}
if( dy <= 0 ){
dy = 0;
}else if( dy >= lagouth - p.offsetHeight){
dy = lagouth - p.offsetHeight;
}
p.style.cssText = 'left :' + dx +'px; top :' + dy + 'px';
}
document.onmouseup = function(event){
document.onmousemove = null;
}
}
},
gameOver : function(){
document.getElementById("fire").pause();
document.getElementById('bigboom').play();
clearInterval(this.plane.itimer2);
clearInterval(this.plane.itimer1);
this.mystart.style.display = 'block';
document.getElementsByClassName('score')[0].style.display = 'none';
document.getElementById('name-over').getElementsByTagName('i')[0].innerHTML = 'GAME OVER!';
document.getElementById('name-over').getElementsByTagName('p')[0].innerHTML = this.score.innerHTML;
document.getElementById('startBtn').value = 'AGAIN';
while(this.layout.hasChildNodes()){
this.layout.removeChild(this.layout.firstChild);
};
this.score.innerHTML = '0';
},
TC : function(obj1,obj2){ //碰撞检测
var t1 = obj1.offsetTop, //上
r1 = obj1.offsetLeft + obj1.offsetWidth, //右
b1 = obj1.offsetTop + obj1.offsetHeight, //下
l1 = obj1.offsetLeft, //左
t2 = obj2.offsetTop, //上
r2 = obj2.offsetLeft + obj2.offsetWidth, //右
b2 = obj2.offsetTop + obj2.offsetHeight, //下
l2 = obj2.offsetLeft; //左
if(t1 > b2 || b1 < t2 || r1 < l2 || l1 > r2){
return false;
}else{
return true;
}
},
}
接下来就是我们的页面feiji.jsp
feiji.jsp
代码如下:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<head>
<meta charset="UTF-8" />
<meta name=viewport content="width=device-width, initial-scale=1">
<title>Plane wars</title>
<style type="text/css" media="screen">
*{
margin: 0;
padding: 0;
}
img{
border:0;
}
ol, ul ,li{list-style: none;}
html,body{
/* background: url('img/bj.jpg'); */
height:100%;
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
-khtml-user-select: none;
user-select: none;
}
.layout{
width:100%;
height:100%;
margin: 0 auto;
background: url('img/bj.jpg') center bottom /100% auto;
/* background:#505149; */
position: relative;
overflow: hidden;
animation:movebg 3000s linear infinite;
-moz-animation:movebg 3000s linear infinite; /* Firefox */
-webkit-animation:movebg 3000s linear infinite; /* Safari and Chrome */
-o-animation:movebg 3000s linear infinite; /* Opera */
}
.plane{
width:110px;
height:90px;
/* background:#fff; */
background:url('img/P.png') 0 -101px no-repeat;
position: absolute;
bottom:0;
left:50%;
cursor:pointer;
}
.b1{
width:5px;
height:15px;
border-radius:50% 50% 5px 5px;
background:#fff;
position: absolute;
top:-50px;
left:50%;
}
.enemy0{
width:126px;
height:81px;
/* background:yellow; */
background:url('img/P.png') -377px 0 no-repeat;
position: absolute;
top:-70px;
left:20px;
}
.enemy1{
width:108px;
height:81px;
/* background:green; */
background:url('img/P.png') 0 0 no-repeat;
position: absolute;
top:-150px;
left:600px;
}
.enemy2{
width:126px;
height:87px;
/* background:blue; */
background:url('img/P.png') -242px 0 no-repeat;
position: absolute;
top:-400px;
left:80px;
}
.enemy3{
width:120px;
height:101px;
/* background:red; */
background:url('img/P.png') -114px 0 no-repeat;
position: absolute;
top:-60px;
left:510px;
}
.b2{
width:10px;
height:10px;
position: absolute;
border-radius:50%;
left:50%;
bottom: -50px;
background:#fff;
}
.score{
display: none;
padding: 10px 15px;
font-size:30px;
font-weight:bold;
color:#99B2D6;
background:#031540;
border:5px solid #425579;
border-radius:0 50px 50px 0;
position: absolute;
top:20px;
left:20px;
z-index:1000000;
/* background:red; */
}
@keyframes movebg
{
from {background-position:0 10000%;} to {background-position:0 0%;}
}
@-moz-keyframes movebg /* Firefox */
{
from {background-position:0 10000%;} to {background-position:0 0;}
}
@-webkit-keyframes movebg /* Safari and Chrome */
{
from {background-position:0 10000%;} to {background-position:0 0%;}
}
@-o-keyframes movebg /* Opera */
{
from {background-position:0 10000%;} to {background-position:0 0;}
}
#start{
width: 100%;
height:100%;
background:rgba(0, 0, 0, 0.7);
position: absolute;
top:0;
left:0;
}
#startBtn{
background:blue;
color: #fff;
font-size:50px;
margin:100px 0 0 -115px;
padding: 10px 30px;
border:5px solid #fff;
border-radius:50px;
position: absolute;
top:50%;
left:50%;
outline:none;
cursor:pointer;
}
#name-over{
font-family:'微软雅黑';
width:100%;
padding: 120px 0 10px;
margin: -200px 0 0 0;
font-size:50px;
font-weight:bold;
text-align:center;
color:rgba(106,124,197,1);
line-height:70px;
background:rgba(106,124,197,0.5) url('img/P1.png') center 20px no-repeat;
position: absolute;
top:50%;
left:0;
}
</style>
</head>
<body>
<audio id="bgmuc" autoplay loop src="audio/bjyy.mp3"></audio>
<audio id="fire" loop src="audio/9519.mp3"></audio>
<audio id="boom" src="audio/baoza.mp3"></audio>
<audio id="bigboom" src="audio/bigboom.mp3"></audio>
<div class="layout" id="layout"></div>
<div class="score">得分:
<span id="score">0</span>
</div>
<div id="start">
<div id="name-over"><i>Plane Wars</i><p>0</p></div>
<input id="startBtn" type="button" name="mystartBtn" value="START">
</div>
</body>
<script src="js/main.js"></script>
</html>
效果如图所示:
谢谢大家,多多指教!!!