来建立我们的主角小恐龙吧。
建立小恐龙组件 dino.vue
src\components\window-app-google-dino\dino.vue
<template lang="pug">
.dino
</template>
<style scoped lang="sass">
.dino
position: absolute
width: 80px
bottom: 30px
left: 30px
</style>
<script>
export default {
name: 'Dino',
components: {},
props: {},
data() {
return {};
},
computed: {},
watch: {},
created() {},
mounted() {},
beforeDestroy() {},
methods: {},
};
</script>
在 game-scene.vue
引入 dino.vue
。
src\components\window-app-google-dino\game-scene.vue <script>
// ...
import { mapState } from 'vuex';
import Dino from './dino.vue';
export default {
name: 'GameScene',
components: {
dino: Dino,
},
// ...
};
src\components\window-app-google-dino\game-scene.vue <template lang="pug">
.game-scene(@click='start')
.ground
dino(ref='dino')
// ...
再来帮小恐龙加入图片、动画等等效果,注入灵魂。
将准备好的图片放入 src\assets\google-dino
目录并新增以下变数。
src\components\window-app-google-dino\dino.vue <script>
/**
* @typedef {Object} Status 人物状态
* @property {Boolean} jumping 跳跃
* @property {Boolean} squatting 蹲下
*/
import imgJump from '@/assets/google-dino/dino-jump.png';
export default {
name: 'Dino',
// ...
data() {
return {
/** @type {Status} */
status: {
jumping: false,
squatting: false,
},
/** 目前显示图片 */
imgSrc: imgJump,
/** 计时器,处理图片动画 */
timer: null,
};
},
// ...
};
methods
新增功能。
import imgRun01 from '@/assets/google-dino/dino-run-1.png';
import imgRun02 from '@/assets/google-dino/dino-run-2.png';
import imgJump from '@/assets/google-dino/dino-jump.png';
import imgDie from '@/assets/google-dino/dino-die.png';
import imgSquat01 from '@/assets/google-dino/dino-squat-1.png';
import imgSquat02 from '@/assets/google-dino/dino-squat-2.png';
export default {
name: 'Dino',
// ...
methods: {
/** 开始 */
start() {
this.status.jumping = false;
this.status.squatting = false;
this.timer = setInterval(() => {
this.processSpriteImg();
}, 150);
},
/** 结束 */
over() {
this.imgSrc = imgDie;
clearInterval(this.timer);
},
/** 透过切换图片的方式动画 */
processSpriteImg() {
/** @type {Status} */
const status = this.status;
// 跑步
if (this.imgSrc === imgRun01) {
this.imgSrc = imgRun02;
} else {
this.imgSrc = imgRun01;
}
},
},
// ...
};
透过 props
取得游戏状态并侦测状态变化,执行对应动作。
src\components\window-app-google-dino\dino.vue <script>
// ...
import { GameStatus } from './game-scene.vue';
export default {
name: 'Dino',
// ...
props: {
gameStatus: {
type: String,
default: '',
},
},
// ...
watch: {
gameStatus(status) {
if (status === GameStatus.START) {
this.start();
return;
}
if (status === GameStatus.GAME_OVER) {
this.over();
return;
}
},
},
// ...
};
记得 game-scene.vue
模板中的 dino
也要加入参数。
src\components\window-app-google-dino\game-scene.vue <template lang="pug">
.game-scene(@click='start')
.ground
dino(ref='dino', :game-status='gameStatus')
// ...
最後在 .dino
下方加个 img
显示小恐龙图片。
src\components\window-app-google-dino\dino.vue <template lang="pug">
.dino
img(:src='imgSrc')
目前应该会长这样。
点一下画面,看看游戏开始後小恐龙会不会开始跑步。
小恐龙成功开跑!
再来就是让小恐龙跳跃和蹲下了。
跳跃动画使用 GSAP 实现。
GSAP 是一套专门处理动画与特效的 JS 套件,可以实现动画时间轴管理等等功能,功能非常强大。
概念为「透过 GSAP 控制跳跃高度数值,并将高度数值绑定至 CSS 样式,呈现 DOM 移动效果」。
实作过程如下:
data()
yOffset
:目前跳跃高度。gsapAni
:储存 GSAP 动画变数。methods
processSpriteImg()
:加入跳跃图片initGsapAni()
:初始化 GSAP 物件jump()
:开始跳跃。呼叫 GSAP 跳跃动画物件computed
style
:将变数转为 CSS 属性created()
呼叫 initGsapAni()
src\components\window-app-google-dino\dino.vue <script>
// ...
import { gsap } from 'gsap';
export default {
name: 'Dino',
// ...
data() {
return {
// ...
/** 跳跃量 */
yOffset: 0,
/** GSAP 动画 */
gsapAni: {
jump: null,
},
};
},
computed: {
style() {
return {
transform: `translateY(-${this.yOffset}px)`,
};
},
},
created() {
// 初始化 GSAP 动画物件
this.initGsapAni();
},
// ...
methods: {
// ...
/** 透过切换图片的方式动画 */
processSpriteImg() {
/** @type {Status} */
const status = this.status;
// 跳跃
if (status.jumping) {
this.imgSrc = imgJump;
return;
}
// 跑步
if (this.imgSrc === imgRun01) {
this.imgSrc = imgRun02;
} else {
this.imgSrc = imgRun01;
}
},
/** 初始化 GSAP 动画 */
initGsapAni() {
/** @type {Status} */
const status = this.status;
const jumpTimeline = gsap.timeline();
// 动画持续时间
const duration = 0.32;
jumpTimeline
.to(this, {
duration,
yOffset: 150,
ease: 'power1.out',
onStart() {
status.jumping = true;
},
})
.to(this, {
duration,
yOffset: 0,
ease: 'power1.in',
onComplete() {
status.jumping = false;
},
})
.pause();
this.gsapAni.jump = jumpTimeline;
},
/** 跳跃 */
jump() {
if (this.status.jumping) return;
this.gsapAni.jump.restart();
},
// ...
};
除了绑定 style
外,加入 @click
,测试跳跃动画。
src\components\window-app-google-dino\dino.vue <template lang="pug">
.dino(:style='style', @click='jump')
img(:src='imgSrc')
点击看看小恐龙会不会跳跃。
成功起跳!
蹲下动作就简单很多,单纯就是状态切换而已。
实作过程如下:
methods
processSpriteImg()
:加入蹲下图片setSquat()
:设定是否蹲下src\components\window-app-google-dino\dino.vue <script>
// ...
export default {
name: 'Dino',
// ...
methods: {
// ...
/** 透过切换图片的方式动画 */
processSpriteImg() {
/** @type {Status} */
const status = this.status;
// 跳跃
if (status.jumping) {
this.imgSrc = imgJump;
return;
}
// 蹲下
if (status.squatting) {
if (this.imgSrc === imgSquat01) {
this.imgSrc = imgSquat02;
} else {
this.imgSrc = imgSquat01;
}
return;
}
// 跑步
if (this.imgSrc === imgRun01) {
this.imgSrc = imgRun02;
} else {
this.imgSrc = imgRun01;
}
},
// ...
/** 设定是否蹲下 */
setSquat(status = true) {
this.status.squatting = status;
},
};
这次使用右键测试「蹲下」动作,按着蹲下,放开回复动作。
src\components\window-app-google-dino\dino.vue <template lang="pug">
.dino(
:style='style',
@click='jump',
@mousedown.right='setSquat(true)',
@mouseup.right='setSquat(false)',
@contextmenu.prevent
)
img(:src='imgSrc')
尝试看看是否左键跳跃,右键蹲下。
成功!恭喜复活恐龙惹!(´,,•ω•,,)
最後是最容易忘记也最重要的一步,就是销毁计时器。利用 beforeDestroy()
呼叫 over()
达成效果。
src\components\window-app-google-dino\dino.vue <script>
export default {
name: 'Dino',
// ...
beforeDestroy() {
this.over();
},
// ...
};
以上程序码已同步至 GitLab,大家可以前往下载:
<<: Android Studio初学笔记-Day22-ToolBar
组合技 Drone + godog + Mattermost 当有需求要在k8s上透过drone定期...
有点受不了没什麽演算法底子还要掰出 Leetcode 文章QQ 今天来记录当初学习的过程和後来的想法...
物件导向的封装特性 封装特性:在一个物件产生之後,物件的部分成员属性和成员方法在逻辑上是不允许在物件...
写在前面 placeholder for test placeholder for test pla...
前言: 昨天我们介绍了一个普通的资讯页面是如何完成的,今天我们要来介绍另一个很常用到的页面种类,资...