目录
重写 小结一下心得
本人重写了整个项目
有了点小心得
页面跳转
director.loadScene(`s2`)
背景移动
canvas 是画布
为什么要向上图布局?
方便计算相对坐标,脚本还是只写一个
绑定上 BG 一样跑,不影响
typescript
export class ts_2_bg extends Component {
@property speed : number = 100
start() {
}
update(deltaTime: number) {
let pos1 = this.node.getPosition()
this.node.setPosition(
pos1.x,
pos1.y - deltaTime * this.speed
)
pos1 = this.node.getPosition()
if (pos1.y < -851) {this.node.setPosition(pos1.x,852)}
}
}
精简 player
老师的代码好处 所见即所得
本人代码没那么多弯弯绕绕
新手容易绕晕,暂时只用了一种发射模式,
道理是一样的,后续更新双发
typescript
@ccclass('ts_player')
export class ts_player extends Component {
@property(Prefab) bullet1 : Prefab = null // 子弹
@property rate : number = 0.4 // 子弹发射频率
time1 : number = 0 // 过去的时间
@property(Node) zidan_weizhi : Node = null
protected onLoad(): void { // 打开监听
input.on(
Input.EventType.TOUCH_MOVE, // 设置获取的类型
this.onmove, // 赋值给onmove函数
this
)
}
protected onDestroy(): void { // 关闭监听
input.off(
Input.EventType.TOUCH_MOVE,
this.onmove,
this
)
}
onmove(event:EventTouch){
const p = this.node.position; // 获取坐标
let pos1 = new Vec3( // 创建一个新的变量.来存储将要变更坐标,以便于判断
p.x + event.getDeltaX(), // 当前X坐标 + 移动的X坐标
p.y + event.getDeltaY(),
)
if (pos1.x < -240) pos1.x = -240 // 限制左边
if (pos1.x > 240) pos1.x = 240 // 限制右边
if (pos1.y < -426) pos1.y = -426 // 限制下边
if (pos1.y > 426) pos1.y = 426 // 限制上边
this.node.setPosition(pos1.x , pos1.y) // 设置新的位置
}
start() {
}
update(deltaTime: number) {
this.time1 += deltaTime
if (this.time1 >= this.rate) {
this.time1 = 0 // 重置发射计时
const zidan1 = instantiate(this.bullet1) // 实例化
this.zidan_weizhi.addChild(zidan1) // 位置上创建实体
let pw = this.node.getWorldPosition()
zidan1.setWorldPosition(pw.x,pw.y + 40,pw.z)
}
}
}
我之前子弹,敌机老是搞成一条直线,移动后新老精灵都跟随移动
试了好久,发现这样才能实现前后精灵不联动
- 实例化
- 实体化
- 设置世界坐标
这是我试了好久总结出来的
子弹代码
typescript
@ccclass('ts_bullet')
export class ts_bullet extends Component {
@property speed1 : number = 200
start() {
let collider = this.getComponent(Collider2D);
if (collider) {collider.on(Contact2DType.BEGIN_CONTACT, this.onBeginContact, this);}
}
onBeginContact (selfCollider: Collider2D, otherCollider: Collider2D) {
this.node.destroy()
}
update(deltaTime: number) {
let pos = this.node.position
this.node.setPosition(pos.x,pos.y + deltaTime * this.speed1)
let posy = this.node.position.y
if (posy > 810) {this.node.destroy()}
}
}
敌机精灵
我在写敌机的时候,写了2遍,才明白过来
所谓的精灵,它是一个抽出来的概念
简单的说,就是实体化后它能不能满足你的需求(个体独立)
举个简单的例子,
猪生仔,仔有自己的血,自己的动作,自己的速度,自己的饱腹度...
这就是精灵,独立个体,有自己的属性
- 图片丢进 cavas
- 再把 cavas 里的图片拖进资源栏里就形成了初级精灵 (空白精灵,除了图,没有其他属性)
- 双击这个初级精灵,对精灵进行编辑 (添加动画,绑定脚本等等),这是在完善这个精灵
- 最后生成精灵,生成是独立于精灵的,子弹是精灵,敌机时精灵,玩家也算是精灵,但很特殊
说了这么多,上图片,上代码
敌机这里就很明显看出来我所说的
自己要理解这个逻辑,后面就很清楚这个游戏的大致框架
敌机属性代码
typescript
@ccclass('ts_enemy_att')
export class ts_enemy_run extends Component {
@property name1 : string = ''
@property speed : number = 200 // 移动速度
@property hp : number = 1 // 生命值
@property(Animation) anim : Animation = null // 动画
start() {
let collider = this.getComponent(Collider2D);
if (collider) {
collider.on(Contact2DType.BEGIN_CONTACT, this.onBeginContact, this); // 开始触发
//collider.on(Contact2DType.END_CONTACT, this.onEndContact, this); // 结束触发没必要
}
}
onBeginContact (selfCollider: Collider2D, otherCollider: Collider2D) {
// 只在两个碰撞体开始接触时被调用一次
console.log('onBeginContact');
this.hp -= 1
DelayNode
if (this.hp > 0) {this.anim.play(`${this.name1}_hit`)}
else {this.anim.play(`${this.name1}_down`)}
}
update(deltaTime: number) {
let pos = this.node.getPosition()
this.node.setPosition(pos.x , pos.y - deltaTime * this.speed)
if (this.node.position.y < -426) {this.node.destroy()}
}
}
我为什么说不是敌机0代码,而是敌机代码
你要把敌机的共有属性抽离出来,写相同的代码
不一样的地方,就用绑定的形式来调用
敌机生成
typescript
@ccclass('ts_enemy_0')
export class ts_enemy_0 extends Component {
@property(Node) linshi : Node = null // 临时生成位置
@property rate0 : number = 1 // 0刷新时间
@property rate1 : number = 2
@property rate2 : number = 4
@property(Prefab) enemy0 : Prefab = null // 精灵0
@property(Prefab) enemy1 : Prefab = null
@property(Prefab) enemy2 : Prefab = null
start() {
this.schedule(this.onrate0,this.rate0) // 设置定时器 (调用方法 , 定时)
this.schedule(this.onrate1,this.rate1)
this.schedule(this.onrate2,this.rate2)
}
protected onDestroy(): void { // 销毁时
this.unschedule(this.onrate0())
}
onrate0(){
let en0 = instantiate(this.enemy0) // 实例化
this.linshi.addChild(en0) // 实体化
let posx = math.randomRangeInt(-240,240) // 获取随机数
let pw = this.linshi.getWorldPosition() // 获取临时点世界坐标
en0.setWorldPosition(pw.x + posx , pw.y + 426 , pw.z) // 设置敌机位置
}
onrate1(){
let en0 = instantiate(this.enemy1) // 实例化
this.linshi.addChild(en0) // 实体化
let posx = math.randomRangeInt(-240,240) // 获取随机数
let pw = this.linshi.getWorldPosition() // 获取临时点世界坐标
en0.setWorldPosition(pw.x + posx , pw.y + 426 , pw.z) // 设置敌机位置
}
onrate2(){
let en0 = instantiate(this.enemy2) // 实例化
this.linshi.addChild(en0) // 实体化
let posx = math.randomRangeInt(-240,240) // 获取随机数
let pw = this.linshi.getWorldPosition() // 获取临时点世界坐标
en0.setWorldPosition(pw.x + posx , pw.y + 426 , pw.z) // 设置敌机位置
}
update(deltaTime: number) {
}
}
修复瞬移BUG
优化代码
但这一版的代码还是有问题
敌机死后可以再次被击杀(突然想起可以休眠,明天再实验)
肉眼击中了,但没有触发碰撞?子弹穿过去了,但再对准,又可以了
下次更新再说了