“This is the 25th day of my participation in the First Challenge 2022. For details: First Challenge 2022”
Introduction to the
In the previous section, model and model animation were loaded. In this section, keyboard was used to control model movement and coherent animation to realize attack action.
implementation
Based on the template
- In the previous section, we loaded the model and animated it. This section is modified on the basis of the previous section.
Modify the lights and add shadows
- Enable shadow rendering.
// Turn on shadows
renderer.shadowMap.enabled = true
Copy the code
- Add directional light to enable shadow casting.
let dLight = null
{
const light = new THREE.DirectionalLight(0xaaaaaa)
light.position.set(0.200.100)
light.lookAt(new THREE.Vector3())
light.castShadow = true
light.shadow.camera.top = 300
light.shadow.camera.bottom = -300
light.shadow.camera.left = -300
light.shadow.camera.right = 300
// Enable shadow casting
light.castShadow = true
dLight = light
scene.add(light)
}
Copy the code
- Enable shadow receive on the ground grid.
mesh.receiveShadow = true
Copy the code
- Modify the model grid object to enable shadow casting. The focus of directional light is set as model grid object, which is used to move the model synchronously.
// Set each part of the model to be projected
mesh.traverse(function (child) {
if (child.isMesh) {
child.castShadow = true
child.receiveShadow = true}})// Set the ray focus model
dLight.target = mesh
Copy the code
- cancel
OrbitControls
Control modifies the global camera position to synchronize camera movement as model grid objects move.
// camera.position.set(1000, 500, 1500)
camera.position.set(-1000.1000.100)
// Control the camera
// const controls = new OrbitControls(camera, canvas)
// controls.update()
Copy the code
Modify keyboard listening events
- When two keys are pressed together in the browser, both events are listened for, but only the latter event is responded to. That is to say
keydown
It will only continue to respond to the last key pressed. - We need to add states to the keys that control model movement,
keydown
When triggered, it is changed totrue
Press the state,keyup
When triggered, it is changed tofalse
Non-pressed state. In order to determine which ones to press.
1. Monitor W, A, S and D to control the direction.
// Monitor whether the keyboard is pressed
let keyCodeW = false
let keyCodeS = false
let keyCodeA = false
let keyCodeD = false
let keyCodeK = false / / attack
document.addEventListener(
'keydown'.(e) = > {
var ev = e || window.event
switch (ev.keyCode) {
case 87:
keyCodeW = true
break
case 83:
keyCodeS = true
break
case 65:
keyCodeA = true
break
case 68:
keyCodeD = true
break
case 75:
keyCodeK = true
attack()
break
default:
break}},false
)
document.addEventListener(
'keyup'.(e) = > {
var ev = e || window.event
switch (ev.keyCode) {
case 87:
keyCodeW = false
break
case 83:
keyCodeS = false
break
case 65:
keyCodeA = false
break
case 68:
keyCodeD = false
break
default:
break}},false
)
Copy the code
- According to the keys to control the movement of the model, control the orientation of the model. It also controls the directional light and the camera to follow the model.
// Control movement
function onCodeMove(mesh) {
if (keyCodeW) {
mesh.position.x += 2
camera.position.x += 2
dLight.position.x += 2
mesh.rotation.y = Math.PI * 0.5
}
if (keyCodeA) {
mesh.position.z -= 2
camera.position.z -= 2
dLight.position.z -= 2
mesh.rotation.y = Math.PI
}
if (keyCodeS) {
mesh.position.x -= 2
camera.position.x -= 2
dLight.position.x -= 2
mesh.rotation.y = Math.PI * 1.5
}
if (keyCodeD) {
mesh.position.z += 2
camera.position.z += 2
dLight.position.z += 2
mesh.rotation.y = Math.PI * 2
}
if (keyCodeW && keyCodeD) {
mesh.rotation.y = Math.PI * 0.25
}
if (keyCodeW && keyCodeA) {
mesh.rotation.y = Math.PI * 0.75
}
if (keyCodeA && keyCodeS) {
mesh.rotation.y = Math.PI * 1.25
}
if (keyCodeS && keyCodeD) {
mesh.rotation.y = Math.PI * 1.75
}
if (keyCodeK) {
} else {
resetMove()
}
}
let moveNum = false
// Reset the movement
function resetMove() {
// Press the keyboard to run animation
if (keyCodeW || keyCodeS || keyCodeA || keyCodeD) {
gui['action'] (3)
moveNum = true
} else {
// Execute only once
if (moveNum) {
moveNum = false
gui['action'] (24)}}}Copy the code
- Change the model to a global variable and change the rendering function.
.let meshHY = null.// Set the ray focus model
dLight.target = mesh
meshHY = mesh
...
Copy the code
/ / rendering
function render() {...if (meshHY) {
onCodeMove(meshHY)
}
...
}
Copy the code
Add attack Action
- In the previous keyboard listening event, you can see that K’s listening is treated specially. Cancel the move action when you press K,
And call the attack() method.
- Global variables required by the attack action
let attackList = [12.8.9.10] // The sequence of the combo
let attackCombo = true
let skills = 0 / / the subscript
let clickNum = 0 // Number of clicks
Copy the code
- The attack action is a combination of multiple animations, creating an array to hold the animations to be executed.
- Set the
attackCombo
State to ensure that the last animation is not repeated until the end of execution. - According to the
skills
andclickNum
Determine how many animations to execute and reset the parameters after animation execution.
// Model attack
function attack() {
clickNum++
if (attackCombo) {
attackCombo = false
// Execute the first animation
gui['action'](attackList[skills])
timeCallback()
}
}
function timeCallback() {
setTimeout(function () {
// Proceed to the next action
skills++
// Determine the number of clicks to determine whether there is another action, if all actions complete the loop
if (skills === clickNum || skills > attackList.length - 1) {
skills = 0
clickNum = 0
attackCombo = true
keyCodeK = false
moveNum = true
resetMove()
} else {
gui['action'](attackList[skills])
timeCallback()
}
}, meshHY.animations[attackList[skills]].duration * 1000)}Copy the code
- A simple model control is done.
- The code address