In the last article we created the first step of the game, building the foundation. In this article we will create the second step of the game, controlling the main character
The main character movement uses TWEEN as the animation engine
Since this is not an introduction to Tweenjs, I won’t mention the basics here, but feel free to leave a comment if you need to
This is a wrapped animation
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()
}
}
Copy the code
Very simple, starting with a vector3 vector and ending with a Vector3 vector
Calling the animation also requires updating the animation in the Render method
// Render (): void {this.animate() this.renderer.render(this.scene, this.camera); this.controls.update(); TWEEN.update(); }Copy the code
Control the main character animation
T:number = 5000 // The movement time of the protagonist decreases with the increase of height
// Control the main character
leadHandle() {
// Control movement
const lead = this.leadCube
// Start point of animation
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)
// Animation end point
const end = new THREE.Vector3(ex, start.y, ez)
console.log(start, end)
// Turn on the main character animation
// The difficulty increases with each additional layer minus 100 milliseconds
const t = Math.max(this.T - this.leadCount * 100.1000)
this.tween = new Animate(this.leadCube, end, t)
}
Copy the code
Operational control
The game uses Spaces to control protagonist pauses and other actions
Listen for keyDown events
window.addEventListener('keydown'.this.leadStop.bind(this))
Copy the code
Protagonist stop event
// The main character stops
leadStop(event) {
// Determine whether to click space
if (event.keyCode === 32) {
if (this.tween) {
// Pause the animation
this.tween.tween.stop()
this.tween = null
// Generate the next protagonist
this.createlead()
}
}
}
Copy the code
So far the game looks like this
At present, the next character can only be generated after clicking the space, so there is also a need for the protagonist to finish the movement to regenerate the next protagonist
this.tween.tween.onComplete(this.leadOperation.bind(this))
Copy the code
LeadOperation method
// Process the main characters, including generating new main characters, cutting main characters, redrawing the base plate, etc
leadOperation(){
// Generate the next protagonist
this.createlead()
}
Copy the code
Later articles will cover crop features, free fall, game over, etc
InitGame currently complete code
const THREE = require("three");
import { createCube } from '.. /utils/tools'
import { getSize, getPosition } from '.. /utils/getBox'
// Introduce encapsulated animation
import { Animate } from '.. /utils/animate'
class CreateGame {
scene: any
floorCube: any // Initial baseboard
floorGroup: any / / base plate group
size: number = 30 // Main character width and length
leadY: number = 5 // The height of the protagonist
leadCount: number = 0 / / counter
startPoint: number = 60 // The hero starts at x or z
leadInterval: any = null / / loop
leadCube: any = null / / the protagonist
tween: any = null / / animation
offset: number = 40 // The offset of the hero's starting and ending positions
T:number = 500 // The hero's movement time decreases with height
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
// Get the size
getSize(mesh, size)
const position = new THREE.Vector3()
// The position of the backplane should be 0 by default
getPosition(mesh, position)
const gy = position.y // The Y value of the backplane
const y = size.y + gy + this.leadY / 2 // The main character's Y value
// Set the odd-th hero to come from the negative side of the z axis, and the even-th hero to come from the X axis
// You need a hero counter, which can also be used to count scores
// The starting point is 30 away from the base plate
// The initial position of the main character
const flag: boolean = this.leadCount % 2= = =0 // Is it even
// start point of x
let sx: number = (flag ? -this.startPoint - this.offset : 0) + this.size / 2
// z start point
let sz: number = (flag ? 0 : -this.startPoint - this.offset) + this.size / 2
// Create a protagonist
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)
// After creating a role, the counter increases by 1
this.leadCount++
// Start controlling the main character
// const startVector3 = new THREE.Vector3(sx,y,sz)
this.leadHandle()
}
// Control the main character
leadHandle():void {
// Control movement
const lead = this.leadCube
// Start point of animation
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)
// Animation end point
const end = new THREE.Vector3(ex, start.y, ez)
console.log(start, end)
// Turn on the main character animation
// The difficulty increases with each additional layer minus 100 milliseconds
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))}}// The main character stops
leadStop(event):void {
// Determine whether to click space
if (event.keyCode === 32) {
if (this.tween) {
// Pause the animation
this.tween.tween.stop()
this.tween = null
this.leadOperation()
}
}
}
// Process the main characters, including generating new main characters, cutting main characters, redrawing the base plate, etc
leadOperation(){
// Generate the next protagonist
this.createlead()
}
}
export { CreateGame }
Copy the code
The code may be a little rough, please correct
3D stacking game – The first basic initialization game