canvas,前端的游戏开发重要语言之一,对于特别热爱打游戏的我来说,这是一个充满吸引力的学习,这不,先写个小时候最经常玩的雷霆机小游戏。
这是游戏页面,游戏分为简单版和偏难版本,两者的区别是玩家战机的子弹数量。
�偏难版本
简单版本
游戏结束
说完游戏效果,来看看游戏里要实现的规则。
0.所有图片的预加载
1.玩家战机的绘制,敌方战机的绘制,子弹的绘制
2.玩家战机和敌方战机的碰撞检测,敌方战机和子弹的碰撞
3.分数的记录,其中消灭敌方战机有三种情况得分,第一种战机1分,第二种战机2分,第三种战机3分
4.键盘控制方向(注意组合键的使用)
5.玩家战机的生命值变化
6.游戏难度的设置
7.游戏声音的设置
以上几条则为这个游戏的核心实现
这里用构造函数实现会减少不必要的麻烦
为了方便看,下面是游戏完整代码
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<meta name="viewport" content="initial-scale=1">
<style type="text/css">
canvas{
border: 1px solid black;
position: absolute;
left: 40%;
right: 50%;
top: 100px;
}
.gameover{
width: 320px;
height: 568px;
font-size: 12px;
position: absolute;
left: 40%;
right: 50%;
top: 100px;
text-align: center;
border: 1px solid black;
background: #ffcc00;
}
.grade{
color: red;
}
.btn{
margin-top: 20px;
background: coral;
}
.img{
width: 200px;
margin-top: 10px;
}
.easy,.difficult{
width: 40px;
margin-right: 5px;
background: coral;
}
</style>
</head>
<body>
<canvas id="mycanvas" width="320" height="568"></canvas>
<div class="gameover">
<img src="img/gameover2.png" style="margin-top: 100px;"/><br />
<div class="fenShu">您的得分为:<span class="grade"></span>分</div>
<button class="btn"></button>
<div style="margin-top: 20px;">选择难度: <button class="easy">偏难</button><button class="difficult">简单</button></div>
<div>
<img src="img/3.png" alt="" class="img"/>
</div>
</div>
</body>
<script type="text/javascript">
//对象:主机,敌机,子弹
//方法:画,动
//碰撞:主机碰撞敌机,子弹碰撞敌机(像素碰撞-----会出现性能问题)
//玩法,声音(选做)
var gameover = document.getElementsByClassName("gameover")[0];
var gradeS = document.getElementsByClassName("grade")[0];
var btn = document.getElementsByClassName("btn")[0];
var fenShu = document.getElementsByClassName("fenShu")[0];
var easy = document.getElementsByClassName("easy")[0];
var difficult = document.getElementsByClassName("difficult")[0];
//第一步,预加载
fenShu.style.display = "none";
btn.innerHTML = "开始";
easy.onclick = function(){
var boss = 0;
start(boss);
}
difficult.onclick = function(){
var boss = 1;
start(boss);
}
function start(boss){
btn.onclick = function(){
gameover.style.display = "none";
game(boss);
}
}
function game(boss){
var imgArr = {
"bg":"img/background.png",
"herofly":"img/herofly.png",
"bullet2":"img/bullet2.png",
"bullet1":"img/bullet1.png",
"enemy1":"img/enemy1.png",
"enemy2":"img/enemy2.png",
"enemy3":"img/enemy3.png",
}
var imgLength = 0;
for(var i in imgArr){
imgLength++;
}
var loadArr = {};
var num = 0;
for(let i in imgArr){
var img = new Image();
img.src = imgArr[i];
img.onload = function(){
loadArr[i] = this;
num++;
if(num>=imgLength){
main(loadArr,boss);
}
}
}
}
function main(loadArr,boss){
var canvas = document.getElementById("mycanvas");
var context = canvas.getContext("2d");
canvas.width = loadArr.bg.width;
canvas.height = loadArr.bg.height;
/*******************用到的参数开始*************/
//控制背景图片
var a = 0;
var c = 0;
//子弹参数
var bullet = [];
var nums = 0;
//敌方战机参数
var s;
var airArrs = [];
//分数
var grade = 0;
/*****************用到的参数结束*************/
//加背景图片
function bgAct(c){
context.clearRect(0,0,canvas.width,canvas.height);
a = c;
context.drawImage(loadArr.bg,0,a);
context.drawImage(loadArr.bg,0,-canvas.height+a);
}
//主机对象
function Hero(x,y,blood,obj){
this.x = x,
this.y = y,
this.blood = blood,
this.obj = obj,
this.w = loadArr.herofly.width/5;
this.h = loadArr.herofly.height;
console.log(loadArr.herofly);
console.log(loadArr.herofly.width);
this.index = 0;
this.num = 0;
this.fx = "formal";
}
Hero.prototype.draw = function(){
this.num++;
if(this.blood<=0){
if(this.num%2==0){
this.index++;
}
}
context.drawImage(this.obj,this.index*this.w,0,this.w,this.h,this.x,this.y,this.w,this.h);
}
//子弹构造函数
function Bullet(x,y,power,obj,speed){
this.x = x;
this.y = y;
this.power = power;
this.obj = obj;
this.w = this.obj.width;
this.h = this.obj.height;
this.speed = speed;
}
Bullet.prototype.draw = function(){
context.drawImage(this.obj,0,0,this.w,this.h,this.x,this.y,this.w,this.h);
}
Bullet.prototype.move = function(){
this.y -= this.speed;
//清除子弹
if(this.y<0){
bullet.shift();
}
}
Bullet.prototype.isClear = function(){
if(this.y<0){
return true;
}else{
return false;
}
}
//敌方战机构造函数
function airplay(x,y,blood,obj,s,grade){
this.x = x;
this.y = y - obj.height;
this.blood = blood;
this.obj = obj;
this.s = s;
this.w = this.obj.width/this.s;
this.h = this.obj.height;
this.index = 0;
this.num = 0;
this.grade = grade;
}
airplay.prototype.draw = function(){
this.num++;
if(this.blood<=0){
if(this.num%6==0){
this.index++;
}
}
context.drawImage(this.obj,this.index*this.w,0,this.w,this.h,this.x,this.y,this.w,this.h);
}
airplay.prototype.move = function(){
this.y += 3;
if(this.y>=canvas.height){
airArrs.shift();
}
}
//实例化玩家战机
var x = 120;
var y = canvas.height - 82;
var newHero = new Hero(x,y,60,loadArr.herofly);
newHero.draw();
//实例化子弹
if(boss==0){
var newbullet = new Bullet(newHero.x+30,newHero.y-10,10,loadArr.bullet1,4);
newbullet.draw();
}
if(boss==1){
var newbullet = new Bullet(newHero.x+10,newHero.y-10,10,loadArr.bullet2,4);
newbullet.draw();
}
//实例化敌方战机
if(rand(0,30)<10){
s = 5;
var newairplay = new airplay(rand(0,canvas.width-loadArr.enemy1.width/5),0,1,loadArr.enemy1,s,1);
}else if(rand(0,30)<20 && rand(0,30)>=10){
s = 6;
var newairplay = new airplay(rand(0,canvas.width-loadArr.enemy2.width/6),0,2,loadArr.enemy2,s,2);
}else{
s = 10;
var newairplay = new airplay(rand(0,canvas.width-loadArr.enemy3.width/10),0,3,loadArr.enemy3,s,3);
}
newairplay.draw();
newairplay.move();
//玩家战机生命值
life(newHero.blood);
//做动画
function act(){
nums++;
context.clearRect(0,0,canvas.width,canvas.height);
c++;
if(Math.abs(a)>=canvas.height){
c = 0;
}
bgAct(c);
//玩家战机生命值
life(newHero.blood);
if(nums%50==0){
if(rand(0,30)<10){
s = 5;
var newairplay = new airplay(rand(0,canvas.width-loadArr.enemy1.width/5),0,1,loadArr.enemy1,s,1);
airArrs.push(newairplay);
}else if(rand(0,30)<20 && rand(0,30)>=10){
s = 6;
var newairplay = new airplay(rand(0,canvas.width-loadArr.enemy2.width/6),0,2,loadArr.enemy2,s,2);
airArrs.push(newairplay);
}else{
s = 10;
var newairplay = new airplay(rand(0,canvas.width-loadArr.enemy3.width/10),0,3,loadArr.enemy3,s,3);
airArrs.push(newairplay);
}
}
for(let i = 0;i<airArrs.length;i++){
airArrs[i].draw();
airArrs[i].move();
//敌机和玩家战机碰撞
if(airArrs[i]) {
if(airArrs[i].x<newHero.x+newHero.w && airArrs[i].x+airArrs[i].w>newHero.x && airArrs[i].y<newHero.y+newHero.h && airArrs[i].y+airArrs[i].h>newHero.y){
newHero.blood--;
//设置碰撞的声音
var audio = document.createElement("audio");
audio.src = "audio/enemy2_down.mp3";
audio.autoplay = "autoplay";
}
}
}
if(nums%10==0){
if(boss==0){
var newbullet = new Bullet(newHero.x+30,newHero.y-10,10,loadArr.bullet1,4);
}
if(boss==1){
var newbullet = new Bullet(newHero.x+10,newHero.y-10,10,loadArr.bullet2,4);
}
bullet.push(newbullet);
}
newHero.draw();
for(var i=0;i<bullet.length;i++){
bullet[i].draw();
bullet[i].move();
for(let j in airArrs){
//子弹和敌机碰撞
if(airArrs[j] && bullet[i]) {
if(bullet[i].x<airArrs[j].x+airArrs[j].w && bullet[i].x+bullet[i].w>airArrs[j].x &&bullet[i].y<airArrs[j].y+airArrs[j].h && bullet[i].y+bullet[i].h>airArrs[j].y){
airArrs[j].blood--;
var audio = document.createElement("audio");
audio.src = "audio/enemy3_down.mp3";
audio.autoplay = "autoplay";
if(airArrs[j].blood==0){
grade = grade + airArrs[j].grade++;
}
bullet.splice(i,1);
if(airArrs[j].index >= airArrs[j].s){
airArrs.splice(j,1);
break;
}
}
}
}
}
//循环声音
if(nums%5==0){
var audio = document.createElement("audio");
audio.src = "audio/bullet.mp3";
audio.autoplay = "autoplay";
}
var www = window.requestAnimationFrame(act);
//如果玩家战机死亡的一系列操作
if(newHero.blood <= 0){
if(nums%10==0){
cancelAnimationFrame(www);
gameover.style.display = "block";
fenShu.style.display = "block";
btn.innerHTML = "重新开始";
gradeS.innerHTML = grade;
audios = document.createElement("audio");
audios.src = "audio/game_music.mp3";
audios.play();
repeat(boss);
easy.onclick = function(){
var boss = 0;
repeat(boss);
}
difficult.onclick = function(){
var boss = 1;
repeat(boss);
}
}
}
}
act();
//随机函数
function rand(min,max){
return parseInt(Math.random()*(max-min)+min);
}
//键盘控制方向
var disArr = [0,0,0,0];
document.onkeydown = function(ev){
var ev = window.ev || ev;
disArr[ev.keyCode - 37] = 1;
}
document.onkeyup = function(ev){
var ev = window.ev || ev;
disArr[ev.keyCode - 37] = 0;
}
setInterval(function(){
if(disArr[0]){
newHero.x -=10;
if(newHero.x<=0){
newHero.x = 0;
}
}
if(disArr[1]){
newHero.y -=10;
if(newHero.y<=0){
newHero.y = 0;
}
}
if(disArr[2]){
newHero.x +=10;
if(newHero.x>=canvas.width-newHero.w){
newHero.x = canvas.width-newHero.w;
}
}
if(disArr[3]){
newHero.y +=10;
if(newHero.y>=canvas.height-newHero.h){
newHero.y = canvas.height-newHero.h;
}
}
},20)
//定义一个玩家飞机的血条和分数
function life(x){
var i = parseInt((100/120)*2*x);
context.fillText("剩余生命:",20,15);
context.beginPath();
context.strokeStyle = "green";
context.moveTo(80,10);
context.lineTo(80 + x*2,10);
context.lineWidth = 12;
context.lineCap = "round";
context.stroke();
context.fillText(i+"%",90,15);
//得分
context.fillText("您的得分:",20,40);
context.fillText(grade+"分",80,40);
}
//游戏结束重新开始
function repeat(boss){
btn.onclick = function(){
audios.pause();
context.clearRect(0,0,canvas.width,canvas.height);
gameover.style.display = "none";
game(boss);
}
}
}
</script>
</html>
如果你也喜欢游戏,如果你也喜欢代码,欢迎关注我,在学习的路上,一起前进!_