commit
b57c7a28d3
34 changed files with 18599 additions and 0 deletions
@ -0,0 +1,113 @@ |
|||||
|
# Logs |
||||
|
logs |
||||
|
*.log |
||||
|
npm-debug.log* |
||||
|
yarn-debug.log* |
||||
|
yarn-error.log* |
||||
|
lerna-debug.log* |
||||
|
|
||||
|
# Diagnostic reports (https://nodejs.org/api/report.html) |
||||
|
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json |
||||
|
|
||||
|
# Runtime data |
||||
|
pids |
||||
|
*.pid |
||||
|
*.seed |
||||
|
*.pid.lock |
||||
|
|
||||
|
# Directory for instrumented libs generated by jscoverage/JSCover |
||||
|
lib-cov |
||||
|
|
||||
|
# Coverage directory used by tools like istanbul |
||||
|
coverage |
||||
|
*.lcov |
||||
|
|
||||
|
# nyc test coverage |
||||
|
.nyc_output |
||||
|
|
||||
|
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) |
||||
|
.grunt |
||||
|
|
||||
|
# Bower dependency directory (https://bower.io/) |
||||
|
bower_components |
||||
|
|
||||
|
# node-waf configuration |
||||
|
.lock-wscript |
||||
|
|
||||
|
# Compiled binary addons (https://nodejs.org/api/addons.html) |
||||
|
build/Release |
||||
|
|
||||
|
# Dependency directories |
||||
|
node_modules/ |
||||
|
jspm_packages/ |
||||
|
|
||||
|
# TypeScript v1 declaration files |
||||
|
typings/ |
||||
|
|
||||
|
# TypeScript cache |
||||
|
*.tsbuildinfo |
||||
|
|
||||
|
# Optional npm cache directory |
||||
|
.npm |
||||
|
|
||||
|
# Optional eslint cache |
||||
|
.eslintcache |
||||
|
|
||||
|
# Microbundle cache |
||||
|
.rpt2_cache/ |
||||
|
.rts2_cache_cjs/ |
||||
|
.rts2_cache_es/ |
||||
|
.rts2_cache_umd/ |
||||
|
|
||||
|
# Optional REPL history |
||||
|
.node_repl_history |
||||
|
|
||||
|
# Output of 'npm pack' |
||||
|
*.tgz |
||||
|
|
||||
|
# Yarn Integrity file |
||||
|
.yarn-integrity |
||||
|
|
||||
|
# dotenv environment variables file |
||||
|
.env |
||||
|
.env.test |
||||
|
|
||||
|
# parcel-bundler cache (https://parceljs.org/) |
||||
|
.cache |
||||
|
|
||||
|
# Next.js build output |
||||
|
.next |
||||
|
|
||||
|
# Nuxt.js build / generate output |
||||
|
.nuxt |
||||
|
dist |
||||
|
|
||||
|
# Gatsby files |
||||
|
.cache/ |
||||
|
# Comment in the public line in if your project uses Gatsby and *not* Next.js |
||||
|
# https://nextjs.org/blog/next-9-1#public-directory-support |
||||
|
# public |
||||
|
|
||||
|
# vuepress build output |
||||
|
.vuepress/dist |
||||
|
|
||||
|
# Serverless directories |
||||
|
.serverless/ |
||||
|
|
||||
|
# FuseBox cache |
||||
|
.fusebox/ |
||||
|
|
||||
|
# DynamoDB Local files |
||||
|
.dynamodb/ |
||||
|
|
||||
|
# TernJS port file |
||||
|
.tern-port |
||||
|
|
||||
|
.vscode/ |
||||
|
|
||||
|
.idea/ |
||||
|
yarn.lock |
||||
|
|
||||
|
dist |
||||
|
dist/* |
||||
|
.~README.md |
@ -0,0 +1,13 @@ |
|||||
|
{ |
||||
|
"printWidth": 140, |
||||
|
"singleQuote": true, |
||||
|
"semi": true, |
||||
|
"trailingComma": "all", |
||||
|
"arrowParens": "avoid", |
||||
|
"tabWidth": 2, |
||||
|
"useTabs": false, |
||||
|
"bracketSpacing": true, |
||||
|
"jsxBracketSameLine": false, |
||||
|
"proseWrap": "always", |
||||
|
"endOfLine": "lf" |
||||
|
} |
@ -0,0 +1,375 @@ |
|||||
|
# 鸟妈妈回家 |
||||
|
|
||||
|
# 运行步骤 |
||||
|
1. git clone https://dd.tall.wiki/gitea/ccsens_fe/bird-go-home.git |
||||
|
2. 全局安装gulp npm i gulp -g |
||||
|
3. npm i 或者 yarn |
||||
|
4. 运行gulp |
||||
|
5. 运行vscode的Go Live |
||||
|
6. 部署服务器 dist目录 |
||||
|
|
||||
|
|
||||
|
|
||||
|
## 游戏介绍 |
||||
|
|
||||
|
“鸟妈妈回家”游戏用于 康复训练,上肢训练 |
||||
|
|
||||
|
游戏使用Adobe Animate制作,游戏包含如下几个模块: |
||||
|
|
||||
|
+ 主体:鸟、背景(山、云朵、树木等)、成功次数(也能代表得分) |
||||
|
+ 开始倒计时:开始面板、倒计时文本 |
||||
|
+ 返回按钮 |
||||
|
+ 难度级别 |
||||
|
+ 游戏计时 |
||||
|
+ 结束modal:界面面板、得分文本 |
||||
|
+ 测试模块 |
||||
|
|
||||
|
|
||||
|
|
||||
|
该游戏源文件,使用旧版的flash软件制作,转换成animate支持的canvas模式。 |
||||
|
|
||||
|
游戏原有动画均在图层中制作。包括游戏动作成功的字数,也在动画中制作。游戏动作设计调整难度较大,次数修改成本较高。目前是固定的20次,一般情况是够用。 |
||||
|
|
||||
|
|
||||
|
|
||||
|
## 目录结构说明 |
||||
|
|
||||
|
通过如下命令输出的目录结构: |
||||
|
|
||||
|
```bash |
||||
|
tree -I "node_modules|package-lock.json|yarn.lock" |
||||
|
``` |
||||
|
|
||||
|
|
||||
|
|
||||
|
```bash |
||||
|
│ .gitignore |
||||
|
│ .prettierrc |
||||
|
│ .svrxrc.js |
||||
|
│ dist.zip |
||||
|
│ gulpfile.js |
||||
|
│ package-lock.json |
||||
|
│ package.json |
||||
|
│ README.md |
||||
|
│ |
||||
|
├─dist |
||||
|
│ │ bird.js |
||||
|
│ │ index.html |
||||
|
│ │ main.js |
||||
|
│ │ |
||||
|
│ ├─images |
||||
|
│ │ Bitmap1.png |
||||
|
│ │ Bitmap2.png |
||||
|
│ │ Bitmap3.png |
||||
|
│ │ Bitmap4.png |
||||
|
│ │ Bitmap5.png |
||||
|
│ │ level.png |
||||
|
│ │ stopDemo.png |
||||
|
│ │ suspend.png |
||||
|
│ │ _preloader.gif |
||||
|
│ │ 任务完成_.png |
||||
|
│ │ 倒计时_.png |
||||
|
│ │ 再来一次_.png |
||||
|
│ │ 树林前景_.png |
||||
|
│ │ 计时_.png |
||||
|
│ │ 返回按钮_.png |
||||
|
│ │ |
||||
|
│ ├─libs |
||||
|
│ │ └─1.0.0 |
||||
|
│ │ createjs.min.js |
||||
|
│ │ |
||||
|
│ └─sounds |
||||
|
│ amazing.mp3 |
||||
|
│ bgmMusic.mp3 |
||||
|
│ excitationMusic.mp3 |
||||
|
│ unbelievable.mp3 |
||||
|
│ |
||||
|
├─public |
||||
|
│ │ bird.html |
||||
|
│ │ bird.js |
||||
|
│ │ index.html |
||||
|
│ │ 鸟妈妈回家_HTML5 Canvas.fla |
||||
|
│ │ |
||||
|
│ ├─images |
||||
|
│ │ Bitmap1.png |
||||
|
│ │ Bitmap2.png |
||||
|
│ │ Bitmap3.png |
||||
|
│ │ Bitmap4.png |
||||
|
│ │ Bitmap5.png |
||||
|
│ │ level.png |
||||
|
│ │ stopDemo.png |
||||
|
│ │ suspend.png |
||||
|
│ │ _preloader.gif |
||||
|
│ │ 任务完成_.png |
||||
|
│ │ 倒计时_.png |
||||
|
│ │ 再来一次_.png |
||||
|
│ │ 树林前景_.png |
||||
|
│ │ 计时_.png |
||||
|
│ │ 返回按钮_.png |
||||
|
│ │ |
||||
|
│ ├─libs |
||||
|
│ │ └─1.0.0 |
||||
|
│ │ createjs.min.js |
||||
|
│ │ |
||||
|
│ └─sounds |
||||
|
│ amazing.mp3 |
||||
|
│ bgmMusic.mp3 |
||||
|
│ excitationMusic.mp3 |
||||
|
│ unbelievable.mp3 |
||||
|
│ |
||||
|
└─src |
||||
|
│ custom.js |
||||
|
│ index.js |
||||
|
│ test.js |
||||
|
│ |
||||
|
└─classes |
||||
|
again.js |
||||
|
back.js |
||||
|
count.js |
||||
|
demo.js |
||||
|
end.js |
||||
|
level.js |
||||
|
main.js |
||||
|
sound.js |
||||
|
suspend.js |
||||
|
time.js |
||||
|
``` |
||||
|
|
||||
|
| 文件 | 说明 | 备注 | |
||||
|
| ------------------- | ------------------------------------------------------------ | ----------------------------------------------- | |
||||
|
| bird.html | animate自动生成的html,不编辑使用index.html代替 | | |
||||
|
| bird.js | animate自动生成,index.html有引用 | | |
||||
|
| images/* | animate生成的图片资源 | 这里没有使用雪碧图,这个文件fla导出雪碧图就卡死 | |
||||
|
| index.html | 入口界面 | | |
||||
|
| js/custom.js | 自定义初始化整合js | **可作为模板复制修改**,config及initStage | |
||||
|
| js/index.js | animate生成的内嵌到bird.html中的js提取,并添加了初始化入口函数initStage | | |
||||
|
| js/test.js | 测试程序,正式版可删除 | | |
||||
|
| js/classes/* | 封装的各个模块类 | | |
||||
|
| js/classes/back.js | 返回按钮类封装 | **通用** | |
||||
|
| js/classes/bird.js | 游戏主体类封装 | 不通用 | |
||||
|
| js/classes/count.js | 开始时倒计时组件类封装 | **通用**,配合custom里的配置使用 | |
||||
|
| js/classes/end.js | 游戏结束,得分面板 | **通用**,配合custom里的config总分,总次数使用 | |
||||
|
| js/classes/level.js | 游戏级别组件封装类 | **通用**,配合custom里的config里的level使用 | |
||||
|
| js/classes/sound.js | 游戏音频封装类 | **通用**,资源可能需要替换 | |
||||
|
| js/classes/time.js | 游戏时长、计时组件封装类 | **通用**,配合custom里的config里的time使用 | |
||||
|
| libs/* | animate导出的createjs文件 | 不用动 | |
||||
|
| sounds/*.mp3 | 音频资源 | | |
||||
|
| *.fla | animate源文件 | | |
||||
|
|
||||
|
|
||||
|
|
||||
|
## 具体代码说明 |
||||
|
|
||||
|
### index.html |
||||
|
|
||||
|
入口界面,依据animate生成的 bird.html 修改而来。主要添加了测试功能区,以及js文件的整合引入。其他不动 |
||||
|
|
||||
|
```js |
||||
|
<script src="libs/1.0.0/createjs.min.js"></script> |
||||
|
<script src="bird.js"></script> |
||||
|
<script src="main.js"></script> |
||||
|
<!-- write your code here --> |
||||
|
</head> |
||||
|
<body onload="init();" style="margin: 0px;"> |
||||
|
<div id="animation_container" style="background-color:rgba(255, 255, 255, 1.00); width:1280px; height:720px"> |
||||
|
<canvas id="canvas" width="1280" height="720" style="position: absolute; display: none; background-color:rgba(255, 255, 255, 1.00);"></canvas> |
||||
|
<div id="dom_overlay_container" style="pointer-events:none; overflow:hidden; width:1280px; height:720px; position: absolute; left: 0px; top: 0px; display: none;"> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div id='_preload_div_' style='position:absolute; top:0; left:0; display: inline-block; height:720px; width: 1280px; text-align: center;'> <span style='display: inline-block; height: 100%; vertical-align: middle;'></span> <img src=images/_preloader.gif style='vertical-align: middle; max-height: 100%'/></div> |
||||
|
</body> |
||||
|
``` |
||||
|
|
||||
|
### index.js |
||||
|
|
||||
|
将原bird.html中的内嵌js部分抽离,并添加initStage调用,如下: |
||||
|
|
||||
|
```js |
||||
|
function handleComplete(evt, comp) { |
||||
|
//This function is always called, irrespective of the content. You can use the variable "stage" after it is created in token create_stage. |
||||
|
var lib = comp.getLibrary(); |
||||
|
var ss = comp.getSpriteSheet(); |
||||
|
var queue = evt.target; |
||||
|
var ssMetadata = lib.ssMetadata; |
||||
|
// for循环 i=0; 前面需要加 let, 否则编译会报错 |
||||
|
for (i = 0; i < ssMetadata.length; i++) { |
||||
|
ss[ssMetadata[i].name] = new createjs.SpriteSheet({ images: [queue.getResult(ssMetadata[i].name)], frames: ssMetadata[i].frames }); |
||||
|
} |
||||
|
var preloaderDiv = document.getElementById('_preload_div_'); |
||||
|
preloaderDiv.style.display = 'none'; |
||||
|
canvas.style.display = 'block'; |
||||
|
exportRoot = new lib.鸟妈妈回家_HTML5Canvas(); |
||||
|
stage = new lib.Stage(canvas); |
||||
|
//Registers the "tick" event listener. |
||||
|
fnStartAnimation = function () { |
||||
|
stage.addChild(exportRoot); |
||||
|
|
||||
|
initStage(lib); |
||||
|
|
||||
|
createjs.Ticker.framerate = lib.properties.fps; |
||||
|
createjs.Ticker.addEventListener('tick', stage); |
||||
|
}; |
||||
|
//Code to support hidpi screens and responsive scaling. |
||||
|
AdobeAn.makeResponsive(true, 'both', true, 1, [canvas, preloaderDiv, anim_container, dom_overlay_container]); |
||||
|
AdobeAn.compositionLoaded(lib.properties.id); |
||||
|
fnStartAnimation(); |
||||
|
} |
||||
|
|
||||
|
``` |
||||
|
|
||||
|
### custom.js |
||||
|
|
||||
|
配置,全局变量 及initStage整个调用各个类,注意类的调用有先后顺序之分。图层顺序在上的后调用 |
||||
|
|
||||
|
```js |
||||
|
const config = { |
||||
|
count: 5, // 默认倒计时时长 |
||||
|
duration: 60, // 总时长 s |
||||
|
level: 1, // 游戏难度级别 |
||||
|
total: 100, // 总分 |
||||
|
times: 20, // 动作次数 |
||||
|
}; |
||||
|
|
||||
|
let library = null; |
||||
|
let state = 0; // 游戏状态 0->未开始 1->进行中 2->结束 |
||||
|
|
||||
|
function initStage(lib) { |
||||
|
library = lib; |
||||
|
|
||||
|
window.main = Main.of(gameOver); // 初始化鸟等 |
||||
|
window.timeInstance = Time.of(gameOver); // 初始化游戏时间 |
||||
|
// window.soundInstance = Sound.of(); // 初始化音频 |
||||
|
Level.of(2); // 游戏难度级别 |
||||
|
Back.of(); // 返回按钮 |
||||
|
} |
||||
|
|
||||
|
// 游戏结束 显示结束得分面板 |
||||
|
function gameOver() { |
||||
|
state = 2; |
||||
|
const times = main.times; |
||||
|
const score = parseInt((config.total / config.times) * times); |
||||
|
End.of(score); |
||||
|
} |
||||
|
|
||||
|
``` |
||||
|
|
||||
|
### 游戏模块组件类说明 |
||||
|
|
||||
|
以time.js 游戏计时模块为例: |
||||
|
|
||||
|
每个类除了自身的功能定义、调用之外, |
||||
|
|
||||
|
+ 统一添加了 *of* 静态方法,封装了 new 操作(不喜欢看到new)、调用了初始化 init 函数、并返回示例,因此调用时只需要`Time.of(...)` 就可以 |
||||
|
+ 如果有涉及到跟其他类的关联调用,如end方法中的 endCallback,以回调函数的形式传参使用 |
||||
|
+ 尽最大可能减少全局变量,外部变量的引用,保证函数的引用透明,让他纯,减少副作用,提高复用性 |
||||
|
|
||||
|
```js |
||||
|
/** |
||||
|
* 游戏时长 计时 |
||||
|
* @param {function} endCallback 倒计时结束的回调函数 |
||||
|
* @param {number} duration 游戏时长 |
||||
|
* @param {number} count 游戏倒计时时长 |
||||
|
* |
||||
|
* @property {number} duration 游戏时长 |
||||
|
* @property {number} count 游戏倒计时时长 |
||||
|
* @property {number} startTime 游戏开始是ms |
||||
|
* @property {boolean} started 游戏是否开始 |
||||
|
* @property {object} lib 资源库 |
||||
|
* @property {object} bg 时间倒计时背景 |
||||
|
* @property {object} text 倒计时文本 |
||||
|
* @property {number} timerId 定时器id |
||||
|
* @property {function} endCallback 结束回调函数 |
||||
|
*/ |
||||
|
function Time(endCallback, duration, count) { |
||||
|
this.duration = duration; |
||||
|
this.count = count; |
||||
|
this.startTime = Date.now(); |
||||
|
|
||||
|
this.started = false; // 是否开始游戏 |
||||
|
|
||||
|
this.lib = library; |
||||
|
this.bg = null; |
||||
|
this.text = null; |
||||
|
this.timerId = null; |
||||
|
this.endCallback = endCallback; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 静态方法 封装new init 返回实例 |
||||
|
* @param {function} endCallback 倒计时结束的回调函数 |
||||
|
* @param {number} duration 游戏时长 |
||||
|
* @param {number} count 游戏倒计时时长 |
||||
|
* @returns |
||||
|
*/ |
||||
|
Time.of = function (endCallback, duration = config.duration || 60, count = config.count || 5) { |
||||
|
const instance = new Time(endCallback, duration, count); |
||||
|
instance.init(); |
||||
|
return instance; |
||||
|
}; |
||||
|
|
||||
|
// 初始化 |
||||
|
Time.prototype.init = function () { |
||||
|
this.renderBg(); |
||||
|
this.renderText(this.duration); |
||||
|
}; |
||||
|
|
||||
|
// 开始游戏 开始倒计时 |
||||
|
Time.prototype.start = function (startTime = Date.now()) { |
||||
|
this.started = true; |
||||
|
state = 1; |
||||
|
this.startTime = startTime; |
||||
|
this.update(); |
||||
|
}; |
||||
|
|
||||
|
// 开始游戏 开始倒计时 |
||||
|
Time.prototype.end = function () { |
||||
|
this.started = false; |
||||
|
this.timerId && clearTimeout(this.timerId); |
||||
|
this.timerId = null; |
||||
|
// 执行结束后的回调 |
||||
|
this.endCallback(); |
||||
|
}; |
||||
|
|
||||
|
// 渲染背景 |
||||
|
Time.prototype.renderBg = function () { |
||||
|
const initX = this.lib.properties.width - 100; |
||||
|
const initY = 80; |
||||
|
const instance = new this.lib.timeBg(); |
||||
|
instance.x = initX; |
||||
|
instance.y = initY; |
||||
|
this.bg = instance; |
||||
|
stage.addChild(instance); |
||||
|
}; |
||||
|
|
||||
|
// 渲染文本 |
||||
|
Time.prototype.renderText = function (time) { |
||||
|
const text = new createjs.Text(time, 'bold 40px Arial', '#823d16'); |
||||
|
text.x = this.lib.properties.width - 100; |
||||
|
text.y = 100; |
||||
|
text.textAlign = 'center'; |
||||
|
text.textBaseline = 'alphabetic'; |
||||
|
this.text = text; |
||||
|
stage.addChild(text); |
||||
|
}; |
||||
|
|
||||
|
// 更新文本 |
||||
|
Time.prototype.update = function () { |
||||
|
if (this.timerId || !this.started) return; |
||||
|
// const endTime = this.startTime + this.count * 1000 + this.duration * 1000; |
||||
|
const endTime = this.startTime + this.duration * 1000; |
||||
|
// console.log('endTime: ', endTime); |
||||
|
this.timerId = setInterval(() => { |
||||
|
let leftTime = Math.round((endTime - Date.now()) / 1000); |
||||
|
console.log('leftTime: ', leftTime); |
||||
|
this.text && stage.removeChild(this.text); |
||||
|
if (leftTime <= 0) { |
||||
|
leftTime = 0; |
||||
|
this.end(); |
||||
|
} |
||||
|
this.renderText(leftTime); |
||||
|
}, 1000); |
||||
|
}; |
||||
|
|
||||
|
``` |
||||
|
|
||||
|
**特别说明:**时间关系,还有很多需要完善的,比如上文中的endCallback就没有做类型判断。后续除了程序的健壮性优化提升之外,还须添加webpack工程化打包构建等,避免源代码暴露,代码体积、模块导入引用等都能得到好的提升 |
@ -0,0 +1,34 @@ |
|||||
|
const { task, series, parallel, src, dest, watch } = require('gulp'); |
||||
|
const babel = require('gulp-babel'); |
||||
|
const uglify = require('gulp-uglify'); |
||||
|
const concat = require('gulp-concat'); |
||||
|
const clean = require('gulp-clean'); |
||||
|
const livereload = require('gulp-livereload'); |
||||
|
|
||||
|
const cleanTask = function () { |
||||
|
return src('dist/*', { read: false }).pipe(clean()); |
||||
|
}; |
||||
|
|
||||
|
const script = function () { |
||||
|
return src('src/**/*.js') |
||||
|
.pipe(babel({ presets: ['@babel/env'] })) |
||||
|
.pipe(uglify()) |
||||
|
.pipe(concat('main.js')) |
||||
|
.pipe(dest('dist/')) |
||||
|
.pipe(livereload({ start: true, port: 3001, reloadPage: 'dist/index.html' })); |
||||
|
}; |
||||
|
|
||||
|
const copy = function () { |
||||
|
src('./public/index.html').pipe(dest('dist/')); |
||||
|
src('./public/source-code.js').pipe(dest('dist/')); |
||||
|
src('./public/images/*').pipe(dest('dist/images')); |
||||
|
src('./public/libs/**/*').pipe(dest('dist/libs')); |
||||
|
src('./public/sounds/*').pipe(dest('dist/sounds')); |
||||
|
}; |
||||
|
|
||||
|
const watchTask = function () { |
||||
|
livereload.listen(); |
||||
|
watch('src/*', script); |
||||
|
}; |
||||
|
|
||||
|
exports.default = parallel(copy, script, watchTask); |
File diff suppressed because it is too large
@ -0,0 +1,29 @@ |
|||||
|
{ |
||||
|
"name": "bird-go-home", |
||||
|
"version": "1.0.0", |
||||
|
"description": "", |
||||
|
"main": ".svrxrc.js", |
||||
|
"scripts": { |
||||
|
"dev": "gulp" |
||||
|
}, |
||||
|
"repository": { |
||||
|
"type": "git", |
||||
|
"url": "gitea@dd.tall.wiki:ccsens_fe/bird-go-home.git" |
||||
|
}, |
||||
|
"keywords": [], |
||||
|
"author": "", |
||||
|
"license": "ISC", |
||||
|
"devDependencies": { |
||||
|
"@babel/core": "^7.15.5", |
||||
|
"@babel/preset-env": "^7.15.6", |
||||
|
"gulp": "^4.0.2", |
||||
|
"gulp-babel": "^8.0.0", |
||||
|
"gulp-clean": "^0.4.0", |
||||
|
"gulp-concat": "^2.6.1", |
||||
|
"gulp-livereload": "^4.0.2", |
||||
|
"gulp-uglify": "^3.0.2" |
||||
|
}, |
||||
|
"dependencies": { |
||||
|
"vinyl-paths": "^4.0.0" |
||||
|
} |
||||
|
} |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 18 KiB |
After Width: | Height: | Size: 290 KiB |
After Width: | Height: | Size: 50 KiB |
After Width: | Height: | Size: 736 KiB |
After Width: | Height: | Size: 48 KiB |
@ -0,0 +1,37 @@ |
|||||
|
<!DOCTYPE html> |
||||
|
<!-- |
||||
|
NOTES: |
||||
|
1. All tokens are represented by '$' sign in the template. |
||||
|
2. You can write your code only wherever mentioned. |
||||
|
3. All occurrences of existing tokens will be replaced by their appropriate values. |
||||
|
4. Blank lines will be removed automatically. |
||||
|
5. Remove unnecessary comments before creating your template. |
||||
|
--> |
||||
|
<html> |
||||
|
<head> |
||||
|
<meta charset="UTF-8"> |
||||
|
<meta name="authoring-tool" content="Adobe_Animate_CC"> |
||||
|
<title>source-code</title> |
||||
|
<!-- write your code here --> |
||||
|
<style> |
||||
|
#animation_container, #_preload_div_ { |
||||
|
position:absolute; |
||||
|
margin:auto; |
||||
|
left:0;right:0; |
||||
|
top:0;bottom:0; |
||||
|
} |
||||
|
</style> |
||||
|
<script src="libs/1.0.0/createjs.min.js"></script> |
||||
|
<script src="source-code.js"></script> |
||||
|
<script src="main.js"></script> |
||||
|
<!-- write your code here --> |
||||
|
</head> |
||||
|
<body onload="init();" style="margin:0px;"> |
||||
|
<div id="animation_container" style="background-color:rgba(255, 255, 255, 1.00); width:1280px; height:720px"> |
||||
|
<canvas id="canvas" width="1280" height="720" style="position: absolute; display: none; background-color:rgba(255, 255, 255, 1.00);"></canvas> |
||||
|
<div id="dom_overlay_container" style="pointer-events:none; overflow:hidden; width:1280px; height:720px; position: absolute; left: 0px; top: 0px; display: none;"> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div id='_preload_div_' style='position:absolute; top:0; left:0; display: inline-block; height:720px; width: 1280px; text-align: center;'> <span style='display: inline-block; height: 100%; vertical-align: middle;'></span> <img src=images/_preloader.gif style='vertical-align: middle; max-height: 100%'/></div> |
||||
|
</body> |
||||
|
</html> |
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,82 @@ |
|||||
|
<!DOCTYPE html> |
||||
|
<!-- |
||||
|
NOTES: |
||||
|
1. All tokens are represented by '$' sign in the template. |
||||
|
2. You can write your code only wherever mentioned. |
||||
|
3. All occurrences of existing tokens will be replaced by their appropriate values. |
||||
|
4. Blank lines will be removed automatically. |
||||
|
5. Remove unnecessary comments before creating your template. |
||||
|
--> |
||||
|
<html> |
||||
|
<head> |
||||
|
<meta charset="UTF-8"> |
||||
|
<meta name="authoring-tool" content="Adobe_Animate_CC"> |
||||
|
<title>source-code</title> |
||||
|
<!-- write your code here --> |
||||
|
<style> |
||||
|
#animation_container, #_preload_div_ { |
||||
|
position:absolute; |
||||
|
margin:auto; |
||||
|
left:0;right:0; |
||||
|
top:0;bottom:0; |
||||
|
} |
||||
|
</style> |
||||
|
<script src="libs/1.0.0/createjs.min.js"></script> |
||||
|
<script src="source-code.js"></script> |
||||
|
<script> |
||||
|
var canvas, stage, exportRoot, anim_container, dom_overlay_container, fnStartAnimation; |
||||
|
function init() { |
||||
|
canvas = document.getElementById("canvas"); |
||||
|
anim_container = document.getElementById("animation_container"); |
||||
|
dom_overlay_container = document.getElementById("dom_overlay_container"); |
||||
|
var comp=AdobeAn.getComposition("3B394831DA9AF040BDA8D246B0227116"); |
||||
|
var lib=comp.getLibrary(); |
||||
|
createjs.MotionGuidePlugin.install(); |
||||
|
var loader = new createjs.LoadQueue(false); |
||||
|
loader.addEventListener("fileload", function(evt){handleFileLoad(evt,comp)}); |
||||
|
loader.addEventListener("complete", function(evt){handleComplete(evt,comp)}); |
||||
|
var lib=comp.getLibrary(); |
||||
|
loader.loadManifest(lib.properties.manifest); |
||||
|
} |
||||
|
function handleFileLoad(evt, comp) { |
||||
|
var images=comp.getImages(); |
||||
|
if (evt && (evt.item.type == "image")) { images[evt.item.id] = evt.result; } |
||||
|
} |
||||
|
function handleComplete(evt,comp) { |
||||
|
//This function is always called, irrespective of the content. You can use the variable "stage" after it is created in token create_stage. |
||||
|
var lib=comp.getLibrary(); |
||||
|
var ss=comp.getSpriteSheet(); |
||||
|
var queue = evt.target; |
||||
|
var ssMetadata = lib.ssMetadata; |
||||
|
for(i=0; i<ssMetadata.length; i++) { |
||||
|
ss[ssMetadata[i].name] = new createjs.SpriteSheet( {"images": [queue.getResult(ssMetadata[i].name)], "frames": ssMetadata[i].frames} ) |
||||
|
} |
||||
|
var preloaderDiv = document.getElementById("_preload_div_"); |
||||
|
preloaderDiv.style.display = 'none'; |
||||
|
canvas.style.display = 'block'; |
||||
|
exportRoot = new lib.高尔夫1_HTML5Canvas(); |
||||
|
stage = new lib.Stage(canvas); |
||||
|
stage.enableMouseOver(); |
||||
|
//Registers the "tick" event listener. |
||||
|
fnStartAnimation = function() { |
||||
|
stage.addChild(exportRoot); |
||||
|
createjs.Ticker.framerate = lib.properties.fps; |
||||
|
createjs.Ticker.addEventListener("tick", stage); |
||||
|
} |
||||
|
//Code to support hidpi screens and responsive scaling. |
||||
|
AdobeAn.makeResponsive(true,'both',true,1,[canvas,preloaderDiv,anim_container,dom_overlay_container]); |
||||
|
AdobeAn.compositionLoaded(lib.properties.id); |
||||
|
fnStartAnimation(); |
||||
|
} |
||||
|
</script> |
||||
|
<!-- write your code here --> |
||||
|
</head> |
||||
|
<body onload="init();" style="margin:0px;"> |
||||
|
<div id="animation_container" style="background-color:rgba(255, 255, 255, 1.00); width:1280px; height:720px"> |
||||
|
<canvas id="canvas" width="1280" height="720" style="position: absolute; display: none; background-color:rgba(255, 255, 255, 1.00);"></canvas> |
||||
|
<div id="dom_overlay_container" style="pointer-events:none; overflow:hidden; width:1280px; height:720px; position: absolute; left: 0px; top: 0px; display: none;"> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div id='_preload_div_' style='position:absolute; top:0; left:0; display: inline-block; height:720px; width: 1280px; text-align: center;'> <span style='display: inline-block; height: 100%; vertical-align: middle;'></span> <img src=images/_preloader.gif style='vertical-align: middle; max-height: 100%'/></div> |
||||
|
</body> |
||||
|
</html> |
File diff suppressed because it is too large
Binary file not shown.
@ -0,0 +1,47 @@ |
|||||
|
/** |
||||
|
* 再玩一次类 |
||||
|
* @property {object} lib 库对象 |
||||
|
* @property {object} btnAgain 面板元素对象 |
||||
|
*/ |
||||
|
function Again() { |
||||
|
this.lib = library; |
||||
|
|
||||
|
this.btnAgain = null; |
||||
|
} |
||||
|
|
||||
|
Again.of = (function () { |
||||
|
let instance = null; |
||||
|
return function () { |
||||
|
if (!instance) { |
||||
|
instance = new Again(); |
||||
|
} |
||||
|
instance.init(); |
||||
|
return instance; |
||||
|
}; |
||||
|
})(); |
||||
|
|
||||
|
// 初始化
|
||||
|
Again.prototype.init = function () { |
||||
|
this.showAgainBtn(); |
||||
|
}; |
||||
|
|
||||
|
// 渲染背景面板
|
||||
|
Again.prototype.showAgainBtn = function () { |
||||
|
const lib = this.lib; |
||||
|
const btnAgain = new lib.btnAgain(); |
||||
|
btnAgain.x = lib.properties.width / 2; |
||||
|
btnAgain.y = lib.properties.height / 2 + 150; |
||||
|
this.btnAgain = btnAgain; |
||||
|
this.btnAgain.addEventListener( |
||||
|
'click', |
||||
|
function () { |
||||
|
if (config.mode === 0) { |
||||
|
againMessage(); |
||||
|
} else { |
||||
|
location.reload(); |
||||
|
} |
||||
|
}, |
||||
|
false, |
||||
|
); |
||||
|
stage.addChild(btnAgain); |
||||
|
}; |
@ -0,0 +1,32 @@ |
|||||
|
function Back() { |
||||
|
this.lib = library; |
||||
|
|
||||
|
this.back = null; |
||||
|
} |
||||
|
|
||||
|
Back.of = (function () { |
||||
|
let instance = null; |
||||
|
return function () { |
||||
|
if (!instance) { |
||||
|
instance = new Back(); |
||||
|
} |
||||
|
instance.init(); |
||||
|
return instance; |
||||
|
}; |
||||
|
})(); |
||||
|
|
||||
|
Back.prototype.init = function () { |
||||
|
const target = new this.lib.btnBack(); |
||||
|
target.x = 40; |
||||
|
target.y = 80; |
||||
|
target.scaleX = 1.3; |
||||
|
target.scaleY = 1.3; |
||||
|
target.addEventListener('click', this.goHome, false); |
||||
|
this.back = target; |
||||
|
stage.addChild(target); |
||||
|
}; |
||||
|
|
||||
|
// 返回主菜单 TODO:
|
||||
|
Back.prototype.goHome = function () { |
||||
|
console.log('goHome'); |
||||
|
}; |
@ -0,0 +1,102 @@ |
|||||
|
// Count.of(startTime, defaultCount) 调用即可
|
||||
|
|
||||
|
/** |
||||
|
* 倒计时类 |
||||
|
* @param {number} startTime 开始倒计时的时间 |
||||
|
* @param {number} defaultCount 倒计时时长 TODO: const startTime = +gameInfo.startTime; |
||||
|
* @property {object} modal 面板对象 |
||||
|
* @property {object} text 倒计时文本对象 |
||||
|
* @property {number} default 倒计时值 |
||||
|
* @property {number} timer 计时器id |
||||
|
* @property {object} lib 库对象 |
||||
|
* @property {function} countEndCallback 结束回调函数 |
||||
|
*/ |
||||
|
function Count(countEndCallback, startTime, defaultCount = config.count || 5) { |
||||
|
this.default = defaultCount; |
||||
|
this.startTime = startTime; |
||||
|
|
||||
|
this.modal = null; |
||||
|
this.text = null; |
||||
|
this.timer = null; |
||||
|
this.lib = library; |
||||
|
this.countEndCallback = countEndCallback; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 静态方法 封装new 及 init方法 |
||||
|
* 使用时直接调用此方法 |
||||
|
* @param {function} countEndCallback 倒计时结束的回调函数 |
||||
|
* @param {number} defaultCount 倒计时时长 |
||||
|
* @returns |
||||
|
*/ |
||||
|
Count.of = (function () { |
||||
|
let instance = null; |
||||
|
return function (countEndCallback, startTime = Date.now(), defaultCount) { |
||||
|
if (!instance) { |
||||
|
instance = new Count(countEndCallback, startTime, defaultCount); |
||||
|
} |
||||
|
instance.init(); |
||||
|
return instance; |
||||
|
}; |
||||
|
})(); |
||||
|
|
||||
|
// 初始化方法
|
||||
|
Count.prototype.init = function () { |
||||
|
this.renderModal(); |
||||
|
this.renderContent(); |
||||
|
}; |
||||
|
|
||||
|
// 渲染面板
|
||||
|
Count.prototype.renderModal = function () { |
||||
|
const target = new this.lib.bgModalBegin(); |
||||
|
target.x = this.lib.properties.width / 2; |
||||
|
target.y = this.lib.properties.height / 2; |
||||
|
this.modal = target; |
||||
|
stage.addChild(target); // 显示开始游戏的倒计时面板
|
||||
|
}; |
||||
|
|
||||
|
// 渲染倒计时文本内容
|
||||
|
Count.prototype.renderContent = function () { |
||||
|
const endCountTime = this.startTime + this.default * 1000; |
||||
|
let leftCount = Math.round((endCountTime - Date.now()) / 1000); |
||||
|
|
||||
|
this.update(leftCount); // 开始开始游戏的 倒计时
|
||||
|
|
||||
|
this.timer = setInterval(() => { |
||||
|
leftCount = Math.round((endCountTime - Date.now()) / 1000); |
||||
|
stage.removeChild(this.text); |
||||
|
this.update(leftCount); |
||||
|
}, 1000); |
||||
|
}; |
||||
|
|
||||
|
// 更新倒计时文本
|
||||
|
Count.prototype.update = function (time) { |
||||
|
if (time <= 0) { |
||||
|
// 发送倒计时结束的消息
|
||||
|
clearInterval(this.timer); |
||||
|
stage.removeChild(this.text); |
||||
|
stage.removeChild(this.modal); |
||||
|
// sendEndCountRequest(); // 发送倒计时结束的消息
|
||||
|
this.countEnd(); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
this.renderText(time); |
||||
|
}; |
||||
|
|
||||
|
// 渲染文本
|
||||
|
Count.prototype.renderText = function (time) { |
||||
|
const text = new createjs.Text(time, 'bold 100px Arial', '#87431c'); |
||||
|
text.x = this.lib.properties.width / 2; |
||||
|
text.y = this.lib.properties.height / 2 + 20; |
||||
|
text.textAlign = 'center'; |
||||
|
text.textBaseline = 'alphabetic'; |
||||
|
this.text = text; |
||||
|
stage.addChild(text); |
||||
|
}; |
||||
|
|
||||
|
// 结束倒计时 开始游戏
|
||||
|
Count.prototype.countEnd = function () { |
||||
|
// 执行结束后的回调
|
||||
|
this.countEndCallback(); |
||||
|
}; |
@ -0,0 +1,47 @@ |
|||||
|
/** |
||||
|
* 演示模式类 |
||||
|
* @property {object} lib 库对象 |
||||
|
* @property {object} stopDemo 面板元素对象 |
||||
|
*/ |
||||
|
function Demo() { |
||||
|
this.lib = library; |
||||
|
|
||||
|
this.stopDemo = null; |
||||
|
} |
||||
|
|
||||
|
Demo.of = (function () { |
||||
|
let instance = null; |
||||
|
return function () { |
||||
|
if (!instance) { |
||||
|
instance = new Demo(); |
||||
|
} |
||||
|
instance.init(); |
||||
|
return instance; |
||||
|
}; |
||||
|
})(); |
||||
|
|
||||
|
// 初始化
|
||||
|
Demo.prototype.init = function () { |
||||
|
this.showStopDemo(); |
||||
|
}; |
||||
|
|
||||
|
// 显示演示模式按钮
|
||||
|
Demo.prototype.showStopDemo = function () { |
||||
|
const lib = this.lib; |
||||
|
const stopDemo = new lib.stopDemo(); |
||||
|
stopDemo.x = 50; |
||||
|
stopDemo.y = lib.properties.height - 100; |
||||
|
this.stopDemo = stopDemo; |
||||
|
// 关闭演示模式
|
||||
|
this.stopDemo.addEventListener( |
||||
|
'click', |
||||
|
function () { |
||||
|
stage.removeChild(stopDemo); |
||||
|
location.hash = ''; |
||||
|
location.reload(); |
||||
|
isDemo = false; |
||||
|
}, |
||||
|
false, |
||||
|
); |
||||
|
stage.addChild(stopDemo); |
||||
|
}; |
@ -0,0 +1,65 @@ |
|||||
|
/** |
||||
|
* 游戏结束 |
||||
|
* @param {number} score 最终得分 |
||||
|
* |
||||
|
* @property {object} lib 资源对象 |
||||
|
* @property {number} score 最终得分 |
||||
|
* @property {object} modal 面板元素对象 |
||||
|
* @property {object} text 文本元素对象 |
||||
|
*/ |
||||
|
function End(score) { |
||||
|
this.lib = library; |
||||
|
|
||||
|
this.score = score; |
||||
|
|
||||
|
this.modal = null; |
||||
|
this.text = null; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 静态方法 封装new init 返回实例 |
||||
|
* @param {number} score 最终得分 |
||||
|
* @returns |
||||
|
*/ |
||||
|
End.of = (function () { |
||||
|
let instance = null; |
||||
|
return function (score) { |
||||
|
if (!instance) { |
||||
|
instance = new End(score); |
||||
|
} |
||||
|
instance.init(); |
||||
|
return instance; |
||||
|
}; |
||||
|
})(); |
||||
|
|
||||
|
// 初始化
|
||||
|
End.prototype.init = function () { |
||||
|
this.renderModal(); |
||||
|
this.renderText(this.score); |
||||
|
Again.of(); |
||||
|
}; |
||||
|
|
||||
|
// 渲染背景面板
|
||||
|
End.prototype.renderModal = function () { |
||||
|
const lib = this.lib; |
||||
|
const target = new lib.bgModalEnd(); |
||||
|
target.x = lib.properties.width / 2; |
||||
|
target.y = lib.properties.height / 2; |
||||
|
this.modal = target; |
||||
|
stage.addChild(target); |
||||
|
}; |
||||
|
|
||||
|
/** |
||||
|
* 渲染得分文本对象 |
||||
|
* @param {number} score 最终得分 |
||||
|
*/ |
||||
|
End.prototype.renderText = function (score) { |
||||
|
const lib = this.lib; |
||||
|
const target = new createjs.Text(score, 'bold 100px Arial', '#793b18'); |
||||
|
target.x = lib.properties.width / 2; |
||||
|
target.y = lib.properties.height / 2 + 70; |
||||
|
target.textAlign = 'center'; |
||||
|
target.textBaseline = 'alphabetic'; |
||||
|
this.text = target; |
||||
|
stage.addChild(target); |
||||
|
}; |
@ -0,0 +1,34 @@ |
|||||
|
/** |
||||
|
* 难度等级类 |
||||
|
* @param {number} level 等级数字代码 |
||||
|
*/ |
||||
|
function Level(level) { |
||||
|
this.lib = library; |
||||
|
|
||||
|
this.level = level; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 静态方法 封装new init 返回实例 |
||||
|
* @param {number} level 等级数值 |
||||
|
* @returns |
||||
|
*/ |
||||
|
Level.of = function (level) { |
||||
|
const instance = new Level(level); |
||||
|
instance.init(); |
||||
|
return instance; |
||||
|
}; |
||||
|
|
||||
|
// 初始化 渲染
|
||||
|
// 更新config中的level属性
|
||||
|
Level.prototype.init = function () { |
||||
|
const initX = this.lib.properties.width / 2; |
||||
|
const initY = 80; |
||||
|
const target = new this.lib.Level(); |
||||
|
target.x = initX; |
||||
|
target.y = initY; |
||||
|
|
||||
|
target.gotoAndStop(`level-${this.level}`); |
||||
|
config.level = this.level; |
||||
|
stage.addChild(target); |
||||
|
}; |
@ -0,0 +1,82 @@ |
|||||
|
/** |
||||
|
* 游戏主体 |
||||
|
* @param {function} endCallback 游戏结束的回调函数 |
||||
|
* @param {number} max 最多运动次数 |
||||
|
* |
||||
|
* @property {object} lib 资源对象 |
||||
|
* @property {object} element 主体元素对象 |
||||
|
* @property {number} prevTime 上次完成的时间ms |
||||
|
* @property {number} max 最多运动(play)次数 |
||||
|
* @property {number} times 当前运动次数 play依次+1 |
||||
|
* @property {function} endCallback 结束后 调用的回调函数 |
||||
|
*/ |
||||
|
function Main(endCallback, max) { |
||||
|
this.lib = library; |
||||
|
|
||||
|
this.element = null; |
||||
|
this.prevTime = 0; |
||||
|
|
||||
|
this.max = max; |
||||
|
this.times = 0; |
||||
|
this.endCallback = endCallback; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 静态方法 封装new init 返回实例 |
||||
|
* @param {function} endCallback 游戏结束的回调函数 |
||||
|
* @param {number} max 最多运动次数 |
||||
|
*/ |
||||
|
Main.of = (function () { |
||||
|
let instance = null; |
||||
|
return function (endCallback, max = config.times) { |
||||
|
if (!instance) { |
||||
|
instance = new Main(endCallback, max); |
||||
|
} |
||||
|
instance.init(); |
||||
|
return instance; |
||||
|
}; |
||||
|
})(); |
||||
|
|
||||
|
// 初始方法
|
||||
|
Main.prototype.init = function () { |
||||
|
const target = new this.lib.Main(); |
||||
|
this.element = target; |
||||
|
stage.addChild(target); |
||||
|
}; |
||||
|
|
||||
|
// play
|
||||
|
// 限制了两次动作间隔时间不能少于2s
|
||||
|
// 游戏状态在进行中才能触发
|
||||
|
// play次数 >= 最多完成次数 调用结束的callback
|
||||
|
Main.prototype.play = function (direction) { |
||||
|
if (Date.now() - this.prevTime <= 1200 || state !== 1) return; |
||||
|
// if (state !== 1) return;
|
||||
|
this.element.play(); |
||||
|
this.times += 1; |
||||
|
|
||||
|
this.computeScore(this.times, direction); |
||||
|
window.soundInstance.playda(direction); |
||||
|
setTimeout(function () { |
||||
|
window.soundInstance.playjin(); |
||||
|
}, 1900); |
||||
|
|
||||
|
this.prevTime = Date.now(); |
||||
|
if (this.times >= this.max) { |
||||
|
this.times = this.max; |
||||
|
this.endCallback(); |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
/** |
||||
|
* 计算当前的次数与分值 并发送给父窗口 |
||||
|
* @param {number} times 当前动作执行成功的次数 |
||||
|
* @param {number} direction play code |
||||
|
*/ |
||||
|
Main.prototype.computeScore = function (times, direction = 0) { |
||||
|
const directionTarget = config.config.scores.find(item => item.direction === direction); |
||||
|
config.currentTimes = times; |
||||
|
config.currentScore += directionTarget.score; |
||||
|
if (config.mode === 0) { |
||||
|
sendMessage({ event: 'play', data: { currentTimes: times, currentScore: config.currentScore } }); |
||||
|
} |
||||
|
}; |
@ -0,0 +1,61 @@ |
|||||
|
// 音频处理类;
|
||||
|
function Sound() { |
||||
|
this.lib = library; |
||||
|
|
||||
|
this.music = {}; |
||||
|
} |
||||
|
|
||||
|
Sound.of = (function () { |
||||
|
let instance = null; |
||||
|
return function () { |
||||
|
if (!instance) { |
||||
|
instance = new Sound(); |
||||
|
} |
||||
|
instance.init(); |
||||
|
return instance; |
||||
|
}; |
||||
|
})(); |
||||
|
|
||||
|
Sound.prototype.init = function () { |
||||
|
createjs.Sound.alternateExtensions = ['wav']; |
||||
|
const sounds = [ |
||||
|
{ src: 'sounds/beijing.wav', id: 'bgm' }, |
||||
|
{ src: 'sounds/daqiu.wav', id: 'daqiu' }, |
||||
|
{ src: 'sounds/jinqiu.wav', id: 'jinqiu' }, |
||||
|
]; |
||||
|
const _this = this; |
||||
|
createjs.Sound.addEventListener('fileload', function (event) { |
||||
|
_this.music[event.id] = createjs.Sound.createInstance(event.id); |
||||
|
}); |
||||
|
createjs.Sound.registerSounds(sounds, './'); |
||||
|
this.playBgm(); |
||||
|
}; |
||||
|
|
||||
|
Sound.prototype.playBgm = function () { |
||||
|
this.music.bgm && this.music.bgm.play({ loop: -1, volume: 0.3 }); // 播放背景音乐
|
||||
|
}; |
||||
|
|
||||
|
Sound.prototype.playda = function (direction) { |
||||
|
if (direction === 0) { |
||||
|
this.music.daqiu && this.music.daqiu.play(); |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
Sound.prototype.playjin = function () { |
||||
|
this.music.jinqiu && this.music.jinqiu.play(); |
||||
|
}; |
||||
|
|
||||
|
// let music = {};
|
||||
|
// function initSound() {
|
||||
|
// createjs.Sound.alternateExtensions = ['mp3'];
|
||||
|
// const sounds = [
|
||||
|
// { src: 'public/sounds/bgmMusic.mp3', id: 'bgm' },
|
||||
|
// { src: 'public/sounds/excitationMusic.mp3', id: 'excitation' },
|
||||
|
// { src: 'public/sounds/amazing.mp3', id: 'amazing' },
|
||||
|
// { src: 'public/sounds/unbelievable.mp3', id: 'unbelievable' },
|
||||
|
// ];
|
||||
|
// createjs.Sound.addEventListener('fileload', function (event) {
|
||||
|
// music[event.id] = createjs.Sound.createInstance(event.id);
|
||||
|
// });
|
||||
|
// createjs.Sound.registerSounds(sounds, '../../');
|
||||
|
// }
|
@ -0,0 +1,55 @@ |
|||||
|
/** |
||||
|
* 暂停游戏类(暂停继续游戏) |
||||
|
* @property {object} lib 库对象 |
||||
|
* @property {object} suspend 面板元素对象 |
||||
|
*/ |
||||
|
function Suspend() { |
||||
|
this.lib = library; |
||||
|
|
||||
|
this.suspend = null; |
||||
|
} |
||||
|
|
||||
|
Suspend.of = (function () { |
||||
|
let instance = null; |
||||
|
return function () { |
||||
|
if (!instance) { |
||||
|
instance = new Suspend(); |
||||
|
} |
||||
|
instance.init(); |
||||
|
return instance; |
||||
|
}; |
||||
|
})(); |
||||
|
|
||||
|
// 初始化
|
||||
|
Suspend.prototype.init = function () { |
||||
|
this.suspendGame(); |
||||
|
}; |
||||
|
|
||||
|
// 暂停游戏按钮
|
||||
|
Suspend.prototype.suspendGame = function () { |
||||
|
const lib = this.lib; |
||||
|
const suspend = new lib.suspend(); |
||||
|
suspend.x = 50; |
||||
|
suspend.y = lib.properties.height - 100; |
||||
|
this.suspend = suspend; |
||||
|
const _this = this; |
||||
|
// 继续游戏
|
||||
|
this.suspend.addEventListener( |
||||
|
'click', |
||||
|
function () { |
||||
|
_this.hide(); |
||||
|
continueMessage(); |
||||
|
}, |
||||
|
false, |
||||
|
); |
||||
|
// stage.addChild(this.suspend);
|
||||
|
// stage.removeChild(this.suspend);
|
||||
|
}; |
||||
|
|
||||
|
Suspend.prototype.hide = function () { |
||||
|
stage.removeChild(this.suspend); |
||||
|
}; |
||||
|
|
||||
|
Suspend.prototype.show = function () { |
||||
|
stage.addChild(this.suspend); |
||||
|
}; |
@ -0,0 +1,125 @@ |
|||||
|
/** |
||||
|
* 游戏时长 计时 |
||||
|
* @param {function} endCallback 倒计时结束的回调函数 |
||||
|
* @param {number} duration 游戏时长 |
||||
|
* @param {number} count 游戏倒计时时长 |
||||
|
* |
||||
|
* @property {number} duration 游戏时长 |
||||
|
* @property {number} count 游戏倒计时时长 |
||||
|
* @property {number} startTime 游戏开始是ms |
||||
|
* @property {boolean} started 游戏是否开始 |
||||
|
* @property {object} lib 资源库 |
||||
|
* @property {object} bg 时间倒计时背景 |
||||
|
* @property {object} text 倒计时文本 |
||||
|
* @property {number} timerId 定时器id |
||||
|
* @property {function} endCallback 结束回调函数 |
||||
|
*/ |
||||
|
function Time(endCallback, duration, count) { |
||||
|
this.duration = duration; |
||||
|
this.count = count; |
||||
|
this.startTime = Date.now(); |
||||
|
|
||||
|
this.started = false; // 是否开始游戏
|
||||
|
|
||||
|
this.lib = library; |
||||
|
this.bg = null; |
||||
|
this.text = null; |
||||
|
this.timerId = null; |
||||
|
this.endCallback = endCallback; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 静态方法 封装new init 返回实例 |
||||
|
* @param {function} endCallback 倒计时结束的回调函数 |
||||
|
* @param {number} duration 游戏时长 |
||||
|
* @param {number} count 游戏倒计时时长 |
||||
|
* @returns |
||||
|
*/ |
||||
|
Time.of = (function () { |
||||
|
let instance = null; |
||||
|
return function (endCallback, duration = config.duration || 60, count = config.count || 5) { |
||||
|
if (!instance) { |
||||
|
instance = new Time(endCallback, duration, count); |
||||
|
} |
||||
|
instance.init(); |
||||
|
return instance; |
||||
|
}; |
||||
|
})(); |
||||
|
|
||||
|
// 初始化
|
||||
|
Time.prototype.init = function () { |
||||
|
this.renderBg(); |
||||
|
this.renderText(this.duration); |
||||
|
}; |
||||
|
|
||||
|
// 设置时长
|
||||
|
Time.prototype.setDuration = function (duration) { |
||||
|
this.duration = duration; |
||||
|
this.renderText(this.duration); |
||||
|
}; |
||||
|
|
||||
|
// 开始游戏 开始倒计时
|
||||
|
Time.prototype.start = function (startTime = Date.now()) { |
||||
|
this.started = true; |
||||
|
state = 1; |
||||
|
this.startTime = startTime; |
||||
|
this.duration = leftDuration ? leftDuration : this.duration; |
||||
|
this.update(); |
||||
|
}; |
||||
|
|
||||
|
// 暂停游戏 暂停倒计时
|
||||
|
Time.prototype.pause = function () { |
||||
|
this.started = false; |
||||
|
state = 3; |
||||
|
clearTimeout(this.timerId); |
||||
|
this.timerId = null; |
||||
|
}; |
||||
|
|
||||
|
// 结束游戏 结束倒计时
|
||||
|
Time.prototype.end = function () { |
||||
|
this.started = false; |
||||
|
this.timerId && clearTimeout(this.timerId); |
||||
|
this.timerId = null; |
||||
|
// 执行结束后的回调
|
||||
|
this.endCallback(); |
||||
|
}; |
||||
|
|
||||
|
// 渲染背景
|
||||
|
Time.prototype.renderBg = function () { |
||||
|
const initX = this.lib.properties.width - 100; |
||||
|
const initY = 80; |
||||
|
const instance = new this.lib.timeBg(); |
||||
|
instance.x = initX; |
||||
|
instance.y = initY; |
||||
|
this.bg = instance; |
||||
|
stage.addChild(instance); |
||||
|
}; |
||||
|
|
||||
|
// 渲染文本
|
||||
|
Time.prototype.renderText = function (time) { |
||||
|
if (this.text) stage.removeChild(this.text); |
||||
|
const text = new createjs.Text(time, 'bold 40px Arial', '#823d16'); |
||||
|
text.x = this.lib.properties.width - 100; |
||||
|
text.y = 100; |
||||
|
text.textAlign = 'center'; |
||||
|
text.textBaseline = 'alphabetic'; |
||||
|
this.text = text; |
||||
|
stage.addChild(text); |
||||
|
}; |
||||
|
|
||||
|
// 更新文本
|
||||
|
Time.prototype.update = function () { |
||||
|
if (this.timerId || !this.started) return; |
||||
|
// const endTime = this.startTime + this.duration * 1000;
|
||||
|
this.timerId = setInterval(() => { |
||||
|
// let leftTime = Math.round((endTime - Date.now()) / 1000);
|
||||
|
this.duration--; |
||||
|
leftDuration = this.duration; |
||||
|
this.text && stage.removeChild(this.text); |
||||
|
if (this.duration <= 0) { |
||||
|
this.duration = 0; |
||||
|
this.end(); |
||||
|
} |
||||
|
this.renderText(this.duration); |
||||
|
}, 1000); |
||||
|
}; |
@ -0,0 +1,53 @@ |
|||||
|
const config = { |
||||
|
count: 5, // 默认倒计时时长
|
||||
|
duration: 60, // 总时长 s
|
||||
|
total: 100, // 总分
|
||||
|
times: 20, // 动作次数
|
||||
|
level: 1, // 游戏难度级别
|
||||
|
mode: 1, // 模式 0-> 正常模式 1-> 演示模式
|
||||
|
currentScore: 0, // 当前得分
|
||||
|
currentTimes: 0, // 当前次数
|
||||
|
config: { |
||||
|
scores: [{ direction: 0, score: 5 }], |
||||
|
directions: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], |
||||
|
}, // 得分配置
|
||||
|
}; |
||||
|
|
||||
|
let library = null; |
||||
|
let state = 0; // 游戏状态 0->未开始 1->进行中 2->结束 3->暂停
|
||||
|
let isDemo = false; // 是不是演示模式
|
||||
|
let leftDuration = null; // 暂停时的时间
|
||||
|
|
||||
|
function initStage(lib) { |
||||
|
library = lib; |
||||
|
|
||||
|
window.main = Main.of(gameOver); // 初始化鸟等
|
||||
|
window.timeInstance = Time.of(gameOver); // 初始化游戏时间
|
||||
|
window.soundInstance = Sound.of(); // 初始化音频
|
||||
|
|
||||
|
Level.of(config.level); // 游戏难度级别
|
||||
|
Back.of(); // 返回按钮
|
||||
|
isHash(); |
||||
|
window.suspend = Suspend.of(); |
||||
|
|
||||
|
window.addEventListener( |
||||
|
'click', |
||||
|
function () { |
||||
|
if (!window.soundInstance) return; |
||||
|
window.soundInstance.playBgm(); |
||||
|
}, |
||||
|
false, |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
// 游戏结束 显示结束得分面板
|
||||
|
function gameOver() { |
||||
|
state = 2; |
||||
|
const times = main.times; |
||||
|
setTimeout(() => { |
||||
|
End.of(config.currentScore || 0); |
||||
|
if (config.mode === 0) { |
||||
|
finishMessage(config.currentScore, times); |
||||
|
} |
||||
|
}, 2000); |
||||
|
} |
@ -0,0 +1,53 @@ |
|||||
|
var canvas, stage, exportRoot, anim_container, dom_overlay_container, fnStartAnimation; |
||||
|
function init() { |
||||
|
canvas = document.getElementById('canvas'); |
||||
|
anim_container = document.getElementById('animation_container'); |
||||
|
dom_overlay_container = document.getElementById('dom_overlay_container'); |
||||
|
var comp = AdobeAn.getComposition('3B394831DA9AF040BDA8D246B0227116'); |
||||
|
var lib = comp.getLibrary(); |
||||
|
createjs.MotionGuidePlugin.install(); |
||||
|
var loader = new createjs.LoadQueue(false); |
||||
|
loader.addEventListener('fileload', function (evt) { |
||||
|
handleFileLoad(evt, comp); |
||||
|
}); |
||||
|
loader.addEventListener('complete', function (evt) { |
||||
|
handleComplete(evt, comp); |
||||
|
}); |
||||
|
var lib = comp.getLibrary(); |
||||
|
loader.loadManifest(lib.properties.manifest); |
||||
|
} |
||||
|
function handleFileLoad(evt, comp) { |
||||
|
var images = comp.getImages(); |
||||
|
if (evt && evt.item.type == 'image') { |
||||
|
images[evt.item.id] = evt.result; |
||||
|
} |
||||
|
} |
||||
|
function handleComplete(evt, comp) { |
||||
|
//This function is always called, irrespective of the content. You can use the variable "stage" after it is created in token create_stage.
|
||||
|
var lib = comp.getLibrary(); |
||||
|
var ss = comp.getSpriteSheet(); |
||||
|
var queue = evt.target; |
||||
|
var ssMetadata = lib.ssMetadata; |
||||
|
for (let i = 0; i < ssMetadata.length; i++) { |
||||
|
ss[ssMetadata[i].name] = new createjs.SpriteSheet({ images: [queue.getResult(ssMetadata[i].name)], frames: ssMetadata[i].frames }); |
||||
|
} |
||||
|
var preloaderDiv = document.getElementById('_preload_div_'); |
||||
|
preloaderDiv.style.display = 'none'; |
||||
|
canvas.style.display = 'block'; |
||||
|
exportRoot = new lib.高尔夫1_HTML5Canvas(); |
||||
|
stage = new lib.Stage(canvas); |
||||
|
stage.enableMouseOver(); |
||||
|
//Registers the "tick" event listener.
|
||||
|
fnStartAnimation = function () { |
||||
|
stage.addChild(exportRoot); |
||||
|
|
||||
|
initStage(lib); |
||||
|
|
||||
|
createjs.Ticker.framerate = lib.properties.fps; |
||||
|
createjs.Ticker.addEventListener('tick', stage); |
||||
|
}; |
||||
|
//Code to support hidpi screens and responsive scaling.
|
||||
|
AdobeAn.makeResponsive(true, 'both', true, 1, [canvas, preloaderDiv, anim_container, dom_overlay_container]); |
||||
|
AdobeAn.compositionLoaded(lib.properties.id); |
||||
|
fnStartAnimation(); |
||||
|
} |
@ -0,0 +1,132 @@ |
|||||
|
window.addEventListener( |
||||
|
'message', |
||||
|
function (e) { |
||||
|
const res = e.data; |
||||
|
console.log('子->接受: ', res); |
||||
|
switch (res.event) { |
||||
|
case 'start': |
||||
|
startGame(res.data); |
||||
|
return; |
||||
|
case 'play': |
||||
|
playGame(res.data); |
||||
|
return; |
||||
|
case 'pause': |
||||
|
pauseGame(res.data); |
||||
|
return; |
||||
|
case 'continue': |
||||
|
continueGame(res.data); |
||||
|
return; |
||||
|
default: |
||||
|
finishGame(res.data); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
function startGame(data) { |
||||
|
if (state === 2) { |
||||
|
location.reload(); |
||||
|
return; |
||||
|
} |
||||
|
const { count, game, status, param } = data; |
||||
|
config.count = count.duration; |
||||
|
config.duration = game.duration; |
||||
|
config.total = game.totalScore; |
||||
|
config.times = game.totalTimes; |
||||
|
config.level = game.level; |
||||
|
config.config = game.config; |
||||
|
config.mode = game.mode; |
||||
|
|
||||
|
window.timeInstance.setDuration(game.duration); |
||||
|
Level.of(config.level); |
||||
|
if (config.mode === 0) { |
||||
|
// 开始倒计时
|
||||
|
Count.of(countOver); |
||||
|
} else { |
||||
|
sevenClick(); |
||||
|
} |
||||
|
if (!window.soundInstance) return; |
||||
|
window.soundInstance.playBgm(); |
||||
|
} |
||||
|
|
||||
|
function playGame(data) { |
||||
|
if (state !== 1) return; |
||||
|
const { status, param } = data; |
||||
|
// config.currentScore = score;
|
||||
|
// config.currentTimes = times;
|
||||
|
state = status; |
||||
|
if (config.config.directions[config.currentTimes] === param.direction) { |
||||
|
main.play(param.direction); |
||||
|
} else { |
||||
|
alert('动作不匹配'); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
function pauseGame(data) { |
||||
|
if (state !== 1) return; |
||||
|
state = data.status; |
||||
|
window.suspend.show(); |
||||
|
window.timeInstance.pause(); |
||||
|
} |
||||
|
|
||||
|
function continueGame(data) { |
||||
|
if (state !== 3) return; |
||||
|
state = data.status; |
||||
|
window.suspend.hide(); |
||||
|
window.timeInstance.start(); |
||||
|
} |
||||
|
|
||||
|
function finishGame(data) { |
||||
|
const { score, times, status, param } = data; |
||||
|
state = status; |
||||
|
// config.total = score;
|
||||
|
// config.times = times;
|
||||
|
End.of(score || 0); |
||||
|
window.timeInstance.setDuration(0); |
||||
|
} |
||||
|
}, |
||||
|
false, |
||||
|
); |
||||
|
|
||||
|
// 发消息
|
||||
|
function sendMessage(data) { |
||||
|
if (!data) { |
||||
|
return alert('错误: 发送消息数据为空'); |
||||
|
} |
||||
|
console.log('子->发送: ', data); |
||||
|
top.postMessage(data, document.referrer); |
||||
|
} |
||||
|
|
||||
|
// 发送继续游戏消息
|
||||
|
function continueMessage() { |
||||
|
const data = { |
||||
|
event: 'continue', |
||||
|
data: { |
||||
|
status: 1, // 1 -> 进行中
|
||||
|
}, |
||||
|
}; |
||||
|
sendMessage(data); |
||||
|
} |
||||
|
|
||||
|
// 发送游戏结束消息
|
||||
|
function finishMessage(score, times) { |
||||
|
const data = { |
||||
|
event: 'finish', |
||||
|
data: { |
||||
|
score: score, // 得分
|
||||
|
times: times, // 次数
|
||||
|
status: 2, // 游戏状态 0 1 2
|
||||
|
param: {}, // 额外个性化参数
|
||||
|
}, |
||||
|
}; |
||||
|
sendMessage(data); |
||||
|
} |
||||
|
|
||||
|
// 发送再来一次消息
|
||||
|
function againMessage() { |
||||
|
const data = { |
||||
|
event: 'again', |
||||
|
data: { |
||||
|
param: {}, // 额外个性化参数
|
||||
|
}, |
||||
|
}; |
||||
|
sendMessage(data); |
||||
|
} |
@ -0,0 +1,57 @@ |
|||||
|
// 判断是否在演示模式 能否直接开始游戏
|
||||
|
function isHash() { |
||||
|
if (location.hash && location.hash === '#p') { |
||||
|
isDemo = true; |
||||
|
Demo.of(); |
||||
|
Count.of(countOver); |
||||
|
} else { |
||||
|
// 连点7次触发倒计时
|
||||
|
startGame(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
function startGame() { |
||||
|
var count = 0, |
||||
|
timer; |
||||
|
document.onclick = function () { |
||||
|
if (isDemo || config.mode !== 1) return; |
||||
|
if (count < 6) { |
||||
|
if (timer) { |
||||
|
clearTimeout(timer); |
||||
|
} |
||||
|
count++; |
||||
|
timer = setTimeout(function () { |
||||
|
count = 0; |
||||
|
}, 300); |
||||
|
} else if (count === 6) { |
||||
|
count = 0; |
||||
|
clearTimeout(timer); |
||||
|
sevenClick(); |
||||
|
} |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
function sevenClick() { |
||||
|
isDemo = true; |
||||
|
Count.of(countOver); |
||||
|
addHash(); |
||||
|
} |
||||
|
|
||||
|
// 倒计时结束 开始游戏
|
||||
|
function countOver() { |
||||
|
timeInstance.start(); |
||||
|
} |
||||
|
|
||||
|
// 添加hash值
|
||||
|
function addHash() { |
||||
|
location.hash = '#p'; |
||||
|
Demo.of(); |
||||
|
} |
||||
|
|
||||
|
function test() { |
||||
|
document.addEventListener('click', () => { |
||||
|
if (!isDemo) return; |
||||
|
main.play(config.config.directions[config.currentTimes]); |
||||
|
}); |
||||
|
} |
||||
|
test(); |
Loading…
Reference in new issue