实现玩家特殊子弹,激光,追踪导弹。 本来想录视频转GIF的,但是gif文件过大,超过5M又上传不了,而且压缩后失帧严重,仅截取了一部分转为gif, 请大家原谅。 ZD类中 //激光类型 更新update(): 什么叫偏移? 实现效果 跟朝向型子弹不同。朝向子弹是NPC发的,发射时已经算好了子弹位置和玩家的位置,直接朝向玩家发射,子弹是直线型。 跟踪子弹是玩家发射的,找到NPC,根据NPC角度和坐标和自身的角度算出一个玩家该朝向的角度,而算出角度后,根据目前的角度和该朝向角度的差值进行移动。比如玩家是90度,实际要0度才能达到,并不是直接从90度变为0度,而是90.80,70,。。一个弧形,依次递减到需要朝向的角度。 1)NPC的选取: 在NPCManager中 2)计算打到NPC的角度 申请 更新update() //特殊的更新需要放在前面,进去直接更新,更新完return跳出结束更新 //N角度限制在 -180°~180° //出屏检测 注意:反三角函数求出的角度是 -180°180°,不是0°360° 将n角度从0°~360°转换为 -180°~ 180° 在Player类中 fire方法 53 0 下方飞出 整合movePlayer方法 在update方法中增加状态机 玩家中增加public isHit(x:number , y:number):boolean{} 增加 申请public bh:egret.Bitmap; // 保护罩图片 更新; 在NZDManager类中的更新方法中修改 在玩家死亡方法最后添加 BOSS0中添加死亡爆炸方法 在Player中添加win方法 2)关卡切换 NPCManager中,不同的关卡生成不同的阵列。 在Maingame中添加 BG类中 NPCManager类中 //仓库中所有东西 移除 Player类中 至此,第五天的开发笔记已经完成,学习需要坚持,坚持到最后一定会有结果,每天写下笔记来记录自己的学习内容, 以后有需要也可以查看,大家可以一起学习。 想要我一起学习的可以关注我的公众号 知言不尽 找到我,交流学习,获取图片素材和源代码。
今天是开发飞行射击游戏第五天,玩家多类型子弹及状态和关卡模式。
简介
玩家多状态 下方飞出 正常游戏 胜利等待 胜利飞出 以及
玩家保护 和 关卡切换实现效果
一.激光
正常的子弹按照自己的轨迹运动,激光每次跟着玩家运动。激光的轨迹不是沿着自己的轨迹,而是在玩家移动的基础上有一个偏移坐标。即子弹跟着玩家移动。
需要一个属性:dx,dypublic dx:number; public dy:number; //玩家坐标基础上的偏移值 public static fi:number = 0 ; //激光的动画帧
case 10: //用动画帧构造图片 this.im = Main.createBitmapByName("pzd4"+ZD.fi+"_png"); //每发射一颗子弹 就加一张 ZD.fi++; if(ZD.fi >= 10) ZD.fi = 0; this.addChild(this.im); //每次主循环发射一颗,每颗间距离是80 this.vy = -80; //-80为向上 this.vx = 0 ; this.dx = this.dy = 0 ; this.n = 0; this.gj = 10; break;
//特殊的更新需要放在前面,进去直接更新,更新完return跳出结束更新if(this.id == 10){ //移动的是它和飞机之间的差值 this.dx +=this.vx; this.dy +=this.vy; //偏移值:基础值+偏移 //激光的坐标是在玩家坐标基础上加上改变值,移动的是改变值。这样就实现激光跟随玩家移动 this.x = this.game.player.x + this.dx; this.y = this.game.player.y + this.dy; //出屏检测 if(this.y < -100 ){ this.vis = false; } return; }
对激光来说移动的不是自己的坐标,而是移动和飞机之间的距离,是偏移值,而不是实际坐标二.跟踪子弹的实现
需要选择屏幕当中的一个NPC,如果有就跟踪,如果没有就是竖直向上. //获取NPC public getNPC():NPC{ //仓库长度>0说明有NPC,如果没有跳出 if(this.nm.length > 0 ){ //有npc 随机取一个npc。 let npc = this.nm[Math.floor(Math.random()* this.nm.length)] //判断npc是否在屏幕内,满足条件在屏幕内 if(npc.x > 0 && npc.x < 480 && npc.y > 0 && npc.y < 800){ return npc; } } //没找到 为空 return null; }
3)更新角度的改变打到NPC
public npc:NPC; //追踪的目标//跟踪导弹 case 20: this.im = Main.createBitmapByName("pzd1_3_png"); this.npc = null; break;
if(this.id == 20){ let bn = 0 ; //目标角度 向上 if(this.npc == null){ this.npc = this.game.nm.getNPC(); }else{ bn = Math.atan2(this.npc.x -this.x,this.y-this.npc.y); //这个角度是弧度制,转换成角度值 bn = bn * 180/ Math.PI; }
while(this.n <= -180) this.n += 360; while(this.n > 180) this.n -= 360; //若角度差值小于5度,两个角度变为等值 if(Math.abs(this.n - bn) < ZD.VN){ this.n = bn; }else{ // if(this.n < bn){ if(this.n < bn - 180) this.n -= ZD.VN; else this.n += ZD.VN; }else{ if(this.n > bn + 180) this.n += ZD.VN; else this.n -= ZD.VN; } } //sin用的是弧度制 n是角度制,所以 n* Math.PI / 180 转换为弧度制。 //重新计算速度与角度 this.vx = this.v * Math.sin(this.n * Math.PI / 180); this.vy= -this.v * Math.cos(this.n * Math.PI / 180); this.im.rotation = this.n; this.x +=this.vx; this.y +=this.vy;
if(this.x < -100 || this.x > 580 || this.y < -100 || this.y > 900){ this.vis = false; } return; }
while(this.n <= -180) this.n += 360; while(this.n > 180) this.n -=360;
//追踪导弹this.t++; if(this.t >= 10){ this.game.zm.create(20,this.x,this.y,15,135,this.game); this.game.zm.create(20,this.x,this.y,15,-135,this.game); this.game.zm.create(20,this.x,this.y,15,45,this.game); this.game.zm.create(20,this.x,this.y,15,-45,this.game); this.t = 0 ; }
三.玩家多状态
1 正常游戏
10 胜利等待
11 胜利飞出
在Player的更新update方法中switch(this.m){ case 0 : this.y -=this.v; if(this.y <= 400){ this.m =1; this.t = 0 ; } break; case 1 : this.fire(); this.movePlayer(); break; case 10: this.t++; if(this.t >= 20){ this.t = 0; this.m = 11; } break; case 11: this.y -=this.vy; this.vy +=3; if(this.y < -200){ //游戏胜利的切换 } break; }
将update方法中这段代码变为movePlayer方法public movePlayer(){ if(this.isDown == true ){ let a = this.ny - this.oy; let b = this.nx - this.ox; let c = Math.sqrt(a*a + b*b); if( c > this.v){ this.vx = this.v*b/c; this.vy = this.v*a/c; this.ox += this.vx; this.oy += this.vy; }else{ this.vx = b; this.vy = a; this.ox = this.nx; this.oy = this.ny; } //飞机跟着速度一起移动 this.x +=this.vx ; this.y +=this.vy ; //边界检测 if(this.x < 0) this.x = 0; else if(this.x > 480) this.x = 480; if(this.y < 0) this.y = 0; else if(this.y > 800) this.y = 800; } else{ this.vx = 0; } if(this.vx < 0 ){ //向左飞: if(this.fi > -2) this.fi --; }else if(this.vx > 0) { if(this.fi < 2) this.fi++; } else{ this.fi = 0 ; } this.resetFI(); }
四.玩家的死亡处理
public isHit(x:number , y:number):boolean{ // this.x this.y是圆心, 60是半径 勾股定理 ,进入圆算碰撞。 //两点间距离公式。横坐标差的平方+纵坐标差的平方再开方 if(this.bhT > 0 ){ if((this.x -x )*(this.x -x ) + (this.y -y )*(this.y - y ) < 60*60){ return true; } return false; } if(this.m !=1) return false; if(Math.abs(this.x - x) < 20 && Math.abs(this.y -y )<20){ //玩家死亡 return true; } return false; }
public dead(){ for(let i = 0 ; i < 10 ; i++){ //环数 let dn =Math.random()*Math.PI * 2; for(let j = 0 ; j < 15 ; j ++) //每个环爆炸个数 { this.game.tm.create(0, this.x + (i+1)*30* Math.sin(dn+Math.PI*2*j/15), this.y + (i+1)*30* Math.cos(dn+Math.PI*2*j/15), i,Math.random() * 10 +5,this.game); } } this.x = 240; this.y = 1000; this.m = 0 ; this.t = 0; }
五.增加玩家保护
public bhT:number; //保护罩倒计时 持续3秒
构造 this.bh.anchorOffsetX = this.bh.width/2;
this.bh.anchorOffsetY =this.bh.height/2;
this.addChild(this.bh);
this.bh.scaleX = this.bh.scaleY = 0.5;
this.bhT = 60; //60次主循环是3秒
//保护罩时间>0。减到0 消失,图片可见性为falseif(this.bhT > 0 ){ this.bhT--; if(this.bhT <=0){ this.bh.visible = false; } }
if(this.game.player.isHit(one.x , one.y) ==true ){ one.vis = false; if(this.game.player.m == 1 && this.game.player.bhT <= 0 ){ this.game.player.dead(); } }
this.bhT = 60;
this.bh.visible = true;六.玩家过关 与 关卡切换
public dead(){ for(let i = 0 ; i < 10 ; i++){ //环数 let dn =Math.random()*Math.PI * 2; for(let j = 0 ; j < 15 ; j ++) //每个环爆炸个数 { this.nm.game.tm.create(0, this.x + (i+1)*30* Math.sin(dn+Math.PI*2*j/15), this.y + (i+1)*30* Math.cos(dn+Math.PI*2*j/15), i,Math.random() * 10 +5,this.nm.game); } } this.nm.game.player.win(); }
//通过关卡public win(){ this.t = 0 ; this.m = 10; //胜利 玩家飞出屏幕 }
Maingame中申请 public level:number; //判断当前关卡序号
构造:this.level = 0;
对生成的switch进行状态机嵌套
reset方法public reset(level:number) { this.level = level; this.player.reset(); this.bg.reset(); this.nm.reset(); }
public reset(){ switch(this.game.level){ case 0: for(let i = 0 ; i < 2; i ++){ this.bg[i].texture = RES.getRes("bg11_jpg"); } break; case 1: for(let i = 0 ; i < 2; i ++){ this.bg[i].texture = RES.getRes("bg31_jpg"); } break; } }
public reset(){ //整个仓库长度 ,利用循环可以循环出所有子弹 for(let i = 0 ; i < this.nm.length ; i++){ //找到每颗子弹 let one = this.nm[i]; this.removeChild(one); this.nm.splice(i ,1); i--; } this.t =0; this.cID = 0; }
public dead(){ for(let i = 0 ; i < 10 ; i++){ //环数 let dn =Math.random()*Math.PI * 2; for(let j = 0 ; j < 15 ; j ++) //每个环爆炸个数 { this.game.tm.create(0, this.x + (i+1)*30* Math.sin(dn+Math.PI*2*j/15), this.y + (i+1)*30* Math.cos(dn+Math.PI*2*j/15), i,Math.random() * 10 +5,this.game); } } this.x = 240; this.y = 700; this.m = 0 ; this.t = 0; this.bhT = 60; this.bh.visible = true; }
public reset(){ this.isDown = false; this.x = 240;this.y = 1000; this.m = this.t = 0; this.bhT = 60; //60次主循环是3秒 }
本网页所有视频内容由 imoviebox边看边下-网页视频下载, iurlBox网页地址收藏管理器 下载并得到。
ImovieBox网页视频下载器 下载地址: ImovieBox网页视频下载器-最新版本下载
本文章由: imapbox邮箱云存储,邮箱网盘,ImageBox 图片批量下载器,网页图片批量下载专家,网页图片批量下载器,获取到文章图片,imoviebox网页视频批量下载器,下载视频内容,为您提供.
阅读和此文章类似的: 全球云计算