Commit 7d71f787 authored by Friends233's avatar Friends233

外部通信

parent 6ce3a256
......@@ -581,7 +581,7 @@
"_is3DNode": false,
"_groupIndex": 0,
"groupIndex": 0,
"_id": "07ZQOj+O5DupSUzq6wJ1x1"
"_id": "15/k8hSCpMn5yTkRNsd7E6"
},
{
"__type__": "cc.Sprite",
......@@ -611,7 +611,7 @@
"_fillRange": 0,
"_isTrimmedMode": true,
"_atlas": null,
"_id": "0djeEpGbJNXrPz0cbF9Itp"
"_id": "85fZTJn5FPIodAbSeEnovO"
},
{
"__type__": "7c5ffhlHDpBpoDQ8wfKN7pu",
......@@ -764,7 +764,7 @@
"__type__": "TypedArray",
"ctor": "Float64Array",
"array": [
-152,
-167,
392.553,
0,
0,
......@@ -2349,7 +2349,7 @@
"_is3DNode": false,
"_groupIndex": 0,
"groupIndex": 0,
"_id": "14FuV4E4pKcJXoee/woO9W"
"_id": "beEXxWtEdHO733goHkm2rf"
},
{
"__type__": "cc.Sprite",
......@@ -2379,7 +2379,7 @@
"_fillRange": 0,
"_isTrimmedMode": true,
"_atlas": null,
"_id": "1dmEUoDDFGSr1H3zBl57qz"
"_id": "dazdKb2qVJKo9zqBV0DE+R"
},
{
"__type__": "cc.Node",
......@@ -2441,7 +2441,7 @@
"_is3DNode": false,
"_groupIndex": 0,
"groupIndex": 0,
"_id": "4cuxTEbehCsJYSCSHpIpH/"
"_id": "94CD8dim1Js7UBKY999Q4K"
},
{
"__type__": "cc.Sprite",
......@@ -2471,7 +2471,7 @@
"_fillRange": 0,
"_isTrimmedMode": true,
"_atlas": null,
"_id": "cdmDsSacRKg6pcDEshTXfh"
"_id": "27JbCZHIFL+p6Vx9wQ+Bi2"
},
{
"__type__": "cc.Node",
......@@ -2533,7 +2533,7 @@
"_is3DNode": false,
"_groupIndex": 0,
"groupIndex": 0,
"_id": "3aOKea3k9BY4pPb9dmlQDV"
"_id": "aeiL0lx2FCb4TTXLUMToJp"
},
{
"__type__": "cc.Sprite",
......@@ -2563,7 +2563,7 @@
"_fillRange": 0,
"_isTrimmedMode": true,
"_atlas": null,
"_id": "23LPXn1BRFiItlEoT0OOmm"
"_id": "acy/c1iY5ABqNDyUzVA1Ap"
},
{
"__type__": "cc.Node",
......@@ -2625,7 +2625,7 @@
"_is3DNode": false,
"_groupIndex": 0,
"groupIndex": 0,
"_id": "5biWgPGa9LWIggHPTmoumk"
"_id": "4fWrjhYktAbJDUsbUd/8Zf"
},
{
"__type__": "cc.Sprite",
......@@ -2655,7 +2655,7 @@
"_fillRange": 0,
"_isTrimmedMode": true,
"_atlas": null,
"_id": "6aX2V3JMlN26khZTAyTodl"
"_id": "04cmGQjnJPVICj9Vbp0rHJ"
},
{
"__type__": "7c5ffhlHDpBpoDQ8wfKN7pu",
......@@ -3009,13 +3009,13 @@
"tag": 0,
"_offset": {
"__type__": "cc.Vec2",
"x": -1,
"y": -116.2
"x": 0.9,
"y": -122.9
},
"_size": {
"__type__": "cc.Size",
"width": 28.4,
"height": 54
"width": 41.4,
"height": 29.7
},
"_id": "00DUR/4UFGJZyF3VRt2QCn"
},
......@@ -3229,8 +3229,8 @@
],
"_srcBlendFactor": 770,
"_dstBlendFactor": 771,
"_string": "第关",
"_N$string": "第关",
"_string": "第关",
"_N$string": "第关",
"_fontSize": 22,
"_lineHeight": 22,
"_enableWrapText": true,
......@@ -3583,8 +3583,8 @@
],
"_srcBlendFactor": 770,
"_dstBlendFactor": 771,
"_string": "3/5",
"_N$string": "3/5",
"_string": "0/3",
"_N$string": "0/3",
"_fontSize": 24,
"_lineHeight": 24,
"_enableWrapText": true,
......
/** 关卡信息 */
export const LevelInfo = [
{ level: 1, countDown: 30, colors: ['#EC5F33', '#E52800', '#CA1D00'] }
{ level: 2, countDown: 30, colors: ['#FF9400', '#FF6C00', '#EC5F33', '#E52800', '#CA1D00'] }
{ level: 3, countDown: 30, colors: ['#FFD34A', '#FFC300', '#FFB637', '#FF9400', '#FF6C00', '#EC5F33', '#E52800', '#CA1D00'] }
{ level: 1, colors: ['#EC5F33', '#E52800', '#CA1D00'] }
{ level: 2, colors: ['#FF9400', '#FF6C00', '#EC5F33', '#E52800', '#CA1D00'] }
{ level: 3, colors: ['#FFD34A', '#FFC300', '#FFB637', '#FF9400', '#FF6C00', '#EC5F33', '#E52800', '#CA1D00'] }
]
export const CUSTOM_EVENT = {
/** 爪子动画结束的回调 */
CLIP_ANI_END: 'CLIP_ANI_END',
/** 爪子碰撞 */
CLIP_COLLISION: 'CLIP_COLLISION'
CLIP_COLLISION: 'CLIP_COLLISION',
/** 游戏结束 */
GAME_OVER: 'GAME_OVER',
/** 下一关 */
NEXT_LEVEL: 'NEXT_LEVEL',
/** 过关 */
PASS_LEVEL: 'PASS_LEVEL',
/** 开始游戏 */
GAME_START: 'GAME_START'
}
export const Config = {
......@@ -34,6 +42,9 @@ export const Config = {
/** 普通道具每种最多生成数量 */
propsNum: 2,
/** 每关的游戏时间 */
countDowns: [30, 30, 30]
/** 道具分布图 4*3 */
propsMap: [
[
......
......@@ -6,6 +6,7 @@
// - https://docs.cocos.com/creator/2.4/manual/en/scripting/life-cycle-callbacks.html
import { CUSTOM_EVENT, Config, LevelInfo } from "./Config/GameConfig";
import exportEvent from "./exportEvent";
import { getProbability, getRandomArrayElements, loadGameResources, numToChinese, randomNum, set16ToRgb } from "./utils";
const { ccclass, property } = cc._decorator;
......@@ -70,8 +71,11 @@ export default class GameScene extends cc.Component {
/** 场面上剩余加分道具数量 */
surplusStar = Config.bestPropsNum
/** 游戏配置 */
gameConfig = {...Config}
protected onLoad(): void {
// loadGameResources()
loadGameResources()
/** 开启碰撞检测 */
const cm = cc.director.getCollisionManager()
cm.enabled = true
......@@ -81,21 +85,25 @@ export default class GameScene extends cc.Component {
start() {
this.clip = cc.find('clipMask/clipWrp/clip', this.node)
this.resetConfig()
this.refreshLevelInfo()
this.refreshStageProps()
this.addNodeEvent()
}
/** 重置游戏设置 */
resetConfig() {
this.clipSpeed = Config.normalPropSpeed
this.surplusStar = Config.bestPropsNum
this.clip.getChildByName('line').height = Config.maxLong
/**
* 重置游戏配置
* @param con 游戏配置
*/
resetConfig(con={}) {
this.gameConfig = {
...Config,
...con
}
this.clipSpeed = this.gameConfig.normalPropSpeed
this.surplusStar = this.gameConfig.bestPropsNum
this.clip.getChildByName('line').height = this.gameConfig.maxLong
const rotationAni = cc.find('clipMask/clipWrp', this.node)
.getComponent(cc.Animation)
.getAnimationState('clipRation')
rotationAni.speed = Config.rotationSpeed
rotationAni.speed = this.gameConfig.rotationSpeed
}
/** 爪子碰撞事件 */
......@@ -103,7 +111,7 @@ export default class GameScene extends cc.Component {
const other: cc.Collider = detail.other
this.clipTarget = other.node
this.clipSpeed = other.tag == 1 ? Config.bestPropSpeed : Config.normalPropSpeed
this.clipSpeed = other.tag == 1 ? this.gameConfig.bestPropSpeed : this.gameConfig.normalPropSpeed
this.setClipState(CLIP_STATE.STOP)
}
......@@ -113,6 +121,13 @@ export default class GameScene extends cc.Component {
gameBtn.on(cc.Node.EventType.TOUCH_END, this.playGame, this)
this.node.on(CUSTOM_EVENT.CLIP_ANI_END, this.onAnimCompleted, this)
this.node.on(CUSTOM_EVENT.CLIP_COLLISION, this.onCollEnter, this)
exportEvent.on(CUSTOM_EVENT.NEXT_LEVEL,this.nextLevel,this)
exportEvent.on(CUSTOM_EVENT.GAME_START,(config) => {
this.resetConfig(config)
this.refreshLevelInfo()
this.refreshStageProps()
},this)
// TODO 测试用
const href = window?.location?.href
const isTest = href?.includes('duibadev') || href?.includes('duibatest') || href?.includes('localhost')
......@@ -122,7 +137,6 @@ export default class GameScene extends cc.Component {
const testEventMap = {
next: 'nextLevel',
refreshProp: 'refreshStageProps',
addTime: 'addTime'
}
testNode.children.forEach((n) => {
const event = this?.[testEventMap[n.name]]
......@@ -192,6 +206,10 @@ export default class GameScene extends cc.Component {
this.isGameOver = true
this.setClipState(CLIP_STATE.GAME_OVER)
this.unschedule(this.startCd)
exportEvent.fire(CUSTOM_EVENT.GAME_OVER,{
score:this.starNum,
level:this.actLevel
})
}
/**
......@@ -207,7 +225,6 @@ export default class GameScene extends cc.Component {
const cd = this.countDown - 1 || 0
if (!cd || cd <= 0) {
this.setLable('cdIcon/cd', `0s`)
console.log('倒计时结束')
this.gameOver()
this.unschedule(this.startCd)
return
......@@ -227,7 +244,7 @@ export default class GameScene extends cc.Component {
this.starNum = 0
this.levelObjectives = LevelInfo[level].colors.length
this.actLevelInfo = LevelInfo[level]
this.countDown = this.actLevelInfo.countDown
this.countDown = this.gameConfig.countDowns[level] || 0
this.setLable('levelName', `第${numToChinese(level + 1)}关`)
this.setLable('starIcon/starProc', `${this.starNum}/${this.levelObjectives}`)
......@@ -255,7 +272,11 @@ export default class GameScene extends cc.Component {
this.setLable('starIcon/starProc', `${this.starNum}/${this.levelObjectives}`)
// 达到目标
if (this.starNum >= this.levelObjectives) {
this.nextLevel()
exportEvent.fire(CUSTOM_EVENT.PASS_LEVEL,{
score:this.starNum,
level:this.actLevel
})
// this.nextLevel()
}
}
......@@ -282,14 +303,14 @@ export default class GameScene extends cc.Component {
/** 刷新舞台道具 */
refreshStageProps() {
this.surplusStar = Config.bestPropsNum
this.surplusStar = this.gameConfig.bestPropsNum
const gameStage = cc.find('gameStage', this.node)
const stageProps: cc.Node[] = gameStage.children
const mapIdx = Math.floor(randomNum(0, Config.propsMap.length))
const mapIdx = Math.floor(randomNum(0, this.gameConfig.propsMap.length))
const stageMap: number[] = [...Config.propsMap[mapIdx]]
const stageMap: number[] = [...this.gameConfig.propsMap[mapIdx]]
// 生成加分道具
for (let i = 0; i < Config.bestPropsNum; i++) {
for (let i = 0; i < this.gameConfig.bestPropsNum; i++) {
// 随机取
let idx = Math.floor(randomNum(0, stageMap.length))
......@@ -300,7 +321,7 @@ export default class GameScene extends cc.Component {
}
// 随机道具池
let propsRandom = []
for (let i = 0; i < Config.propsNum; i++) {
for (let i = 0; i < this.gameConfig.propsNum; i++) {
propsRandom.push(...this.propItem)
}
// 剩余格子数量
......@@ -341,7 +362,7 @@ export default class GameScene extends cc.Component {
// 锚点跟爪子之间的大致距离
const offset = 41
const maxLong = Config.maxLong - offset
const maxLong = this.gameConfig.maxLong - offset
// 爪子出手
if (this.clipState == CLIP_STATE.PLAY) {
......@@ -349,14 +370,14 @@ export default class GameScene extends cc.Component {
this.setClipState(CLIP_STATE.STOP)
return
}
this.clip.y -= dt * Config.playSpeed
this.clip.y -= dt * this.gameConfig.playSpeed
}
// 爪子回收
if (this.clipState == CLIP_STATE.STOP) {
if (this.clip.y >= -offset) {
// 恢复初始速度
this.clipSpeed = Config.normalPropSpeed
this.clipSpeed = this.gameConfig.normalPropSpeed
this.setClipState(CLIP_STATE.DEFAULT)
return
}
......
class EventObject {
public type: string;
public target: EventCenterClass;
public detail: Object;
public timeStamp: Number;
constructor(type: string, target: EventCenterClass, detail: Object) {
this.type = type;
this.target = target;
this.detail = detail;
this.timeStamp = +new Date();
}
}
interface EventNameObj {
type: string;
};
type EventName = string | EventNameObj;
export class EventCenterClass {
private _listeners: Object
constructor() {
this._listeners = {}
}
/**
* 增加一个事件监听。
* @param type - 要监听的事件类型。
* @param listener - 事件监听回调函数。
* @param context - 上下文
* @param once - 是否是一次性监听,即回调函数响应一次后即删除,不再响应。
* @returns - 对象本身。链式调用支持。
*/
on<T>(type: string, listener: Function, context: T, once: boolean) {
let listeners: any;
listeners = (this._listeners = this._listeners || {});
const eventListeners = (listeners[type] = listeners[type] || []);
for (let i = 0, len = eventListeners.length; i < len; i++) {
const el = eventListeners[i];
if (el.listener === listener) return;
}
eventListeners.push({ listener, context, once });
return this;
}
/**
* 删除一个事件监听。如果不传入任何参数,则删除所有的事件监听;如果不传入第二个参数,则删除指定类型的所有事件监听。
* @param type - 要删除监听的事件类型。
* @param listener - 要删除监听的回调函数。
* @returns - 对象本身。链式调用支持。
*/
off(type: string, listener: Function) {
let listeners: any;
listeners = (this._listeners = this._listeners || {});
// remove all event listeners
if (arguments.length == 0) {
listeners = null;
return this;
}
const eventListeners = listeners && listeners[type];
if (eventListeners) {
// remove event listeners by specified type
if (arguments.length == 1) {
delete listeners[type];
return this;
}
for (let i = 0, len = eventListeners.length; i < len; i++) {
const el = eventListeners[i];
if (el.listener === listener) {
eventListeners.splice(i, 1);
if (eventListeners.length === 0) delete listeners[type];
break;
}
}
}
return this;
}
/**
* 发送事件。当第一个参数类型为Object时,则把它作为一个整体事件对象。
* @param type - 要发送的事件类型。
* @param detail - 要发送的事件的具体信息,即事件随带参数。
* @returns - 是否成功调度事件。
*/
fire(type: EventName, detail?: Object) {
let event;
let eventType;
if (typeof type === 'string') {
eventType = type;
} else {
event = type;
eventType = type.type;
}
const listeners: any = this._listeners;
if (!listeners) return false;
const eventListeners: any = listeners[eventType];
if (eventListeners) {
const eventListenersCopy = eventListeners.slice(0);
event = event || new EventObject(eventType, this, detail);
for (let i = 0; i < eventListenersCopy.length; i++) {
const el = eventListenersCopy[i];
el.listener.call(el.context, event);
if (el.once) {
const index = eventListeners.indexOf(el);
if (index > -1) {
eventListeners.splice(index, 1);
}
}
}
if (eventListeners.length == 0) delete listeners[eventType];
return true;
}
return false;
}
}
let exportEvent = new EventCenterClass()
export default exportEvent;
\ No newline at end of file
{
"ver": "1.1.0",
"uuid": "d252bfc3-9abd-472c-b0b7-93ce4bbdd2f9",
"importer": "typescript",
"isPlugin": false,
"loadPluginInWeb": true,
"loadPluginInNative": true,
"loadPluginInEditor": false,
"subMetas": {}
}
\ No newline at end of file
......@@ -21,6 +21,7 @@
"author": "爱德 <caoxingru@duiba.com.cn>",
"license": "MIT",
"dependencies": {
"@duiba/event-bus": "^1.0.0",
"ali-oss": "^6.17.1",
"chokidar": "^3.5.3",
"co": "^4.6.0",
......@@ -28,4 +29,4 @@
"progress": "^2.0.3",
"psd": "^3.2.0"
}
}
\ No newline at end of file
}
......@@ -2,6 +2,11 @@
# yarn lockfile v1
"@duiba/event-bus@^1.0.0":
version "1.0.0"
resolved "http://npm.dui88.com:80/@duiba%2fevent-bus/-/event-bus-1.0.0.tgz#dad13916893742ed6082ec3f6d17852e25ad7007"
integrity sha512-AHWKWw9gnXQUj/ar/MHeAhiSUCYZa8ii0FWmqOyAIengeTg6ILNtKjyanB6uH1BHKX7UMOYZETc1BiLbjq1jkw==
"@tootallnate/once@1":
version "1.1.2"
resolved "http://npm.dui88.com:80/@tootallnate%2fonce/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment