原生JS超级马里奥(第四天)

 上一章讲的是马里奥速度改变的事件控制,本章改动较多,例如将马里奥位置改变拆分为一个一个的特征类,还有键盘事件监听,实现马里奥的跳跃功能,各位可以跟着原作者视频一起敲

本章的提交ID:e5caf33c8aecfe9655ccde05ad9700ae20f5ae31

github地址:ainuo5213的超级马里奥

本节目录

原生JS超级马里奥(第四天)_第1张图片

本节效果

原生JS超级马里奥(第四天)_第2张图片

目录说明:

        1. traits/JumpTrait.js:马里奥的跳跃特征类,用于改变马里奥的纵向速度,实现跳跃

        2. traits/Velocity.js:马里奥的速度特征类,将原有的马里奥位置改变,封装为特征类,实现马里奥位置改变

        3. KeyBoardState.js:键盘事件监听类,针对空格键的监听键盘事件,用于调用马里奥的弹跳特征对象的update方法用,实现键盘的空格键的跳跃

入口文件改动:

原生JS超级马里奥(第四天)_第3张图片

 入口文件中加入全局的键盘事件监听,用于空格键抬起和按下时,马里奥相应的取消跳跃和跳跃

马里奥抽象实体类改动:

原生JS超级马里奥(第四天)_第4张图片

马里奥抽象实体将入了抽象特征类Trait,并在马里奥抽象实体类Enityt中加入了addTrait、update方法,其中addTrait用于向实体添加特征,update用于将每个特征中的update方法执行一次,达到马里奥特征的改动,而这个update方法又被main中的时间函数不断的调用,所以只要特征类数据更新时,马里奥就会持续不断的调用update

马里奥对象改动:

原生JS超级马里奥(第四天)_第5张图片

马里奥对象里,将原本更新位置的方法拆分到了VelocityTrait特征类,加入了一个新的特征类JumpTrait,称为跳跃特征类。当空格键的抬起和按下动作,就会调用马里奥对象上跳跃特征类对应的jump方法和start方法,以此更新马里奥的特征数据,并渲染新的马里奥。

监听空格键的键盘事件

export const STATE_KEYDOWN = 1;
export const STATE_KEYUP = 0;

export const KEYCODE_SPACE = 32;


export class KeyboardState {
    constructor() {
        // 保存当前键盘状态
        this.keyStates = new Map();

        // 保存键盘事件对应的回调函数
        this.keyMap = new Map();
    }

    addMapping = (keyCode, callback) => {

        // 添加map映射
        this.keyMap.set(keyCode, callback);
    }

    handleEvent = event => {
        const { keyCode } = event;
        if (!this.keyMap.has(keyCode)) {
            return;
        }

        // 阻止键盘的默认行为,比如pageDown等
        event.preventDefault();
        const keyState = event.type === 'keydown' ? STATE_KEYDOWN : STATE_KEYUP;
        
        // 如果当前键盘状态已经存在了,就不再添加新的相同的状态
        if (this.keyStates.get(keyCode) === keyState) {
            return;
        }

        this.keyStates.set(keyCode, keyState);

        const callback = this.keyMap.get(keyCode);
        callback(keyState);
    }

    listenTo = window => {
        // 监听键盘按下和抬起的事件,并交由处理程序
        ['keydown', 'keyup'].forEach(r => {
            window.addEventListener(r, event => {
                event.preventDefault();
                this.handleEvent(event);
            });
        })
    }
}

监听键盘的空格按下和抬起动作需要提前设置映射规则,然后全局监听window,当空格的抬起和按下动作发生时,执行对应的回调函数,来达到马里奥的跳跃和取消跳跃

马里奥跳跃特征类

import { Trait } from '../Entity.js'

export class JumpTrait extends Trait {
    constructor() {
        super('jump');

        // 时长
        this.duration = 0.5;

         // 下降速度
        this.velocity = 200;

        // 参与时间
        this.engageTime = 0;
    }

    start = () => {

        // 开始,设置参与时间为其时长
        this.engageTime = this.duration;
    }

    cancel = () => {

        // 结束,设置参与时间为0
        this.engageTime = 0;
    }
 
    update = (entity, deltaTime) => {

        // 更新方法,如果还剩余参与时间就还要更新,然后将参与时间减去已经过去的delta时间
        if (this.engageTime > 0) {
            entity.vel.y = -this.velocity;
            this.engageTime -= deltaTime;
        }
    }
}

跳跃特征类继承自特征抽象类,并实现的update方法,新增了start和cancel,用于控制马里奥跳跃动作的开始和结束

马里奥位置改变的速度特征类

import { Trait } from '../Entity.js'

export class VelocityTrait extends Trait {
    constructor() {
        super('velocity');
    }

    update = (entity, deltaTime) => {

        // 改变马里奥的位置
        entity.pos.x += entity.vel.x * deltaTime;
        entity.pos.y += entity.vel.y * deltaTime;
    }
}

马里奥位置改变的速度特征类也继承自特征抽象类,他的代码就是之前在马里奥实现类里面改变马里奥位置的代码。

至此整个跳跃过程更新完毕。

本章需要小伙伴们理解面向对象语言中的多态、封装和继承三大特征,实现类和基类调用方法时遵循的规则,本章不是很难,好好理解即可

你可能感兴趣的:(原生js,es6,web小游戏开发,javascript,小游戏,es6,前端,超级玛丽)