前言
本文会介绍怎么根据拾取道具来改变子弹形态默认子弹是M
s子弹
h子弹
定义子弹方向
首先可以想到子弹不仅有中间发射还有左右发射,所以定义三种状态
//Constant.ts
/**
* 定义子弹方向
*/
public static Direction = {
LEFT: 1,
MIDDLE: 2,
RIGHT: 3,
}
定义子弹状态及根据状态移动
//Bullet.ts
private _direction = Constant.Direction.MIDDLE;//子弹方向,默认直线发射
/**
* * 根据子弹方向控制移动
* 这里定义的左右一定是给扇形子弹使用的,因为其他直线发射就可以和il
*/
if(this._direction === Constant.Direction.LEFT){
this.node.setPosition(pos.x - this._bulletSpeed * 0.2, pos.y, moveLength);
} else if(this._direction === Constant.Direction.RIGHT){
this.node.setPosition(pos.x + this._bulletSpeed * 0.2, pos.y, moveLength);
} else{
this.node.setPosition(pos.x, pos.y, moveLength);
}
还要接受传来的状态
show(speed: number, isEnemyBullet: boolean, direction = Constant.Direction.MIDDLE) {
this._bulletSpeed = speed
this._isEnemyBullet = isEnemyBullet
this._direction = direction;
}
编写 M、H、S子弹创建逻辑
原来创建的子弹是M将原来方法重命名就好啦
这样重命名的好处是相关联的不用一个个去修改那么麻烦,直接就一起修改了,然后把S型子弹与H型子弹创建方法写好
//GameManager.ts
/**
* 创建子弹
*/
public createPlayerBulletM() {
// 子弹实例化
const bullet = instantiate(this.bullet01);
// 将子弹放在子弹管理节点下面
bullet.setParent(this.bulletRoot);
// 获取飞机位置
const pos = this.playerPlane.position;
// 设置子弹位置
bullet.setPosition(pos.x, pos.y, pos.z - 7);
// 设置子弹速度
const bulletComp = bullet.getComponent(Bullet);
bulletComp.show(this.bulletSpeed, false)
}
/**
* H形状子弹创建
*/
public createPlayerBulletH() {
const pos = this.playerPlane.position;
// left
const bullet1 = instantiate(this.bullet03);
bullet1.setParent(this.bulletRoot);
bullet1.setPosition(pos.x - 2.5, pos.y, pos.z - 7);
const bulletComp1 = bullet1.getComponent(Bullet);
bulletComp1.show(this.bulletSpeed, false);
// right
const bullet2 = instantiate(this.bullet03);
bullet2.setParent(this.bulletRoot);
bullet2.setPosition(pos.x + 2.5, pos.y, pos.z - 7);
const bulletComp2 = bullet2.getComponent(Bullet);
bulletComp2.show(this.bulletSpeed, false);
}
/**
* S型子弹创建
*/
public createPlayerBulletS() {
const pos = this.playerPlane.position;
// middle
const bullet = instantiate(this.bullet05);
bullet.setParent(this.bulletRoot);
bullet.setPosition(pos.x, pos.y, pos.z - 7);
const bulletComp = bullet.getComponent(Bullet);
bulletComp.show(this.bulletSpeed, false);
// left
const bullet1 = instantiate(this.bullet05);
bullet1.setParent(this.bulletRoot);
bullet1.setPosition(pos.x - 4, pos.y, pos.z - 7);
const bulletComp1 = bullet1.getComponent(Bullet);
bulletComp1.show(this.bulletSpeed, false, Constant.Direction.LEFT);
// right
const bullet2 = instantiate(this.bullet05);
bullet2.setParent(this.bulletRoot);
bullet2.setPosition(pos.x + 4, pos.y, pos.z - 7);
const bulletComp2 = bullet2.getComponent(Bullet);
bulletComp2.show(this.bulletSpeed, false, Constant.Direction.RIGHT);
}
根据状态来判断创建什么类型飞机
//GameManager.ts
// 判断是触摸状态 并且射击时间大于我们的周期 发射子弹
if (this._isShooting && this._currShootTime > this.shootTime) {
/**
* 根据吃道具类型来产生子弹
*/
if (this._bulletType === Constant.BulletPropType.BULLET_H) {
this.createPlayerBulletH();
} else if (this._bulletType === Constant.BulletPropType.BULLET_S) {
this.createPlayerBulletS();
} else {
this.createPlayerBulletM();
}
this._currShootTime = 0;
}
完整代码
- GameManager.ts
import { _decorator, Component, Node, Prefab, instantiate, math, Vec3, BoxCollider, macro } from 'cc';
import { Bullet } from '../bullet/Bullet';
import { BulletProp } from '../bullet/BulletProp';
import { EnemyPlane } from '../plane/EnemyPlane';
import { Constant } from './Constant';
const { ccclass, property } = _decorator;
@ccclass('GameManager')
export class GameManager extends Component {
// 关联玩家飞机
@property(Node)
public playerPlane: Node = null;
// 关联所有子弹
@property(Prefab)
public bullet01: Prefab = null;
@property(Prefab)
public bullet02: Prefab = null;
@property(Prefab)
public bullet03: Prefab = null;
@property(Prefab)
public bullet04: Prefab = null;
@property(Prefab)
public bullet05: Prefab = null;
// 射击周期
@property
public shootTime = 0.3;
// 子弹移动速度
@property
public bulletSpeed = 1;
/** 关联敌机 */
@property(Prefab)
public enemy01: Prefab = null;
@property(Prefab)
public enemy02: Prefab = null;
@property
public createEnemtTime = 1;//创建敌机时间
@property
public enemy1Speed = 0.5;//敌机1速度
@property
public enemy2Speed = 0.7;//敌机2速度
//子弹管理节点
@property(Node)
public bulletRoot: Node = null;
// prop 定义道具属性
@property(Prefab)
public bulletPropM: Prefab = null;
@property(Prefab)
public bulletPropH: Prefab = null;
@property(Prefab)
public bulletPropS: Prefab = null;
@property
public bulletPropSpeed = 0.3;//道具速度
private _currShootTime = 0;
// 是否触摸屏幕
private _isShooting = false;
private _currCreateEnemyTime = 0//当前创建的敌机时间
private _combinationInterval = Constant.Combination.PLAN1//组合间隔状态
private _bulletType = Constant.BulletPropType.BULLET_M;//子弹类型
start() {
this._init();
}
update(deltaTime: number) {
// 这步加时间是为了发射子弹
this._currShootTime += deltaTime;
// 判断是触摸状态 并且射击时间大于我们的周期 发射子弹
if (this._isShooting && this._currShootTime > this.shootTime) {
/**
* 根据吃道具类型来产生子弹
*/
if (this._bulletType === Constant.BulletPropType.BULLET_H) {
this.createPlayerBulletH();
} else if (this._bulletType === Constant.BulletPropType.BULLET_S) {
this.createPlayerBulletS();
} else {
this.createPlayerBulletM();
}
this._currShootTime = 0;
}
this._currCreateEnemyTime += deltaTime
//判断组合方式
if (this._combinationInterval == Constant.Combination.PLAN1) {
//只创建单一的飞机 0-10秒飞机创建
if (this._currCreateEnemyTime > this.createEnemtTime) {//普通飞机创建
this.createEnemyPlane()
this._currCreateEnemyTime = 0
}
} else if (this._combinationInterval == Constant.Combination.PLAN2) {
// 10-20秒飞机创建
if (this._currCreateEnemyTime > this.createEnemtTime * 0.9) {//0.9飞机组合间隔
const randomCombination = math.randomRangeInt(1, 3)//随机1,2飞机
if (randomCombination === Constant.Combination.PLAN2) {
this.createCombination1()
} else {
this.createEnemyPlane()
}
this._currCreateEnemyTime = 0
}
} else {
//20+ 飞机创建
if (this._currCreateEnemyTime > this.createEnemtTime * 0.8) {//0.8飞机组合间隔
const randomCombination = math.randomRangeInt(1, 4)//随机1,2,3飞机
if (randomCombination === Constant.Combination.PLAN2) {
this.createCombination1()
} else if (randomCombination === Constant.Combination.PLAN3) {
this.createCombination2()
} else {
this.createEnemyPlane()
}
this._currCreateEnemyTime = 0
}
}
}
/**
* 加分
*/
public addScore() {
}
/**
* 创建子弹
*/
public createPlayerBulletM() {
// 子弹实例化
const bullet = instantiate(this.bullet01);
// 将子弹放在子弹管理节点下面
bullet.setParent(this.bulletRoot);
// 获取飞机位置
const pos = this.playerPlane.position;
// 设置子弹位置
bullet.setPosition(pos.x, pos.y, pos.z - 7);
// 设置子弹速度
const bulletComp = bullet.getComponent(Bullet);
bulletComp.show(this.bulletSpeed, false)
}
/**
* H形状子弹创建
*/
public createPlayerBulletH() {
const pos = this.playerPlane.position;
// left
const bullet1 = instantiate(this.bullet03);
bullet1.setParent(this.bulletRoot);
bullet1.setPosition(pos.x - 2.5, pos.y, pos.z - 7);
const bulletComp1 = bullet1.getComponent(Bullet);
bulletComp1.show(this.bulletSpeed, false);
// right
const bullet2 = instantiate(this.bullet03);
bullet2.setParent(this.bulletRoot);
bullet2.setPosition(pos.x + 2.5, pos.y, pos.z - 7);
const bulletComp2 = bullet2.getComponent(Bullet);
bulletComp2.show(this.bulletSpeed, false);
}
/**
* S型子弹创建
*/
public createPlayerBulletS() {
const pos = this.playerPlane.position;
// middle
const bullet = instantiate(this.bullet05);
bullet.setParent(this.bulletRoot);
bullet.setPosition(pos.x, pos.y, pos.z - 7);
const bulletComp = bullet.getComponent(Bullet);
bulletComp.show(this.bulletSpeed, false);
// left
const bullet1 = instantiate(this.bullet05);
bullet1.setParent(this.bulletRoot);
bullet1.setPosition(pos.x - 4, pos.y, pos.z - 7);
const bulletComp1 = bullet1.getComponent(Bullet);
bulletComp1.show(this.bulletSpeed, false, Constant.Direction.LEFT);
// right
const bullet2 = instantiate(this.bullet05);
bullet2.setParent(this.bulletRoot);
bullet2.setPosition(pos.x + 4, pos.y, pos.z - 7);
const bulletComp2 = bullet2.getComponent(Bullet);
bulletComp2.show(this.bulletSpeed, false, Constant.Direction.RIGHT);
}
/**
* 创建敌机子弹
* @param targetPos 敌机子弹位置
*/
public createEnemyBullet(targetPos: Vec3) {
// 子弹实例化
const bullet = instantiate(this.bullet01);
// 将子弹放在子弹管理节点下面
bullet.setParent(this.bulletRoot);
// 设置子弹位置
bullet.setPosition(targetPos.x, targetPos.y, targetPos.z + 6);
// 设置子弹速度
const bulletComp = bullet.getComponent(Bullet);
bulletComp.show(1, true)
/**
* 敌机子弹分组
*/
const colliderComp = bullet.getComponent(BoxCollider);
colliderComp.setGroup(Constant.CollisionType.ENEMY_BULLET);
colliderComp.setMask(Constant.CollisionType.SELF_PLANE);//设置掩码
}
/**
* 创建敌机
*
*/
public createEnemyPlane() {
// 两架飞机随机选一(1,2)
const whichEnemy = math.randomRangeInt(1, 3)
let prefab: Prefab = null
let speed = 0
// 创建敌机1或2
if (whichEnemy == Constant.EnemyType.TYPE1) {
prefab = this.enemy01
speed = this.enemy1Speed
} else {
prefab = this.enemy02
speed = this.enemy2Speed
}
// 预制实例化
const enemy = instantiate(prefab)
console.log(enemy);
enemy.setParent(this.node)
const enemyComp = enemy.getComponent(EnemyPlane)
enemyComp.show(this, speed, true)//单架敌机需要发射子弹
// 设置飞机位置
const randomPos = math.randomRangeInt(-25, 26)
enemy.setPosition(randomPos, 0, -50)
}
/**
* 组合1创建 横向排列 z轴50,x轴从-20开始
*
*/
public createCombination1() {
const enemyArray = new Array<Node>(5)//飞机数组
for (let i = 0; i < enemyArray.length; i++) {
// 敌机资源实例化
enemyArray[i] = instantiate(this.enemy01)
const element = enemyArray[i]
element.parent = this.node
element.setPosition(-20 + i * 10, 0, -50)//-20起始左位置,10飞机间隔,其实创建位置
//设置飞机速度
const enemyComp = element.getComponent(EnemyPlane)
enemyComp.show(this, this.enemy1Speed, false)//组合飞机不需要发射子弹
}
}
/**
* 组合2创建 V字排列
*
*/
public createCombination2() {
const enemyArray = new Array<Node>(7)//飞机数组
// 位置数组
const combinationPos = [
-21, 0, -60,
-14, 0, -55,
-7, 0, -50,
0, 0, -45,
7, 0, -50,
14, 0, -55,
21, 0, -60
]
for (let i = 0; i < enemyArray.length; i++) {
// 敌机资源实例化
enemyArray[i] = instantiate(this.enemy02)
const element = enemyArray[i]
element.parent = this.node
const startIndex = i * 3//因为位置数组有7个 但是位置有3×7 21个 所以每架飞机位置偏移是3
element.setPosition(combinationPos[startIndex], combinationPos[startIndex + 1], combinationPos[startIndex + 2])
//设置飞机速度
const enemyComp = element.getComponent(EnemyPlane)
enemyComp.show(this, this.enemy2Speed, false)//组合飞机不需要发射子弹
}
}
/**
* 创建子弹道具
* 随机1~3是根据然后创建相对应的道具
*/
public createBulletProp() {
const randomProp = math.randomRangeInt(1, 4);
let prefab: Prefab = null;
if (randomProp === Constant.BulletPropType.BULLET_H) {
prefab = this.bulletPropH;
} else if (randomProp === Constant.BulletPropType.BULLET_H) {
prefab = this.bulletPropS;
} else {
prefab = this.bulletPropM;
}
//实例化道具
const prop = instantiate(prefab);
prop.setParent(this.node);
prop.setPosition(15, 0, -50);
const propComp = prop.getComponent(BulletProp);
propComp.show(this, -this.bulletPropSpeed);
}
/**
* 触摸状态设置
* @param value true/false
*/
public isShooting(value: boolean) {
this._isShooting = value;
}
/**
* 改变子弹类型
* @param type 类型
*/
public changeBulletType(type: number) {
this._bulletType = type;
}
/**
* 默认发射子弹
*/
private _init() {
this._currShootTime = this.shootTime;
this._changePlanMode();
}
/**
* 设计定时器
*/
private _changePlanMode() {
/**
* 每10秒改变一次状态,,根据状态就能决定采用什么组合
*/
this.schedule(this._modeChanged, 10, macro.REPEAT_FOREVER);//组件自带定时器(回调函数,间隔时间,重复次数,延迟时间)
}
private _modeChanged() {
this._combinationInterval++
this.createBulletProp();//创建子弹道具
}
}
- Bullet.ts
import { _decorator, Component, Node, Collider, ITriggerEvent } from 'cc';
import { Constant } from '../framework/Constant';
const { ccclass, property } = _decorator;
@ccclass('Bullet')
export class Bullet extends Component {
// 子弹速度
private _bulletSpeed = 0;
private _direction = Constant.Direction.MIDDLE;//子弹方向,默认直线发射
private _isEnemyBullet = false;//判断是否是敌机子弹
//监听事件
onEnable() {
const collider = this.getComponent(Collider);//获取碰撞组件
collider.on('onTriggerEnter', this._onTriggerEnter, this);//碰撞到了立马处理逻辑
}
//取消事件
onDisable() {
const collider = this.getComponent(Collider);//获取碰撞组件
collider.off('onTriggerEnter', this._onTriggerEnter, this);
}
update(deltaTime: number) {
// 子弹移动
const pos = this.node.position;
let moveLength = 0
// 敌机子弹
if (this._isEnemyBullet) {
moveLength = pos.z + this._bulletSpeed;
this.node.setPosition(pos.x, pos.y, moveLength);
// 超出屏幕销毁
if (moveLength > 50) {//敌机子弹移动的最大位置范围为50
this.node.destroy();
}
} else {//玩家子弹
moveLength = pos.z - this._bulletSpeed;
/**
* * 根据子弹方向控制移动
* 这里定义的左右一定是给扇形子弹使用的,因为其他直线发射就可以和il
*/
if(this._direction === Constant.Direction.LEFT){
this.node.setPosition(pos.x - this._bulletSpeed * 0.2, pos.y, moveLength);
} else if(this._direction === Constant.Direction.RIGHT){
this.node.setPosition(pos.x + this._bulletSpeed * 0.2, pos.y, moveLength);
} else{
this.node.setPosition(pos.x, pos.y, moveLength);
}
// 超出屏幕销毁
if (moveLength < -50) {//玩家子弹移动的最大位置范围为-50
this.node.destroy();
}
}
}
/**
* 设置子弹移动速度即判断子弹是谁发出的
* @param speed 子弹速度
* @param isEnemyBullet 是否是敌机子弹
*/
show(speed: number, isEnemyBullet: boolean, direction = Constant.Direction.MIDDLE) {
this._bulletSpeed = speed
this._isEnemyBullet = isEnemyBullet
this._direction = direction;
}
/**
* 子弹碰撞销毁
* @param event:ITriggerEvent
*/
private _onTriggerEnter(event: ITriggerEvent) {
console.log('trigger bullet destroy');
this.node.destroy();
}
}
- Constant.ts
export class Constant{
/**
* 敌机类型
*/
public static EnemyType = {
TYPE1:1,
TYPE2:2,
}
/**
* 组合类型
*/
public static Combination = {
PLAN1:1,
PLAN2:2,
PLAN3:3,
}
/**
* 碰撞类型
*/
public static CollisionType = {// 这里顺序对应面板设置碰撞分组的类型
SELF_PLANE: 1 << 1,//玩家飞机类型
ENEMY_PLANE: 1 << 2,//敌方飞机类型
SELF_BULLET: 1 << 3,//玩家子弹类型
ENEMY_BULLET: 1 << 4,//敌机子弹类型
BULLET_PROP: 1 << 5,//道具碰撞类型
};
/**
* 道具类型
*/
public static BulletPropType = {
BULLET_M: 1,
BULLET_H: 2,
BULLET_S: 3,
}
/**
* 定义子弹方向
*/
public static Direction = {
LEFT: 1,
MIDDLE: 2,
RIGHT: 3,
}
}