微信小游戏飞机大战Cocos Creator+TypeScript
微信小游戏飞机大战
- 实现工具:
Cocos Creator + VSCode
- 游戏预览:
- 实现原理:
1. 背景移动
实现飞机飞行的方法不是让飞机往前跑,而是通过后移背景图片,使得产生飞机向前跑的视觉效果。
这里设置两个一样的背景图,为了同时控制两个背景图,所以放在一个节点下面,将背景控制的脚本加载在背景节点上。通过this.node.children获得两个背景图,在update(dt)中移动两个背景图, 考虑到越界问题,当背景超过下界的时候,将图片下界向上移动到Canvas上端,从而实现一直有背景图片的效果。
Code:
const {ccclass, property} = cc._decorator;
const height : number = 810;
@ccclass
export default class BgControl extends cc.Component {update (dt) {//让节点下的bg移动,然而节点并没有移动for(let bgnode of this.node.children){bgnode.y -= dt*80;//判断是否越界if(bgnode.y < -height/2){bgnode.y += height*2;}}}
}
将脚本添加到bg节点下面
2. 玩家操控飞机
添加飞机图片,小程序实现的是玩家触碰手机,跟随手触的位置更新更新位置,所以,给飞机添加监听器。
在玩家控制脚本中的onload()方法中添加监听器:
const {ccclass, property} = cc._decorator;@ccclass
export default class PlayerControl extends cc.Component {//子弹预设体@property(cc.Prefab)BulletPre: cc.Prefab = null;onLoad () {/*匿名函数this.node.on(cc.Node.EventType.TOUCH_MOVE,(event)=>{this.node.setPosition(event.getLocation());});*///声明函数this.node.on(cc.Node.EventType.TOUCH_MOVE,this.TouchAction,this);this.schedule(this.Shot, 0.5);//开启碰撞检测cc.director.getCollisionManager().enabled=true;}//如果点击了TouchAction(event){this.node.setPosition(event.getLocation());}
运行就可以发现点击飞机,飞机就可以跟着鼠标的位置移动了。
3. 飞机打出子弹
子弹要设置碰撞组件,为下面子弹和飞机碰撞做准备,先编写子弹控制脚本,因为要将子弹设为预设体,当设置为碰撞组件并添加好子弹控制脚本后,将子弹拖到到资源管理中,生成子弹预设体,再删除原子弹精灵。
export default class BulletControl extends cc.Component {//设置子弹的速度@property()speed : number = 900;update (dt) {//子弹前进this.node.y += dt*this.speed;//如果越界则自动销毁if(this.node.y>810){this.node.destroy();}}
子弹越界后要销毁子弹,这里暂时只实现子弹向前飞行的脚本,后面将实现碰撞的检测。
实现子弹的基本功能后,子弹初始化的位置是飞机的头部,所以在飞机节点下生成子弹,这里设置飞机0.5秒产生一个子弹,在玩家脚本中,添加子弹生成脚本。
onLoad () {/*匿名函数this.node.on(cc.Node.EventType.TOUCH_MOVE,(event)=>{this.node.setPosition(event.getLocation());});*///声明函数this.node.on(cc.Node.EventType.TOUCH_MOVE,this.TouchAction,this);this.schedule(this.Shot, 0.5);//开启碰撞检测cc.director.getCollisionManager().enabled=true;}//如果点击了TouchAction(event){this.node.setPosition(event.getLocation());}//打子弹Shot(){//加载预设体let bullet = cc.instantiate(this.BulletPre);//获得当前的场景let scene = cc.director.getScene();//设置子弹的父节点bullet.parent = scene;//设置子弹的位置bullet.x = this.node.x;bullet.y = this.node.y + 65;}
这时候运行程序,应该会实现子弹打出子弹的功能,若出现问题,请检测有没有没有将资源拖动到脚本中。
4. 敌人被击毁
将敌机图片拖动层级管理器,并添加碰撞,并设置tag=1
以按照tag值检测碰撞,给敌机添加敌机控制脚本
const {ccclass, property} = cc._decorator;@ccclass
export default class EnemyControl extends cc.Component {[x: string]: any;IsDie : boolean = false;start () {}//敌人死亡die(){this.IsDie = true;cc.loader.loadRes("enemy0_die", cc.SpriteFrame, (err, res)=>{this.node.getComponent(cc.Sprite).spriteFrame=res;//不知道错在哪里了});this.schedule(function() {this.node.destroy();}, 0.3);this.father.AddScore();}update (dt) {if(!this.IsDie){this.node.y -= 300*dt;}if(this.node.y < 0){this.node.destroy();}}
}
这里的die()函数是敌机死亡动作,会先加载爆炸图片,然后过0.3s后才毁灭。在upadate(dt)使敌机向前跑,并越界后销毁。
子弹碰撞事件在子弹脚本中实现
//碰撞事件onCollisionStay(other) {console.log('on collision stay');//如果碰撞的是敌人if(other.tag==1){//调用敌方的死亡方法//因为other是敌人的一个控件,所以通过other获得敌人脚本let enemy = other.getComponent(EnemyControl);//敌人死亡enemy.die();//得分加1//销毁自己this.node.destroy();}//如果碰撞的是自己if(other.tag==0){let self = other.getComponent(PlayerControl);//敌人死亡self.GameOver();//销毁自己this.node.destroy();}}
通过other.getComponent(EnemyControl)方法获得敌人脚本,同样如果要实现子弹碰撞自己的功能,先要为自己添加碰撞组件,这里我设置自己的tag=0,然后先调用被碰撞体的死亡事件,再自己毁灭。
5. 产生敌人
由于一个敌人是不够的,所以要自动生成更多敌人,这里的做法和之前的子弹做法有点相似,将敌人设为预设体,设置敌人产生节点。
设置一个空节点用于产生敌机
import EnemyControl from "./EnemyControl";
const {ccclass, property} = cc._decorator;@ccclass
export default class EnemysControl extends cc.Component {// LIFE-CYCLE CALLBACKS:@property(cc.Prefab)enemyPre : cc.Prefab = null;score : number = 0;@property(cc.Label)Score: cc.Label = null;onLoad () {this.schedule(function() {//创建敌机let enemy = cc.instantiate(this.enemyPre);//获得当前的场景let scene = cc.director.getScene();//设置敌机的父节点enemy.parent = scene;//设置敌机位置enemy.y = this.node.y;//y和节点位置相同enemy.x = Math.random()*400;//保存EnemysControl脚本enemy.getComponent(EnemyControl).father = this;//输出一下得分console.log(this.score);this.Score.string= "得分:"+this.score;}, 2);}AddScore(){this.score++;}start () {}//检测敌机飞出界面PassLine(){}// update (dt) {}
}
这里我设置2s产生一个敌人,节点y的位置为空节点的位置,x为0-400的随机数。
6. 实现计分功能
我的思路是按照击毁的飞机计分,在敌机毁灭的时候,调用敌机产生器的AddScore()方法,但是我是怎么实现调用产生它的节点的方法呢。
//敌人死亡die(){this.IsDie = true;cc.loader.loadRes("enemy0_die", cc.SpriteFrame, (err, res)=>{this.node.getComponent(cc.Sprite).spriteFrame=res;//不知道错在哪里了});this.schedule(function() {this.node.destroy();}, 0.3);this.father.AddScore();}
我获得敌人生成的脚本,然后保存在敌机的father中,敌机通过访问生成敌机脚本中的AddScore()方法让score加以,并更新Label Score的值.
Code:
import EnemyControl from "./EnemyControl";
const {ccclass, property} = cc._decorator;@ccclass
export default class EnemysControl extends cc.Component {// LIFE-CYCLE CALLBACKS:@property(cc.Prefab)enemyPre : cc.Prefab = null;score : number = 0;@property(cc.Label)Score: cc.Label = null;onLoad () {this.schedule(function() {//创建敌机let enemy = cc.instantiate(this.enemyPre);//获得当前的场景let scene = cc.director.getScene();//设置敌机的父节点enemy.parent = scene;//设置敌机位置enemy.y = this.node.y;//y和节点位置相同enemy.x = Math.random()*400;//保存EnemysControl脚本enemy.getComponent(EnemyControl).father = this;//输出一下得分console.log(this.score);}, 2);}AddScore(){this.score++;this.Score.string= "得分:"+this.score;}start () {}PassLine(){}// update (dt) {}
}
总的代码及资源结构:
层级管理器:
资源管理器:
飞机控件
敌人产生控件
脚本
const {ccclass, property} = cc._decorator;
const height : number = 810;
@ccclass
export default class BgControl extends cc.Component {update (dt) {//让节点下的bg移动,然而节点并没有移动for(let bgnode of this.node.children){bgnode.y -= dt*80;//判断是否越界if(bgnode.y < -height/2){bgnode.y += height*2;}}}
}
const {ccclass, property} = cc._decorator;@ccclass
export default class PlayerControl extends cc.Component {//子弹预设体@property(cc.Prefab)BulletPre: cc.Prefab = null;onLoad () {/*匿名函数this.node.on(cc.Node.EventType.TOUCH_MOVE,(event)=>{this.node.setPosition(event.getLocation());});*///声明函数this.node.on(cc.Node.EventType.TOUCH_MOVE,this.TouchAction,this);this.schedule(this.Shot, 0.5);//开启碰撞检测cc.director.getCollisionManager().enabled=true;}//如果点击了TouchAction(event){this.node.setPosition(event.getLocation());}//打子弹Shot(){//加载预设体let bullet = cc.instantiate(this.BulletPre);//获得当前的场景let scene = cc.director.getScene();//设置子弹的父节点bullet.parent = scene;//设置子弹的位置bullet.x = this.node.x;bullet.y = this.node.y + 65;}start () {}//游戏结束GameOver(){// 停止 Player 节点的跳跃动作this.node.stopAllActions(); // 重新加载场景 gamecc.director.loadScene('Game');this.node.destroy();}//碰撞事件onCollisionStay(other) {//如果碰撞的是敌人if(other.tag==1){this.GameOver();}}
}
import EnemyControl from "./EnemyControl";
import PlayerControl from "./PlayerControl";const {ccclass, property} = cc._decorator;@ccclass
export default class BulletControl extends cc.Component {//设置子弹的速度@property()speed : number = 900;update (dt) {//子弹前进this.node.y += dt*this.speed;//如果越界则自动销毁if(this.node.y>810){this.node.destroy();}}//碰撞事件onCollisionStay(other) {console.log('on collision stay');//如果碰撞的是敌人if(other.tag==1){//调用敌方的死亡方法//因为other是敌人的一个控件,所以通过other获得敌人脚本let enemy = other.getComponent(EnemyControl);//敌人死亡enemy.die();//得分加1//销毁自己this.node.destroy();}//如果碰撞的是自己if(other.tag==0){let self = other.getComponent(PlayerControl);//敌人死亡self.GameOver();//销毁自己this.node.destroy();}}
}
const {ccclass, property} = cc._decorator;@ccclass
export default class EnemyControl extends cc.Component {[x: string]: any;IsDie : boolean = false;// LIFE-CYCLE CALLBACKS:// onLoad () {}start () {}//敌人死亡die(){this.IsDie = true;cc.loader.loadRes("enemy0_die", cc.SpriteFrame, (err, res)=>{this.node.getComponent(cc.Sprite).spriteFrame=res;//不知道错在哪里了});this.schedule(function() {this.node.destroy();}, 0.3);this.father.AddScore();}update (dt) {if(!this.IsDie){this.node.y -= 300*dt;}if(this.node.y < 0){this.node.destroy();}}
}
import EnemyControl from "./EnemyControl";
const {ccclass, property} = cc._decorator;@ccclass
export default class EnemysControl extends cc.Component {// LIFE-CYCLE CALLBACKS:@property(cc.Prefab)enemyPre : cc.Prefab = null;score : number = 0;@property(cc.Label)Score: cc.Label = null;onLoad () {this.schedule(function() {//创建敌机let enemy = cc.instantiate(this.enemyPre);//获得当前的场景let scene = cc.director.getScene();//设置敌机的父节点enemy.parent = scene;//设置敌机位置enemy.y = this.node.y;//y和节点位置相同enemy.x = Math.random()*400;//保存EnemysControl脚本enemy.getComponent(EnemyControl).father = this;//输出一下得分console.log(this.score);}, 2);}AddScore(){this.score++;this.Score.string= "得分:"+this.score;}start () {}PassLine(){}// update (dt) {}
}
运行结果:
代码及素材我保存在百度云盘:
链接:https://pan.baidu.com/s/1EkMg7z981c4BDqEYtXi9-Q
提取码:8421
–来自百度网盘超级会员V3的分享
Cocos Creator版本是2.4.0哦,如有错误还请指导。
微信小游戏飞机大战Cocos Creator+TypeScript相关推荐
- 【游戏开发实战】使用Unity 2019制作仿微信小游戏飞机大战(七):主角飞机碰撞与爆炸
文章目录 零.教程目录 一.前言 二.本篇目标 三.飞机机碰撞组件:BoxCollider2D.Rigidbody2D 四.添加Tag:Enemy 五.主角飞机碰撞处理:OnTriggerEnter2 ...
- c 语言500行小游戏代码,500行代码使用python写个微信小游戏飞机大战游戏.pdf
500行行代代码码使使用用python写写个个微微信信小小游游戏戏飞飞机机大大战战游游戏戏 这篇文章主要介绍了500行代码使用python写个微信小游戏飞机大战游戏,本文通过实例代码给大家介绍的非常详 ...
- 微信小游戏排行榜:Cocos Creator
上一篇文章介绍了主域和子域的概念,微信小游戏:主域子域,这一篇介绍一下怎样在微信小游戏中制作好友排行榜 创建工程 由于开放数据域是一个封闭.独立的 JavaScript 作用域,所以开发者需要创建两个 ...
- python代码示例500行源代码-500行代码使用python写个微信小游戏飞机大战游戏
这几天在重温微信小游戏的飞机大战,玩着玩着就在思考人生了,这飞机大战怎么就可以做的那么好,操作简单,简单上手. 帮助蹲厕族.YP族.饭圈女孩在无聊之余可以有一样东西让他们振作起来!让他们的左手 / 右 ...
- 微信小游戏开发之Cocos Creator使用微信云开发和微信开放能力
主题 Cocos Creator集成微信云开发和调用微信开放能力 特别说明 CocosCreator微信小游戏开发系列文章,是我在逐步开发过程中,基于官方文档之上,记录一些重点内容,以及对官方文档中有 ...
- 微信小游戏 资源服务器,Cocos Creator 微信小游戏 远程资源设置
版本:2.3.4 参考: cocos教程:发布到微信小游戏 因为微信小游戏有包体大小限制. 主包4M 分包最大4M 一共最多16M 那么假如我们的游戏有个20M,50M,那就放不下了.只能放到远程服务 ...
- 微信小游戏-飞机大战(DoodlePlane)
项目内容介绍 两种模式 经典模式 打落敌机可得分数,碰到敌机减少飞机携带的血瓶,当为血瓶数为零时碰到敌机游戏结束. 无敌模式 处于无敌状态的飞机一次可发射五发子弹,且飞机碰到敌机时飞机不受影响. 在两 ...
- 【Python】Python小游戏--飞机大战
一.前言 今天已经初四,舒服的在家躺尸的春节也算过去了,又要开始辛勤的(苦逼的)学习和工作了.说点题外话,今年春节的病毒疫情真的弄的人心惶惶,我也在这为国家和武汉加油,也向一线工作人员致敬,希望早日结 ...
- 用JAVA制作小游戏——飞机大战(三)
本篇博客是对飞机大战游戏项目完整代码的展示 详细代码讲解: 用JAVA制作小游戏--飞机大战(一) 用JAVA制作小游戏--飞机大战(二) 最下方附整个程序的文件下载链接 代码展示 主界面 impor ...
- 用JAVA制作小游戏——飞机大战(二)
本篇博客是对飞机大战游戏使用代码的展示 重难点: 首先需要鼠标能够控制战机,使鼠标在窗口内时始终能够使战机的位置与鼠标相同,实现鼠标控制战斗机移动. 其次需要能够以一定的速度产生子弹和敌机,并且以一定 ...
最新文章
- python保存代码_python操作文件读写新增保存代码
- SAP进销存难点分析及对策
- centos重启报错Umounting file systems:umount:/opt:device is busy
- scrcpy投屏_scrcpy 使用教程:将安卓设备投屏到 PC 端
- java 批量提交_【INSERT】逐行提交、批量提交及极限提速方法
- chrome打开网址但是没有地址栏
- sql中带in条件的查询及提高效率
- excel常用函数公式及技巧_Excel公式使用技巧大全
- 累次积分怎么计算_【高等数学】二重积分化累次积分方法
- HTML5页面增强元素
- arcmap叠置分析_ArcGIS常见的叠加操作分析情况汇总
- 2017服务器cpu性能排行,CPU性能怎么看?桌面CPU天梯图2017年12月最新版
- Blue Coat 最新报告显示 移动端恶意攻击愈演愈烈
- 威胁web应用安全的错误
- 圣安德鲁斯计算机科学排名,2020年圣安德鲁斯大学历史世界排名最好是第几位...
- com.google.inject.ProvisionException: Guice provision errors问题解决
- API接口是什么?(京东API详解)
- 用idea将一个java文件打包成可执行jar包并能正确运行
- LambdaMART介绍
- 怎么把计算机中更改你的视图,如何修改电脑中文件或文件夹显示的详细信息选项...