@shijiu/jsview-vue-samples 2.0.1106 → 2.0.1119-next-vue.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/DemoHomepage/router.js +5 -0
- package/ImpactStop/App.vue +1 -0
- package/Parkour/App.vue +13 -0
- package/Parkour/Common/Context.js +19 -0
- package/Parkour/Common/MatchmanInfo.js +62 -0
- package/Parkour/Common/Random.js +61 -0
- package/Parkour/Common/Sound.js +50 -0
- package/Parkour/appConfig/HOW_TO_CONFIG.md +20 -0
- package/Parkour/appConfig/app.config.mjs +5 -0
- package/Parkour/appConfig/app_sign_private_key_sample.crt +28 -0
- package/Parkour/appConfig/app_sign_public_key_sample.pem +9 -0
- package/Parkour/appConfig/jsview.config.mjs +43 -0
- package/Parkour/assets/Bgimages/bg1.png +0 -0
- package/Parkour/assets/Bgimages/bg2.png +0 -0
- package/Parkour/assets/Bgimages/bg3.png +0 -0
- package/Parkour/assets/Bgimages/bg4.png +0 -0
- package/Parkour/assets/Bgimages/bg5.png +0 -0
- package/Parkour/assets/audio/jump.mp3 +0 -0
- package/Parkour/assets/audio/lose.mp3 +0 -0
- package/Parkour/assets/role_skin1/fail.json +44 -0
- package/Parkour/assets/role_skin1/fail.png +0 -0
- package/Parkour/assets/role_skin1/jump_down.json +20 -0
- package/Parkour/assets/role_skin1/jump_down.png +0 -0
- package/Parkour/assets/role_skin1/jump_up.json +44 -0
- package/Parkour/assets/role_skin1/jump_up.png +0 -0
- package/Parkour/assets/role_skin1/roll.json +44 -0
- package/Parkour/assets/role_skin1/roll.png +0 -0
- package/Parkour/assets/role_skin1/run.json +52 -0
- package/Parkour/assets/role_skin1/run.png +0 -0
- package/Parkour/components/Backdrop.vue +56 -0
- package/Parkour/components/GameSence.vue +554 -0
- package/Parkour/components/Matchman.vue +85 -0
- package/package.json +1 -1
package/DemoHomepage/router.js
CHANGED
|
@@ -200,6 +200,11 @@ let routeList = [
|
|
|
200
200
|
name:'雷达图',
|
|
201
201
|
path:'/Game/RadarChart',
|
|
202
202
|
component:()=>import('jsview-vue-samples/JsvRadarChart/App.vue')
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
name:'跑酷游戏',
|
|
206
|
+
path:'/Game/Parkour',
|
|
207
|
+
component:()=>import('jsview-vue-samples/parkour/App.vue')
|
|
203
208
|
}
|
|
204
209
|
];
|
|
205
210
|
|
package/ImpactStop/App.vue
CHANGED
package/Parkour/App.vue
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<GameSence :key="SenceKey"></GameSence>
|
|
3
|
+
</template>
|
|
4
|
+
|
|
5
|
+
<script setup>
|
|
6
|
+
import { provide, shallowRef } from 'vue';
|
|
7
|
+
import GameSence from './components/GameSence.vue';
|
|
8
|
+
//定义变量key,通过修改key值来进行页面重载
|
|
9
|
+
let SenceKey = shallowRef(0)
|
|
10
|
+
provide("SenceKey", SenceKey)
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
<style lang="scss" scoped></style>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/* 在此存放Demo中全局影响的变量*/
|
|
2
|
+
import { shallowRef } from "vue";
|
|
3
|
+
class Context {
|
|
4
|
+
constructor() {
|
|
5
|
+
this.left = shallowRef(0);
|
|
6
|
+
//各ref
|
|
7
|
+
this.TopRef1=shallowRef(null)
|
|
8
|
+
this.TopRef2=shallowRef(null)
|
|
9
|
+
this.MidRef1=shallowRef(null);
|
|
10
|
+
this.MidRef2=shallowRef(null);
|
|
11
|
+
this.BottomRef1=shallowRef(null)
|
|
12
|
+
this.BottomRef2=shallowRef(null);
|
|
13
|
+
this.ObstacleRef1=shallowRef(null)
|
|
14
|
+
this.ObstacleRef2=shallowRef(null)
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
export {
|
|
18
|
+
Context
|
|
19
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/* 此js文件用于更新火柴人的动作 */
|
|
2
|
+
import fail_json from "../assets/role_skin1/fail.json"
|
|
3
|
+
import fail_png from "../assets/role_skin1/fail.png"
|
|
4
|
+
import roll_json from "../assets/role_skin1/roll.json"
|
|
5
|
+
import roll_png from "../assets/role_skin1/roll.png"
|
|
6
|
+
import jumpDown_json from "../assets/role_skin1/jump_down.json"
|
|
7
|
+
import jumpDown_png from "../assets/role_skin1/jump_down.png"
|
|
8
|
+
import jumpUp_json from "../assets/role_skin1/jump_up.json"
|
|
9
|
+
import jumpUp_png from "../assets/role_skin1/jump_up.png"
|
|
10
|
+
import run_json from "../assets/role_skin1/run.json"
|
|
11
|
+
import run_png from "../assets/role_skin1/run.png"
|
|
12
|
+
|
|
13
|
+
//精灵图信息函数
|
|
14
|
+
const _formatInfo = (action_json) => {
|
|
15
|
+
const info = {
|
|
16
|
+
frames: [],
|
|
17
|
+
meta: {
|
|
18
|
+
size: action_json.meta.size,
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
let frames_ref = info.frames;
|
|
22
|
+
let max_width = 0;
|
|
23
|
+
let max_height = 0;
|
|
24
|
+
|
|
25
|
+
for (let i = 0; i < action_json.frames.length; i++) {
|
|
26
|
+
const target = action_json.frames[i].spriteSourceSize;
|
|
27
|
+
frames_ref.push({
|
|
28
|
+
target,
|
|
29
|
+
source: action_json.frames[i].frame,
|
|
30
|
+
});
|
|
31
|
+
const sprite_with = target.x + target.w;
|
|
32
|
+
const sprite_height = target.y + target.h;
|
|
33
|
+
if (sprite_with > max_width) {
|
|
34
|
+
max_width = sprite_with;
|
|
35
|
+
}
|
|
36
|
+
if (sprite_height > max_height) {
|
|
37
|
+
max_height = sprite_height;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return { info, maxW: max_width, maxH: max_height };
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
//存入整个json对象
|
|
44
|
+
const jsonObject={
|
|
45
|
+
fail_json,
|
|
46
|
+
roll_json,
|
|
47
|
+
jumpDown_json,
|
|
48
|
+
jumpUp_json,
|
|
49
|
+
run_json
|
|
50
|
+
}
|
|
51
|
+
const pngObject={
|
|
52
|
+
fail_png,
|
|
53
|
+
roll_png,
|
|
54
|
+
jumpDown_png,
|
|
55
|
+
jumpUp_png,
|
|
56
|
+
run_png
|
|
57
|
+
}
|
|
58
|
+
export {
|
|
59
|
+
_formatInfo,
|
|
60
|
+
jsonObject,
|
|
61
|
+
pngObject,
|
|
62
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/* 此js文件用于初始化以及更新随机背景图和地板 */
|
|
2
|
+
import bg1 from "../assets/Bgimages/bg1.png"
|
|
3
|
+
import bg2 from "../assets/Bgimages/bg2.png"
|
|
4
|
+
import bg3 from "../assets/Bgimages/bg3.png"
|
|
5
|
+
import bg4 from "../assets/Bgimages/bg4.png"
|
|
6
|
+
import bg5 from "../assets/Bgimages/bg5.png"
|
|
7
|
+
import { shallowRef } from "vue"
|
|
8
|
+
import { buildPreloadInfo } from "jsview"
|
|
9
|
+
import { Context } from "./Context"
|
|
10
|
+
/* 背景图相关 */
|
|
11
|
+
//定义随机背景图数组
|
|
12
|
+
const bgArray = [bg1, bg2, bg3, bg4, bg5]
|
|
13
|
+
//随机背景图
|
|
14
|
+
const randomBg = (bg, array) => {
|
|
15
|
+
array.value = []
|
|
16
|
+
const randomIndex = Math.floor(Math.random() * bgArray.length);
|
|
17
|
+
bg.value = bgArray[randomIndex]
|
|
18
|
+
array.value.push(buildPreloadInfo(bg.value))
|
|
19
|
+
return bg
|
|
20
|
+
}
|
|
21
|
+
/* 地板相关 */
|
|
22
|
+
|
|
23
|
+
//拿地板定位left的值
|
|
24
|
+
let GameContext = new Context()
|
|
25
|
+
//设定缝隙长度
|
|
26
|
+
const gapWidth = 280;
|
|
27
|
+
//给定最大长度
|
|
28
|
+
const maxLength = 820;
|
|
29
|
+
//给定最小长度
|
|
30
|
+
const minLength = 600
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
//随机的div样式
|
|
34
|
+
const randomFloor = (array) => {
|
|
35
|
+
for (let i = 0; i < 2; i++) {
|
|
36
|
+
const length = Math.floor(Math.random() * (maxLength - minLength + 1)) + minLength + gapWidth
|
|
37
|
+
GameContext.left.value += length
|
|
38
|
+
let top = shallowRef(0)
|
|
39
|
+
if (i !== 0) {
|
|
40
|
+
top.value = 500 - Math.floor(Math.random() * 180)
|
|
41
|
+
} else {
|
|
42
|
+
top.value = 500
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
array.value.push({ length: length, left: GameContext.left.value, top: top.value })
|
|
46
|
+
}
|
|
47
|
+
array.value.forEach((item, index) => {
|
|
48
|
+
if (index == 0) {
|
|
49
|
+
item.left = 0
|
|
50
|
+
} else {
|
|
51
|
+
item.left = array.value[index - 1].left + array.value[index - 1].length;
|
|
52
|
+
}
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
return array
|
|
56
|
+
}
|
|
57
|
+
export {
|
|
58
|
+
randomFloor,
|
|
59
|
+
randomBg,
|
|
60
|
+
gapWidth
|
|
61
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/* 音频 */
|
|
2
|
+
import { JsvSoundPool } from "jsview";
|
|
3
|
+
import jumpAudio from "../assets/audio/jump.mp3"
|
|
4
|
+
import failAudio from "../assets/audio/lose.mp3"
|
|
5
|
+
|
|
6
|
+
class Sound {
|
|
7
|
+
initSound() {
|
|
8
|
+
this.soundPool = new JsvSoundPool(10);
|
|
9
|
+
this.soundPool.request(
|
|
10
|
+
`url(${jumpAudio})`,
|
|
11
|
+
null,
|
|
12
|
+
1,
|
|
13
|
+
(state, audioController) => {
|
|
14
|
+
console.log("load jump audio ", state)
|
|
15
|
+
if (state === 0) {
|
|
16
|
+
Sound._AudioController1 = audioController;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
);
|
|
20
|
+
this.soundPool.request(
|
|
21
|
+
`url(${failAudio})`,
|
|
22
|
+
null,
|
|
23
|
+
1,
|
|
24
|
+
(state, audioController) => {
|
|
25
|
+
console.log("load fail audio ", state)
|
|
26
|
+
if (state === 0) {
|
|
27
|
+
Sound._AudioController2 = audioController;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
playJumpSound() {
|
|
34
|
+
if (Sound._AudioController1) {
|
|
35
|
+
Sound._AudioController1.play();
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
playFailSound() {
|
|
40
|
+
if (Sound._AudioController2) {
|
|
41
|
+
Sound._AudioController2.play();
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
destroy () {
|
|
46
|
+
this.soundPool.destroy()
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
}
|
|
50
|
+
export default Sound ;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
app_data文件夹用来记录APP的设定信息,包括APP的全球唯一标识,签名信息
|
|
2
|
+
|
|
3
|
+
1. 全球唯一标识AppName设定方法:
|
|
4
|
+
修改app.config.js文件中的AppName信息,一般命名方法为 domain/子应用名
|
|
5
|
+
|
|
6
|
+
2. 签名信息,使用RSA签名,设定方法:
|
|
7
|
+
使用在线生成工具生成RSA钥匙对,例如 http://www.metools.info/code/c80.html
|
|
8
|
+
注意选择设定信息有三点要注意:
|
|
9
|
+
A. 秘钥长度固定为 2048 bit
|
|
10
|
+
B. 秘钥格式固定为 PKCS#8
|
|
11
|
+
(生成出的公钥以 -----BEGIN PUBLIC KEY----- 开头,而非 -----BEGIN RSA PUBLIC KEY-----)
|
|
12
|
+
C. 密码不要设置
|
|
13
|
+
将生成的公钥复制粘贴到文件app_sign_public_key.pem中,内容可以参照 app_sign_public_key_sample.pem 文件
|
|
14
|
+
同理,将私钥复制粘贴到文件app_sign_private_key.crt中
|
|
15
|
+
|
|
16
|
+
JsView签名原理说明:
|
|
17
|
+
在进行js build时,会将 main.jsv.xxxx.js (包含AppName具体值)文件的md5值用私钥进行编码,编码出的内容和公钥一起写入到该文件的文件头中,JsView加载后用公钥反编码出该md5值,和文件的md5进行比对,若md5一致则认为此公钥合法,然后此公钥会和AppName进行映射,作为设定快捷访问地址等权限控制的调用作为参考,以防止其他APP对本APP(以AppName为查询键)的私有内容进行非法访问和破坏。
|
|
18
|
+
|
|
19
|
+
注意: 私钥(app_sign_private_key.crt)不要被泄漏,私钥若泄漏,则其他APP可以伪装AppName,查询本APP的私有内容,覆盖本APP设定的快捷访问地址。
|
|
20
|
+
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
-----BEGIN PRIVATE KEY-----
|
|
2
|
+
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCyAMjq7vLF45SQ
|
|
3
|
+
Xk3KtelbgEOR57okn2vFXMRa9lrHEkfP72YPnP7INHxMQ8pWIEx8nfhOTjCQbzAN
|
|
4
|
+
5omUxjJizNsqcgfKldLgdwQAUENozMSsxWiteMyjvH0aX5X0vbpSOykUnkg/UROG
|
|
5
|
+
vCyIj1buylww8FAMA4TamxfivOCLmQU7qlZNq7bZ/ZOYsdvAYRfd5Ey0Si8kgsk8
|
|
6
|
+
/I9halBymQeVylBB+qY5d4L0IVLjcjbc9y9tU0+o4NoqFfkKCFQaSNXqYVey9yCG
|
|
7
|
+
eHtpx9XT+SNDzvFTbGQaAVyoYSKjshQk58u1yn9kRp0t7rUvRfAQh6ocKBlPMucP
|
|
8
|
+
x4zTv8PPAgMBAAECggEAJzhVDK6pf0Cts0GUEl4SlL6mJLfSI8+ch1fxS7mMNuCo
|
|
9
|
+
QgCVlEsbODGYUZV+N4vWTn7f/yDrQme9RtLM7aLd5zcL80Y8wT5RwHN4xjjpIWY8
|
|
10
|
+
z3SPo+lB7bHSPsVg3RQQwZ2XZ5uYf5r1mnJLvasXlHWx6naIrJz54NDbanIDZ75p
|
|
11
|
+
YMvN/JIF4CQR58CNsPI3I8Ww5hnCSAynKlJy6qOf+C0XYxTRUs4TkZFa851a3E1q
|
|
12
|
+
4E8HMCvt4BZiGfyvLyS6+2pDevY9gcym1yIYwhcIRviD8S1hGpGPcmHbbt7Sj70Y
|
|
13
|
+
hr4oqbgxhlpQl9y2iUZ4VSKN3f1eU2O5Qufsn2cpQQKBgQDgZ2o+W5AIThqepzkK
|
|
14
|
+
+ExiXXVkHmSAtne5uLEz8SU/xwc0c0j9sOUlmpCvgn+aKbQO8MModAblPgo2QvI1
|
|
15
|
+
YTnX/V+TBm/4mBmCq+F7i0z2ZrexGO6CSbe8lVSBy/sAbzNMeK6fPnS0aO4ZWjYS
|
|
16
|
+
SDQ8/FAbxsHjUo2u5UDHJBj+JQKBgQDLENxo7EsCVB0R80WpL1VhkzXz3VTeMaSs
|
|
17
|
+
rj81eu7Ji/55Eh7QzPI3TUNcFAUHRN8THT320dCiXkg0s/YTKD2j9s7mnAFjyNnG
|
|
18
|
+
oiAmOvSpSKZgRGHh63LzwIDtSSQoeJQw+6ujvvF2elsWJ7s3t1N6tZD/E9E291yF
|
|
19
|
+
WFDixdn14wKBgQCQV5TMVYMZBHw07uVPPBWN9AWth6sn67apPLam7YcDNhdZUopx
|
|
20
|
+
vFY40OoeKre/RvHt5knx/GfvDu/spTU8xrQ5TV4rqSle4x8NoVehayHvIHUpshrA
|
|
21
|
+
rYBFClzYPIfQaLa7iqjv/3F8Fj6JCjDbo5wOWlGA/GD8wr4l8IqxTXPSDQKBgQCr
|
|
22
|
+
rmWqj5wbK+In+vU6RLp69Gr48nd+I5qGJAtsu7KG08UhtyA2iA+AkeIRRxu5OZEg
|
|
23
|
+
J+jrdBhgLjX92OiC6dKzfUcP0XWbV4RHW2qy58VSGgoP+cCHsPhO/MID24KmdMtV
|
|
24
|
+
XnGOzzB2apv37z9pq6T4aelcvvRy9E9UrYY1M/FC4QKBgA7CryIz/+Ps7zrn50BN
|
|
25
|
+
TM3wsqomVe2sKj6OIE7f7SLdmA4cAco+xoXBExLxP7aqgrBj4B/7ovloF6edsGMI
|
|
26
|
+
RF8yP8OceBIruFEKwUh4m0uoWshLJVnjk0iU+X8OD5lUCRhEZ6zO6svt5HTP1d+o
|
|
27
|
+
XcUVzSIc3bxXpKmwXAfLKVED
|
|
28
|
+
-----END PRIVATE KEY-----
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
-----BEGIN PUBLIC KEY-----
|
|
2
|
+
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsgDI6u7yxeOUkF5NyrXp
|
|
3
|
+
W4BDkee6JJ9rxVzEWvZaxxJHz+9mD5z+yDR8TEPKViBMfJ34Tk4wkG8wDeaJlMYy
|
|
4
|
+
YszbKnIHypXS4HcEAFBDaMzErMVorXjMo7x9Gl+V9L26UjspFJ5IP1EThrwsiI9W
|
|
5
|
+
7spcMPBQDAOE2psX4rzgi5kFO6pWTau22f2TmLHbwGEX3eRMtEovJILJPPyPYWpQ
|
|
6
|
+
cpkHlcpQQfqmOXeC9CFS43I23PcvbVNPqODaKhX5CghUGkjV6mFXsvcghnh7acfV
|
|
7
|
+
0/kjQ87xU2xkGgFcqGEio7IUJOfLtcp/ZEadLe61L0XwEIeqHCgZTzLnD8eM07/D
|
|
8
|
+
zwIDAQAB
|
|
9
|
+
-----END PUBLIC KEY-----
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
jsviewConfig: {
|
|
3
|
+
// (可选配置)remote loader
|
|
4
|
+
remoteLoader: null,
|
|
5
|
+
|
|
6
|
+
// (可选配置)localStorage支持
|
|
7
|
+
// presetKeys为预置key,可以直接使用localStorage.xxx的形式,避免undefined错误
|
|
8
|
+
localStorage: {
|
|
9
|
+
domain: null, // 默认自动使用app.config.mjs的AppName作为domain, 可以设置为其他值
|
|
10
|
+
presetKeys: [
|
|
11
|
+
'value1',
|
|
12
|
+
'value3'
|
|
13
|
+
]
|
|
14
|
+
},
|
|
15
|
+
|
|
16
|
+
cookies: {
|
|
17
|
+
domain: '' // 当非null非空时,激活cookie功能,使ajax请求时自动带上cookies,并且document.cookie的get/set可用
|
|
18
|
+
},
|
|
19
|
+
|
|
20
|
+
// (可选配置)填写main.js或者bundle.js相对于index.html的相对位置,
|
|
21
|
+
// 用于image/import.then的相对寻址, vue3默认值是/js/
|
|
22
|
+
jsSubPath: '/js/'
|
|
23
|
+
},
|
|
24
|
+
|
|
25
|
+
vendorConfig: {
|
|
26
|
+
// (可选配置)设置屏幕坐标映射值,screenWidth为屏幕画布定义的宽度,displayScale为清晰度,
|
|
27
|
+
// 默认值是画布宽度1280px, 清晰度为1.0
|
|
28
|
+
designedMap: {
|
|
29
|
+
screenWidth: 1280,
|
|
30
|
+
displayScale: 1.5
|
|
31
|
+
},
|
|
32
|
+
|
|
33
|
+
// (可选配置)按键接受的扩展,例如将静音按键(JAVA键值为164)映射为JS键值20001,
|
|
34
|
+
// PS:注意'164'的引号
|
|
35
|
+
bindKeys: {
|
|
36
|
+
keys: {
|
|
37
|
+
164: 20001
|
|
38
|
+
},
|
|
39
|
+
syncKeys: {
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{"frames": [
|
|
2
|
+
|
|
3
|
+
{
|
|
4
|
+
"filename": "1.png",
|
|
5
|
+
"frame": {"x":0,"y":0,"w":154,"h":112},
|
|
6
|
+
"rotated": false,
|
|
7
|
+
"trimmed": false,
|
|
8
|
+
"spriteSourceSize": {"x":0,"y":0,"w":154,"h":112},
|
|
9
|
+
"sourceSize": {"w":154,"h":112}
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
"filename": "2.png",
|
|
13
|
+
"frame": {"x":154,"y":0,"w":154,"h":112},
|
|
14
|
+
"rotated": false,
|
|
15
|
+
"trimmed": false,
|
|
16
|
+
"spriteSourceSize": {"x":0,"y":0,"w":154,"h":112},
|
|
17
|
+
"sourceSize": {"w":154,"h":112}
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"filename": "3.png",
|
|
21
|
+
"frame": {"x":0,"y":112,"w":154,"h":112},
|
|
22
|
+
"rotated": false,
|
|
23
|
+
"trimmed": false,
|
|
24
|
+
"spriteSourceSize": {"x":0,"y":0,"w":154,"h":112},
|
|
25
|
+
"sourceSize": {"w":154,"h":112}
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"filename": "4.png",
|
|
29
|
+
"frame": {"x":154,"y":112,"w":154,"h":112},
|
|
30
|
+
"rotated": false,
|
|
31
|
+
"trimmed": false,
|
|
32
|
+
"spriteSourceSize": {"x":0,"y":0,"w":154,"h":112},
|
|
33
|
+
"sourceSize": {"w":154,"h":112}
|
|
34
|
+
}],
|
|
35
|
+
"meta": {
|
|
36
|
+
"app": "http://www.texturepacker.com",
|
|
37
|
+
"version": "1.0",
|
|
38
|
+
"image": "fail.png",
|
|
39
|
+
"format": "RGBA8888",
|
|
40
|
+
"size": {"w":308,"h":224},
|
|
41
|
+
"scale": "1",
|
|
42
|
+
"smartupdate": "$TexturePacker:SmartUpdate:44519538b3a9873cd0d16979a0037991$"
|
|
43
|
+
}
|
|
44
|
+
}
|
|
Binary file
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{"frames": [
|
|
2
|
+
|
|
3
|
+
{
|
|
4
|
+
"filename": "5.png",
|
|
5
|
+
"frame": {"x":0,"y":0,"w":154,"h":112},
|
|
6
|
+
"rotated": false,
|
|
7
|
+
"trimmed": false,
|
|
8
|
+
"spriteSourceSize": {"x":0,"y":0,"w":154,"h":112},
|
|
9
|
+
"sourceSize": {"w":154,"h":112}
|
|
10
|
+
}],
|
|
11
|
+
"meta": {
|
|
12
|
+
"app": "http://www.texturepacker.com",
|
|
13
|
+
"version": "1.0",
|
|
14
|
+
"image": "jump_down.png",
|
|
15
|
+
"format": "RGBA8888",
|
|
16
|
+
"size": {"w":154,"h":112},
|
|
17
|
+
"scale": "1",
|
|
18
|
+
"smartupdate": "$TexturePacker:SmartUpdate:9728b77a05eee5f78b6fb375d523d989$"
|
|
19
|
+
}
|
|
20
|
+
}
|
|
Binary file
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{"frames": [
|
|
2
|
+
|
|
3
|
+
{
|
|
4
|
+
"filename": "1.png",
|
|
5
|
+
"frame": {"x":0,"y":0,"w":154,"h":112},
|
|
6
|
+
"rotated": false,
|
|
7
|
+
"trimmed": false,
|
|
8
|
+
"spriteSourceSize": {"x":0,"y":0,"w":154,"h":112},
|
|
9
|
+
"sourceSize": {"w":154,"h":112}
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
"filename": "2.png",
|
|
13
|
+
"frame": {"x":154,"y":0,"w":154,"h":112},
|
|
14
|
+
"rotated": false,
|
|
15
|
+
"trimmed": false,
|
|
16
|
+
"spriteSourceSize": {"x":0,"y":0,"w":154,"h":112},
|
|
17
|
+
"sourceSize": {"w":154,"h":112}
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"filename": "3.png",
|
|
21
|
+
"frame": {"x":0,"y":112,"w":154,"h":112},
|
|
22
|
+
"rotated": false,
|
|
23
|
+
"trimmed": false,
|
|
24
|
+
"spriteSourceSize": {"x":0,"y":0,"w":154,"h":112},
|
|
25
|
+
"sourceSize": {"w":154,"h":112}
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"filename": "4.png",
|
|
29
|
+
"frame": {"x":154,"y":112,"w":154,"h":112},
|
|
30
|
+
"rotated": false,
|
|
31
|
+
"trimmed": false,
|
|
32
|
+
"spriteSourceSize": {"x":0,"y":0,"w":154,"h":112},
|
|
33
|
+
"sourceSize": {"w":154,"h":112}
|
|
34
|
+
}],
|
|
35
|
+
"meta": {
|
|
36
|
+
"app": "http://www.texturepacker.com",
|
|
37
|
+
"version": "1.0",
|
|
38
|
+
"image": "jump_up.png",
|
|
39
|
+
"format": "RGBA8888",
|
|
40
|
+
"size": {"w":308,"h":224},
|
|
41
|
+
"scale": "1",
|
|
42
|
+
"smartupdate": "$TexturePacker:SmartUpdate:5c6da59e8456caf422003adf18575284$"
|
|
43
|
+
}
|
|
44
|
+
}
|
|
Binary file
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{"frames": [
|
|
2
|
+
|
|
3
|
+
{
|
|
4
|
+
"filename": "1.png",
|
|
5
|
+
"frame": {"x":0,"y":0,"w":154,"h":112},
|
|
6
|
+
"rotated": false,
|
|
7
|
+
"trimmed": false,
|
|
8
|
+
"spriteSourceSize": {"x":0,"y":0,"w":154,"h":112},
|
|
9
|
+
"sourceSize": {"w":154,"h":112}
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
"filename": "2.png",
|
|
13
|
+
"frame": {"x":154,"y":0,"w":154,"h":112},
|
|
14
|
+
"rotated": false,
|
|
15
|
+
"trimmed": false,
|
|
16
|
+
"spriteSourceSize": {"x":0,"y":0,"w":154,"h":112},
|
|
17
|
+
"sourceSize": {"w":154,"h":112}
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"filename": "3.png",
|
|
21
|
+
"frame": {"x":0,"y":112,"w":154,"h":112},
|
|
22
|
+
"rotated": false,
|
|
23
|
+
"trimmed": false,
|
|
24
|
+
"spriteSourceSize": {"x":0,"y":0,"w":154,"h":112},
|
|
25
|
+
"sourceSize": {"w":154,"h":112}
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"filename": "4.png",
|
|
29
|
+
"frame": {"x":154,"y":112,"w":154,"h":112},
|
|
30
|
+
"rotated": false,
|
|
31
|
+
"trimmed": false,
|
|
32
|
+
"spriteSourceSize": {"x":0,"y":0,"w":154,"h":112},
|
|
33
|
+
"sourceSize": {"w":154,"h":112}
|
|
34
|
+
}],
|
|
35
|
+
"meta": {
|
|
36
|
+
"app": "http://www.texturepacker.com",
|
|
37
|
+
"version": "1.0",
|
|
38
|
+
"image": "roll.png",
|
|
39
|
+
"format": "RGBA8888",
|
|
40
|
+
"size": {"w":308,"h":224},
|
|
41
|
+
"scale": "1",
|
|
42
|
+
"smartupdate": "$TexturePacker:SmartUpdate:6a43ab2eec0ad9894ba8d16f6312c57d$"
|
|
43
|
+
}
|
|
44
|
+
}
|
|
Binary file
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{"frames": [
|
|
2
|
+
|
|
3
|
+
{
|
|
4
|
+
"filename": "1.png",
|
|
5
|
+
"frame": {"x":0,"y":0,"w":154,"h":112},
|
|
6
|
+
"rotated": false,
|
|
7
|
+
"trimmed": false,
|
|
8
|
+
"spriteSourceSize": {"x":0,"y":0,"w":154,"h":112},
|
|
9
|
+
"sourceSize": {"w":154,"h":112}
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
"filename": "2.png",
|
|
13
|
+
"frame": {"x":154,"y":0,"w":154,"h":112},
|
|
14
|
+
"rotated": false,
|
|
15
|
+
"trimmed": false,
|
|
16
|
+
"spriteSourceSize": {"x":0,"y":0,"w":154,"h":112},
|
|
17
|
+
"sourceSize": {"w":154,"h":112}
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"filename": "3.png",
|
|
21
|
+
"frame": {"x":308,"y":0,"w":154,"h":112},
|
|
22
|
+
"rotated": false,
|
|
23
|
+
"trimmed": false,
|
|
24
|
+
"spriteSourceSize": {"x":0,"y":0,"w":154,"h":112},
|
|
25
|
+
"sourceSize": {"w":154,"h":112}
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"filename": "4.png",
|
|
29
|
+
"frame": {"x":0,"y":112,"w":154,"h":112},
|
|
30
|
+
"rotated": false,
|
|
31
|
+
"trimmed": false,
|
|
32
|
+
"spriteSourceSize": {"x":0,"y":0,"w":154,"h":112},
|
|
33
|
+
"sourceSize": {"w":154,"h":112}
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"filename": "5.png",
|
|
37
|
+
"frame": {"x":154,"y":112,"w":154,"h":112},
|
|
38
|
+
"rotated": false,
|
|
39
|
+
"trimmed": false,
|
|
40
|
+
"spriteSourceSize": {"x":0,"y":0,"w":154,"h":112},
|
|
41
|
+
"sourceSize": {"w":154,"h":112}
|
|
42
|
+
}],
|
|
43
|
+
"meta": {
|
|
44
|
+
"app": "http://www.texturepacker.com",
|
|
45
|
+
"version": "1.0",
|
|
46
|
+
"image": "run.png",
|
|
47
|
+
"format": "RGBA8888",
|
|
48
|
+
"size": {"w":462,"h":224},
|
|
49
|
+
"scale": "1",
|
|
50
|
+
"smartupdate": "$TexturePacker:SmartUpdate:444a5be59b33f66d1f4dacf466c293fd$"
|
|
51
|
+
}
|
|
52
|
+
}
|
|
Binary file
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div>
|
|
3
|
+
<JsvPreload :preloadList="props.preload_info" :onPreloadDone="onPreloadDone"></JsvPreload>
|
|
4
|
+
<JsvActorMove :style="{ width: 1280 * 1.5, height: 720, backgroundImage: props.bgImg, }" :control="props.control">
|
|
5
|
+
<div v-for="(item, index) in props.ArrayItem" :style="{
|
|
6
|
+
width: item.length - gapWidth,
|
|
7
|
+
height: 30,
|
|
8
|
+
top: item.top,
|
|
9
|
+
left: item.left,
|
|
10
|
+
backgroundColor: '#FFFFFF',
|
|
11
|
+
}">
|
|
12
|
+
<!-- 红色障碍物 -->
|
|
13
|
+
<div v-if="index === 1" :style="{ width: 70, height: 70, top: -180, left: 400, backgroundColor: '#FF1213' }"
|
|
14
|
+
:ref="props.ObstacleRef">
|
|
15
|
+
<div :style="{ top: -50, left: 6, fontSize: 30, color: '#FFFFFF' }">双跳</div>
|
|
16
|
+
<div :style="{ top: 80, left: 6, fontSize: 30, color: '#FFFFFF' }">下滚</div>
|
|
17
|
+
</div>
|
|
18
|
+
<!-- 上层判定边缘坠落区域 -->
|
|
19
|
+
<div :style="{ width: item.length - gapWidth + 10, height: 5, left: 0, top: -2, backgroundColor: 'rgba(0, 0, 0, 0.5)' }"
|
|
20
|
+
:ref="props.TopRef">
|
|
21
|
+
</div>
|
|
22
|
+
<!-- 中层判定碰到就恢复奔跑状态的区域 -->
|
|
23
|
+
<div :style="{ width: item.length - gapWidth, height: 24, top: 6, left: 0, backgroundColor: 'rgba(255, 255, 255, 0.5)' }"
|
|
24
|
+
:ref="props.MidRef">
|
|
25
|
+
</div>
|
|
26
|
+
<!-- 下层碰到地板就死的区域 -->
|
|
27
|
+
<div :style="{ width: item.length - gapWidth, height: 10, left: 0, top: 30, backgroundColor: '#000000' }"
|
|
28
|
+
:ref="props.BottomRef">
|
|
29
|
+
</div>
|
|
30
|
+
</div>
|
|
31
|
+
</JsvActorMove>
|
|
32
|
+
</div>
|
|
33
|
+
</template>
|
|
34
|
+
|
|
35
|
+
<script setup>
|
|
36
|
+
import { JsvActorMove, JsvPreload, jJsvRuntimeBridge } from "jsview"
|
|
37
|
+
import { gapWidth } from "../Common/Random";
|
|
38
|
+
const props = defineProps({
|
|
39
|
+
ArrayItem: Array,
|
|
40
|
+
bgImg: String,
|
|
41
|
+
preload_info: Array,
|
|
42
|
+
control: Object,
|
|
43
|
+
TopRef: null,
|
|
44
|
+
MidRef: null,
|
|
45
|
+
BottomRef: null,
|
|
46
|
+
ObstacleRef: null
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
const onPreloadDone = () => {
|
|
50
|
+
//图片加载好后摘掉画布
|
|
51
|
+
jJsvRuntimeBridge.notifyPageLoaded()
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
</script>
|
|
55
|
+
|
|
56
|
+
<style lang="scss" scoped></style>
|
|
@@ -0,0 +1,554 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<jsv-focus-block autoFocus :onAction="actionDefines">
|
|
3
|
+
<Backdrop :control="control1" :ArrayItem="ArrayItem1" :bgImg="bgImg1" :preload_info="preload_info1"
|
|
4
|
+
:TopRef="GameContext.TopRef1" :MidRef="GameContext.MidRef1" :BottomRef="GameContext.BottomRef1"
|
|
5
|
+
:ObstacleRef="GameContext.ObstacleRef1" :style="{ left: 1280 * 1.5 }"></Backdrop>
|
|
6
|
+
<Backdrop :control="control2" :ArrayItem="ArrayItem2" :bgImg="bgImg2" :preload_info="preload_info2"
|
|
7
|
+
:TopRef="GameContext.TopRef2" :MidRef="GameContext.MidRef2" :BottomRef="GameContext.BottomRef2"
|
|
8
|
+
:ObstacleRef="GameContext.ObstacleRef2"></Backdrop>
|
|
9
|
+
<Matchman />
|
|
10
|
+
<!-- 游戏结束的弹窗 -->
|
|
11
|
+
<div v-if="isover" :style="{
|
|
12
|
+
width: 460,
|
|
13
|
+
height: 180,
|
|
14
|
+
top: 280,
|
|
15
|
+
left: 440 - 60,
|
|
16
|
+
backgroundColor: 'rgba(255, 255, 255, 0.8)',
|
|
17
|
+
color: '#000000',
|
|
18
|
+
fontSize: 50,
|
|
19
|
+
textAlign: 'center',
|
|
20
|
+
borderRadius: 30
|
|
21
|
+
}">游戏结束
|
|
22
|
+
<div :style="{
|
|
23
|
+
width: 460,
|
|
24
|
+
height: 180,
|
|
25
|
+
top: 90,
|
|
26
|
+
left: 0,
|
|
27
|
+
}">按[OK]键重新开始</div>
|
|
28
|
+
</div>
|
|
29
|
+
<!-- 变速动画 -->
|
|
30
|
+
<div v-if="isshow"
|
|
31
|
+
:style="{ width: 300, height: 50, color: '#FF1213', top: 40, left: 660, fontSize: 40, animation: 'show 2s ease-in-out' }"
|
|
32
|
+
@animationend="AnimEnd">
|
|
33
|
+
当前速度:{{ speed }}</div>
|
|
34
|
+
</jsv-focus-block>
|
|
35
|
+
</template>
|
|
36
|
+
|
|
37
|
+
<script setup>
|
|
38
|
+
import {
|
|
39
|
+
JsvActorMoveControl, SpriteController,
|
|
40
|
+
createImpactTracer,
|
|
41
|
+
createImpactCallback,
|
|
42
|
+
createImpactAutoFroze,
|
|
43
|
+
} from "jsview"
|
|
44
|
+
import { shallowRef, onMounted, watch, onBeforeUnmount, ref, provide, inject } from "vue";
|
|
45
|
+
import Matchman from "./Matchman.vue"
|
|
46
|
+
import { _formatInfo, jsonObject } from "../Common/MatchmanInfo"
|
|
47
|
+
import { randomBg, randomFloor } from "../Common/Random";
|
|
48
|
+
import Backdrop from "./Backdrop.vue";
|
|
49
|
+
import Sound from "../Common/Sound.js"
|
|
50
|
+
import { Context } from "../Common/Context";
|
|
51
|
+
/* 火柴人相关变量控制 */
|
|
52
|
+
|
|
53
|
+
//音频
|
|
54
|
+
const PlaySound = new Sound()
|
|
55
|
+
|
|
56
|
+
//给定ref
|
|
57
|
+
let match = shallowRef(null)
|
|
58
|
+
provide("match", match)
|
|
59
|
+
|
|
60
|
+
//火柴人纵向动作控制器
|
|
61
|
+
const verticalControl = new JsvActorMoveControl();
|
|
62
|
+
provide("verticalControl", verticalControl)
|
|
63
|
+
|
|
64
|
+
//雪碧图控制器
|
|
65
|
+
const spriteController_run = new SpriteController()
|
|
66
|
+
provide("spriteController_run", spriteController_run)
|
|
67
|
+
|
|
68
|
+
const spriteController_jump = new SpriteController()
|
|
69
|
+
provide("spriteController_jump", spriteController_jump)
|
|
70
|
+
|
|
71
|
+
const spriteController_down = new SpriteController()
|
|
72
|
+
provide("spriteController_down", spriteController_down)
|
|
73
|
+
|
|
74
|
+
const spriteController_roll = new SpriteController()
|
|
75
|
+
provide("spriteController_roll", spriteController_roll)
|
|
76
|
+
|
|
77
|
+
const spriteController_fail = new SpriteController()
|
|
78
|
+
provide("spriteController_fail", spriteController_fail)
|
|
79
|
+
|
|
80
|
+
//主碰撞区域的ref
|
|
81
|
+
let body = shallowRef(null)
|
|
82
|
+
provide("body", body)
|
|
83
|
+
//副碰撞区域(顶层碰撞)的ref
|
|
84
|
+
let head = shallowRef(null)
|
|
85
|
+
provide("head", head)
|
|
86
|
+
//初始化跑步状态json
|
|
87
|
+
let sprite_info = ref(_formatInfo(jsonObject.run_json));
|
|
88
|
+
provide("sprite_info", sprite_info)
|
|
89
|
+
//尺寸
|
|
90
|
+
const view_size = {
|
|
91
|
+
w: sprite_info.value.maxW,
|
|
92
|
+
h: sprite_info.value.maxH,
|
|
93
|
+
};
|
|
94
|
+
provide('view_size', view_size)
|
|
95
|
+
//切换主副碰撞体的变量
|
|
96
|
+
let ischange = shallowRef(null)
|
|
97
|
+
provide("ischange", ischange)
|
|
98
|
+
//跳跃计数
|
|
99
|
+
let num = shallowRef(0)
|
|
100
|
+
//跳跃变量
|
|
101
|
+
let isjump = shallowRef(false)
|
|
102
|
+
provide("isjump", isjump)
|
|
103
|
+
//滚动变量
|
|
104
|
+
let isroll = shallowRef(false)
|
|
105
|
+
provide("isroll", isroll)
|
|
106
|
+
//跑动变量
|
|
107
|
+
let isrun = shallowRef(true)
|
|
108
|
+
provide('isrun', isrun)
|
|
109
|
+
//落下变量
|
|
110
|
+
let isdown = shallowRef(false)
|
|
111
|
+
provide("isdown", isdown)
|
|
112
|
+
//结束变量
|
|
113
|
+
let isover = shallowRef(false)
|
|
114
|
+
provide("isover", isover)
|
|
115
|
+
|
|
116
|
+
//火柴人动画结束的回调
|
|
117
|
+
const onAnimEnd = () => {
|
|
118
|
+
ischange.value = false
|
|
119
|
+
//在滚动状态时不会正常触发,
|
|
120
|
+
if (isjump.value) {
|
|
121
|
+
isroll.value = false
|
|
122
|
+
isdown.value = false
|
|
123
|
+
isrun.value = false
|
|
124
|
+
num.value = 0
|
|
125
|
+
}
|
|
126
|
+
else if (!isover.value) {
|
|
127
|
+
isroll.value = false
|
|
128
|
+
isdown.value = false
|
|
129
|
+
isjump.value = false
|
|
130
|
+
isrun.value = true
|
|
131
|
+
num.value = 0
|
|
132
|
+
} else {
|
|
133
|
+
isover.value = true
|
|
134
|
+
isroll.value = false
|
|
135
|
+
isdown.value = false
|
|
136
|
+
isjump.value = false
|
|
137
|
+
isrun.value = false
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
}
|
|
141
|
+
provide("onAnimEnd", onAnimEnd)
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
/* 背景图相关 */
|
|
145
|
+
//背景控制
|
|
146
|
+
const control1 = new JsvActorMoveControl()
|
|
147
|
+
const control2 = new JsvActorMoveControl()
|
|
148
|
+
//随机数组
|
|
149
|
+
let ArrayItem1 = ref([])
|
|
150
|
+
let ArrayItem2 = ref([])
|
|
151
|
+
//随机背景图片
|
|
152
|
+
let bgImg1 = shallowRef('')
|
|
153
|
+
let bgImg2 = shallowRef('')
|
|
154
|
+
//预加载的背景图
|
|
155
|
+
const preload_info1 = shallowRef([]);
|
|
156
|
+
const preload_info2 = shallowRef([])
|
|
157
|
+
|
|
158
|
+
//背景和地板初始化
|
|
159
|
+
randomFloor(ArrayItem1)
|
|
160
|
+
randomFloor(ArrayItem2)
|
|
161
|
+
randomBg(bgImg1, preload_info1)
|
|
162
|
+
randomBg(bgImg2, preload_info2)
|
|
163
|
+
|
|
164
|
+
/* 整体控制 */
|
|
165
|
+
|
|
166
|
+
//拿取ref给子组件
|
|
167
|
+
let GameContext = new Context()
|
|
168
|
+
|
|
169
|
+
//碰撞管理
|
|
170
|
+
let bump = shallowRef(false)
|
|
171
|
+
let sensorList = [];
|
|
172
|
+
|
|
173
|
+
//碰撞即停变量
|
|
174
|
+
let viewsAutoFroze = null;
|
|
175
|
+
|
|
176
|
+
//变化标志
|
|
177
|
+
let flag1 = shallowRef(0)
|
|
178
|
+
let flag2 = shallowRef(0)
|
|
179
|
+
|
|
180
|
+
//接收key
|
|
181
|
+
let SenceKey = inject("SenceKey")
|
|
182
|
+
|
|
183
|
+
//地板碰撞函数
|
|
184
|
+
const collisionCallback = () => {
|
|
185
|
+
if (!bump.value) {
|
|
186
|
+
if (!isroll.value) {
|
|
187
|
+
isrun.value = true
|
|
188
|
+
isdown.value = false
|
|
189
|
+
isjump.value = false
|
|
190
|
+
isover.value = false
|
|
191
|
+
num.value = 0
|
|
192
|
+
}
|
|
193
|
+
} else {
|
|
194
|
+
isover.value = true
|
|
195
|
+
isroll.value = false
|
|
196
|
+
isrun.value = false
|
|
197
|
+
isdown.value = false
|
|
198
|
+
isjump.value = false
|
|
199
|
+
num.value = 0
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
//边缘坠落函数
|
|
204
|
+
const separate = () => {
|
|
205
|
+
if (!isjump.value) {
|
|
206
|
+
verticalControl.throwAlongY(
|
|
207
|
+
0,
|
|
208
|
+
4000,
|
|
209
|
+
{ type: "catch", position: 300, direction: 1 },
|
|
210
|
+
() => {
|
|
211
|
+
gameOver()
|
|
212
|
+
}, // 未碰撞落地时,游戏结束
|
|
213
|
+
() => {
|
|
214
|
+
isdown.value = true
|
|
215
|
+
isroll.value = false
|
|
216
|
+
isrun.value = false
|
|
217
|
+
isdown.value = false
|
|
218
|
+
isjump.value = false
|
|
219
|
+
isover.value = false
|
|
220
|
+
} // 到达拐点时调整成落下状态
|
|
221
|
+
);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
//键盘事件
|
|
226
|
+
const onKeyDown = (ev) => {
|
|
227
|
+
if (ev.keyCode == 8 || ev.keyCode == 27 || ev.keyCode == 10000) {
|
|
228
|
+
//交给主页处理,这里不做处理
|
|
229
|
+
}
|
|
230
|
+
else if (isover.value) {
|
|
231
|
+
if (ev.keyCode == 13) {
|
|
232
|
+
SenceKey.value += 1
|
|
233
|
+
} else {
|
|
234
|
+
return true
|
|
235
|
+
}
|
|
236
|
+
} else if (ev.keyCode == 38 && num.value < 2) {
|
|
237
|
+
ischange.value = false
|
|
238
|
+
isroll.value = false
|
|
239
|
+
isjump.value = true
|
|
240
|
+
isdown.value = false
|
|
241
|
+
isrun.value = false
|
|
242
|
+
isover.value = false
|
|
243
|
+
num.value += 1
|
|
244
|
+
verticalControl.throwAlongY(
|
|
245
|
+
-1000,
|
|
246
|
+
2450,
|
|
247
|
+
{ type: "catch", position: 300, direction: 1 },
|
|
248
|
+
() => {
|
|
249
|
+
gameOver()
|
|
250
|
+
}, // 未碰撞落地时,游戏结束
|
|
251
|
+
() => {
|
|
252
|
+
isroll.value = false
|
|
253
|
+
isrun.value = false
|
|
254
|
+
isdown.value = true
|
|
255
|
+
isjump.value = false
|
|
256
|
+
isover.value = false
|
|
257
|
+
} // 到达拐点时调整成落下状态
|
|
258
|
+
);
|
|
259
|
+
//跳跃音频
|
|
260
|
+
PlaySound.playJumpSound()
|
|
261
|
+
|
|
262
|
+
} else if (ev.keyCode == 40) {
|
|
263
|
+
isroll.value = true
|
|
264
|
+
isrun.value = false
|
|
265
|
+
isdown.value = false
|
|
266
|
+
isjump.value = false
|
|
267
|
+
isover.value = false
|
|
268
|
+
num.value = 0
|
|
269
|
+
ischange.value = true
|
|
270
|
+
spriteController_roll.start()
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
//游戏结束函数
|
|
274
|
+
const gameOver = () => {
|
|
275
|
+
spriteController_fail.start()
|
|
276
|
+
isover.value = true
|
|
277
|
+
isrun.value = false
|
|
278
|
+
isdown.value = false
|
|
279
|
+
isjump.value = false
|
|
280
|
+
isroll.value = false
|
|
281
|
+
num.value = 0
|
|
282
|
+
//播放失败音频,停止运动
|
|
283
|
+
PlaySound.playFailSound()
|
|
284
|
+
control1.pause()
|
|
285
|
+
control2.pause()
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
const actionDefines = {
|
|
289
|
+
onKeyDown
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
//速度显示变量
|
|
293
|
+
let speed = shallowRef(274)
|
|
294
|
+
//控制速度动画div的变量
|
|
295
|
+
let isshow = shallowRef(true)
|
|
296
|
+
|
|
297
|
+
//速度动画结束回调
|
|
298
|
+
const AnimEnd = () => {
|
|
299
|
+
isshow.value = false
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
//监听背景图运动 更新随机地板以及变速
|
|
303
|
+
watch(flag1, (n, o) => {
|
|
304
|
+
if (n == 1) {
|
|
305
|
+
isshow.value = true
|
|
306
|
+
speed.value = 640
|
|
307
|
+
control1.altStraightSpeed(640, 3000)
|
|
308
|
+
control2.altStraightSpeed(640, 3000)
|
|
309
|
+
ArrayItem1.value = []
|
|
310
|
+
randomFloor(ArrayItem1)
|
|
311
|
+
} else if (n == 2) {
|
|
312
|
+
ArrayItem1.value = []
|
|
313
|
+
}
|
|
314
|
+
bgImg1.value = ''
|
|
315
|
+
randomBg(bgImg1, preload_info1)
|
|
316
|
+
})
|
|
317
|
+
watch(flag2, (n, o) => {
|
|
318
|
+
if (n == 1) {
|
|
319
|
+
isshow.value = true
|
|
320
|
+
speed.value = 384
|
|
321
|
+
control1.altStraightSpeed(384, 3000)
|
|
322
|
+
control2.altStraightSpeed(384, 3000)
|
|
323
|
+
}
|
|
324
|
+
ArrayItem2.value = []
|
|
325
|
+
randomFloor(ArrayItem2)
|
|
326
|
+
bgImg2.value = ''
|
|
327
|
+
randomBg(bgImg2, preload_info2)
|
|
328
|
+
})
|
|
329
|
+
|
|
330
|
+
/* 在此生命周期进行碰撞体定义操作以及初始化音频 */
|
|
331
|
+
onMounted(() => {
|
|
332
|
+
//初始化音频
|
|
333
|
+
PlaySound.initSound()
|
|
334
|
+
//初始落下
|
|
335
|
+
verticalControl.throwAlongY(
|
|
336
|
+
0,
|
|
337
|
+
9000,
|
|
338
|
+
{ type: "catch", position: 300, direction: 1 },
|
|
339
|
+
() => {
|
|
340
|
+
gameOver()
|
|
341
|
+
},
|
|
342
|
+
() => {
|
|
343
|
+
isroll.value = false
|
|
344
|
+
isrun.value = false
|
|
345
|
+
isdown.value = true
|
|
346
|
+
isjump.value = false
|
|
347
|
+
isover.value = false
|
|
348
|
+
num.value = 1
|
|
349
|
+
}
|
|
350
|
+
);
|
|
351
|
+
//给定碰撞即停句柄
|
|
352
|
+
viewsAutoFroze = createImpactAutoFroze(
|
|
353
|
+
[match.value.mainDiv], null
|
|
354
|
+
);
|
|
355
|
+
|
|
356
|
+
//移动两个背景图
|
|
357
|
+
control1.scrollMoveAlongX(-1280 * 2 * 1.5, 274, 0, () => {
|
|
358
|
+
flag1.value += 1
|
|
359
|
+
return true
|
|
360
|
+
})
|
|
361
|
+
control2.scrollMoveAlongX(-1280 * 1.5, 274, 1280 * 1.5, () => {
|
|
362
|
+
flag2.value += 1
|
|
363
|
+
return true
|
|
364
|
+
})
|
|
365
|
+
|
|
366
|
+
//创建碰撞体,因为每个场景只有两个地板,直接为2
|
|
367
|
+
for (let i = 0; i < 2; i++) {
|
|
368
|
+
|
|
369
|
+
//第一屏 上层碰撞体,边缘坠落(火柴人主碰撞体)
|
|
370
|
+
sensorList.push(
|
|
371
|
+
createImpactTracer(
|
|
372
|
+
body.value,
|
|
373
|
+
GameContext.TopRef1.value[i],
|
|
374
|
+
createImpactCallback(() => {
|
|
375
|
+
collisionCallback()
|
|
376
|
+
}, () => {
|
|
377
|
+
num.value = 1
|
|
378
|
+
separate()
|
|
379
|
+
}, null),
|
|
380
|
+
)
|
|
381
|
+
);
|
|
382
|
+
//第二屏 上层碰撞体,边缘坠落(火柴人主碰撞体)
|
|
383
|
+
sensorList.push(
|
|
384
|
+
createImpactTracer(
|
|
385
|
+
body.value,
|
|
386
|
+
GameContext.TopRef2.value[i],
|
|
387
|
+
createImpactCallback(() => {
|
|
388
|
+
collisionCallback()
|
|
389
|
+
}, () => {
|
|
390
|
+
num.value = 1
|
|
391
|
+
separate()
|
|
392
|
+
}, null),
|
|
393
|
+
)
|
|
394
|
+
);
|
|
395
|
+
|
|
396
|
+
//第一屏 中层碰撞(火柴人主碰撞体)
|
|
397
|
+
sensorList.push(
|
|
398
|
+
createImpactTracer(
|
|
399
|
+
body.value,
|
|
400
|
+
GameContext.MidRef1.value[i],
|
|
401
|
+
createImpactCallback(() => {
|
|
402
|
+
//此处计算是针对于pc端 320为初始小人top,50和40为上下两个碰撞体大小。20是为视觉效果更好。
|
|
403
|
+
verticalControl.jumpTo(0, ArrayItem1.value[i].top - 320 - 50 - 40 - 20)
|
|
404
|
+
collisionCallback()
|
|
405
|
+
}, null),
|
|
406
|
+
viewsAutoFroze
|
|
407
|
+
)
|
|
408
|
+
);
|
|
409
|
+
//第二屏 中层碰撞(火柴人主碰撞体)
|
|
410
|
+
sensorList.push(
|
|
411
|
+
createImpactTracer(
|
|
412
|
+
body.value,
|
|
413
|
+
GameContext.MidRef2.value[i],
|
|
414
|
+
createImpactCallback(() => {
|
|
415
|
+
verticalControl.jumpTo(0, ArrayItem2.value[i].top - 320 - 50 - 40 - 20)
|
|
416
|
+
collisionCallback()
|
|
417
|
+
}, null),
|
|
418
|
+
viewsAutoFroze
|
|
419
|
+
)
|
|
420
|
+
);
|
|
421
|
+
|
|
422
|
+
//第一屏 下层碰撞体,碰撞即游戏结束(火柴人主碰撞体)
|
|
423
|
+
sensorList.push(
|
|
424
|
+
createImpactTracer(
|
|
425
|
+
body.value,
|
|
426
|
+
GameContext.BottomRef1.value[i],
|
|
427
|
+
createImpactCallback(() => {
|
|
428
|
+
if (isjump.value) {
|
|
429
|
+
bump.value = true
|
|
430
|
+
gameOver()
|
|
431
|
+
}
|
|
432
|
+
}, null),
|
|
433
|
+
viewsAutoFroze
|
|
434
|
+
)
|
|
435
|
+
);
|
|
436
|
+
// 第一屏 下层碰撞体,碰撞即游戏结束(火柴人副碰撞体)
|
|
437
|
+
sensorList.push(
|
|
438
|
+
createImpactTracer(
|
|
439
|
+
head.value,
|
|
440
|
+
GameContext.BottomRef1.value[i],
|
|
441
|
+
createImpactCallback(() => {
|
|
442
|
+
if (isjump.value) {
|
|
443
|
+
bump.value = true
|
|
444
|
+
gameOver()
|
|
445
|
+
}
|
|
446
|
+
}, null),
|
|
447
|
+
viewsAutoFroze
|
|
448
|
+
)
|
|
449
|
+
);
|
|
450
|
+
|
|
451
|
+
//第二屏 下层碰撞体,碰撞即游戏结束(火柴人主碰撞体)
|
|
452
|
+
sensorList.push(
|
|
453
|
+
createImpactTracer(
|
|
454
|
+
body.value,
|
|
455
|
+
GameContext.BottomRef2.value[i],
|
|
456
|
+
createImpactCallback(() => {
|
|
457
|
+
if (isjump.value) {
|
|
458
|
+
bump.value = true
|
|
459
|
+
gameOver()
|
|
460
|
+
}
|
|
461
|
+
}, null),
|
|
462
|
+
viewsAutoFroze
|
|
463
|
+
)
|
|
464
|
+
);
|
|
465
|
+
// 第一屏 下层碰撞体,碰撞即游戏结束(火柴人副碰撞体)
|
|
466
|
+
sensorList.push(
|
|
467
|
+
createImpactTracer(
|
|
468
|
+
head.value,
|
|
469
|
+
GameContext.BottomRef2.value[i],
|
|
470
|
+
createImpactCallback(() => {
|
|
471
|
+
if (isjump.value) {
|
|
472
|
+
bump.value = true
|
|
473
|
+
gameOver()
|
|
474
|
+
}
|
|
475
|
+
}, null),
|
|
476
|
+
viewsAutoFroze
|
|
477
|
+
)
|
|
478
|
+
);
|
|
479
|
+
}
|
|
480
|
+
//第一屏 与障碍物相撞(火柴人主碰撞体)
|
|
481
|
+
sensorList.push(
|
|
482
|
+
createImpactTracer(
|
|
483
|
+
body.value,
|
|
484
|
+
GameContext.ObstacleRef1.value[0],
|
|
485
|
+
createImpactCallback(() => {
|
|
486
|
+
bump.value = true
|
|
487
|
+
gameOver()
|
|
488
|
+
}, null),
|
|
489
|
+
viewsAutoFroze
|
|
490
|
+
)
|
|
491
|
+
);
|
|
492
|
+
//第一屏 与障碍物相撞(火柴人副碰撞体)
|
|
493
|
+
sensorList.push(
|
|
494
|
+
createImpactTracer(
|
|
495
|
+
head.value,
|
|
496
|
+
GameContext.ObstacleRef1.value[0],
|
|
497
|
+
createImpactCallback(() => {
|
|
498
|
+
bump.value = true
|
|
499
|
+
gameOver()
|
|
500
|
+
}, null),
|
|
501
|
+
viewsAutoFroze
|
|
502
|
+
)
|
|
503
|
+
);
|
|
504
|
+
//第二屏 与障碍物相撞(火柴人主碰撞体)
|
|
505
|
+
sensorList.push(
|
|
506
|
+
createImpactTracer(
|
|
507
|
+
body.value,
|
|
508
|
+
GameContext.ObstacleRef2.value[0],
|
|
509
|
+
createImpactCallback(() => {
|
|
510
|
+
bump.value = true
|
|
511
|
+
gameOver()
|
|
512
|
+
}, null),
|
|
513
|
+
viewsAutoFroze
|
|
514
|
+
)
|
|
515
|
+
);
|
|
516
|
+
//第二屏 与障碍物相撞(火柴人副碰撞体)
|
|
517
|
+
sensorList.push(
|
|
518
|
+
createImpactTracer(
|
|
519
|
+
head.value,
|
|
520
|
+
GameContext.ObstacleRef2.value[0],
|
|
521
|
+
createImpactCallback(() => {
|
|
522
|
+
bump.value = true
|
|
523
|
+
gameOver()
|
|
524
|
+
}, null),
|
|
525
|
+
viewsAutoFroze
|
|
526
|
+
)
|
|
527
|
+
);
|
|
528
|
+
|
|
529
|
+
})
|
|
530
|
+
|
|
531
|
+
/* 重要! 退出后应该释放所有碰撞监听者 */
|
|
532
|
+
onBeforeUnmount(() => {
|
|
533
|
+
for (const sensor of sensorList) {
|
|
534
|
+
sensor.Recycle();
|
|
535
|
+
}
|
|
536
|
+
viewsAutoFroze?.Recycle();
|
|
537
|
+
//摧毁音频
|
|
538
|
+
PlaySound.destroy();
|
|
539
|
+
})
|
|
540
|
+
</script>
|
|
541
|
+
|
|
542
|
+
<style lang="scss" scoped>
|
|
543
|
+
@keyframes show {
|
|
544
|
+
from {
|
|
545
|
+
transform: scale3d(1, 1, 1);
|
|
546
|
+
opacity: 1;
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
to {
|
|
550
|
+
transform: scale3d(1.2, 1.2, 1.2);
|
|
551
|
+
opacity: 0;
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
</style>
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div>
|
|
3
|
+
<JsvPreload :preloadList="preload_info"></JsvPreload>
|
|
4
|
+
<JsvActorMove :control="verticalControl" :style="{ top: 720 / 2 - 40, left: 50 }" ref="match">
|
|
5
|
+
<!-- 跑动 -->
|
|
6
|
+
<JsvSpriteAnim :spriteInfo="sprite_info_run.info" :loop="'infinite'" :viewSize="view_size" :duration="0.5"
|
|
7
|
+
:autostart="true" :imageUrl="pngObject.run_png" :controller="spriteController_run" v-show="isrun">
|
|
8
|
+
</JsvSpriteAnim>
|
|
9
|
+
<!-- 跳起 -->
|
|
10
|
+
<JsvSpriteAnim :spriteInfo="sprite_info_jumpUp.info" :loop="1" :viewSize="view_size" :duration="0.6"
|
|
11
|
+
:autostart="true" :imageUrl="pngObject.jumpUp_png" :controller="spriteController_jump" v-show="isjump">
|
|
12
|
+
</JsvSpriteAnim>
|
|
13
|
+
<!-- 落下 -->
|
|
14
|
+
<JsvSpriteAnim :spriteInfo="sprite_info_jumpDown.info" :loop="'infinite'" :viewSize="view_size" :duration="1"
|
|
15
|
+
:autostart="true" :imageUrl="pngObject.jumpDown_png" :controller="spriteController_down" v-show="isdown">
|
|
16
|
+
</JsvSpriteAnim>
|
|
17
|
+
<!-- 滚动 -->
|
|
18
|
+
<JsvSpriteAnim :spriteInfo="sprite_info_roll.info" :loop="2" :viewSize="view_size" :duration="0.4" :autostart="true"
|
|
19
|
+
:imageUrl="pngObject.roll_png" :onAnimEnd="onAnimEnd" :controller="spriteController_roll" v-show="isroll">
|
|
20
|
+
</JsvSpriteAnim>
|
|
21
|
+
<!-- 失败 -->
|
|
22
|
+
<JsvSpriteAnim :spriteInfo="sprite_info_fail.info" :loop="1" :viewSize="view_size" :duration="0.6" :autostart="true"
|
|
23
|
+
:imageUrl="pngObject.fail_png" :controller="spriteController_fail" v-show="isover" :onAnimEnd="onAnimEnd">
|
|
24
|
+
</JsvSpriteAnim>
|
|
25
|
+
<!-- 主碰撞体 -->
|
|
26
|
+
<div key="body" ref="body" :style="{
|
|
27
|
+
top: 60,
|
|
28
|
+
left: 70,
|
|
29
|
+
width: 20,
|
|
30
|
+
height: 50,
|
|
31
|
+
backgroundColor: 'rgba(0,0,0,0)'
|
|
32
|
+
}"></div>
|
|
33
|
+
<!-- 副碰撞体 上层区域 -->
|
|
34
|
+
<div key="head" ref="head" :style="{
|
|
35
|
+
top: 20,
|
|
36
|
+
left: 70,
|
|
37
|
+
width: 20,
|
|
38
|
+
height: 40,
|
|
39
|
+
backgroundColor: 'rgba(0,0,0,0)'
|
|
40
|
+
}" v-show="!ischange"></div>
|
|
41
|
+
</JsvActorMove>
|
|
42
|
+
</div>
|
|
43
|
+
</template>
|
|
44
|
+
|
|
45
|
+
<script setup>
|
|
46
|
+
import {
|
|
47
|
+
JsvActorMove,
|
|
48
|
+
JsvSpriteAnim,
|
|
49
|
+
JsvPreload,
|
|
50
|
+
buildPreloadInfo,
|
|
51
|
+
} from "jsview"
|
|
52
|
+
import { inject } from "vue";
|
|
53
|
+
import { pngObject, _formatInfo, jsonObject } from "../Common/MatchmanInfo";
|
|
54
|
+
//预加载火柴人信息
|
|
55
|
+
const preload_info = [buildPreloadInfo(pngObject.fail_png), buildPreloadInfo(pngObject.roll_png), buildPreloadInfo(pngObject.jumpDown_png), buildPreloadInfo(pngObject.jumpUp_png), buildPreloadInfo(pngObject.run_png)]
|
|
56
|
+
//接收信息
|
|
57
|
+
let verticalControl = inject("verticalControl")
|
|
58
|
+
let body = inject("body")
|
|
59
|
+
let head = inject("head")
|
|
60
|
+
let ischange = inject("ischange")
|
|
61
|
+
const onAnimEnd = inject("onAnimEnd")
|
|
62
|
+
let view_size = inject("view_size")
|
|
63
|
+
let match = inject("match")
|
|
64
|
+
let isrun = inject("isrun")
|
|
65
|
+
let isroll = inject("isroll")
|
|
66
|
+
let isdown = inject("isdown")
|
|
67
|
+
let isjump = inject("isjump")
|
|
68
|
+
let isover = inject('isover')
|
|
69
|
+
|
|
70
|
+
//不同形态控制器
|
|
71
|
+
const spriteController_run = inject("spriteController_run")
|
|
72
|
+
const spriteController_jump = inject("spriteController_jump")
|
|
73
|
+
const spriteController_down = inject("spriteController_down")
|
|
74
|
+
const spriteController_roll = inject("spriteController_roll")
|
|
75
|
+
const spriteController_fail = inject("spriteController_fail")
|
|
76
|
+
|
|
77
|
+
const sprite_info_run = _formatInfo(jsonObject.run_json)
|
|
78
|
+
const sprite_info_jumpUp = _formatInfo(jsonObject.jumpUp_json)
|
|
79
|
+
const sprite_info_jumpDown = _formatInfo(jsonObject.jumpDown_json)
|
|
80
|
+
const sprite_info_roll = _formatInfo(jsonObject.roll_json)
|
|
81
|
+
const sprite_info_fail = _formatInfo(jsonObject.fail_json)
|
|
82
|
+
|
|
83
|
+
</script>
|
|
84
|
+
|
|
85
|
+
<style lang="scss" scoped></style>
|