Browse Source

init

master
wally 4 years ago
commit
2de2f54d5b
  1. 108
      .gitignore
  2. 13
      .prettierrc
  3. 5
      .svrxrc.js
  4. 324
      README.md
  5. BIN
      RECOVER_tomato-right.fla
  6. BIN
      images/_preloader.gif
  7. BIN
      images/tomato_right_atlas_1.png
  8. BIN
      images/tomato_right_atlas_10.png
  9. BIN
      images/tomato_right_atlas_11.png
  10. BIN
      images/tomato_right_atlas_12.png
  11. BIN
      images/tomato_right_atlas_2.png
  12. BIN
      images/tomato_right_atlas_3.png
  13. BIN
      images/tomato_right_atlas_4.png
  14. BIN
      images/tomato_right_atlas_5.png
  15. BIN
      images/tomato_right_atlas_6.png
  16. BIN
      images/tomato_right_atlas_7.png
  17. BIN
      images/tomato_right_atlas_8.png
  18. BIN
      images/tomato_right_atlas_9.png
  19. BIN
      images/番茄炒蛋_右手)_1_atlas_1.png
  20. BIN
      images/番茄炒蛋_右手)_1_atlas_10.png
  21. BIN
      images/番茄炒蛋_右手)_1_atlas_11.png
  22. BIN
      images/番茄炒蛋_右手)_1_atlas_12.png
  23. BIN
      images/番茄炒蛋_右手)_1_atlas_2.png
  24. BIN
      images/番茄炒蛋_右手)_1_atlas_3.png
  25. BIN
      images/番茄炒蛋_右手)_1_atlas_4.png
  26. BIN
      images/番茄炒蛋_右手)_1_atlas_5.png
  27. BIN
      images/番茄炒蛋_右手)_1_atlas_6.png
  28. BIN
      images/番茄炒蛋_右手)_1_atlas_7.png
  29. BIN
      images/番茄炒蛋_右手)_1_atlas_8.png
  30. BIN
      images/番茄炒蛋_右手)_1_atlas_9.png
  31. BIN
      images/番茄炒蛋_右手)_HTML5 Canvas_atlas_1.png
  32. BIN
      images/番茄炒蛋_右手)_HTML5 Canvas_atlas_10.png
  33. BIN
      images/番茄炒蛋_右手)_HTML5 Canvas_atlas_11.png
  34. BIN
      images/番茄炒蛋_右手)_HTML5 Canvas_atlas_12.png
  35. BIN
      images/番茄炒蛋_右手)_HTML5 Canvas_atlas_2.png
  36. BIN
      images/番茄炒蛋_右手)_HTML5 Canvas_atlas_3.png
  37. BIN
      images/番茄炒蛋_右手)_HTML5 Canvas_atlas_4.png
  38. BIN
      images/番茄炒蛋_右手)_HTML5 Canvas_atlas_5.png
  39. BIN
      images/番茄炒蛋_右手)_HTML5 Canvas_atlas_6.png
  40. BIN
      images/番茄炒蛋_右手)_HTML5 Canvas_atlas_7.png
  41. BIN
      images/番茄炒蛋_右手)_HTML5 Canvas_atlas_8.png
  42. BIN
      images/番茄炒蛋_右手)_HTML5 Canvas_atlas_9.png
  43. BIN
      images/番茄炒鸡蛋1.jpg
  44. 47
      index.html
  45. 27
      js/classes/back.js
  46. 88
      js/classes/count.js
  47. 59
      js/classes/end.js
  48. 34
      js/classes/level.js
  49. 56
      js/classes/main.js
  50. 31
      js/classes/sound.js
  51. 105
      js/classes/time.js
  52. 28
      js/custom.js
  53. 51
      js/index.js
  54. 7
      js/test.js
  55. 19
      libs/1.0.0/createjs.min.js
  56. BIN
      tomato-right.fla
  57. 80
      tomato-right.html
  58. 1921
      tomato-right.js
  59. BIN
      恢复_tomato-right.fla

108
.gitignore

@ -0,0 +1,108 @@
# 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/

13
.prettierrc

@ -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"
}

5
.svrxrc.js

@ -0,0 +1,5 @@
module.exports = {
port: 3000,
https: false,
// registry: 'https://registry.npm.taobao.org',
}

324
README.md

@ -0,0 +1,324 @@
# 鸟妈妈回家
## 游戏介绍
“鸟妈妈回家”游戏用于 康复训练,上肢训练
游戏使用Adobe Animate制作,游戏包含如下几个模块:
+ 主体:鸟、背景(山、云朵、树木等)、成功次数(也能代表得分)
+ 开始倒计时:开始面板、倒计时文本
+ 返回按钮
+ 难度级别
+ 游戏计时
+ 结束modal:界面面板、得分文本
+ 测试模块
该游戏源文件,使用旧版的flash软件制作,转换成animate支持的canvas模式。
游戏原有动画均在图层中制作。包括游戏动作成功的字数,也在动画中制作。游戏动作设计调整难度较大,次数修改成本较高。目前是固定的20次,一般情况是够用。
## 目录结构说明
```bash
.
├── README.md
├── bird.html
├── bird.js
├── images
│   ├── Bitmap1.png
│   ├── Bitmap2.png
│   ├── Bitmap3.png
│   ├── Bitmap4.png
│   ├── Bitmap5.png
│   ├── _preloader.gif
│   ├── level.png
│   ├── 任务完成_.png
│   ├── 倒计时_.png
│   ├── 树林前景_.png
│   ├── 计时_.png
│   └── 返回按钮_.png
├── index.html
├── js
│   ├── classes
│   │   ├── back.js
│   │   ├── bird.js
│   │   ├── count.js
│   │   ├── end.js
│   │   ├── level.js
│   │   ├── sound.js
│   │   └── time.js
│   ├── custom.js
│   ├── index.js
│   └── test.js
├── libs
│   └── 1.0.0
│   └── createjs.min.js
├── sounds
│   ├── amazing.mp3
│   ├── bgmMusic.mp3
│   ├── excitationMusic.mp3
│   └── unbelievable.mp3
└── 鸟妈妈回家_HTML5 Canvas.fla
```
| 文件 | 说明 | 备注 |
| ------------------- | ------------------------------------------------------------ | ----------------------------------------------- |
| 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="js/index.js"></script>
<script src="js/custom.js"></script>
<script src="js/classes/bird.js"></script>
<script src="js/classes/count.js"></script>
<script src="js/classes/back.js"></script>
<script src="js/classes/time.js"></script>
<script src="js/classes/level.js"></script>
<script src="js/classes/sound.js"></script>
<script src="js/classes/end.js"></script>
<script src="js/test.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>
<div style="position: fixed; top: 0; left: 0; z-index: 999;padding: 20px">
<h3>测试功能区</h3>
<button onclick="Count.of()">开始倒计时</button>
<button onclick="timeInstance.start()">开始游戏</button>
<button>结束游戏</button>
</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; 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.bird = Bird.of(gameOver); // 初始化鸟等
window.timeInstance = Time.of(gameOver); // 初始化游戏时间
// window.soundInstance = Sound.of(); // 初始化音频
Level.of(2); // 游戏难度级别
Back.of(); // 返回按钮
}
// 游戏结束 显示结束得分面板
function gameOver() {
state = 2;
const times = bird.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工程化打包构建等,避免源代码暴露,代码体积、模块导入引用等都能得到好的提升

BIN
RECOVER_tomato-right.fla

Binary file not shown.

BIN
images/_preloader.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

BIN
images/tomato_right_atlas_1.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

BIN
images/tomato_right_atlas_10.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 214 KiB

BIN
images/tomato_right_atlas_11.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 KiB

BIN
images/tomato_right_atlas_12.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 437 KiB

BIN
images/tomato_right_atlas_2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

BIN
images/tomato_right_atlas_3.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

BIN
images/tomato_right_atlas_4.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

BIN
images/tomato_right_atlas_5.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

BIN
images/tomato_right_atlas_6.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

BIN
images/tomato_right_atlas_7.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

BIN
images/tomato_right_atlas_8.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

BIN
images/tomato_right_atlas_9.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

BIN
images/番茄炒蛋_右手)_1_atlas_1.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

BIN
images/番茄炒蛋_右手)_1_atlas_10.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 214 KiB

BIN
images/番茄炒蛋_右手)_1_atlas_11.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 KiB

BIN
images/番茄炒蛋_右手)_1_atlas_12.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 324 KiB

BIN
images/番茄炒蛋_右手)_1_atlas_2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

BIN
images/番茄炒蛋_右手)_1_atlas_3.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

BIN
images/番茄炒蛋_右手)_1_atlas_4.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

BIN
images/番茄炒蛋_右手)_1_atlas_5.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

BIN
images/番茄炒蛋_右手)_1_atlas_6.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

BIN
images/番茄炒蛋_右手)_1_atlas_7.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

BIN
images/番茄炒蛋_右手)_1_atlas_8.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

BIN
images/番茄炒蛋_右手)_1_atlas_9.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

BIN
images/番茄炒蛋_右手)_HTML5 Canvas_atlas_1.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

BIN
images/番茄炒蛋_右手)_HTML5 Canvas_atlas_10.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 214 KiB

BIN
images/番茄炒蛋_右手)_HTML5 Canvas_atlas_11.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 KiB

BIN
images/番茄炒蛋_右手)_HTML5 Canvas_atlas_12.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 346 KiB

BIN
images/番茄炒蛋_右手)_HTML5 Canvas_atlas_2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

BIN
images/番茄炒蛋_右手)_HTML5 Canvas_atlas_3.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

BIN
images/番茄炒蛋_右手)_HTML5 Canvas_atlas_4.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

BIN
images/番茄炒蛋_右手)_HTML5 Canvas_atlas_5.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

BIN
images/番茄炒蛋_右手)_HTML5 Canvas_atlas_6.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

BIN
images/番茄炒蛋_右手)_HTML5 Canvas_atlas_7.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

BIN
images/番茄炒蛋_右手)_HTML5 Canvas_atlas_8.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

BIN
images/番茄炒蛋_右手)_HTML5 Canvas_atlas_9.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

BIN
images/番茄炒鸡蛋1.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 612 KiB

47
index.html

@ -0,0 +1,47 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="authoring-tool" content="Adobe_Animate_CC">
<title>tomato-right</title>
<style>
html {background-color: #000}
#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="tomato-right.js"></script>
<script src="js/index.js"></script>
<script src="js/custom.js"></script>
<script src="js/classes/main.js"></script>
<script src="js/classes/count.js"></script>
<script src="js/classes/back.js"></script>
<script src="js/classes/time.js"></script>
<script src="js/classes/level.js"></script>
<script src="js/classes/sound.js"></script>
<script src="js/classes/end.js"></script>
<script src="js/test.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>
<div style="position: fixed; top: 0; left: 0; z-index: 999;padding: 20px">
<h3>测试功能区</h3>
<button onclick="Count.of()">开始倒计时</button>
<button onclick="timeInstance.start()">开始游戏</button>
<button>结束游戏</button>
</div>
</body>
</html>

27
js/classes/back.js

@ -0,0 +1,27 @@
function Back() {
this.lib = library;
this.back = null;
}
Back.of = function () {
const 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');
};

88
js/classes/count.js

@ -0,0 +1,88 @@
// 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 库对象
*/
function Count(startTime = Date.now(), defaultCount = config.count || 5) {
this.default = defaultCount;
this.startTime = startTime;
this.modal = null;
this.text = null;
this.timer = null;
this.lib = library;
}
/**
* 静态方法 封装new init方法
* 使用时直接调用此方法
* @param {number} defaultCount 倒计时时长
* @returns
*/
Count.of = function (defaultCount) {
const instance = new Count(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) {
console.log(time);
// 发送倒计时结束的消息
clearInterval(this.timer);
stage.removeChild(this.text);
stage.removeChild(this.modal);
// sendEndCountRequest(); // 发送倒计时结束的消息
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);
};

59
js/classes/end.js

@ -0,0 +1,59 @@
/**
* 游戏结束
* @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 (score) {
const instance = new End(score);
instance.init();
return instance;
};
// 初始化
End.prototype.init = function () {
this.renderModal();
this.renderText(this.score);
};
// 渲染背景面板
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);
};

34
js/classes/level.js

@ -0,0 +1,34 @@
/**
* 难度等级类
* @param {number} level 等级数字代码
*/
function Level(level = config.level || 1) {
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);
};

56
js/classes/main.js

@ -0,0 +1,56 @@
/**
* 游戏主体
* @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 (endCallback, max = config.times) {
const 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 () {
if (Date.now() - this.prevTime <= 2000 || state !== 1) return;
this.element.play();
this.times += 1;
this.prevTime = Date.now();
if (this.times >= this.max) {
this.times = this.max;
this.endCallback();
}
console.log('this.times: ', this.times);
};

31
js/classes/sound.js

@ -0,0 +1,31 @@
// 音频处理类
function Sound() {
this.lib = library;
this.music = {};
}
Sound.of = function () {
const instance = new Sound();
instance.init();
return instance;
};
Sound.prototype.init = function () {
createjs.Sound.alternateExtensions = ['mp3'];
const sounds = [
{ src: 'sounds/bgmMusic.mp3', id: 'bgm' },
{ src: 'sounds/excitationMusic.mp3', id: 'excitation' },
{ src: 'sounds/amazing.mp3', id: 'amazing' },
{ src: 'sounds/unbelievable.mp3', id: 'unbelievable' },
];
createjs.Sound.addEventListener('fileload', function (event) {
console.log('event: ', event);
this.music[event.id] = createjs.Sound.createInstance(event.id);
});
createjs.Sound.registerSounds(sounds, '../../');
};
Sound.prototype.playBgm = function () {
this.music.bgm && this.music.bgm.play({ loop: -1, volume: 0.3 }); // 播放背景音乐
};

105
js/classes/time.js

@ -0,0 +1,105 @@
/**
* 游戏时长 计时
* @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);
};

28
js/custom.js

@ -0,0 +1,28 @@
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);
}

51
js/index.js

@ -0,0 +1,51 @@
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('2B30B07054B0CF48B3232A903ABD7650');
var lib = comp.getLibrary();
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.tomatoright();
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();
}

7
js/test.js

@ -0,0 +1,7 @@
function test() {
document.addEventListener('click', () => {
main.play();
});
}
test();

19
libs/1.0.0/createjs.min.js

File diff suppressed because one or more lines are too long

BIN
tomato-right.fla

Binary file not shown.

80
tomato-right.html

@ -0,0 +1,80 @@
<!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>tomato-right</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="tomato-right.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("2B30B07054B0CF48B3232A903ABD7650");
var lib=comp.getLibrary();
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.tomatoright();
stage = new lib.Stage(canvas);
//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>

1921
tomato-right.js

File diff suppressed because it is too large

BIN
恢复_tomato-right.fla

Binary file not shown.
Loading…
Cancel
Save