“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

  1. Enable shadow rendering.
  // Turn on shadows
  renderer.shadowMap.enabled = true
Copy the code
  1. 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
  1. Enable shadow receive on the ground grid.
mesh.receiveShadow = true
Copy the code
  1. 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
  1. cancelOrbitControlsControl 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 saykeydownIt will only continue to respond to the last key pressed.
  • We need to add states to the keys that control model movement,keydownWhen triggered, it is changed totruePress the state,keyupWhen triggered, it is changed tofalseNon-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
  1. 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
  1. 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
  1. The attack action is a combination of multiple animations, creating an array to hold the animations to be executed.
  2. Set theattackComboState to ensure that the last animation is not repeated until the end of execution.
  3. According to theskillsandclickNumDetermine 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