3D堆叠游戏——第二步 控制 控制主角移动以及停止


主题列表:juejin, github, smartblue, cyanosis, channing-cyan, fancy, hydrogen, condensed-night-purple, greenwillow, v-green, vue-pro, healer-readable, mk-cute, jzman, geek-black, awesome-green

贡献主题:https://github.com/xitu/juejin-markdown-themes

theme: juejin

highlight:

上一篇文章中制作了游戏的第一步创建基础 这一篇将制作游戏第二步,控制主角

主角移动主要使用TWEEN 作为动画引擎

因为不是介绍tweenjs所以这里不提基础用法,如果有需要可以留言,专门研究一下

这个是封装好的动画

``` typescript const TWEEN = require("@tweenjs/tween.js");

export class Animate { tween constructor(mesh:any, e:any, t:number) { this.tween = new TWEEN.Tween(mesh.position) this.tween.to(e, t) this.tween.start() } }

```

很简单,从起始vector3向量到结束vector3向量

调用动画还需要在render方法中对动画进行更新

// 渲染 render(): void { this.animate() this.renderer.render(this.scene, this.camera); this.controls.update(); TWEEN.update(); }

控制主角动画

参数为起始点为主角position 终点为计算后结果,运动时间 T:number = 5000 // 主角运动时间,随着高度增加而衰减

typescript // 控制主角 leadHandle() { // 控制移动 const lead = this.leadCube // 动画起始点 const start = lead.position let ex = lead.position.x let ez = lead.position.z ex = ex === this.size / 2 ? this.size / 2 : (Math.abs(ex) + this.offset) ez = ez === this.size / 2 ? this.size / 2 : (Math.abs(ez) + this.offset) // 动画结束点 const end = new THREE.Vector3(ex, start.y, ez) console.log(start, end) // 开启主角动画 // 每增加一层减100毫秒 难度增加 const t = Math.max(this.T - this.leadCount * 100, 1000) this.tween = new Animate(this.leadCube, end, t) }

操作控制

游戏使用空格控制主角暂停和其他操作

监听一下keydown事件

typescript window.addEventListener('keydown', this.leadStop.bind(this))

主角停止事件

typescript // 主角停止 leadStop(event) { // 判断是否点击空格 if (event.keyCode === 32) { if (this.tween) { // 暂停动画 this.tween.tween.stop() this.tween = null // 生成下一个主角 this.createlead() } } }

目前游戏效果是这样的

目前生成下一个角色只有在点击空格之后,所以还需要一个是主角运动结束 再生成下一个主角

typescript this.tween.tween.onComplete(this.leadOperation.bind(this))

leadOperation方法

typescript // 对主角进行处理,包括生成新的主角,裁切主角,重绘底板等 leadOperation(){ // 生成下一个主角 this.createlead() }

之后的文章会写到裁切功能,自由落体,游戏结束等

initGame目前完整代码

``` typescript const THREE = require("three"); import { createCube } from '../utils/tools' import { getSize, getPosition } from '../utils/getBox' // 引入封装好的动画 import { Animate } from '../utils/animate'

class CreateGame { scene: any floorCube: any // 初始底板 floorGroup: any // 底板组 size: number = 30 // 主角宽度和长度 leadY: number = 5 // 主角高度 leadCount: number = 0 // 计数器 startPoint: number = 60 // 主角起始位置 x或z leadInterval: any = null // 循环 leadCube: any = null // 主角 tween: any = null // 动画 offset: number = 40 // 主角起始位置和终点位置偏移量 T:number = 500 // 主角运动时间,随着高度增加而衰减 constructor(element: any) { this.scene = element.scene this.floorGroup = new THREE.Group() this.scene.add(this.floorGroup) this.initFloor() window.addEventListener('keydown', this.leadStop.bind(this)) } initFloor() { const w: number = this.size const h: number = 50 const l: number = this.size const floorParams = { w: w, h: h, l: l, x: w / 2, y: h / 2, z: l / 2 } this.floorCube = createCube(floorParams) this.floorGroup.add(this.floorCube) this.floorGroup.updateMatrix() } createlead() { const size = new THREE.Vector3() const mesh = this.floorGroup // 获取尺寸 getSize(mesh, size) const position = new THREE.Vector3() // 获取底板的位置 默认应该都是0 getPosition(mesh, position) const gy = position.y // 底板的Y值 const y = size.y + gy + this.leadY / 2 // 主角的Y值 // 设定第奇数个主角从z轴的负方向来,第偶数个主角从X轴方向来 // 需要一个主角计数器,同样可以用来计算分数 // 起始点距离底板30 // 主角初始位置 const flag: boolean = this.leadCount % 2 === 0 // 是否是偶数主角 // x 起始点 let sx: number = (flag ? -this.startPoint - this.offset : 0) + this.size / 2 // z 起始点 let sz: number = (flag ? 0 : -this.startPoint - this.offset) + this.size / 2 // 创建一个主角 const leadParam = { w: this.size, h: this.leadY, l: this.size, x: sx, y, z: sz } this.leadCube = createCube(leadParam) this.floorGroup.add(this.leadCube) // 创建角色后计数器自增1 this.leadCount++ // 开始控制主角 // const startVector3 = new THREE.Vector3(sx,y,sz) this.leadHandle() } // 控制主角 leadHandle():void { // 控制移动 const lead = this.leadCube // 动画起始点 const start = lead.position let ex = lead.position.x let ez = lead.position.z ex = ex === this.size / 2 ? this.size / 2 : (Math.abs(ex) + this.offset) ez = ez === this.size / 2 ? this.size / 2 : (Math.abs(ez) + this.offset) // 动画结束点 const end = new THREE.Vector3(ex, start.y, ez) console.log(start, end) // 开启主角动画 // 每增加一层减100毫秒 难度增加 const t = Math.max(this.T - this.leadCount * 100, 1000) this.tween = new Animate(this.leadCube, end, t)

if(this.tween) {
  console.log(this.tween.tween)
  this.tween.tween.onComplete(this.leadOperation.bind(this))
}

} // 主角停止 leadStop(event):void { // 判断是否点击空格 if (event.keyCode === 32) { if (this.tween) { // 暂停动画 this.tween.tween.stop() this.tween = null this.leadOperation() } } }

// 对主角进行处理,包括生成新的主角,裁切主角,重绘底板等 leadOperation(){ // 生成下一个主角 this.createlead()

} }

export { CreateGame } ```

代码可能有点粗糙,还望指正

3D堆叠游戏——第一步 基础 初始化游戏

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

孙华鹏

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值