本游戏使用的是html5的canvas,运行游戏需要浏览器支持html5。

本篇文章详细讲解如何用html5来开发一款射击游戏,雷电可以说是射击游戏中的经典,下面就来模仿一下。

先看一下游戏截图

演示地址

http://fsanguo.comoj.com/html5/barrage2/index.html

游戏开发,需要用到开源引擎:lufylegend.js

lufylegend.js引擎下载地址

http://lufylegend.com/lufylegend

游戏预计用到下面几个文件

index.html

js文件夹|---Main.js

    |---Plain.js//飞机
         |---Bullet.js//子弹
         |---Global.js//共通

images文件夹|--图片

我简单说一下制作过程,源代码在最下面

首先建立index.html文件,

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>弹幕</title>
<!--
<meta name="viewport" content="width=480,initial-scale=0.5, minimum-scale=0.5, maximum-scale=1.0,user-scalable=no" />-->
<meta name="viewport" content="width=480,initial-scale=0.6" />
<script type="text/javascript" src="../legend/legend.js"></script>
<script type="text/javascript" src="./js/Global.js"></script>
<script type="text/javascript" src="./js/Bullet.js"></script>
<script type="text/javascript" src="./js/Plain.js"></script>
<script type="text/javascript" src="./js/Main.js"></script>
</head>
<body>
<div id="mylegend">loading……</div></body>
</html>

打开Main.js

在里面添加代码,先将图片全部读取,并显示进度条

以及,将一些可能会用到的变量添加进去

/*** Main* */
//设定游戏速度,屏幕大小,回调函数
init(50,"mylegend",480,800,main);/**层变量*/
//显示进度条所用层
var loadingLayer;
//游戏最底层
var backLayer;
//控制层
var ctrlLayer;/**int变量*/
//读取图片位置
var loadIndex = 0;
//贞数
var frames = 0;
//BOOS START
var boosstart = false;
//GAME OVER
var gameover = false;
//GAME CLEAR
var gameclear = false;
//得分
var point = 0;
/**对象变量*/
//玩家
var player;
//得分
var pointText;/**数组变量*/
//图片path数组
var imgData = new Array();
//读取完的图片数组
var imglist = {};
//子弹数组
var barrage = new Array();
//子弹速度数组
var barrageSpeed = [5,10];
//储存所有敌人飞机的数组
var enemys = new Array();function main(){//准备读取图片imgData.push({name:"back",path:"./images/back.jpg"});imgData.push({name:"enemy",path:"./images/e.png"});imgData.push({name:"player",path:"./images/player.png"});imgData.push({name:"boss",path:"./images/boss.png"});imgData.push({name:"ctrl",path:"./images/ctrl.png"});imgData.push({name:"item1",path:"./images/1.png"});//实例化进度条层loadingLayer = new LSprite();loadingLayer.graphics.drawRect(1,"black",[50, 200, 200, 20],true,"#ffffff");addChild(loadingLayer);//开始读取图片loadImage();
}
function loadImage(){//图片全部读取完成,开始初始化游戏if(loadIndex >= imgData.length){removeChild(loadingLayer);legendLoadOver();gameInit();return;}//开始读取图片loader = new LLoader();loader.addEventListener(LEvent.COMPLETE,loadComplete);loader.load(imgData[loadIndex].path,"bitmapData");
}
function loadComplete(event){//进度条显示loadingLayer.graphics.clear();loadingLayer.graphics.drawRect(1,"black",[50, 200, 200, 20],true,"#ffffff");loadingLayer.graphics.drawRect(1,"black",[50, 203, 200*(loadIndex/imgData.length), 14],true,"#000000");//储存图片数据imglist[imgData[loadIndex].name] = loader.content;//读取下一张图片loadIndex++;loadImage();
}

现在,所用到的图片已经全部都加载完毕,先添加背景,显示一张图片

用legend库件显示图片非常简单

function gameInit(event){//游戏底层实例化backLayer = new LSprite();addChild(backLayer);//添加游戏背景bitmapdata = new LBitmapData(imglist["back"]);bitmap = new LBitmap(bitmapdata);backLayer.addChild(bitmap);}

效果如下

射击游戏,子弹是亮点,如何添加多种子弹是游戏的关键

要使子弹有变化,必须要设定相应的角度,加速度,等多种变量

下面为了实现这些变化,我们来建立一个子弹类

/*** 子弹类 * */
function Bullet(belong,x,y,angle,xspeed,yspeed,aspeed,speed){base(this,LSprite,[]);var self = this;//子弹所属self.belong = belong;//出现位置self.x = x;self.y = y;//角度self.angle = angle;//移动速度self.speed = speed;//xy轴速度self.xspeed = xspeed;self.yspeed = yspeed;//旋转角度加成self.aspeed = aspeed;//子弹图片var bitmapdata,bitmap;bitmapdata = new LBitmapData(imglist["item1"]);bitmap = new LBitmap(bitmapdata);self.bitmap = bitmap;//显示self.addChild(bitmap);
}

然后,在子弹移动过程中,根据这些变量来实现多种变换

在共通类中,加入一个子弹数组,用来区分各种子弹

/*** 子弹类型数组* 【开始角度,增加角度,子弹速度,角度加速度,子弹总数,发动频率,枪口旋转】* */
Global.bulletList = new Array({startAngle:0,angle:20,speed:5,aspeed:0,count:1,shootspeed:10,sspeed:0},//1发
);

游戏最基本的子弹,当然就是每次发一个子弹

在共通类里建一个发射子弹的函数

/*** 发射子弹* @param 飞机* */
Global.setBullet = function(plainObject){var i,j,obj,xspeed,yspeed,kaku;//获取子弹属性var bullet = Global.bulletList[0];//开始发射for(i=0;i<bullet.count;i++){//发射角度kaku = i*bullet.angle + bullet.startAngle;//子弹xy轴速度xspeed = bullet.speed*Math.sin(kaku * Math.PI / 180);yspeed = barrageSpeed[0]*Math.cos(kaku * Math.PI / 180);//子弹实例化obj = new Bullet(0,210,300,kaku,xspeed,yspeed,bullet.aspeed,bullet.speed);//显示backLayer.addChild(obj);barrage.push(obj);}
};

这里,最终需要根据发射的飞机不同而不同,所以我加入了参数飞机

那现在建立飞机类,如下

/*** 飞机类* */
function Plain(name,belong,x,y,bullets){base(this,LSprite,[]);var self = this;//飞机名称self.name = name;//飞机位置self.x = x;self.y = y;//飞机所属self.belong = belong;//子弹数组self.bullets = bullets;//初始子弹self.bullet = self.bullets[Math.floor(Math.random()*self.bullets.length)];self.shootspeed = Global.bulletList[self.bullet].shootspeed;//枪口旋转角度self.sspeed = 0;//射击频率控制self.shootctrl = 0;//获取飞机属性self.list = Global.getPlainStatus(self);//飞机图片self.bitmap = self.list[0];//显示self.addChild(self.bitmap);//枪口位置self.shootx = self.list[1];self.shooty = self.list[2];//移动速度self.speed = self.list[3];//飞机hpself.hp = self.list[4];//移动方向self.move = [0,0];//发射子弹数self.shootcount = 0;//是否发射子弹self.canshoot = true;if(name=="player")self.canshoot = false;
}/*** 循环* */
Plain.prototype.onframe = function (){var self = this;//移动self.x += self.move[0]*self.speed;self.y += self.move[1]*self.speed;switch (self.name){case "player"://自机移动位置限制if(self.x < 0)self.x = 0;else if(self.x + self.bitmap.getWidth() > LGlobal.width)self.x = LGlobal.width-self.bitmap.getWidth();if(self.y < 0)self.y = 0;else if(self.y + self.bitmap.getHeight() > LGlobal.height)self.y = LGlobal.height-self.bitmap.getHeight();break;case "boss"://敌机BOSS移动if(self.y < 0){self.y = 0;self.move[1] = 1;}else if(self.y + self.bitmap.getHeight() > LGlobal.height){self.y = LGlobal.height-self.bitmap.getHeight();self.move[1] = -1;}//碰撞检测self.hitTest();break;case "enemy":default://碰撞检测self.hitTest();}//射击if(self.canshoot)self.shoot();
};/*** 碰撞检测* */
Plain.prototype.hitTest = function (){var self = this;var disx,disy,sw,ew;sw = (self.bitmap.getWidth() + self.bitmap.getHeight())/4;ew = (player.bitmap.getWidth() + player.bitmap.getHeight())/4;disx = self.x+sw - (player.x + ew);disy = self.y+self.bitmap.getHeight()/2 - (player.y + player.bitmap.getHeight()/2);if(disx*disx + disy*disy < (sw+ew)*(sw+ew)){player.visible = false;gameover = true;}
};
/*** 射击* */
Plain.prototype.shoot = function (){var self = this;if(self.shootctrl++ < self.shootspeed)return;self.shootctrl = 0;if(self.name == "boss"){if(self.shootcount++ % 20 > 5)return;}else{if(self.shootcount++ % 10 > 5)return;}Global.setBullet(self);if(self.name == "boss"){if(self.shootcount % 20 < 5)return;}else{if(self.shootcount % 10 < 5)return;}if(self.bullets.length <= 1)return;self.bullet = self.bullets[Math.floor(Math.random()*self.bullets.length)];self.shootspeed = Global.bulletList[self.bullet].shootspeed;
};

代码已经加入了详细的注释,不难理解吧

完善子弹类如下

/*** 子弹类 * */
function Bullet(belong,x,y,angle,xspeed,yspeed,aspeed,speed){base(this,LSprite,[]);var self = this;//子弹所属self.belong = belong;//出现位置self.x = x;self.y = y;//角度self.angle = angle;//移动速度self.speed = speed;//xy轴速度self.xspeed = xspeed;self.yspeed = yspeed;//旋转角度加成self.aspeed = aspeed;//子弹图片var bitmapdata,bitmap;bitmapdata = new LBitmapData(imglist["item1"]);bitmap = new LBitmap(bitmapdata);self.bitmap = bitmap;//显示self.addChild(bitmap);
}/*** 循环* @param 子弹序号* */
Bullet.prototype.onframe = function (index){var self = this;//子弹移动self.x += self.xspeed;self.y += self.yspeed;//子弹角度变更if(self.aspeed != 0){self.angle += self.aspeed;//子弹角度变更后,重新计算xy轴速度self.xspeed = self.speed*Math.sin(self.angle * Math.PI / 180);self.yspeed = self.speed*Math.cos(self.angle * Math.PI / 180);}//子弹位置检测if(self.x < 0 || self.x > LGlobal.width || self.y < 0 || self.y > LGlobal.height){//从屏幕移除backLayer.removeChild(self);//从子弹数组移除barrage.splice(index,1);}else{self.hitTest(index);}};
/*** 子弹碰撞检测* @param 子弹序号* */
Bullet.prototype.hitTest = function (index){var self = this;var disx,disy,sw,ew,obj,i;if(self.belong == player.belong){//自机子弹for(i=0;i<enemys.length;i++){obj = enemys[i];sw = self.bitmap.getWidth()/2;ew = obj.bitmap.getWidth()/2;disx = self.x+sw - (obj.x + ew);disy = self.y+self.bitmap.getHeight()/2 - (obj.y + obj.bitmap.getHeight()/2);//距离检测if(disx*disx + disy*disy < ew*ew){obj.hp--;if(obj.hp == 0){point += 1;pointText.text = point;//从屏幕移除backLayer.removeChild(obj);//从敌机数组移除enemys.splice(i,1);if(obj.name == "boss"){gameclear = true;}}//从屏幕移除backLayer.removeChild(self);//从子弹数组移除barrage.splice(index,1);}}}else{//敌机子弹obj = player;sw = self.bitmap.getWidth()/2;ew = obj.bitmap.getWidth()/2;disx = self.x+sw - (obj.x + ew);disy = self.y+self.bitmap.getHeight()/2 - (obj.y + obj.bitmap.getHeight()/2);//距离检测if(disx*disx + disy*disy < ew*ew - 10){obj.visible = false;gameover = true;//从屏幕移除backLayer.removeChild(self);//从子弹数组移除barrage.splice(index,1);}}
};

子弹发射函数,修改如下

/*** 发射子弹* @param 飞机* */
Global.setBullet = function(plainObject){var i,j,obj,xspeed,yspeed,kaku;//获取子弹属性var bullet = Global.bulletList[plainObject.bullet];//设定枪口旋转plainObject.sspeed += bullet.sspeed;//开始发射for(i=0;i<bullet.count;i++){//发射角度kaku = i*bullet.angle + bullet.startAngle + plainObject.sspeed;//子弹xy轴速度xspeed = bullet.speed*Math.sin(kaku * Math.PI / 180);yspeed = barrageSpeed[0]*Math.cos(kaku * Math.PI / 180);//子弹实例化obj = new Bullet(plainObject.belong,plainObject.x+plainObject.shootx,plainObject.y+plainObject.shooty,kaku,xspeed,yspeed,bullet.aspeed,bullet.speed);//显示backLayer.addChild(obj);barrage.push(obj);}
};

在Main文件里添加循环

/*** 循环* */
function onframe(){var i;//循环子弹for(i=0;i<barrage.length;i++){barrage[i].onframe(i);}//循环敌机for(i=0;i<enemys.length;i++){enemys[i].onframe();}
}

现在,我只需要添加飞机,就可以发射子弹了

plain = new Plain("enemy",1,200,300,[0]);

看效果

修改,子弹的相应参数,如下

/*** 子弹类型数组* 【开始角度,增加角度,子弹速度,角度加速度,子弹总数,发动频率,枪口旋转】* */
Global.bulletList = new Array({startAngle:0,angle:20,speed:5,aspeed:0,count:1,shootspeed:10,sspeed:0},//1发{startAngle:-20,angle:20,speed:5,aspeed:0,count:3,shootspeed:10,sspeed:0},//3发{startAngle:0,angle:20,speed:5,aspeed:0,count:1,shootspeed:1,sspeed:20},//1发旋转{startAngle:0,angle:20,speed:5,aspeed:0,count:18,shootspeed:3,sspeed:0},//环发{startAngle:0,angle:20,speed:5,aspeed:1,count:18,shootspeed:3,sspeed:0},//环发旋转{startAngle:180,angle:20,speed:5,aspeed:0,count:1,shootspeed:5,sspeed:0},//1发 up{startAngle:160,angle:20,speed:5,aspeed:0,count:3,shootspeed:5,sspeed:0}//3发 up
);

效果分别为

lufylegend.js引擎包内包含这个demo,请直接下载lufylegend.js引擎,查看引擎包内源码

lufylegend.js引擎下载地址

http://lufylegend.com/lufylegend

html5游戏开发-弹幕+仿雷电小游戏demo相关推荐

  1. 视频教程-Layabox3D游戏开发入门-微信3D小游戏案例 -微信开发

    Layabox3D游戏开发入门-微信3D小游戏案例 有多年Unity程序开发经验,有策划和美术设计的经验.愿意在csdn这个平台和大家一起分享! 金龙 ¥29.00 立即订阅 扫码下载「CSDN程序员 ...

  2. 使用processing写一个仿雷电小游戏

    Processing编程--仿雷电STG 1.前言 2.内容展示 3.实现过程 3.1.背景云彩的随机生成 3.2.飞行尾气的实现 3.3.击中敌人的粒子效果 3.4怪物类 3.5.武器系统 4.一些 ...

  3. 游戏开发15课 微信小游戏自审报告

    微信小游戏个人提交的时候需要写下自审报告 然后打印签名 后拍照上传以下是模板有兴趣的可以看看 自审报告 本⼈根据<网络游戏管理暂行办法>对我开发的小游戏产品<xxxx>进行自行 ...

  4. 游戏开发22课 cocoscreator 小游戏分包

    小游戏分包 部分小游戏平台支持分包功能以便对资源.脚本和场景进行划分.Creator 从 v2.4 开始支持 Asset Bundle,开发者可以将需要分包的内容划分成多个 Asset Bundle, ...

  5. php 连连看游戏开发,JavaScript编写连连看小游戏_javascript技巧

    天天看到别人玩连连看, 表示没有认真玩过, 不就把两个一样的图片连接在一起么, 我自己写一个都可以呢. 使用Javascript写了一个, 托管到github, 在线DEMO地址查看:打开 最终的效果 ...

  6. 【游戏开发实战】使用Unity 2019制作仿微信小游戏飞机大战(七):主角飞机碰撞与爆炸

    文章目录 零.教程目录 一.前言 二.本篇目标 三.飞机机碰撞组件:BoxCollider2D.Rigidbody2D 四.添加Tag:Enemy 五.主角飞机碰撞处理:OnTriggerEnter2 ...

  7. 基于Java+Swing实现雷电小游戏

    基于Java+Swing实现雷电小游戏 一.系统介绍 二.功能展示 三.其他系统 四.获取源码 一.系统介绍 基于java的雷电游戏基本功能包括:敌方飞机随机飞行.我方飞机手动控制飞行,射击比拼,游戏 ...

  8. Unity3D游戏开发之仿仙剑奇侠传仙灵岛机关的实现

    我们继续来做点和仙剑相关的东西,首先我们来看一副图: 这幅图呢,是仙剑奇侠传的第一个迷宫场景--仙灵岛的莲花池.男主角李逍遥为替婶婶求药独闯仙灵岛,在经历了前面的小草妖战斗后,李逍遥就来到了 莲花池, ...

  9. [Unity3D]Unity3D游戏开发之仿仙剑奇侠传仙灵岛机关的实现

    大家好,我是秦元培,欢迎大家关注我的博客,我的博客地址是blog.csdn.net/qinyuanpei. 在前面的文章中,我们分别实现了一个自定义的角色控制器<[Unity3D]Unity3D ...

最新文章

  1. 在单链表的第i个位置后插入一个节点(阿里+腾讯等面试题总结)
  2. IOS 消息机制(NSNotificationCenter)
  3. Frequency 频率统计
  4. 利用局域网性能测试仪保障企业网络环境
  5. linux kernel and user space通信机制,Linux内核空间与用户空间通信机制地研究.doc
  6. 前端学习(1035):bootstrap-js插件1
  7. linux回到桌面的命令符_三 基本的base shell 命令
  8. 马斯克称下一代超级工厂占地可能没必要更大 但可能更先进
  9. 【Java并发.2】线程安全性
  10. 吴恩达《机器学习训练秘籍》完整中文版,现在可免费下载 | 资源
  11. GMM-HMM语音识别原理详解 - 全文
  12. 基于图像的三维重建与基于三维点云数据的曲面拟合
  13. Oracle12C日志出现error=904怎样解决
  14. 蓝叠模拟器的adb程序位置
  15. #Geek Point# 创业、艺术家和量子物理
  16. ZOJ 2480 Simplest Task in Windows
  17. 从阿里巴巴icon引入图标到微信小程序(可以改变大小,颜色)
  18. Android中图片圆形设置三种方法介绍
  19. java后台生成echarts图表
  20. STM32控制NRF24L01无线模块进行通信

热门文章

  1. 上传大文件(100G)的解决方案
  2. WPF -- 动画 (缓冲动画)
  3. 微软浏览器Edge打不开怎么办
  4. Flutter | 由Builder Widget而引发的思考
  5. 计算机专业独显好还是集显好,集成显卡和独立显卡有什么区别?哪个性能更好?...
  6. 【后门工具】哥斯拉,YYDS#
  7. EMCC监控_ORACLE
  8. MS DOS、Windows 9x、Windows XP、Windows 7/8引导相关文件
  9. Greendjohn的音乐
  10. 首站告捷 | GBASE数据库中华行在穗城圆满落幕