Commit 99c26aaa authored by 熊东起's avatar 熊东起

game

parents
# project ignores
node_modules
released
.DS_Store
scripts/copyJs.js
\ No newline at end of file
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>接食材</title>
<meta name="viewport" content="width=device-width,initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="full-screen" content="true" />
<meta name="screen-orientation" content="portrait" />
<meta name="x5-fullscreen" content="true" />
<meta name="360-fullscreen" content="true" />
<!-- <meta name="viewport" content="width=device-width,minimum-scale=1.0,user-scalable=no"> -->
<!-- <script src="https://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script> -->
<!-- 小程序分享得用这个 -->
<!-- <script src="https://res.wx.qq.com/open/js/jweixin-1.3.2.js"></script> -->
<!-- 易盾js -->
<!-- <script type="text/javascript" src="//cstaticdun.126.net/load.min.js"></script> -->
<!-- <script src="libs/zepto.min.js"></script> -->
<!-- <script src="libs/p2.js"></script> -->
<script src="libs/fyge.min.js"></script>
<script src="libs/svgaParser.min.js"></script>
<style>
html,
body {
padding: 0;
margin: 0;
border: 0;
width: 100%;
height: 100%;
overflow: hidden;
position: absolute;
/* background-color: #000000; */
}
</style>
</head>
<body>
<script src="output.js"></script>
<!-- <div id="__loading__" style="position:absolute;left:50%;top:50%;margin-left:-45px;color:#ffffff">拼命加载中...</div> -->
<!-- <img src="" id="img" /> -->
<div id="cusEngine" style="line-height:0;font-size:0">
<canvas id="canvas" style="width: 100%;height: 100%"></canvas>
</div>
</body>
<!-- 帧率检测 -->
<!-- <script src="libs/stats.js"></script> -->
<script>
window.addEventListener("load", function() {
//获取canvas
var canvas = document.getElementById("canvas");
canvas.width = document.body.clientWidth * (window.devicePixelRatio || 1)
canvas.height = document.body.clientHeight * (window.devicePixelRatio || 1)
var main = new MainPrizeFell(canvas,70);
// console.log(main.stage)
var mouseEvent = main.stage.onMouseEvent.bind(main.stage);
canvas.addEventListener("touchstart", mouseEvent, false);
canvas.addEventListener('touchmove', mouseEvent, false);
canvas.addEventListener('touchend', mouseEvent, false);
// localStorage.clear();
})
</script>
</html>
\ No newline at end of file
import { Main } from './Main';
Page({
//暂时先不用吧,有问题
data: {
},
onLoad(query) {
// 页面加载
console.info(`Page onLoad with query: ${JSON.stringify(query)}`);
},
onReady() {
return
my.development = true;
// my._createCanvas({
// id: 'canvas',
// success: (ccc) => {
// const dpr = my.getSystemInfoSync().pixelRatio
// const windowWidth = my.getSystemInfoSync().windowWidth;
// const windowHeight = my.getSystemInfoSync().windowHeight;
// ccc.width = windowWidth * dpr;
// ccc.height = windowHeight * dpr;
// // const context = canvas.getContext("2d");
// console.log(ccc.width, ccc.height, dpr)
// //初始化
// FYGE.initedByCanvas(ccc);
// //测试
// var aa = ccc.createImage();
// aa.src = "https://yun.duiba.com.cn/db_games/activity/etc/optionImages/%E5%8D%8E%E4%B8%BAP30.jpg";
// console.log(aa)
// //帧率控制
// FYGE.Stage.addFPS("canva4stats")
// this.main = new Main(ccc)
// console.log(ccc.width, ccc.height)
// }
// })
},
onCanvasReady() {
my.development = true;
my._createCanvas({
id: 'canvas',
success: (ccc) => {
const dpr = my.getSystemInfoSync().pixelRatio
const windowWidth = my.getSystemInfoSync().windowWidth;
const windowHeight = my.getSystemInfoSync().windowHeight;
ccc.width = windowWidth * dpr;
ccc.height = windowHeight * dpr;
this.main = new Main(ccc)
}
})
},
onShow() {
// 页面显示
// FYGE.Stage.pause = false
if (this.main) this.main.run();
},
onHide() {
// 页面隐藏
// FYGE.Stage.pause = true
if (this.main) this.main.pause();
},
onUnload() {
// 页面被关闭
// Stage.stop()
this.main.destroy();
},
onTitleClick() {
// 标题被点击
},
onPullDownRefresh() {
// 页面被下拉
},
onReachBottom() {
// 页面被拉到底部
},
onShareAppMessage() {
// 返回自定义分享信息
return {
title: 'My App',
desc: 'My App description',
path: 'pages/index/index',
};
},
log(e) {
if (this.main) this.main.stage.onMouseEvent(e)
},
});
This source diff could not be displayed because it is too large. You can view the blob instead.
declare module SvgaParser {
/**
* 加载方法
* @param url 资源路径
* @param success
* @param failure
*/
export function loadSvga(url: string, success: (videoItem: VideoEntity) => void, failure?: (err: string) => void): void;
/**
* 导出只是当作类型接口用
*/
export interface VideoEntity {
/**
* SVGA 文件版本
*/
version: string;
/**
* 影片尺寸
*/
videoSize: {
width: number;
height: number;
};
/**
* 帧率,60,30等每秒
*/
FPS: number;
/**
* 总帧数
*/
frames: number;
/**
* base64图片数据记录
*/
images: {
[key: string]: string
};
/**
* 图片是否已被缓存,缓存全局,注意名字覆盖
*/
hasBeenCached: boolean;
/**
* sprite对象数据
*/
sprites: SpriteEntity[];
}
interface SpriteEntity {
/**
* 标识
*/
matteKey: string;
/**
* 图片key值
*/
imageKey: string;
/**
* 帧数据数组
*/
frames: FrameEntity[];
}
/**
* 还有很多其他数据,暂不需要,比如矢量路径和遮罩路径暂时都无
*/
interface FrameEntity {
/**
* 透明度
*/
alpha: number;
/**
* 2维矩阵数据
*/
transform: {
a: number,
b: number,
c: number,
d: number,
tx: number,
ty: number,
};
}
}
declare module "svga-parser" { export = SvgaParser; }
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
var Stats = function () {
var startTime = Date.now(), prevTime = startTime;
var ms = 0, msMin = Infinity, msMax = 0;
var fps = 0, fpsMin = Infinity, fpsMax = 0;
var frames = 0, mode = 0;
var container = document.createElement('div');
container.id = 'stats';
container.addEventListener('mousedown', function (event) { event.preventDefault(); setMode(++mode % 2) }, false);
container.style.cssText = 'width:80px;opacity:0.9;cursor:pointer';
var fpsDiv = document.createElement('div');
fpsDiv.id = 'fps';
fpsDiv.style.cssText = 'padding:0 0 3px 3px;text-align:left;background-color:#002';
container.appendChild(fpsDiv);
var fpsText = document.createElement('div');
fpsText.id = 'fpsText';
fpsText.style.cssText = 'color:#0ff;font-family:Helvetica,Arial,sans-serif;font-size:9px;font-weight:bold;line-height:15px';
fpsText.innerHTML = 'FPS';
fpsDiv.appendChild(fpsText);
var fpsGraph = document.createElement('div');
fpsGraph.id = 'fpsGraph';
fpsGraph.style.cssText = 'position:relative;width:74px;height:30px;background-color:#0ff';
fpsDiv.appendChild(fpsGraph);
while (fpsGraph.children.length < 74) {
var bar = document.createElement('span');
bar.style.cssText = 'width:1px;height:30px;float:left;background-color:#113';
fpsGraph.appendChild(bar);
}
var msDiv = document.createElement('div');
msDiv.id = 'ms';
msDiv.style.cssText = 'padding:0 0 3px 3px;text-align:left;background-color:#020;display:none';
container.appendChild(msDiv);
var msText = document.createElement('div');
msText.id = 'msText';
msText.style.cssText = 'color:#0f0;font-family:Helvetica,Arial,sans-serif;font-size:9px;font-weight:bold;line-height:15px';
msText.innerHTML = 'MS';
msDiv.appendChild(msText);
var msGraph = document.createElement('div');
msGraph.id = 'msGraph';
msGraph.style.cssText = 'position:relative;width:74px;height:30px;background-color:#0f0';
msDiv.appendChild(msGraph);
while (msGraph.children.length < 74) {
var bar = document.createElement('span');
bar.style.cssText = 'width:1px;height:30px;float:left;background-color:#131';
msGraph.appendChild(bar);
}
var setMode = function (value) {
mode = value;
switch (mode) {
case 0:
fpsDiv.style.display = 'block';
msDiv.style.display = 'none';
break;
case 1:
fpsDiv.style.display = 'none';
msDiv.style.display = 'block';
break;
}
}
var updateGraph = function (dom, value) {
var child = dom.appendChild(dom.firstChild);
child.style.height = value + 'px';
}
return {
REVISION: 11,
domElement: container,
setMode: setMode,
begin: function () {
startTime = Date.now();
},
end: function () {
var time = Date.now();
ms = time - startTime;
msMin = Math.min(msMin, ms);
msMax = Math.max(msMax, ms);
msText.textContent = ms + ' MS (' + msMin + '-' + msMax + ')';
updateGraph(msGraph, Math.min(30, 30 - (ms / 200) * 30));
frames++;
if (time > prevTime + 1000) {
fps = Math.round((frames * 1000) / (time - prevTime));
fpsMin = Math.min(fpsMin, fps);
fpsMax = Math.max(fpsMax, fps);
fpsText.textContent = fps + ' FPS (' + fpsMin + '-' + fpsMax + ')';
updateGraph(fpsGraph, Math.min(30, 30 - (fps / 100) * 30));
prevTime = time;
frames = 0;
}
return time;
},
update: function () {
startTime = this.end();
}
}
};
//执行
var stats = new Stats();
stats.domElement.style.position = 'absolute';
stats.domElement.style.top = '0px';
document.body.appendChild(stats.domElement);
aa();
function aa() {
stats.update();
requestAnimationFrame(aa)
}
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
const path = require('path');
const config = {
"/projectx/projectId/scoring_1/submit.do": {
data: './json/finalSubmit.json'
}
}
for (let item in config) {
/* let key = item.replace(new RegExp("{", "g"), "");
key = key.replace(new RegExp("}", "g"), "");
config[key] = config[item]; */
if (config.hasOwnProperty(item))
config[item].path = path.resolve(__dirname, config[item].data);
}
module.exports = config;
\ No newline at end of file
{
"success": true,
"code": "000",
"data": {
"score": 3456
},
"message": "no"
}
\ No newline at end of file
interface ResData {
/**
* 分组数据
*/
groups: GroupInt[];
//暂时没有工具,不用
resources?: any;
path?: string;
}
interface GroupInt {
/**
* 所有的资源名字,根据,分割,根据后缀区分类型
*
*/
keys: string;//"aa.png,bb.jpg,name.json"
/**
* 文件夹名字吧
*/
name: string;
/**
* 图集
* 线上打包合图可能有多张,暂时发现texturePacker版本问题只有一张
*/
atlas: {
[name: string]: {
"x": number,
"y": number,
"w": number,
"h": number,
"ox": number,
"oy": number,
"sw": number,
"sh": number,
"ro": boolean
},
};
}
/**
* 简单点,有工具的话像egret那样玩,可以自动生成图片组数据
*/
export namespace RES {
let resData: ResData
/**
* 资源路径
*/
export let resPath: string;
/**
* movieClip的ve数据
*/
let videoEntityHash: {
// [name: string]: FYGE.VideoEntity
} = {};
/**
* 音频的加载
*/
let soundHash = {}
/**
* 记录组加载完成
*/
let groupsCompleteHash: {
[name: string]: boolean
} = {}
/**
* 记录加载的promise
*/
let groupsPromiseHash: {
[name: string]: Promise<any>
} = {}
/**
* 单独资源加载的promise记录
*/
let singleResPromiseHash: {
[name: string]: Promise<any>
} = {}
/**
*
* @param res 资源数据,就是对象,不考虑加载json先
* res格式{
* path:1111/
* groups: [
* {
*
* }
* ];
* }
* @param path
*/
export function loadConfig(res) {
resData = res;
resPath = res.path;
}
/**
* 根据组名加载一组资源,通常用于加载一个视图的的所有资源
* 里的promise的resolve并没有返回值
* @param name
*/
export function loadGroup(name: string): Promise<any> {
//已经加载完成的直接返回
if (groupsCompleteHash[name]) {
return new Promise((resolve) => {
resolve()
})
}
//如果是正在加载中的,返回正在加载中的promise
if (groupsPromiseHash[name]) {
return groupsPromiseHash[name];
}
//如果首次加载
//获取资源组
let arr = getGroupResByName(name);
//如果不存在arr,直接返回空p,且标记完成
if (!arr || !arr.length) {
groupsCompleteHash[name] = true;
return new Promise((resolve) => {
resolve()
})
}
// 建一个promise
let p = new Promise((resolve, reject) => {
loadResList((s) => {
//移除
delete groupsPromiseHash[name];
if (s) {
groupsCompleteHash[name] = true;
resolve()
} else {
reject();
}
}, arr/*, resPath + name*/)
})
groupsPromiseHash[name] = p;
return p;
}
/**
* var textue = await RES.getResAsync(str);
* @param str 可以是网络图片路径或键值
* @param comFun 加载回调
* @param thisObj this指向
*/
export function getResAsync(str: string, comFun?: (res: any, str: string) => void, thisObj?: any): Promise<any> {
str = str || "";
// var arr = str.split(".");
var type = str.substring(str.lastIndexOf(".") + 1, str.length);
//如果是图片
if (type == "png" || type == "jpg") {
//原先就有了,加载过的,且已加载完成的
if (FYGE.TextureCache[str]) {
//回调形式
comFun && comFun.call(thisObj, FYGE.TextureCache[str], str)
// return FYGE.TextureCache[str];
new Promise((r) => {
r(FYGE.TextureCache[str])
})
}
//未加载完成的
else if (singleResPromiseHash[str]) {
return returnSingleResPromise(str, comFun, thisObj)
}
else {
//判断是否在资源里,判断是否要加载图集,注意已排除jpg
var groupName = hasRes(str);
if (groupName && type != "jpg") {
var group = getGroupByName(groupName);
if (group && group.atlas) {
//加载图集,现在就一张,以后有机会改
var json = groupName + ".json"//group.atlas.split(",")[0];
//找json是否在加载中
if (singleResPromiseHash[json]) {
return singleResPromiseHash[json].then(
(r) => {
//只返回需要的
comFun && comFun.call(thisObj, FYGE.TextureCache[str], str)
return FYGE.TextureCache[str]
},
() => {
comFun && comFun.call(thisObj, null, str)
return null
}
)
} else {
return getResAsync(json)
.then(() => {
comFun && comFun.call(thisObj, FYGE.TextureCache[str], str)
return FYGE.TextureCache[str]
}, () => {
comFun && comFun.call(thisObj, null, str)
return null
})
}
}
}
var src = groupName ? resPath + groupName + "/" + str : str;
var p = new Promise((resolve, reject) => {
FYGE.GlobalLoader.loadImage((s, image) => {
//移除
delete singleResPromiseHash[str];
//入缓存
if (s) {
//@ts-ignore
FYGE.Texture.addToCache(FYGE.Texture.from(image), str);
comFun && comFun.call(thisObj, FYGE.TextureCache[str], str)
resolve(FYGE.TextureCache[str])
} else {
comFun && comFun.call(thisObj, null, str)
reject()
}
}, src)
})
singleResPromiseHash[str] = p
return p
}
}
else if (type == "svga") {//暂时不用,小程序时,也千万别把svga放入其他组,开发时和线上做区分
if (videoEntityHash[str]) {
comFun && comFun.call(thisObj, videoEntityHash[str], str)
return new Promise((r) => {
r(videoEntityHash[str])
})
}
//未加载完成的
else if (singleResPromiseHash[str]) {
return returnSingleResPromise(str, comFun, thisObj)
} else {
var groupName = hasRes(str);
var src = groupName ? resPath + groupName + "/" + str : str;
var p = new Promise((resolve, reject) => {
//@ts-ignore //以后要加
FYGE.GlobalLoader.loadSvga((s, v) => {
//移除
delete singleResPromiseHash[str];
//入缓存
if (s) {
if (s) videoEntityHash[str] = v;
comFun && comFun.call(thisObj, v, str)
resolve(v)
} else {
comFun && comFun.call(thisObj, null, str)
reject()
}
}, src)
})
singleResPromiseHash[str] = p;
return p
}
}
//json图集的话,不晓得用啥判断加载完成,所以不删除promise吧,其实json可能只是数据,不管先
else if (type == "json") {
if (singleResPromiseHash[str]) {
return returnSingleResPromise(str, comFun, thisObj)
} else {
var groupName = hasRes(str);//json现在肯定在内,暂时不能加载其他域名的json
var src = groupName ? resPath + groupName + "/" + str : str;
var p = new Promise((resolve, reject) => {
var jsonData = getGroupByName(groupName).atlas
FYGE.GlobalLoader.loadImage((s, data) => {
if (s) {
var t = FYGE.createTextureSheet(new FYGE.BaseTexture(data/*.img*/), jsonData)
comFun && comFun.call(thisObj, t, str)
resolve(t)
} else {
//加载失败,移除要,否则再次触发加载会出问题
delete singleResPromiseHash[str];
comFun && comFun.call(thisObj, null, str)
reject()
}
}, src.replace("json", "png"))
})
singleResPromiseHash[str] = p
return p
}
}
}
/**
* 待写,根据网络路径加载图片
*/
export function getResByUrl() {
}
/**
* 获取素材,
* @param str
* @return 已加载好得素材或null
*/
export function getRes(str: string)/*: Texture | VideoEntity*/ {
str = str || "";
var type = str.substring(str.lastIndexOf(".") + 1, str.length);
if (type == "png" || type == "jpg") {
return FYGE.TextureCache[str] || null;
}
else if (type == "svga") {
return videoEntityHash[str] || null;
}
else if (type == "mp3") {
return soundHash[str] || null;
}
}
/**
* 判断是否在资源组里
* 考虑是否init就做表
* 有就返回组名,为了加载路径,不然以后有工具可以放入resources
*/
function hasRes(str: string): string {
for (var i = 0; i < resData.groups.length; i++) {
var group = resData.groups[i];
var keys = group.keys;
if (keys && keys.split(",").indexOf(str) > -1) {
return group.name;
}
//如果是图集的json,altas现在是图集
if (group.atlas && group.name + ".json" == str) {
return group.name;
}
}
return null
}
/**
* 处理数据,获得所有资源单项
* @param name
*/
function getGroupResByName(name: string) {
var group: GroupInt = getGroupByName(name);
if (!group) return null;
//判断加载图集还是单图
if (group.atlas) {
// var arr: string[] = [].concat(group.atlas.split(","));
var arr = [name + ".json"]
//再添加非图片的资源,和图集已排除jpg
if (group.keys) {
arr = arr.concat(group.keys.split(",").filter((k: string) => {
return k.substr(-4) != ".png" //&& k.substr(-4) != ".jpg"
}))
}
return arr
}
else if (group.keys) {
return group.keys.split(",")
} else {
return null
}
}
/**
* 根据名字找组
* @param name
*/
function getGroupByName(name: string): GroupInt {
var groups = resData.groups;
var group: GroupInt;
for (var i = 0; i < groups.length; i++) {
if (groups[i].name === name) {
group = groups[i];
break;
}
}
return group
}
/**
* 新版的加载一列资源
* @param callback
* @param arr
*/
function loadResList(callback: (allLoaded: boolean) => void, arr: string[]) {
let count = 0;
let countAll = arr.length;
if (!countAll) callback(true);
let mark = true;
for (var i = 0; i < countAll; i++) {
let resName = arr[i];
getResAsync(resName, (res, str) => {
//标记失败,如果有一项资源加载失败,标记下
if (!res) mark = false
if (++count == countAll) callback(mark);
}, this)
}
}
/**
*
* @param str
* @param comFun
* @param thisObj
*/
function returnSingleResPromise(str: string, comFun?: (res: any, str: string) => void, thisObj?: any) {
//已判断是否存在
singleResPromiseHash[str].then(
(r) => {
comFun && comFun.call(thisObj, r, str)
},
() => {
comFun && comFun.call(thisObj, null, str)
}
)
return singleResPromiseHash[str];
}
//貌似不需要,为了加载过一次的资源不用重新加载
function destroyRES() {
}
}
import { destroyWaiting } from "./waitingCtrl";
import { Panel } from "../views/Panel";
import PanelCtrl from "./panelCtrl";
import SceneCtrl from "./sceneCtrl";
import { Scene } from "../views/Scene";
import { destroyToast } from "./toastCtrl";
export { showToast } from "./toastCtrl";
export * from "./waitingCtrl";
/**
* 展示弹框
* @param panel 弹框类
* @param data 数据
*/
export const showPanel = (panel: any, data?: any) => {
PanelCtrl.instance.show(panel, data)
}
/**
* 关闭所有弹框
*/
export const closeAllPanels = () => {
PanelCtrl.instance.closeAll();
}
/**
* 关闭当前弹框
*/
export const closeCurrentPanel = () => {
PanelCtrl.instance.closeCurrent();
}
/**
* 替换场景
* @param scene
* @param data
*/
export const changeScene = (scene: any, data?: any) => {
SceneCtrl.instance.change(scene, data)
}
/**
* 获取当前场景
*/
export function getCurrentScene(): any {
return SceneCtrl.instance.currentScene
}
/**
* 淘宝小程序的alert
* @param {string} title
* @param {string} content
*/
export const showAlert = (title?: string, content?: string) => {
//@ts-ignore
if (my) {
//@ts-ignore
my.alert({
title: title || "",
content: content || ""
});
} else {
console.log(title, content)
}
}
/**
* 替换setTimeout 因为页面销毁时setTimeout不会停
* 所以干脆用Tween的
* @param {Function} callback
* @param {number} time 毫秒计
*/
export function wait(callback: () => void, time: number): {} {
let obj = {};
FYGE.Tween.get(obj)
.wait(time)
.call(callback)
return obj
}
export function clearWait(obj={}) {
FYGE.Tween.removeTweens(obj);
}
/**
* 销毁方法
*/
export function destroyAllCtrls() {
destroyToast();
destroyWaiting();
PanelCtrl.instance.destroy();
SceneCtrl.instance.destroy();
}
\ No newline at end of file
import { Panel } from "../views/Panel";
import { layers } from "../views/layers";
import { showWaiting, hideWaiting } from "./waitingCtrl";
import { showToast } from "./toastCtrl";
export default class PanelCtrl {
/**
* 父级容器
*/
private _parent: FYGE.Container;
/**
* 半透明黑色背景
*/
private _bg: FYGE.Graphics;
/**
* 所有的弹框
*/
private stacks: Panel[] = [];
private static _instance: PanelCtrl;
static get instance() {
return PanelCtrl._instance || (PanelCtrl._instance = new PanelCtrl())
}
init(parent: FYGE.Container) {
this._parent = parent;
let bg = new FYGE.Graphics();
bg.beginFill(0, 1);
bg.drawRect(//引用适配
layers.stageOffsetX - parent.x,
layers.stageOffsetY - parent.y,
layers.stageWidth,
layers.stageHeight
);
bg.endFill();
bg.visible = false;
this._parent.addChild(bg);
this._bg = bg;
}
/**
* 关闭所有弹框
*/
closeAll() {
this.stacks.forEach(e => e.hidePanel());
}
show<T extends Panel>(cls: any, data?: any): T {
showWaiting()
const panel: T = new cls(data);
this.add(panel);
this.stacks.push(panel);
panel.onLoaded = () => {
hideWaiting();
this.updateView();
//start只执行一边
panel.start(data);
}
//资源加载失败时
panel.onLoadError = () => {
hideWaiting();
showToast("资源加载失败")
panel.removeEventListener('onDestroy', this.onPanelHide, this);
this.remove(panel);
}
return panel;
}
private updateView() {
if (!this.stacks.length) {
this._bg.visible = false;
this._current = null;
this._parent.visible = false;
} else {
//显示弹框层
this._parent.visible = true;
//如果首次出现弹框,加个动画
if (this._bg.visible === false) {
this._bg.visible = true;
this._bg.alpha = 0;
FYGE.Tween.removeTweens(this._bg);
FYGE.Tween.get(this._bg).to({ alpha: 0.7 }, 200, FYGE.Ease.cubicOut)
}
}
for (let i = 0; i < this.stacks.length; i++) {
if (i < this.stacks.length - 1) {
this.stacks[i].visible = false;
} else {
this.stacks[i].visible = true;
this.stacks[i].showAni();
this._current = this.stacks[i];
}
}
}
/**
* 添加进父级并添加事件
* @param panel
*/
private add(panel: Panel) {
this._parent.addChild(panel);
panel.addEventListener('onDestroy', this.onPanelHide, this);
}
/**
* 移除
* @param panel
*/
private remove(panel: Panel) {
this._parent.removeChild(panel);
this.stacks = this.stacks.filter(e => e != panel);
}
/**
* 弹框移除时执行
* @param e
*/
private onPanelHide(e: FYGE.Event) {
const panel = e.target as Panel;
panel.removeEventListener('onDestroy', this.onPanelHide, this);
this.remove(panel);
this.updateView();
}
//当前弹框
private _current: Panel;
/**
* 关闭当前弹框
*/
closeCurrent() {
if (this._current) {
this._current.hidePanel();
// this._current.removeEventListener('onDestroy', this.onPanelHide, this);
// this.remove(this._current);
// this.updateView();
}
}
destroy() {
PanelCtrl._instance = null;
this.stacks = null;
this._current = null;
this._parent = null;
this._bg.destroy();
this._bg = null;
}
}
\ No newline at end of file
import { Panel } from "../views/Panel";
import { layers } from "../views/layers";
import { showWaiting, hideWaiting } from "./waitingCtrl";
import { showToast } from "./toastCtrl";
export default class PanelCtrl {
/**
* 父级容器
*/
private _parent: FYGE.Container;
/**
* 半透明黑色背景
*/
private _bg: FYGE.Graphics;
/**
* 所有的弹框
*/
private stacks: Panel[] = [];
private static _instance: PanelCtrl;
static get instance() {
return PanelCtrl._instance || (PanelCtrl._instance = new PanelCtrl())
}
init(parent: FYGE.Container) {
this._parent = parent;
let bg = new FYGE.Graphics();
bg.beginFill(0, 1);
bg.drawRect(//引用适配
layers.stageOffsetX - parent.x,
layers.stageOffsetY - parent.y,
layers.stageWidth,
layers.stageHeight
);
bg.endFill();
bg.visible = false;
this._parent.addChild(bg);
this._bg = bg;
}
/**
* 关闭所有弹框
*/
closeAll() {
this.stacks.forEach(e => e.hidePanel());
}
show<T extends Panel>(cls: any, data?: any): T {
this._bg.alpha = 0.7;
this._bg.visible = true;
showWaiting()
const panel: T = new cls(data);
this.add(panel);
this.stacks.push(panel);
panel.onLoaded = () => {
hideWaiting();
this.updateView();
//start只执行一边
panel.start(data);
}
//资源加载失败时
panel.onLoadError = () => {
hideWaiting();
showToast("资源加载失败")
panel.removeEventListener('onDestroy', this.onPanelHide, this);
this.remove(panel);
}
return panel;
}
private bgAni: "hide" | "show";
private updateView() {
//没有弹框的时候
if (!this.stacks.length) {
// this._bg.visible = false;
// this._current = null;
// this._parent.visible = false;
if (this._bg.visible) {//原先背景存在时,待测试
this.bgAni = "hide"
FYGE.Tween.removeTweens(this._bg);
FYGE.Tween.get(this._bg)
.to({ alpha: 0 }, 200, FYGE.Ease.cubicOut)
.call(() => {
this._bg.visible = false;
this._current = null;
this._parent.visible = false;
})
}
} else {
//显示弹框层
this._parent.visible = true;
if (this.bgAni == "hide") {//如果正在执行蒙层消失动画,
this.bgAni = "show"
FYGE.Tween.removeTweens(this._bg);
this._bg.alpha = 0.7;
}
//如果首次出现弹框,加个动画
if (this._bg.visible === false) {
this._bg.visible = true;
this._bg.alpha = 0;
FYGE.Tween.get(this._bg).to({ alpha: 0.7 }, 200, FYGE.Ease.cubicOut)
}
}
for (let i = 0; i < this.stacks.length; i++) {
if (i < this.stacks.length - 1) {
this.stacks[i].visible = false;
} else {
this.stacks[i].visible = true;
this.stacks[i].showAni();
this._current = this.stacks[i];
}
}
}
/**
* 添加进父级并添加事件
* @param panel
*/
private add(panel: Panel) {
this._parent.addChild(panel);
panel.addEventListener('onDestroy', this.onPanelHide, this);
}
/**
* 移除
* @param panel
*/
private remove(panel: Panel) {
this._parent.removeChild(panel);
this.stacks = this.stacks.filter(e => e != panel);
}
/**
* 弹框移除时执行
* @param e
*/
private onPanelHide(e: FYGE.Event) {
const panel = e.target as Panel;
panel.removeEventListener('onDestroy', this.onPanelHide, this);
this.remove(panel);
this.updateView();
}
//当前弹框
private _current: Panel;
/**
* 关闭当前弹框
*/
closeCurrent() {
if (this._current) {
this._current.hidePanel();
// this._current.removeEventListener('onDestroy', this.onPanelHide, this);
// this.remove(this._current);
// this.updateView();
}
}
destroy() {
PanelCtrl._instance = null;
this.stacks = null;
this._current = null;
this._parent = null;
this._bg = null;
}
}
\ No newline at end of file
import { Scene } from "../views/Scene";
import { showWaiting, hideWaiting } from "./waitingCtrl";
import { showToast } from "./toastCtrl";
export default class SceneCtrl {
private _parent: FYGE.Container;
private _currentScene: Scene;
private static _instance: SceneCtrl;
static get instance() {
return SceneCtrl._instance || (SceneCtrl._instance = new SceneCtrl())
}
init(parent: FYGE.Container) {
this._parent = parent;
}
change(cls: any, data?: any) {
//如果是同一个场景,考虑是替换还是return
if (this._currentScene && this._currentScene instanceof cls) return;
let scene: Scene = new cls(data);
scene.visible = false;
showWaiting();
let preScene: Scene = this._currentScene;
scene.onLoaded = () => {
// console.log(1231666)
hideWaiting();
scene.showAni(() => {
if (preScene) preScene.destroy();
})
scene.visible = true;
//start里可能处理资源信息,所以在onLoaded后执行
scene.start();
}
//加载失败,继续用之前的场景,移除scene
scene.onLoadError = () => {
hideWaiting();
showToast("资源加载失败")
this._currentScene = preScene || null;
this._parent.removeChild(scene);
}
this._currentScene = scene;
this._parent.addChild(scene);
}
get currentScene() {
return this._currentScene
}
destroy() {
SceneCtrl._instance = null;
this._currentScene = null;
this._parent = null;
}
}
\ No newline at end of file
import { layers } from "../views/layers";
import { RES } from "../RES";
let inited = false;
let _toast: Toast;
let _parent: FYGE.Container;
let startY: number
let endY: number
const initToast = () => {
if (!inited) {
inited = true;
_toast = new Toast();
_parent = layers.toastLayer;
_toast.alpha = 0;
//_toast.x = layers.stageOffsetX - _parent.x + (layers.stageWidth - _toast.width) / 2;
var h = _toast.height;
var y = layers.stageOffsetY - _parent.y;
startY = y - h;
endY = y + (layers.stageHeight - h) / 2;
}
}
export const showToast = (msg: string) => {
if(!msg){
console.log('msg为空');
return ;
}
initToast();
_toast.show(msg)
_parent.addChild(_toast);
FYGE.Tween.removeTweens(_toast);
FYGE.Tween.get(_toast)//动画看需求
.set({ y: startY, alpha: 1 })
.to({ y: endY }, 500, FYGE.Ease.quartOut)
.wait(800)
.to({ alpha: 0 }, 300)
.call(() => {
_parent.removeChild(_toast);
})
}
/**
* 对于之前淘宝小程序遇到的问题,需要销毁,否则会出问题
*/
export const destroyToast = () => {
if (inited && _toast && !_toast.destroyed) {
_toast.destroy();
_toast = null;
_parent = null;
inited = false;
}
}
/**
* toast类,不对外导出,适配居中有问题,有时间改
* 自身居中,
*/
class Toast extends FYGE.Container {
msg: FYGE.TextField;
bg: FYGE.Sprite;
PADDING = 40;
constructor() {
super();
this.mouseChildren = false;
this.mouseEnable = false;
var toastBgTexture: FYGE.Texture = RES.getRes("toastBg.png");
this.bg = new FYGE.Sprite(toastBgTexture);
// this.bg.x = (750 - 460) / 2// (layers.stageWidth - this.bg.width) / 2
this.addChild(this.bg);
this.msg = new FYGE.TextField();
this.msg.size = 28;
this.msg.fillColor = "0xffffff";
this.msg.text = "";
this.msg.verticalAlign = FYGE.VERTICAL_ALIGN.MIDDLE;
this.msg.textHeight = toastBgTexture.height;
this.msg.textAlign = FYGE.TEXT_ALIGN.CENTER;
this.addChild(this.msg)
}
/**
* 显示时调用
* @param msg
*/
show(msg: string) {
this.msg.text = msg;
//是否需要根据文本宽度缩放背景
this.bg.width = Math.max(this.msg.textWidth + this.PADDING * 2, 523);
//文本居中适配
this.msg.x = (layers.stageWidth - this.msg.textWidth) / 2//(layers.stageWidth - this.msg.textWidth) / 2;
//背景居中适配,由于上面一行注释,那这行就构造函数里只执行一次吧
this.bg.x = (layers.stageWidth - this.bg.width) / 2
}
destroy() {
super.destroy();
this.msg = null
this.bg = null;
}
}
\ No newline at end of file
import { RES } from "../RES";
import { layers } from "../views/layers";
import { showAlert } from ".";
let inited = false;
let _waiting: Waiting;
let _parent: FYGE.Container
const initWaiting = () => {
if (!inited) {
inited = true;
const waiting = new Waiting();
_parent = layers.topLayer;
_waiting = waiting;
//居中偏移
var offX = (layers.stageWidth - 160/*_waiting.width*/) / 2;
var offY = (layers.stageHeight - _waiting.height) / 2;
//位置适配
_waiting.x = layers.stageOffsetX - _parent.x + offX;
_waiting.y = layers.stageOffsetY - _parent.y + offY;
//阻止事件用
var bg: FYGE.Graphics = new FYGE.Graphics()
.beginFill(0x000000)
.drawRect(-offX, -offY, layers.stageWidth, layers.stageHeight)
.endFill();
bg.alpha = 0;
_waiting.addChildAt(bg, 0);
}
}
/**
* 显示菊花圈
* @param msg 尽量三个字
*/
export const showWaiting = (msg?: string) => {
initWaiting();
_waiting.show(msg)
_parent.addChild(_waiting);
}
/**
* 隐藏菊花圈
*/
export const hideWaiting = () => {
_parent.removeChild(_waiting);
}
export const destroyWaiting = () => {
if (inited && _waiting && !_waiting.destroyed) {
_waiting.destroy();
_waiting = null;
_parent = null;
inited = false;
}
}
/**
* 菊花圈,有机会重写,应该适应所有场景居中
*/
class Waiting extends FYGE.Container {
msg: FYGE.TextField;
constructor() {
super();
//圆角矩形背景
var rectBgTexture: FYGE.Texture = RES.getRes("waitingBg.png")
var rectBg = new FYGE.Sprite(rectBgTexture);
this.addChild(rectBg);
var rotTexture: FYGE.Texture = RES.getRes("waitingRot.png")
let rot = new FYGE.Sprite(rotTexture);
rot.x = (rectBgTexture.width - rotTexture.width) / 2
rot.y = 47//533;
rot.anchorX = rotTexture.width / 2;
rot.anchorY = rotTexture.height / 2;
this.addChild(rot);
let count = 0;
rot.addEventListener(FYGE.Event.ENTER_FRAME, () => {
count++;
if (count % 30 == 0) rot.rotation += 45;
}, this)
this.msg = new FYGE.TextField();
this.msg.y = 125;
this.msg.textWidth = rectBgTexture.width;
this.msg.textAlign = FYGE.TEXT_ALIGN.CENTER;
this.msg.size = 26
this.msg.fillColor = "#ffffff";
this.addChild(this.msg);
}
show(msg: string = "加载中") {
this.msg.text = msg;
}
destroy() {
super.destroy();
this.msg = null;
}
}
const _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
/**
* base64编码汉字,
* 一般用于链接参数传递,
* 先base64.encode,再encodeURIComponent后带入,取参数时会decodeURIComponent,然后再base64.decode后
* 直接调用Base64.ins
*/
export class Base64 {
// private property
// _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
private static instance: Base64;
public static get ins(): Base64 {
if (!this.instance) {
this.instance = new Base64();
}
return this.instance;
}
constructor() {
}
// public method for encoding
encode(input) {
var output = "";
var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
var i = 0;
input = this._utf8_encode(input);
while (i < input.length) {
chr1 = input.charCodeAt(i++);
chr2 = input.charCodeAt(i++);
chr3 = input.charCodeAt(i++);
enc1 = chr1 >> 2;
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
enc4 = chr3 & 63;
if (isNaN(chr2)) {
enc3 = enc4 = 64;
} else if (isNaN(chr3)) {
enc4 = 64;
}
output = output +
_keyStr.charAt(enc1) + _keyStr.charAt(enc2) +
_keyStr.charAt(enc3) + _keyStr.charAt(enc4);
}
return output;
}
// public method for decoding
decode(input) {
var output = "";
var chr1, chr2, chr3;
var enc1, enc2, enc3, enc4;
var i = 0;
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
while (i < input.length) {
enc1 = _keyStr.indexOf(input.charAt(i++));
enc2 = _keyStr.indexOf(input.charAt(i++));
enc3 = _keyStr.indexOf(input.charAt(i++));
enc4 = _keyStr.indexOf(input.charAt(i++));
chr1 = (enc1 << 2) | (enc2 >> 4);
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
chr3 = ((enc3 & 3) << 6) | enc4;
output = output + String.fromCharCode(chr1);
if (enc3 != 64) {
output = output + String.fromCharCode(chr2);
}
if (enc4 != 64) {
output = output + String.fromCharCode(chr3);
}
}
output = this._utf8_decode(output);
return output;
}
// private method for UTF-8 encoding
private _utf8_encode(string) {
string = string.replace(/\r\n/g, "\n");
var utftext = "";
for (var n = 0; n < string.length; n++) {
var c = string.charCodeAt(n);
if (c < 128) {
utftext += String.fromCharCode(c);
} else if ((c > 127) && (c < 2048)) {
utftext += String.fromCharCode((c >> 6) | 192);
utftext += String.fromCharCode((c & 63) | 128);
} else {
utftext += String.fromCharCode((c >> 12) | 224);
utftext += String.fromCharCode(((c >> 6) & 63) | 128);
utftext += String.fromCharCode((c & 63) | 128);
}
}
return utftext;
}
// private method for UTF-8 decoding
private _utf8_decode(utftext) {
var string = "";
var i = 0;
var c = 0;
var c2 = 0;
var c3 = 0
while (i < utftext.length) {
c = utftext.charCodeAt(i);
if (c < 128) {
string += String.fromCharCode(c);
i++;
} else if ((c > 191) && (c < 224)) {
c2 = utftext.charCodeAt(i + 1);
string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
i += 2;
} else {
c2 = utftext.charCodeAt(i + 1);
c3 = utftext.charCodeAt(i + 2);
string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
i += 3;
}
}
return string;
}
}
\ No newline at end of file
/**
* 回收池
*/
export class GPool {
private static pool = {};
/**
* 取出
* @param name
*/
public static takeOut(name: string) {
if (this.pool[name] && this.pool[name].length) {
return this.pool[name].shift();
}
return null;
}
/**
* 回收
* @param name
* @param obj
*/
public static recover(name: string, obj) {
if (!this.pool[name]) {
this.pool[name] = [];
}
this.pool[name].push(obj);
}
}
\ No newline at end of file
/**
* 用到的和业务相关的
* 各种静态方法汇总
*
* 获取修改链接参数
* 获取cookie
* 缓存相关
* 数组相关
*
*/
export class GTool {
/**
* 替换或添加url里的参数
* @param url 修改的url
* @param arg 参数名
* @param arg_val 参数值
*/
public static changeURLArg(url: string, arg: string, arg_val: string | number) {
var pattern = arg + '=([^&]*)';
var replaceText = arg + '=' + arg_val;
if (url.match(pattern)) {
var tmp = '/(' + arg + '=)([^&]*)/gi';
// tmp = url.replace(eval(tmp), replaceText);
tmp = url.replace(new RegExp(tmp), replaceText);
return tmp;
} else {
if (url.match('[\?]')) {
return url + '&' + replaceText;
} else {
return url + '?' + replaceText;
}
}
}
/**
* 读取缓存 用到时重写
*/
public static readCache(key: string, type: string = 'localStorage') {
if (!window.localStorage) {
return false;
}
return window[type].getItem(key);
}
/**
* 写缓存 用到时重写
*/
public static writeCache(key: string, value: any = 'true', type: string = 'localStorage') {
if (!window.localStorage) {
// trace(Func.replace(SysLang.lang_012, [type]));
return;
}
window[type].setItem(key, value);
}
/**
* 获得cacheKey今日次数
* 第二天归0重新计数 用到时重写
* @param cacheKey
*/
public static returnTodayTimes(cacheKey: string): number {
var year1 = this.readCache("year" + cacheKey);
var month1 = this.readCache("month" + cacheKey);
var day1 = this.readCache("day" + cacheKey);
var date = new Date();
var year2 = date.getFullYear().toString();
var month2 = date.getMonth().toString();
var day2 = date.getDate().toString();
if (this.int(year2) <= this.int(year1)) {
if (this.int(month2) <= this.int(month1)) {
if (this.int(day2) <= this.int(day1)) {
return this.int(this.readCache(cacheKey));
}
}
}
//如果不是同一天了,归0
var today = "0";
this.writeCache("year" + cacheKey, year2);
this.writeCache("month" + cacheKey, month2);
this.writeCache("day" + cacheKey, day2);
this.writeCache(cacheKey, today);
return 0;
}
/**
* 随机,两个参数时是数值范围,比如randomT(1,10),一个参数时是数组
* @param e
* @param n
*/
public static randomT(e, n?) {
return e && "number" == typeof e.length && e.length ? e[Math.floor(Math.random() * e.length)] : ("number" != typeof n && (n = e || 1, e = 0), e + Math.random() * (n - e))
}
/**
* 从数组中移除一个元素
* @param e 元素
* @param arr 数组
*/
public static removeEle(e, arr) {
var index = arr.indexOf(e);
if (index >= 0) {
arr.splice(index, 1)
}
}
/**
* 数组中插入一个数值,按顺序的
* 数组是从小到大的
* @param num
* @param arr
*/
public static insert(num, arr) {
for (var i = arr.length - 1; i >= 0; i--) {
if (num > arr[i]) {
//在arr[i]后加num
arr.splice(i + 1, 0, num);
break
}
}
}
/**
* 获取start到end里的n个整数
* @param start 0
* @param end 19
* @param n 3
*/
public static getRandomNumber(start: number, end: number, n: number): number[] {
var arr = [];
for (var i = 0; i < n; i++) {
var number = Math.floor(Math.random() * (end - start + 1) + start);
if (arr.indexOf(number) < 0) {
arr.push(number);
} else {
i--;
}
}
return arr;
}
/**
* 打乱数字数组,改变原数组
* @param arr
*/
public static disturbNumberArr(arr: number[]) {
arr.sort(function () {
return (0.5 - Math.random());
});
}
/**
* 其实打乱数组取前几个就行
* 随机取数组arr中count个元素,不改变原数组
* @param arr
* @param count
*/
public static getRandomArrayElements(arr: any[], count: number) {
var shuffled = arr.slice(0), i = arr.length, min = i - count, temp, index;
//如果count大于等于数组长度,返回所有数组
if (min <= 0) return shuffled;
if (count <= 0) return [];
//随机排序,然后取出后面的元素
while (i-- > min) {
index = Math.floor((i + 1) * Math.random());
temp = shuffled[index];
shuffled[index] = shuffled[i];
shuffled[i] = temp;
}
return shuffled.slice(min);
}
/**
* 随机取数组arr中count个元素,原数组减少count个
* @param arr
* @param count
*/
public static getRandomArrayElementsEx(arr: any[], count: number): any[] {
//如果count大于等于数组长度,返回所有数组
if (arr.length <= count) return arr.slice();
if (count <= 0) return [];
var arrCopy = arr.slice();
var outArr = [];
while (count--) {
var rand = Math.floor(Math.random() * arrCopy.length);
var ele = arrCopy.splice(rand, 1)[0];
outArr.push(ele);
}
return outArr
}
/**
* 向下取整,或把字符串执行parseInt(字符串转数字取整数部分)
* @param n 数字或字符串
*/
private static int(n: any): number {
return n >> 0;//~~n
};
/**
* emoji正则式
*/
public static emojiReg = /[\uD83C|\uD83D|\uD83E][\uDC00-\uDFFF][\u200D|\uFE0F]|[\uD83C|\uD83D|\uD83E][\uDC00-\uDFFF]|[0-9|*|#]\uFE0F\u20E3|[0-9|#]\u20E3|[\u203C-\u3299]\uFE0F\u200D|[\u203C-\u3299]\uFE0F|[\u2122-\u2B55]|\u303D|[\A9|\AE]\u3030|\uA9|\uAE|\u3030/ig
/**
* 在字符串间加空格
* @param str
*/
public static addSpaceInString(str: string) {
if (!str.length || str.length == 1) return str;
var txt = "";
//每个字符后加空格
for (var i = 0; i < str.length - 1; i++) {
txt = txt + str[i] + " ";
}
txt = txt + str[str.length - 1]
return txt
}
}
\ No newline at end of file
export const duiba_md5 = (function (/*$*/) {
//@ts-ignore
function safe_add(x, y) {
var lsw = (x & 65535) + (y & 65535), msw = (x >> 16) + (y >> 16) + (lsw >> 16);
return (msw << 16) | (lsw & 65535)
}
function bit_rol(num, cnt) {
return (num << cnt) | (num >>> (32 - cnt))
}
function md5_cmn(q, a, b, x, s, t) {
return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s), b)
}
function md5_ff(a, b, c, d, x, s, t) {
return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t)
}
function md5_gg(a, b, c, d, x, s, t) {
return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t)
}
function md5_hh(a, b, c, d, x, s, t) {
return md5_cmn(b ^ c ^ d, a, b, x, s, t)
}
function md5_ii(a, b, c, d, x, s, t) {
return md5_cmn(c ^ (b | (~d)), a, b, x, s, t)
}
function binl_md5(x, len) {
x[len >> 5] |= 128 << ((len) % 32);
x[(((len + 64) >>> 9) << 4) + 14] = len;
var i, olda, oldb, oldc, oldd, a = 1732584193, b = -271733879, c = -1732584194, d = 271733878;
for (i = 0; i < x.length; i += 16) {
olda = a;
oldb = b;
oldc = c;
oldd = d;
a = md5_ff(a, b, c, d, x[i], 7, -680876936);
d = md5_ff(d, a, b, c, x[i + 1], 12, -389564586);
c = md5_ff(c, d, a, b, x[i + 2], 17, 606105819);
b = md5_ff(b, c, d, a, x[i + 3], 22, -1044525330);
a = md5_ff(a, b, c, d, x[i + 4], 7, -176418897);
d = md5_ff(d, a, b, c, x[i + 5], 12, 1200080426);
c = md5_ff(c, d, a, b, x[i + 6], 17, -1473231341);
b = md5_ff(b, c, d, a, x[i + 7], 22, -45705983);
a = md5_ff(a, b, c, d, x[i + 8], 7, 1770035416);
d = md5_ff(d, a, b, c, x[i + 9], 12, -1958414417);
c = md5_ff(c, d, a, b, x[i + 10], 17, -42063);
b = md5_ff(b, c, d, a, x[i + 11], 22, -1990404162);
a = md5_ff(a, b, c, d, x[i + 12], 7, 1804603682);
d = md5_ff(d, a, b, c, x[i + 13], 12, -40341101);
c = md5_ff(c, d, a, b, x[i + 14], 17, -1502002290);
b = md5_ff(b, c, d, a, x[i + 15], 22, 1236535329);
a = md5_gg(a, b, c, d, x[i + 1], 5, -165796510);
d = md5_gg(d, a, b, c, x[i + 6], 9, -1069501632);
c = md5_gg(c, d, a, b, x[i + 11], 14, 643717713);
b = md5_gg(b, c, d, a, x[i], 20, -373897302);
a = md5_gg(a, b, c, d, x[i + 5], 5, -701558691);
d = md5_gg(d, a, b, c, x[i + 10], 9, 38016083);
c = md5_gg(c, d, a, b, x[i + 15], 14, -660478335);
b = md5_gg(b, c, d, a, x[i + 4], 20, -405537848);
a = md5_gg(a, b, c, d, x[i + 9], 5, 568446438);
d = md5_gg(d, a, b, c, x[i + 14], 9, -1019803690);
c = md5_gg(c, d, a, b, x[i + 3], 14, -187363961);
b = md5_gg(b, c, d, a, x[i + 8], 20, 1163531501);
a = md5_gg(a, b, c, d, x[i + 13], 5, -1444681467);
d = md5_gg(d, a, b, c, x[i + 2], 9, -51403784);
c = md5_gg(c, d, a, b, x[i + 7], 14, 1735328473);
b = md5_gg(b, c, d, a, x[i + 12], 20, -1926607734);
a = md5_hh(a, b, c, d, x[i + 5], 4, -378558);
d = md5_hh(d, a, b, c, x[i + 8], 11, -2022574463);
c = md5_hh(c, d, a, b, x[i + 11], 16, 1839030562);
b = md5_hh(b, c, d, a, x[i + 14], 23, -35309556);
a = md5_hh(a, b, c, d, x[i + 1], 4, -1530992060);
d = md5_hh(d, a, b, c, x[i + 4], 11, 1272893353);
c = md5_hh(c, d, a, b, x[i + 7], 16, -155497632);
b = md5_hh(b, c, d, a, x[i + 10], 23, -1094730640);
a = md5_hh(a, b, c, d, x[i + 13], 4, 681279174);
d = md5_hh(d, a, b, c, x[i], 11, -358537222);
c = md5_hh(c, d, a, b, x[i + 3], 16, -722521979);
b = md5_hh(b, c, d, a, x[i + 6], 23, 76029189);
a = md5_hh(a, b, c, d, x[i + 9], 4, -640364487);
d = md5_hh(d, a, b, c, x[i + 12], 11, -421815835);
c = md5_hh(c, d, a, b, x[i + 15], 16, 530742520);
b = md5_hh(b, c, d, a, x[i + 2], 23, -995338651);
a = md5_ii(a, b, c, d, x[i], 6, -198630844);
d = md5_ii(d, a, b, c, x[i + 7], 10, 1126891415);
c = md5_ii(c, d, a, b, x[i + 14], 15, -1416354905);
b = md5_ii(b, c, d, a, x[i + 5], 21, -57434055);
a = md5_ii(a, b, c, d, x[i + 12], 6, 1700485571);
d = md5_ii(d, a, b, c, x[i + 3], 10, -1894986606);
c = md5_ii(c, d, a, b, x[i + 10], 15, -1051523);
b = md5_ii(b, c, d, a, x[i + 1], 21, -2054922799);
a = md5_ii(a, b, c, d, x[i + 8], 6, 1873313359);
d = md5_ii(d, a, b, c, x[i + 15], 10, -30611744);
c = md5_ii(c, d, a, b, x[i + 6], 15, -1560198380);
b = md5_ii(b, c, d, a, x[i + 13], 21, 1309151649);
a = md5_ii(a, b, c, d, x[i + 4], 6, -145523070);
d = md5_ii(d, a, b, c, x[i + 11], 10, -1120210379);
c = md5_ii(c, d, a, b, x[i + 2], 15, 718787259);
b = md5_ii(b, c, d, a, x[i + 9], 21, -343485551);
a = safe_add(a, olda);
b = safe_add(b, oldb);
c = safe_add(c, oldc);
d = safe_add(d, oldd)
}
return [a, b, c, d]
}
function binl2rstr(input) {
var i, output = "";
for (i = 0; i < input.length * 32; i += 8) {
output += String.fromCharCode((input[i >> 5] >>> (i % 32)) & 255)
}
return output
}
function rstr2binl(input) {
var i, output = [];
output[(input.length >> 2) - 1] = undefined;
for (i = 0; i < output.length; i += 1) {
output[i] = 0
}
for (i = 0; i < input.length * 8; i += 8) {
output[i >> 5] |= (input.charCodeAt(i / 8) & 255) << (i % 32)
}
return output
}
function rstr_md5(s) {
return binl2rstr(binl_md5(rstr2binl(s), s.length * 8))
}
function rstr_hmac_md5(key, data) {
var i, bkey = rstr2binl(key), ipad = [], opad = [], hash;
ipad[15] = opad[15] = undefined;
if (bkey.length > 16) {
bkey = binl_md5(bkey, key.length * 8)
}
for (i = 0; i < 16; i += 1) {
ipad[i] = bkey[i] ^ 909522486;
opad[i] = bkey[i] ^ 1549556828
}
hash = binl_md5(ipad.concat(rstr2binl(data)), 512 + data.length * 8);
return binl2rstr(binl_md5(opad.concat(hash), 512 + 128))
}
function rstr2hex(input) {
var hex_tab = "0123456789abcdef", output = "", x, i;
for (i = 0; i < input.length; i += 1) {
x = input.charCodeAt(i);
output += hex_tab.charAt((x >>> 4) & 15) + hex_tab.charAt(x & 15)
}
return output
}
function str2rstr_utf8(input) {
return unescape(encodeURIComponent(input))
}
function raw_md5(s) {
return rstr_md5(str2rstr_utf8(s))
}
function hex_md5(s) {
return rstr2hex(raw_md5(s))
}
function raw_hmac_md5(k, d) {
return rstr_hmac_md5(str2rstr_utf8(k), str2rstr_utf8(d))
}
function hex_hmac_md5(k, d) {
return rstr2hex(raw_hmac_md5(k, d))
}
var duiba_md5 = function (string, key?, raw?) {
if (!key) {
if (!raw) {
return hex_md5(string)
} else {
return raw_md5(string)
}
}
if (!raw) {
return hex_hmac_md5(key, string)
} else {
return raw_hmac_md5(key, string)
}
};
var hexcase = 0;
var b64pad = "";
var chrsz = 8;
// $.extend({
// duiba_b64_sha: function (input) {
// return binb2b64(core_sha1(str2binb(input), input.length * chrsz))
// }
// });
function core_sha1(x, len) {
x[len >> 5] |= 128 << (24 - len % 32);
x[((len + 64 >> 9) << 4) + 15] = len;
var w = Array(80);
var a = 1732584193;
var b = -271733879;
var c = -1732584194;
var d = 271733878;
var e = -1009589776;
for (var i = 0; i < x.length; i += 16) {
var olda = a;
var oldb = b;
var oldc = c;
var oldd = d;
var olde = e;
for (var j = 0; j < 80; j++) {
if (j < 16) {
w[j] = x[i + j]
} else {
w[j] = rol(w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16], 1)
}
var t = safe_add(safe_add(rol(a, 5), sha1_ft(j, b, c, d)), safe_add(safe_add(e, w[j]), sha1_kt(j)));
e = d;
d = c;
c = rol(b, 30);
b = a;
a = t
}
a = safe_add(a, olda);
b = safe_add(b, oldb);
c = safe_add(c, oldc);
d = safe_add(d, oldd);
e = safe_add(e, olde)
}
return Array(a, b, c, d, e)
}
function sha1_ft(t, b, c, d) {
if (t < 20) {
return (b & c) | ((~b) & d)
}
if (t < 40) {
return b ^ c ^ d
}
if (t < 60) {
return (b & c) | (b & d) | (c & d)
}
return b ^ c ^ d
}
function sha1_kt(t) {
return (t < 20) ? 1518500249 : (t < 40) ? 1859775393 : (t < 60) ? -1894007588 : -899497514
}
function core_hmac_sha1(key, data) {
var bkey = str2binb(key);
if (bkey.length > 16) {
bkey = core_sha1(bkey, key.length * chrsz)
}
var ipad = Array(16), opad = Array(16);
for (var i = 0; i < 16; i++) {
ipad[i] = bkey[i] ^ 909522486;
opad[i] = bkey[i] ^ 1549556828
}
var hash = core_sha1(ipad.concat(str2binb(data)), 512 + data.length * chrsz);
return core_sha1(opad.concat(hash), 512 + 160)
}
//@ts-ignore
function safe_add(x, y) {
var lsw = (x & 65535) + (y & 65535);
var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
return (msw << 16) | (lsw & 65535)
}
function rol(num, cnt) {
return (num << cnt) | (num >>> (32 - cnt))
}
function str2binb(str) {
var bin = Array();
var mask = (1 << chrsz) - 1;
for (var i = 0; i < str.length * chrsz; i += chrsz) {
bin[i >> 5] |= (str.charCodeAt(i / chrsz) & mask) << (32 - chrsz - i % 32)
}
return bin
}
function binb2str(bin) {
var str = "";
var mask = (1 << chrsz) - 1;
for (var i = 0; i < bin.length * 32; i += chrsz) {
str += String.fromCharCode((bin[i >> 5] >>> (32 - chrsz - i % 32)) & mask)
}
return str
}
function binb2hex(binarray) {
var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
var str = "";
for (var i = 0; i < binarray.length * 4; i++) {
str += hex_tab.charAt((binarray[i >> 2] >> ((3 - i % 4) * 8 + 4)) & 15) + hex_tab.charAt((binarray[i >> 2] >> ((3 - i % 4) * 8)) & 15)
}
return str
}
function binb2b64(binarray) {
var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
var str = "";
for (var i = 0; i < binarray.length * 4; i += 3) {
var triplet = (((binarray[i >> 2] >> 8 * (3 - i % 4)) & 255) << 16) | (((binarray[i + 1 >> 2] >> 8 * (3 - (i + 1) % 4)) & 255) << 8) | ((binarray[i + 2 >> 2] >> 8 * (3 - (i + 2) % 4)) & 255);
for (var j = 0; j < 4; j++) {
if (i * 8 + j * 6 > binarray.length * 32) {
str += b64pad
} else {
str += tab.charAt((triplet >> 6 * (3 - j)) & 63)
}
}
}
str = str + "=";
return str
}
// window.duiba_md5 = duiba_md5;
return duiba_md5
}(/*Zepto*/));
\ No newline at end of file
import { RES } from "../RES";
/**
*
*/
export class Module extends FYGE.Container {
protected data: any;
constructor(data?: any) {
super();
this.data = data;
this.init();
}
/**
* 初始化资源和皮肤
*/
private init() {
this.preLoadRes().then(
() => {
this.initUi();
this.onLoaded && this.onLoaded();
},
() => {
this.onLoadError && this.onLoadError();
}
);
}
/**
* 提前加载的资源
*/
protected preLoadRes() {
return new Promise((resolve, reject) => {
if (this.groupNames && this.groupNames.length) {
var arr: Promise<any>[] = [];
for (var i = 0; i < this.groupNames.length; i++) {
arr.push(RES.loadGroup(this.groupNames[i]))
}
Promise.all(arr).then(resolve, reject)
} else {
resolve()
}
})
}
/**
* 初始化ui
*/
protected initUi() {
}
/**
* 资源加载完成后执行,用于场景及弹框控制
*/
onLoaded: () => void
/**
* 资源加载失败时执行,用于场景及弹框控制
*/
onLoadError: () => void;
/**
* 可以有多个组
*/
get groupNames(): string[] { return null }
/**
* 在构造函数后执行
*/
start(data?: any) {
this.initEvents();
}
/**
* 添加事件
*/
initEvents(): void {
}
/**
* 移除事件
*/
removeEvents(): void {
}
/**
* 鼠标事件
* @param enable
*/
protected enableMouseEvt(enable: boolean): void {
this.mouseEnable = enable;
this.mouseChildren = enable;
}
public destroy(): void {
removeTweens(this);
this.data = null;//看情况吧,有时候hidePanel后用了data,注意
//移除事件
this.removeEvents();
//派发销毁事件,主要用于场景及弹框控制
this.dispatchEvent("onDestroy");
super.destroy();
}
}
/**
* 递归清除显示对象里面所有的Tween
* @param obj
* @param isRecursive 默认true,递归移除子级
*/
function removeTweens(obj, isRecursive: boolean = true) {
if (!obj) return
FYGE.Tween.removeTweens(obj);
if (!isRecursive || !obj.children || !obj.children.length) return
obj.children.forEach(child => {
removeTweens(child)
});
}
\ No newline at end of file
import { Module } from "./Module";
export class Panel extends Module {
private isShowing: boolean
showAni() {
if (this.isShowing) return;
this.isShowing = true;
let oriY = this.y || 0;
this.y = -200;
FYGE.Tween.get(this)
.to({ y: oriY }, 500, FYGE.Ease.quartOut)
.call(() => {
this.isShowing = false;
})
}
initEvents() {
this.closeBtns.forEach(
btn => { if (btn) btn.addEventListener(FYGE.MouseEvent.CLICK, this.hidePanel, this) }
)
}
removeEvents() {
this.closeBtns.forEach(
btn => { if (btn) btn.removeEventListener(FYGE.MouseEvent.CLICK, this.hidePanel, this) }
)
}
/**
* 需要的放入,不重复写关闭按钮事件
*/
protected get closeBtns(): any[] { return [this['closeBtn']] }
hidePanel() {
this.destroy();
}
destroy() {
FYGE.Tween.removeTweens(this)
super.destroy()
}
}
\ No newline at end of file
import { Module } from "./Module";
export class Scene extends Module {
/**
* 显示动画
* 继承时注意,回调要加
* 因为这种动画基本原场景最好不消失
*/
showAni(callback: Function) {
callback()
}
/**
* 统一更新方法
*/
updateScene() {
}
}
\ No newline at end of file
import PanelCtrl from "../ctrls/panelCtrl";
import SceneCtrl from "../ctrls/sceneCtrl";
/**
* 添加进舞台的所有层级
* 仿白鹭的那套
*/
class Layers extends FYGE.Container {
private _bottomLayer: FYGE.Container;
private _sceneLayer: FYGE.Container;
private _popupLayer: FYGE.Container;
private _toastLayer: FYGE.Container;
private _topLayer: FYGE.Container;
private _shareLayer: FYGE.Container;
init(stage: FYGE.Stage) {
stage.addChild(this);
var arr = [
"_bottomLayer",
"_sceneLayer",
"_popupLayer",
"_toastLayer",
"_topLayer",
"_shareLayer"
];
for (var i = 0; i < arr.length; i++) {
this[arr[i]] = new FYGE.Container();
//有些时候,定宽的时候,部分layer置顶,部分居中,再处理
//为了都置顶和置左,stage的方式永远居中视窗,要么改stage永远左上为00
// this[arr[i]].y = this.stageOffsetY;
//如果定宽这里没必要,肯定是0
// this[arr[i]].x = this.stageOffsetX;//去掉,定高时就居中了
this.addChild(this[arr[i]]);
}
// this._sceneLayer.y = this.stageOffsetY
//初始化场景层级
SceneCtrl.instance.init(this.sceneLayer)
//初始化弹框层级
PanelCtrl.instance.init(this.popupLayer)
}
/**
* 底图所在层级,比如统一的背景
*/
get bottomLayer() { return this._bottomLayer }
/**
* 场景
*/
get sceneLayer() { return this._sceneLayer }
/**
* 弹框
*/
get popupLayer() { return this._popupLayer }
/**
* toast所在层级
*/
get toastLayer() { return this._toastLayer }
/**
* 顶层,比如统一标题栏等
*/
get topLayer() { return this._topLayer }
/**
* 分享引导层
*/
get shareLayer() { return this._shareLayer }
/**
* 舞台信息都放在layers里吧
* 舞台可见高度,初始化后才能使用
*/
get stageHeight() {
if (!this.stage) return 0;
return this.stage.viewRect.height;
}
/**
* 舞台可见宽度
*/
get stageWidth() {
if (!this.stage) return 0;
return this.stage.viewRect.width;
}
/**
* 适配方式x两边偏移的量,固定宽度x为0
*/
get stageOffsetX() {
if (!this.stage) return 0;
return this.stage.viewRect.x;
}
get stageOffsetY() {
if (!this.stage) return 0;
return this.stage.viewRect.y;
}
/**
* 舞台中心点位置x
*/
// get stageCenterX(): number {
// return this.stage.viewRect.x + this.stage.viewRect.width >> 1;
// }
/**
* 舞台中心点位置y,layer位置做过偏移的就不对了,所以还是自行算吧
*/
// get stageCenterY(): number {
// return this.stage.viewRect.y + this.stage.viewRect.height >> 1;
// }
}
export const layers = new Layers();
//先执行,在淘宝小程序中重新进入会再次初始化
export function destroyLayers() {
//所有层级移除,init会重新建
layers.removeChildren();
//从父级stage移除自己,init会重新加
if (layers.parent) layers.parent.removeChild(layers)
}
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
{
"name": "tbgame",
"version": "1.0.0",
"description": "",
"main": "index.html",
"devDependencies": {
"ali-oss": "^4.11.4",
"chalk": "^2.3.0",
"co": "^4.6.0",
"del": "^2.2.1",
"fs": "0.0.2",
"imagemin": "^7.0.1",
"imagemin-mozjpeg": "^8.0.0",
"imagemin-pngquant": "*",
"mock-webpack-plugin": "^2.0.0",
"path": "^0.12.7",
"progress": "^2.0.0",
"ts-loader": "^4.0.0",
"tslint": "^5.9.1",
"typescript": "^2.7.2",
"webpack": "^4.1.0",
"webpack-cli": "^3.1.1",
"webpack-dev-server": "^3.1.0",
"webpack-merge": "^4.1.2",
"uglifyjs-webpack-plugin": "^2.1.2"
},
"dependencies": {
"@types/howler": "^2.2.1",
"howler": "^2.2.0"
},
"scripts": {
"flushRes": "node scripts/flushRes",
"handleRes": "node scripts/delRel && node scripts/copyRes && node scripts/createTm && node scripts/textureMerge && node scripts/delTm && node scripts/imageMin",
"upload": "node scripts/upload",
"build": "npm run handleRes && node scripts/mergeJson && npm run upload && npm run buildTS",
"watch": "webpack --watch",
"dev": "webpack-dev-server --open --config webpack.dev.js ",
"buildTS": "webpack --config webpack.prod.js && node scripts/mergeJs && node scripts/copyJs ",
"copyJs": "node scripts/copyJs"
},
"author": "MrKwon",
"license": "ISC"
}
{
"type": "activity",
"name": "kickball-feile"
}
\ No newline at end of file
{
"groups": [
{
"keys": "comCloseBtn.png,toastBg.png,waitingBg.png,waitingRot.png",
"name": "common"
},
{
"keys": "score_0.png,score_1.png,score_2.png,score_3.png,score_4.png,score_5.png,score_6.png,score_7.png,score_8.png,score_9.png,score_f.png",
"name": "dialogScore"
},
{
"keys": "closeBtn1.png,gameAgain.png,gameOverBg1.png",
"name": "gameOverPanel"
},
{
"keys": "add_score_0.png,add_score_1.png,add_score_2.png,add_score_3.png,add_score_4.png,add_score_5.png,add_score_6.png,add_score_7.png,add_score_8.png,add_score_9.png,bangbangBall.png,baohuzhao.png,boom.png,closeMusic.png,cowItem.png,double.png,gameAgain.png,gameBg.jpg,getIce.png,iceBlock.png,iknowbtn.png,left.png,lizhiBall.png,main_countdown.png,main_countdown2.png,mushRoom.png,next.png,openMusic.png,penguin.png,point.png,pot.png,right.png,scoreTitle.png,score_num_0.png,score_num_1.png,score_num_2.png,score_num_3.png,score_num_4.png,score_num_5.png,score_num_6.png,score_num_7.png,score_num_8.png,score_num_9.png",
"name": "PrizeFell"
}
],
"path": "./resource/"
}
\ No newline at end of file
var fs = require("fs");
// fs.writeFileSync(
// "./released/output.js",
// fs.readFileSync("./output.js")
// )
// /Users/wanghongyuan/taobaominiDemo/client/pages/index
var endPath = 'E:/project/taobaominiDemo/taobaominiDemo/client/pages/index/';
var version = Math.round(new Date().getTime() / 1000);
fs.writeFileSync(endPath + "output.js", fs.readFileSync("./released/output.js"));
// console.log("js覆盖完成")
console.log(`版本号:
${version}`)
\ No newline at end of file
var fs = require('fs');
var path = require("path");
function writeFile(p, text) {
fs.writeFile(p, text, function (err) {
// if (!err)
// console.log("写入成功!")
})
}
//递归创建目录 同步方法
function mkdirsSync(dirname) {
if (fs.existsSync(dirname)) {
return true;
} else {
if (mkdirsSync(path.dirname(dirname))) {
// console.log("mkdirsSync = " + dirname);
fs.mkdirSync(dirname);
return true;
}
}
}
function _copy(src, dist) {
var paths = fs.readdirSync(src)
paths.forEach(function (p) {
var _src = src + '/' + p;
var _dist = dist + '/' + p;
var stat = fs.statSync(_src)
if (stat.isFile()) {// 判断是文件还是目录
fs.writeFileSync(_dist, fs.readFileSync(_src));
} else if (stat.isDirectory()) {
copyDir(_src, _dist)// 当是目录是,递归复制
}
})
}
/*
* 复制目录、子目录,及其中的文件
* @param src {String} 要复制的目录
* @param dist {String} 复制到目标目录
*/
function copyDir(src, dist) {
var b = fs.existsSync(dist)
// console.log("dist = " + dist)
if (!b) {
// console.log("mk dist = ",dist)
mkdirsSync(dist);//创建目录
}
// console.log("_copy start")
_copy(src, dist);
}
function createDocs(src, dist, callback) {
// console.log("createDocs...")
copyDir(src, dist);
// console.log("copyDir finish exec callback")
if (callback) {
callback();
}
}
createDocs("./resource", "./released/resource/", function () {
console.log("资源拷贝成功")
})
\ No newline at end of file
var fs = require("fs");
var iconv = require('iconv-lite');
var del = require('del');
var readPath = "./released/resource/";
//读取json文件
var data = iconv.decode(fs.readFileSync(readPath + "res.json"), "utf-8");//GBK
//反序列化
data = JSON.parse(data); //eval(data)
//取出里面的图片,暂存到tm文件夹中,同时删除文件夹里的,和本身json里的
if (!fs.existsSync("./released/tm"))
fs.mkdirSync("./released/tm");
for (var i = 0; i < data.groups.length; i++) {
var name = data.groups[i].name;
var path = readPath + name + "/";
var arr = data.groups[i].keys.split(",");
//取出图片的,注意已排除jpg
var images = arr.filter((f) => { return (f.substr(-4) == ".png" /*|| f.substr(-4) == ".jpg"*/) })
//没有图片,
if (!images.length) continue;
//去掉原先数据里的
// data.groups[i].keys = arr.filter((f) => { return (f.substr(-4) != ".png" && f.substr(-4) != ".jpg") }).join(",");
//添加新的json,加到atlas里
// if (data.groups[i].keys) data.groups[i].keys += ","
data.groups[i].atlas = name + ".json"
//读取原先路径里的图片,写到tm的文件夹里,并删除原文件夹里的图片
fs.mkdirSync("./released/tm/" + name);
for (var m = 0; m < images.length; m++) {
fs.writeFileSync(
"./released/tm/" + name + "/" + images[m],
fs.readFileSync(path + images[m])
)
del(path + images[m])
}
}
//序列化
fs.writeFileSync(readPath + "res.json", JSON.stringify(data, "", "\t"));
var fs = require("fs");
var del = require('del');
function delDir(path, isSelf) {
let files = [];
if (fs.existsSync(path)) {
files = fs.readdirSync(path);
files.forEach((file, index) => {
let curPath = path + "/" + file;
if (fs.statSync(curPath).isDirectory()) {
delDir(curPath); //递归删除文件夹
} else {
fs.unlinkSync(curPath); //删除文件
}
});
if (!isSelf) fs.rmdirSync(path);
}
}
var paths = './released/';//设置删除路径
// delDir(paths, true);//删除文件夹
del(paths).then(() => {
fs.mkdirSync(paths);
}).catch(()=>{
fs.mkdirSync(paths);
})
// var tasks = [];
// function addTask(task) {
// tasks.push(task);
// }
// function next() {
// if (tasks.length > 0) {
// tasks.shift()();
// } else {
// return;
// }
// }
// var delRel = function () {
// del(paths).then(() => {
// // console.log("del")
// next();
// })
// }
// var createRel = function () {
// fs.mkdirSync(paths);
// // console.log("create")
// next();
// }
// addTask(delRel)
// addTask(createRel)
// next();
\ No newline at end of file
var del = require('del');
del("./released/tm")
\ No newline at end of file
//生成res.json
//遍历资源文件夹,生成
var fs = require('fs');
var path = require("path");
var readPath = "./resource/"
var files = fs.readdirSync(readPath);
var obj = { groups: [] };//每项包括keys合name
files.forEach(function (file) {
//路径
let fPath = path.join(readPath, file);
//只处理文件夹
if (fs.statSync(fPath).isDirectory()) {
//继续读每个子文件夹,json和png名字有相同的,只留json,
var sonFiles = fs.readdirSync(fPath);
//没有文件
if (!sonFiles.length) return
//取出所有json
var jsons = sonFiles.filter((f) => { return f.substr(-5) == ".json" })
//去掉json所带png的图片
sonFiles = sonFiles.filter((f) => { return jsons.indexOf(f.substring(0, f.length - 4) + ".json") == -1 })
//去掉mac上的缓存文件
sonFiles = sonFiles.filter((f) => { return f != '.DS_Store' })
var group = {
keys: "",
name: file
}
for (var i = 0; i < sonFiles.length; i++) {
if (i != 0) group.keys += ",";
group.keys += sonFiles[i]
}
obj.groups.push(group)
}
})
obj.path="./resource/"
console.log("资源更新完成")
//生成json
fs.writeFileSync(readPath + "res.json", JSON.stringify(obj, "", "\t"));
//TS也更新
var endPath = './src/';
var endFile = `export const ResJson = ${JSON.stringify(obj, "", "\t")}`
fs.writeFileSync(endPath + "ResJson.ts", endFile);
\ No newline at end of file
const imagemin = require('imagemin');
// const imageminJpegtran = require('imagemin-jpegtran');imagemin-mozjpeg
const imageminJpegtran = require('imagemin-mozjpeg');
const imageminPngquant = require('imagemin-pngquant');
var fs = require('fs');
var path = require('path');
// 要处理的图片文件夹路径
var altasPath = "./released/resource/"
var folders = getFolders(altasPath);
folders.map(async function (folder) {
const files = await imagemin([altasPath + folder + '/*.{png,jpg}'], {
destination: altasPath + folder,
plugins: [
imageminJpegtran(),
imageminPngquant({
quality: [0.6, 0.8]
})
]
});
if (files && files.length) {
files.forEach((v) => {
console.log("压缩图片成功:", v.sourcePath.substring(v.sourcePath.lastIndexOf("/") + 1, v.sourcePath.length))
})
}
});
function getFolders(dir) {
return fs.readdirSync(dir)
.filter(function (file) {
return fs.statSync(path.join(dir, file)).isDirectory();
});
}
\ No newline at end of file
var fs = require("fs");
// fs.writeFileSync(
// "./released/output.js",
// fs.readFileSync("./output.js")
// )
var endPath = './released/';
fs.writeFileSync(endPath + "output.js",
'import * as FYGE from "fyge-tbmini";\n' +
// 'import * as SvgaParser from "svga-parser";\n' +
fs.readFileSync("./output.js"));
console.log("js生成")
var fs = require("fs");
var path = require('path');
var del = require('del');
var iconv = require('iconv-lite');
const join = require('path').join;
//写入图集的文件夹,将文件夹内所有的json合并,并删除原先json
var readPath = "./released/resource/";
//读取json文件
var data = iconv.decode(fs.readFileSync(readPath + "res.json"), "utf-8");//GBK
//反序列化
data = JSON.parse(data);
var files = fs.readdirSync(readPath);
// let obj = {};
let count = 0;
let countAll = files.length
files.forEach(function (file) {
//路径
let fPath = join(readPath, file);
//只处理文件夹
if (fs.statSync(fPath).isDirectory()) {
//读文件夹fPath里的json文件
fs.readdir(fPath, function (err, files) {
if (err) {
console.warn(err)
} else {
var hasJson
//遍历
for (var i = 0; i < files.length; i++) {
let filename = files[i];
if (filename.indexOf(".json") == -1) continue
hasJson = true;
//获取当前文件的绝对路径
let filedir = path.join(fPath, filename);
let content = fs.readFileSync(filedir, 'utf-8');
let group = getGroupByName(filename.replace(".json", ""), data.groups)
group.atlas = JSON.parse(content);
//删除原先json
del(filedir)
if (++count == countAll) endFun();
}
if(!hasJson)if (++count == countAll) endFun();
//序列化,不格式化,节省内存
}
})
} else {
if (++count == countAll) endFun();
}
})
function endFun() {
console.log("资源配置js生成完毕")
// del(join(readPath, "res.json"))
fs.writeFileSync(readPath + "res.json", JSON.stringify(data, "", "\t"));
}
function getGroupByName(name, groups) {
var group;
for (var i = 0; i < groups.length; i++) {
if (groups[i].name === name) {
group = groups[i];
break;
}
}
return group
}
var fs = require("fs");
var exec = require('child_process').exec;
var iconv = require('iconv-lite');
var del = require('del');
const join = require('path').join;
//写入图集的文件夹
var outPath = "./released/resource/";
//读取散图的文件夹
var readPath = "./released/tm/";
var files = fs.readdirSync(readPath);
files.forEach(function (file) {
//路径
let fPath = join(readPath, file);
//只处理文件夹
if (fs.statSync(fPath).isDirectory()) {
//判断文件夹内是否有图片
if (!judgeHasImage(fPath)) return;
var cli = getTmCmd(fPath, outPath + file + "/", file);
//如果文件夹不存在
if (!fs.existsSync(outPath + file)) {
fs.mkdirSync(outPath + file);
}
else {
//图集文件存在就删除
if (fs.existsSync(outPath + file + "/" + file + ".json")) {
del(outPath + file + "/" + file + ".json")
}
if (fs.existsSync(outPath + file + "/" + file + ".png")) {
del(outPath + file + "/" + file + ".png")
}
}
//执行合图指令
exec(cli, { encoding: 'utf8' }, function (err, stdout, stderr) {
if (err) {
console.log(err);
return;
}
// console.log('stdout:' + stdout);
// console.log('stderr:' + stderr);
console.log('生成图集:' + file);
var pathname = outPath + file + "/" + file + ".json";
//有中文命名时处理
var data = iconv.decode(fs.readFileSync(pathname), "utf-8");//GBK
//反序列化
data = JSON.parse(data); //eval(data)
//重写数据
var obj = {};
var frames = data.frames;
var frameKeys = Object.keys(frames);
for (var i = 0; i < frameKeys.length; i++) {
const name = frameKeys[i];
const data = frames[name];
if (!data.frame) continue;
const sourceSize = data.trimmed !== false && data.sourceSize
? data.sourceSize : data.frame;
obj[name] = {
"x": data.frame.x,
"y": data.frame.y,
"w": data.frame.w,
"h": data.frame.h,
"ox": data.trimmed ? data.spriteSourceSize.x : 0,
"oy": data.trimmed ? data.spriteSourceSize.y : 0,
"sw": sourceSize.w,
"sh": sourceSize.h,
"ro": data.rotated,
}
}
//序列化,不格式化,节省内存
fs.writeFileSync(pathname, JSON.stringify(obj, "", "\t"));
})
}
})
//不同版本参数可能不同,具体情况具体分析
function getTmCmd(src, outPath, name) {
var cli =
'TexturePacker ' + //基础指令
src + //要合图集的文件夹路径
' --format json' + //图集数据格式
' --max-size 4096' + //最大尺寸
' --allow-free-size' +//允许使用最小尺寸输出,webgl最好别设置,现在小程序只有canvas模式,所以用最小尺寸导出吧
' --shape-padding 2' + //图片间隔
' --border-padding 2' + //边界间隔
' --enable-rotation' + //旋转 diable-rotation
' --opt RGBA8888' + //图片像素格式
' --trim' + //裁切透明像素 no-trim
' --sheet ' + outPath + name + '.png' + //图片名字
' --data ' + outPath + name + '.json'; //数据名字
return cli
}
/**
* 对文件使用utf8编码
* @param {string} pathname
*/
function applyUtf8(pathname) {
fs.writeFile(pathname, iconv.decode(fs.readFileSync(pathname), "GBK"), {
encoding: "UTF8"
}, function (err) {
if (err) {
throw err;
}
});
}
/**
* 判断文件夹内是否有图片
* @param {*} path
*/
function judgeHasImage(path) {
var files = fs.readdirSync(path);
for (var i = 0; i < files.length; i++) {
var itm = files[i]
var stat = fs.statSync(path + "/" + itm);
if (stat.isDirectory()) {
//递归读取文件
if (judgeHasImage(path + "/" + itm + "/")) return true;
} else {
if (itm.substr(-4) == ".jpg" || itm.substr(-4) == ".png") return true;
}
}
return false;
}
\ No newline at end of file
var fs = require('fs');
var path = require('path');
const co = require('co');
const OSS = require('ali-oss');
const chalk = require('chalk');
const ProgressBar = require('progress');
class TuiaAutoUpload {
constructor(props, type) {
this.type = type;
const defaultOptions = {
dir: undefined,
originDir: undefined
}
this.options = Object.assign({}, defaultOptions, props);
if (!this.options.dir || !this.options.originDir) {
console.log(chalk.red('缺少参数,初始化失败'))
return;
}
this.init();
}
init() {
var _this = this;
this.client = new OSS({
region: 'oss-cn-hangzhou',
accessKeyId: 'LTAI4Fw25WcfcGv7FvcHoiHK',
accessKeySecret: 'NZk1NtT9J5HFaAolNbtQdzTzLLvLYm',
bucket: _this.type === 'prod' ? 'duiba' : 'daily-duiba'
});
this.bar = new ProgressBar(chalk.yellow(` 文件上传中 [:bar] :current/${this.files().length} :percent :elapseds`), {
complete: '●',
incomplete: '○',
width: 20,
total: this.files().length,
callback: () => {
console.log(chalk.green('\n All complete.'));
console.log(chalk.blue(`\n 本次队列文件共${this.files().length}个,已存在文件${this.existFiles}个,上传文件${this.uploadFiles}个,上传失败文件${this.errorFiles}个\n`));
}
})
return this;
}
files() {
var _this = this;
if (this._files) return this._files;
this._files = [];
/**
* 文件遍历方法
* @param filePath 需要遍历的文件路径
*/
function fileDisplay(filePath) {
//根据文件路径读取文件,返回文件列表
var files = fs.readdirSync(filePath);
files.forEach(function (filename) {
//获取当前文件的绝对路径
var filedir = path.join(filePath, filename);
//根据文件路径获取文件信息,返回一个fs.Stats对象
var stats = fs.statSync(filedir);
var isFile = stats.isFile();//是文件
var isDir = stats.isDirectory();//是文件夹
if (isFile) {
var sep = '/';
if ('win32' == process.platform)
sep = '\\';
var newDirArr = filedir.split(sep);
newDirArr.shift();
_this._files.push(newDirArr.join('/'));
}
if (isDir) {
fileDisplay(filedir);//递归,如果是文件夹,就继续遍历该文件夹下面的文件
}
});
}
//调用文件遍历方法
fileDisplay(this.options.dir);
return this._files;
}
start() {
this.files().map((file, index) => {
let _this = this;
const path1 = path.join(path.resolve(__dirname, '..'), 'released', file);
let originFile;
this.existFiles = 0;
this.uploadFiles = 0;
this.errorFiles = 0;
co(function* () {
const originPath = `${_this.options.originDir}${file}`;
try {
originFile = yield _this.client.head(originPath);
} catch (error) {
originFile = error;
}
if (_this.type === 'prod') {
if (originFile.status === 404) {
yield _this.client.put(originPath, path1);
_this.uploadFiles += 1;
} else {
_this.existFiles += 1;
}
} else if (_this.type === 'dev') {
if (originFile.status === 404 || originFile.status === 200) {
_this.existFiles += 1;
}
yield _this.client.put(originPath, path1, {
headers: {
'Cache-Control': 'no-cache'
}
})
_this.uploadFiles += 1;
}
_this.bar.tick();
}).catch(function (err) {
_this.errorFiles += 1;
console.log(err);
});
});
}
}
const configFileName = 'project.json';
if (!fs.existsSync(configFileName)) {
throw new Error(`${configFileName}不存在.`)
}
let config = fs.readFileSync('project.json');
config = JSON.parse(config + '');
if (!config.type) {
throw new Error(`${configFileName}的type不存在.`)
}
if (!config.name) {
throw new Error(`${configFileName}的name不存在.`)
}
const now = new Date();
const version = Math.round(now.getTime() / 1000);
console.log(`版本号:
${version}`)
const autoupload = new TuiaAutoUpload({
dir: './released/',
// dir: path.join(__dirname, './released/'),
originDir: `/db_games/${config.type}/${config.name}/${version}/`
}, "prod")
autoupload.start()
var iconv = require('iconv-lite');
var readPath = "./released/resource/";
//读取json文件
var data = iconv.decode(fs.readFileSync(readPath + "res.json"), "utf-8");//GBK
//反序列化
data = JSON.parse(data);
data.path = `https://yun.duiba.com.cn/db_games/${config.type}/${config.name}/${version}/resource/`
//写入目标文件夹,可配置,每个项目必须修改,或者直接和project的保持一致(淘宝项目文件固定后)
var endPath = './src/';
var endFile = `export const ResJson = ${JSON.stringify(data, "", "\t")}`
fs.writeFileSync(endPath + "ResJson.ts", endFile);
\ No newline at end of file
import { changeScene, destroyAllCtrls } from "../module/ctrls";
import { RES } from "../module/RES";
import { destroyLayers, layers } from "../module/views/layers";
import { MConst } from "./Global/MConst";
import { ResJson } from "./ResJson";
import { destroyNetData, sendTbNet, TbNetName } from "./TaoBaoNet";
import { GameScenes } from "./scenes/GameScenes";
import { SoundMgr } from "./Mgr/SoundMgr";
/**
* 全局事件,为了和小程序交互
* 有可能多处页面用到,所以单开
*/
export const GDispatcher = new FYGE.EventDispatcher();
export class MainPrizeFell {
//主舞台
stage: FYGE.Stage;
private requestID;
private _pause: boolean;
constructor(canvas: HTMLCanvasElement, tickSeconds: number) {
var sysInfo;
MConst.tickSeconds = tickSeconds;
//建舞台
var stage = new FYGE.Stage(
canvas,
750, //设计宽度,按设计搞给的就行
1624, //设计高度
(sysInfo && sysInfo.windowWidth) || document.body.clientWidth,
(sysInfo && sysInfo.windowHeight) || document.body.clientHeight,
FYGE.RENDERER_TYPE.CANVAS
);
this.stage = stage;
//@ts-ignore
FYGE.gameStage = this.stage;
//开始循环
// FYGE.Stage.flushAll();
//stage初始化
stage.addEventListener(FYGE.Event.INIT_STAGE, this.onAddToStage, this);
//帧率
// var stats = new FYGE.Stats("canva4stats");
//循环
var self = this;
// console.log(FYGE)
loop();
function loop() {
if (!self._pause) {
// stats.begin();
FYGE.Tween.flush();
stage.flush();
// stats.end();
}
//@ts-ignore
self.requestID = FYGE.getRequestAnimationFrame()(loop);
}
}
private onAddToStageComplete() {
console.log("测试-资源加载完成");
//FYGE.GDispatcher.dispatchEvent('addComplete');
}
private async onAddToStage() {
// sendLog(LogType.visit);
//初始化层级
layers.init(this.stage);
console.log("初始化层级完成");
//初始化资源配置
RES.loadConfig(ResJson);
console.log("初始化资源配置完成");
//加载通用资源
await RES.loadGroup("common");
console.log("通用资源加载完成");
// await RES.getRes('startBg.jpg');
// await RES.getRes('assistBG.jpg');
await RES.loadGroup("loading");
console.log("loading资源加载完成");
//打开开始场景
SoundMgr.instance.playSound("bgm", true);
SoundMgr.instance.isMusic = true;
changeScene(GameScenes);
}
//在小程序显示时调用onShow
run() {
this._pause = false;
//@ts-ignore Tween计时清零
FYGE.Tween._lastTime = null;
}
//在小程序隐藏时调用onHide
pause() {
SoundMgr.instance.isMusic = false;
this._pause = true;
}
/**
* 添加全局事件,用于小程序的交互调用
* 一直很犹豫要不要放在main的实例里,还是和Main同级导出,还有上面的pause,run,下面的事件等
* @param name
* @param fun
* @param thisObj
*/
addGlobalEvent(
name: string,
fun: Function,
thisObj?: any,
once: boolean = false
) {
if (once) {
GDispatcher.once(name, fun, thisObj);
} else {
GDispatcher.addEventListener(name, fun, thisObj);
}
}
/**
* 派发全局事件,用于小程序的交互调用
* @param name
* @param data
*/
dispatchGlobalEvent(name: string, data?: any) {
GDispatcher.dispatchEvent(name, data);
}
/**
* 移除全局事件,用于小程序交互调用
* @param name
* @param fun
* @param thisObj
*/
removeGlobalEvent(name: string, fun: Function, thisObj?: any) {
GDispatcher.removeEventListener(name, fun, thisObj);
}
//在小程序页面卸载时调用onUnload,多次销毁后会有问题,再检查
destroy() {
SoundMgr.instance.isMusic = false;
//Tween都移除,注意吧,可能原先的也被移除
FYGE.Tween.removeAllTweens();
// removeAllTimeoutId();//这个再看,尽量用tween的修改
//停掉计时器
FYGE.getCancelAnimationFrame()(this.requestID);
//层级销毁
destroyLayers();
//销毁控制器
destroyAllCtrls();
//舞台销毁
this.stage.destroy();
//全局事件置空
GDispatcher.removeAllEventListener();
//网络数据记录清空
destroyNetData();
}
}
import PrizeFell from "../game/PrizeFell";
export namespace DataMgr {
export let game: PrizeFell = null;
export let minEnableCaptchaScore: number = null;
}
\ No newline at end of file
import UILayer from "../Component/UILayer";
import MTimer from "../Global/MTimer";
export default class DebugMgr extends UILayer {
public enabled: boolean = true;
public enabledGraphic: boolean = true;
private shapeMap = {};
private graphicDebugLayer: FYGE.Container = null;
private uiLayer: FYGE.Container = null;
private log: FYGE.TextField = null;
public test: any = null;
private labelFPS = new FYGE.TextField();
public onClick = () => { }
constructor() {
super();
if (!this.enabled) return;
//创建图形调试层
this.graphicDebugLayer = new UILayer();
this.addChild(this.graphicDebugLayer);
//创建UI层
this.uiLayer = new FYGE.Container();
this.addChild(this.uiLayer);
//创建帧率标签
this.labelFPS.size = 30;
this.labelFPS.fillColor = "rgba(255,255,255,1)";
this.labelFPS.text = "0";
this.labelFPS.x = 20;
this.labelFPS.y = 20;
this.uiLayer.addChild(this.labelFPS);
/* this.log = new engine.Label("Log");
this.log.horizontalCenter = 0;
this.log.top = 50;
this.log.textColor = 0xffffff;
this.log.stroke = 0.5;
this.log.size = 32;
this.uiLayer.addChild(this.log); */
//创建调试按钮
/* let button = new engine.Label("调试");
button.textColor = 0x000000;
button.borderColor = 0x000000;
button.border = true;
button.top = 30;
button.right = 50;
this.uiLayer.addChild(button);
button.onTap(this, () => {
this.onClick();
}); */
}
public setLog(msg: string) {
if (!this.enabled) return;
this.log.text = msg;
}
public drawRect(rect: FYGE.Rectangle, style: GraphicDebug.Style = { color: 0x00ff00, lineSize: 1 }) {
if (!this.enabled || !this.enabledGraphic) return;
let shape = new FYGE.Graphics();
shape.beginFill(style.color);
shape.drawRect(rect.x, rect.y, rect.width, rect.height);
shape.endFill();
this.graphicDebugLayer.addChild(shape);
}
public drawCircle(x: number, y: number, radius: number, style: GraphicDebug.Style = { color: 0x00ff00, lineSize: 1 }) {
if (!this.enabled || !this.enabledGraphic) return;
let shape = new FYGE.Graphics();
shape.beginFill(style.color);
shape.drawCircle(x, y, radius);
shape.endFill();
this.graphicDebugLayer.addChild(shape);
}
public drawLine(line: GraphicDebug.Line, style: GraphicDebug.Style = { color: 0x00ff00, lineSize: 1 }) {
if (!this.enabled || !this.enabledGraphic) return;
let shape = new FYGE.Graphics();
shape.beginFill(style.color);
shape.moveTo(line.startX, line.startY);
shape.lineTo(line.endX, line.endY);
shape.endFill();
this.graphicDebugLayer.addChild(shape);
}
public updateLine(key: string, line: GraphicDebug.Line, style: GraphicDebug.Style = { color: 0x00ff00, lineSize: 1 }) {
if (!this.enabled || !this.enabledGraphic) return;
let shape: FYGE.Graphics = this.shapeMap[key];
if (!shape) {
shape = new FYGE.Graphics();
this.graphicDebugLayer.addChild(shape);
this.shapeMap[key] = shape;
}
shape.clear();
shape.beginFill(style.color);
shape.moveTo(line.startX, line.startY);
shape.lineTo(line.endX, line.endY);
shape.endFill();
}
public updateRect(key: string, rect: FYGE.Rectangle, style: GraphicDebug.Style = { color: 0x00ff00, lineSize: 1 }) {
if (!this.enabled || !this.enabledGraphic) return;
let shape: FYGE.Graphics = this.shapeMap[key];
if (!shape) {
shape = new FYGE.Graphics();
this.graphicDebugLayer.addChild(shape);
this.shapeMap[key] = shape;
}
shape.clear();
shape.beginFill(style.color);
shape.drawRect(rect.x, rect.y, rect.width, rect.height);
shape.endFill();
}
public updateCircle(key: string, x: number, y: number, radius: number, style: GraphicDebug.Style = { color: 0x00ff00, lineSize: 1 }) {
if (!this.enabled || !this.enabledGraphic) return;
let shape: FYGE.Graphics = this.shapeMap[key];
if (!shape) {
shape = new FYGE.Graphics();
this.graphicDebugLayer.addChild(shape);
this.shapeMap[key] = shape;
}
shape.clear();
shape.beginFill(style.color);
shape.drawCircle(x, y, radius);
shape.endFill();
}
public clearShape(key: string) {
if (!this.enabled || !this.enabledGraphic) return;
let shape: FYGE.Graphics = this.shapeMap[key];
if (!shape) {
return;
}
delete this.shapeMap[key];
//@ts-ignore
shape.dispose();
}
init(context: FYGE.Container) {
context.addChild(this);
MTimer.onFrame("DebugMgr", this.onUpdate, this);
}
private lastFrameData: { runTime: number, frameCount: number } = { runTime: 0, frameCount: 0 };
private curFrameData: { runTime: number, frameCount: number } = { runTime: 0, frameCount: 0 };
private resetTimer = 0;
private onUpdate(dt: number) {
this.curFrameData.runTime += dt;
this.curFrameData.frameCount += 1;
this.resetTimer += dt;
let average = (this.curFrameData.runTime + this.lastFrameData.runTime) / (this.curFrameData.frameCount + this.lastFrameData.frameCount)
if (this.resetTimer > 200) {
this.labelFPS.text = Math.round(1000 / average).toString();
this.lastFrameData.runTime = this.curFrameData.runTime;
this.lastFrameData.frameCount = this.curFrameData.frameCount;
this.curFrameData.runTime = 0;
this.curFrameData.frameCount = 0;
this.resetTimer = 0;
}
}
private static _instance: DebugMgr = null;
public static get instance(): DebugMgr {
if (!this._instance) {
this._instance = new DebugMgr();
}
return this._instance;
}
}
export namespace GraphicDebug {
export interface Style {
color: number;
lineSize: number;
}
export interface Line {
startX: number;
startY: number;
endX: number;
endY: number;
}
}
\ No newline at end of file
import MTimer from "../Global/MTimer";
export default abstract class GameMgr {
constructor(private name: string) { }
public onInit(): void {
MTimer.onFrame(this.name, this.onUpdate, this);
}
public onDestroy() {
MTimer.removeOnFrame(this.name);
}
protected onUpdate(dt: number) {
}
public pause: boolean = false
}
\ No newline at end of file
import { DataMgr } from "./DataMgr";
import { MConfigs } from "../Global/MConfigs";
import GuideMask from "../game/GuideMask";
import Pot from "../game/Pot";
import Food from "../game/Food";
export default class GuideMgr {
private static _instance: GuideMgr = null;
public static get instance(): GuideMgr {
if (!GuideMgr._instance) {
GuideMgr._instance = new GuideMgr();
}
return GuideMgr._instance;
}
public get guideFlag(): boolean {
var key = "prizeFell.guideFlagKey";
//@ts-ignore
return my ? my.getStorageSync({ key: key }).data != "false"
: localStorage.getItem(key) != "false";
}
public set guideFlag(v: boolean) {
//@ts-ignore
if (my) {
//@ts-ignore
my.setStorageSync({
key: "prizeFell.guideFlagKey",
data: v ? "true" : "false",
});
} else {
localStorage.setItem(
"prizeFell.guideFlagKey",
v ? "true" : "false"
);
}
}
set container(c) {
this._container = c;
}
private _container: FYGE.Container;
private currentGuideMask: GuideMask = null;
//first
public drawFirstGuide(isEnd: boolean = false) {
DataMgr.game.pause = true;
this.currentGuideMask = new GuideMask();
this.currentGuideMask.onClick = (context) => {
//@ts-ignore
context.dispose();
this.currentGuideMask = null;
DataMgr.game.pause = false;
if (isEnd) {
this.guideFlag = false;
}
};
this._container.addChild(this.currentGuideMask);
this.currentGuideMask.drawFirst();
}
//second
public drawSecondGuide(foods: Array<Food>, isEnd: boolean = false) {
DataMgr.game.pause = true;
this.currentGuideMask = new GuideMask();
this.currentGuideMask.onClick = (context) => {
//@ts-ignore
context.dispose();
this.currentGuideMask = null;
DataMgr.game.pause = false;
if (isEnd) {
this.guideFlag = false;
}
};
this._container.addChild(this.currentGuideMask);
this.currentGuideMask.drawSecond(foods);
}
}
import { Howl } from "howler";
export const starMP3Name = {
bgm:
"https://yun.duiba.com.cn/aurora/assets/9ace0b569cbc43c61eb18a84f5d36dcd60423819.mp3",
shoot:
"https://yun.duiba.com.cn/aurora/assets/78d86205f37e736f922bf476a4b278dd4c5d029c.mp3",
collect:
"https://yun.duiba.com.cn/aurora/assets/564b39022bfe147f9eb4bdf6a6b95142186df265.mp3",
dong:
"https://yun.duiba.com.cn/aurora/assets/f259780c1de05136d15c0aa4b5a72b91ff871f16.mp3",
boom:
"https://yun.duiba.com.cn/aurora/assets/ed6f41a38d28e03acf791dd3672c0364e6754821.mp3",
};
export class SoundMgr {
private static _instance: SoundMgr = null;
public static get instance(): SoundMgr {
if (!this._instance) {
this._instance = new SoundMgr();
}
return this._instance;
}
private soundHash: { [key: string]: Howl } = {};
//音乐播放
public async playSound(name: string, loop: boolean) {
if (!this._isMusic) return;
console.log("播放音乐+++", name);
let sound: Howl;
let src = starMP3Name[name];
//循环的,且有缓存,取缓存的
if (this.soundHash[src] && loop) sound = this.soundHash[src];
//没有就新建
if (!sound) sound = new Howl({ src: [src], autoplay: false, loop });
//记录下,方便停止
this.soundHash[src] = sound;
//不循环删除缓存
if (!loop)
sound.on("stop", function () {
delete this.soundHash[src];
});
//播放
sound.play();
//返回一个,可以自行控制
return sound;
}
//音乐停止
public async stopSound(name: string) {
let src = starMP3Name[name];
if (this.soundHash[src]) this.soundHash[src].stop();
}
//是否具有音乐
private _isMusic: boolean = true;
public set isMusic(value: boolean) {
this._isMusic = value;
console.log("音乐操作++");
if (!value) {
this.stopSound("bgm");
} else {
this.playSound("bgm", true);
}
}
public get isMusic(): boolean {
return this._isMusic;
}
}
import FrameAnimation from "../component/FrameAnimation";
import { Pool, PoolGroup, PoolElement } from "../Component/Pool";
export class PoolFrameAnimation extends FrameAnimation implements PoolElement {
onElementInit() {
this.visible = true;
this.curPos = 0;
}
onElementRecycle() {
this.visible = false;
}
}
class AnimationPool extends Pool<PoolFrameAnimation> {
public spwan(key: string): PoolFrameAnimation {
if (this.data.length > 0) {
const element = this.data.shift();
element.onElementInit();
return element;
} else {
let anim = new PoolFrameAnimation(key);
this.layer.addChild(anim);
return anim;
}
}
}
export default class AnimationPoolGroup extends PoolGroup<PoolFrameAnimation> {
public spwan(key: string) {
if (!this.data[key]) {
this.data[key] = new AnimationPool(this.layer);
}
const element = this.data[key].spwan(key);
return element;
}
}
\ No newline at end of file
import { DataMgr } from "../Mgr/DataMgr";
import Food from "../game/Food";
import { Pool, PoolGroup } from "../Component/Pool";
export class FoodPool extends Pool<Food>{
public spwan(id: number) {
let element: Food = null;
if (this.data.length > 0) {
element = this.data.shift();
element.onElementInit();
} else {
element = new Food(id);
this.layer.addChild(element);
}
DataMgr.game._foodList.push(element);
return element;
}
public recycle(element: Food) {
super.recycle(element);
DataMgr.game._foodList = DataMgr.game._foodList.filter(e => e !== element);
}
};
// export class FoodPoolGroup extends PoolGroup<Food>{
// public spwan(id: number) {
// const key = id.toString();
// if (!this.data[key]) {
// const Food =
// this.data[key] = new FoodPool(this.layer)
// }
// let element = this.data[key].spwan(id);
// element.poolKey = key;
// return element;
// }
// }
\ No newline at end of file
export const ResJson = {
"groups": [
{
"keys": "comCloseBtn.png,toastBg.png,waitingBg.png,waitingRot.png",
"name": "common",
"atlas": {
"comCloseBtn.png": {
"x": 2,
"y": 374,
"w": 50,
"h": 50,
"ox": 0,
"oy": 0,
"sw": 50,
"sh": 50,
"ro": false
},
"toastBg.png": {
"x": 2,
"y": 2,
"w": 460,
"h": 130,
"ox": 0,
"oy": 0,
"sw": 460,
"sh": 130,
"ro": false
},
"waitingBg.png": {
"x": 2,
"y": 134,
"w": 160,
"h": 180,
"ox": 0,
"oy": 0,
"sw": 160,
"sh": 180,
"ro": false
},
"waitingRot.png": {
"x": 2,
"y": 316,
"w": 56,
"h": 56,
"ox": 0,
"oy": 0,
"sw": 56,
"sh": 56,
"ro": false
}
}
},
{
"keys": "score_0.png,score_1.png,score_2.png,score_3.png,score_4.png,score_5.png,score_6.png,score_7.png,score_8.png,score_9.png,score_f.png",
"name": "dialogScore",
"atlas": {
"score_0.png": {
"x": 57,
"y": 2,
"w": 32,
"h": 49,
"ox": 5,
"oy": 0,
"sw": 42,
"sh": 49,
"ro": true
},
"score_1.png": {
"x": 108,
"y": 2,
"w": 16,
"h": 45,
"ox": 5,
"oy": 0,
"sw": 26,
"sh": 45,
"ro": false
},
"score_2.png": {
"x": 2,
"y": 117,
"w": 32,
"h": 47,
"ox": 5,
"oy": 0,
"sw": 42,
"sh": 47,
"ro": true
},
"score_3.png": {
"x": 57,
"y": 36,
"w": 23,
"h": 49,
"ox": 5,
"oy": 0,
"sw": 33,
"sh": 49,
"ro": true
},
"score_4.png": {
"x": 52,
"y": 92,
"w": 33,
"h": 47,
"ox": 5,
"oy": 0,
"sw": 43,
"sh": 47,
"ro": true
},
"score_5.png": {
"x": 51,
"y": 127,
"w": 27,
"h": 47,
"ox": 5,
"oy": 0,
"sw": 37,
"sh": 47,
"ro": true
},
"score_6.png": {
"x": 2,
"y": 55,
"w": 30,
"h": 48,
"ox": 5,
"oy": 0,
"sw": 40,
"sh": 48,
"ro": true
},
"score_7.png": {
"x": 2,
"y": 151,
"w": 32,
"h": 46,
"ox": 5,
"oy": 0,
"sw": 42,
"sh": 46,
"ro": true
},
"score_8.png": {
"x": 52,
"y": 61,
"w": 29,
"h": 48,
"ox": 5,
"oy": 0,
"sw": 39,
"sh": 48,
"ro": true
},
"score_9.png": {
"x": 2,
"y": 87,
"w": 28,
"h": 48,
"ox": 5,
"oy": 0,
"sw": 38,
"sh": 48,
"ro": true
},
"score_f.png": {
"x": 2,
"y": 2,
"w": 53,
"h": 51,
"ox": 5,
"oy": 0,
"sw": 63,
"sh": 51,
"ro": false
}
}
},
{
"keys": "closeBtn1.png,gameAgain.png,gameOverBg1.png",
"name": "gameOverPanel",
"atlas": {
"closeBtn1.png": {
"x": 376,
"y": 733,
"w": 48,
"h": 48,
"ox": 0,
"oy": 0,
"sw": 48,
"sh": 48,
"ro": false
},
"gameAgain.png": {
"x": 2,
"y": 733,
"w": 372,
"h": 88,
"ox": 0,
"oy": 0,
"sw": 372,
"sh": 88,
"ro": false
},
"gameOverBg1.png": {
"x": 2,
"y": 2,
"w": 729,
"h": 484,
"ox": 0,
"oy": 0,
"sw": 729,
"sh": 484,
"ro": true
}
}
},
{
"keys": "add_score_0.png,add_score_1.png,add_score_2.png,add_score_3.png,add_score_4.png,add_score_5.png,add_score_6.png,add_score_7.png,add_score_8.png,add_score_9.png,bangbangBall.png,baohuzhao.png,boom.png,closeMusic.png,cowItem.png,double.png,gameAgain.png,gameBg.jpg,getIce.png,iceBlock.png,iknowbtn.png,left.png,lizhiBall.png,main_countdown.png,main_countdown2.png,mushRoom.png,next.png,openMusic.png,penguin.png,point.png,pot.png,right.png,scoreTitle.png,score_num_0.png,score_num_1.png,score_num_2.png,score_num_3.png,score_num_4.png,score_num_5.png,score_num_6.png,score_num_7.png,score_num_8.png,score_num_9.png",
"name": "PrizeFell",
"atlas": {
"add_score_0.png": {
"x": 223,
"y": 685,
"w": 38,
"h": 29,
"ox": 0,
"oy": 0,
"sw": 38,
"sh": 29,
"ro": true
},
"add_score_1.png": {
"x": 172,
"y": 694,
"w": 28,
"h": 29,
"ox": 0,
"oy": 0,
"sw": 28,
"sh": 29,
"ro": true
},
"add_score_2.png": {
"x": 133,
"y": 694,
"w": 37,
"h": 27,
"ox": 0,
"oy": 0,
"sw": 37,
"sh": 27,
"ro": false
},
"add_score_3.png": {
"x": 264,
"y": 548,
"w": 37,
"h": 28,
"ox": 0,
"oy": 0,
"sw": 37,
"sh": 28,
"ro": true
},
"add_score_4.png": {
"x": 478,
"y": 630,
"w": 40,
"h": 31,
"ox": 0,
"oy": 0,
"sw": 40,
"sh": 31,
"ro": true
},
"add_score_5.png": {
"x": 258,
"y": 669,
"w": 38,
"h": 29,
"ox": 0,
"oy": 0,
"sw": 38,
"sh": 29,
"ro": true
},
"add_score_6.png": {
"x": 293,
"y": 652,
"w": 39,
"h": 30,
"ox": 0,
"oy": 0,
"sw": 39,
"sh": 30,
"ro": false
},
"add_score_7.png": {
"x": 261,
"y": 628,
"w": 39,
"h": 30,
"ox": 0,
"oy": 0,
"sw": 39,
"sh": 30,
"ro": true
},
"add_score_8.png": {
"x": 261,
"y": 587,
"w": 39,
"h": 30,
"ox": 0,
"oy": 0,
"sw": 39,
"sh": 30,
"ro": true
},
"add_score_9.png": {
"x": 264,
"y": 509,
"w": 37,
"h": 28,
"ox": 0,
"oy": 0,
"sw": 37,
"sh": 28,
"ro": true
},
"bangbangBall.png": {
"x": 316,
"y": 285,
"w": 90,
"h": 166,
"ox": 0,
"oy": 0,
"sw": 90,
"sh": 166,
"ro": true
},
"baohuzhao.png": {
"x": 2,
"y": 92,
"w": 312,
"h": 221,
"ox": 0,
"oy": 0,
"sw": 312,
"sh": 221,
"ro": false
},
"boom.png": {
"x": 294,
"y": 377,
"w": 126,
"h": 84,
"ox": 0,
"oy": 0,
"sw": 126,
"sh": 84,
"ro": false
},
"closeMusic.png": {
"x": 69,
"y": 661,
"w": 62,
"h": 62,
"ox": 0,
"oy": 0,
"sw": 62,
"sh": 62,
"ro": false
},
"cowItem.png": {
"x": 398,
"y": 580,
"w": 78,
"h": 70,
"ox": 0,
"oy": 0,
"sw": 78,
"sh": 70,
"ro": false
},
"double.png": {
"x": 81,
"y": 586,
"w": 76,
"h": 73,
"ox": 0,
"oy": 0,
"sw": 76,
"sh": 73,
"ro": false
},
"gameAgain.png": {
"x": 2,
"y": 2,
"w": 372,
"h": 88,
"ox": 0,
"oy": 0,
"sw": 372,
"sh": 88,
"ro": false
},
"getIce.png": {
"x": 2,
"y": 315,
"w": 290,
"h": 143,
"ox": 0,
"oy": 0,
"sw": 290,
"sh": 143,
"ro": false
},
"iceBlock.png": {
"x": 2,
"y": 586,
"w": 77,
"h": 70,
"ox": 0,
"oy": 0,
"sw": 77,
"sh": 70,
"ro": false
},
"iknowbtn.png": {
"x": 2,
"y": 523,
"w": 260,
"h": 61,
"ox": 0,
"oy": 0,
"sw": 260,
"sh": 61,
"ro": false
},
"left.png": {
"x": 2,
"y": 658,
"w": 65,
"h": 43,
"ox": 0,
"oy": 0,
"sw": 65,
"sh": 43,
"ro": false
},
"lizhiBall.png": {
"x": 422,
"y": 377,
"w": 88,
"h": 103,
"ox": 0,
"oy": 0,
"sw": 88,
"sh": 103,
"ro": false
},
"main_countdown.png": {
"x": 2,
"y": 703,
"w": 61,
"h": 61,
"ox": 0,
"oy": 0,
"sw": 61,
"sh": 61,
"ro": false
},
"main_countdown2.png": {
"x": 504,
"y": 2,
"w": 4,
"h": 21,
"ox": 0,
"oy": 0,
"sw": 4,
"sh": 21,
"ro": false
},
"mushRoom.png": {
"x": 294,
"y": 560,
"w": 102,
"h": 90,
"ox": 0,
"oy": 0,
"sw": 102,
"sh": 90,
"ro": false
},
"next.png": {
"x": 2,
"y": 460,
"w": 260,
"h": 61,
"ox": 0,
"oy": 0,
"sw": 260,
"sh": 61,
"ro": false
},
"openMusic.png": {
"x": 159,
"y": 630,
"w": 62,
"h": 62,
"ox": 0,
"oy": 0,
"sw": 62,
"sh": 62,
"ro": false
},
"penguin.png": {
"x": 294,
"y": 463,
"w": 95,
"h": 120,
"ox": 0,
"oy": 0,
"sw": 95,
"sh": 120,
"ro": true
},
"point.png": {
"x": 416,
"y": 482,
"w": 94,
"h": 96,
"ox": 0,
"oy": 0,
"sw": 94,
"sh": 96,
"ro": false
},
"pot.png": {
"x": 376,
"y": 2,
"w": 244,
"h": 126,
"ox": 0,
"oy": 0,
"sw": 244,
"sh": 126,
"ro": true
},
"right.png": {
"x": 159,
"y": 586,
"w": 65,
"h": 42,
"ox": 0,
"oy": 0,
"sw": 65,
"sh": 42,
"ro": false
},
"scoreTitle.png": {
"x": 316,
"y": 248,
"w": 189,
"h": 35,
"ox": 0,
"oy": 0,
"sw": 189,
"sh": 35,
"ro": false
},
"score_num_0.png": {
"x": 316,
"y": 92,
"w": 33,
"h": 49,
"ox": 1,
"oy": 1,
"sw": 35,
"sh": 51,
"ro": true
},
"score_num_1.png": {
"x": 484,
"y": 285,
"w": 17,
"h": 47,
"ox": 1,
"oy": 1,
"sw": 19,
"sh": 49,
"ro": false
},
"score_num_2.png": {
"x": 226,
"y": 586,
"w": 33,
"h": 48,
"ox": 1,
"oy": 1,
"sw": 35,
"sh": 50,
"ro": false
},
"score_num_3.png": {
"x": 316,
"y": 190,
"w": 23,
"h": 49,
"ox": 1,
"oy": 1,
"sw": 25,
"sh": 51,
"ro": false
},
"score_num_4.png": {
"x": 223,
"y": 636,
"w": 33,
"h": 47,
"ox": 1,
"oy": 1,
"sw": 35,
"sh": 49,
"ro": false
},
"score_num_5.png": {
"x": 264,
"y": 460,
"w": 28,
"h": 47,
"ox": 1,
"oy": 1,
"sw": 30,
"sh": 49,
"ro": false
},
"score_num_6.png": {
"x": 478,
"y": 580,
"w": 31,
"h": 48,
"ox": 1,
"oy": 1,
"sw": 33,
"sh": 50,
"ro": false
},
"score_num_7.png": {
"x": 341,
"y": 190,
"w": 33,
"h": 48,
"ox": 1,
"oy": 1,
"sw": 35,
"sh": 50,
"ro": false
},
"score_num_8.png": {
"x": 316,
"y": 127,
"w": 30,
"h": 49,
"ox": 1,
"oy": 1,
"sw": 32,
"sh": 51,
"ro": true
},
"score_num_9.png": {
"x": 316,
"y": 159,
"w": 29,
"h": 49,
"ox": 1,
"oy": 1,
"sw": 31,
"sh": 51,
"ro": true
}
}
}
],
"path": "https://yun.duiba.com.cn/db_games/activity/kickball-feile/1601100368/resource/"
}
\ No newline at end of file
import { showToast, wait, clearWait } from "../module/ctrls";
import { GDispatcher } from "./MainPrizeFell";
//接口枚举
export enum TbNetName {
/** 最终提交接口 */
submitFinal = "submitFinal",
}
//返回数据类型
interface dataOut {
success: boolean;
data?: any;
code?: string;
message?: string;
}
//记录数据
let dataRecord: {
[name: string]: any;
} = {};
/**
* 发送接口
* @param netName
* @param parameter
* @param callback
*/
export function sendTbNet(
netName: TbNetName,
parameter?: any,
callback?: (success: boolean, res?: dataOut) => void,
hideMsg: boolean = false
): Promise<dataOut> {
return new Promise((resolve, reject) => {
console.warn("接口发送", netName, JSON.stringify(parameter));
//@ts-ignore 本地开发,直接取数据
// if (!my) {
// // console.warn('确认调用方向')
// var url = "../../mock/json/" + netName + ".json";
// fetchAsync(url).then(
// (data) => {
// //记录数据
// dataRecord[netName] = data;
// //统一错误信息提示
// if (!hideMsg && !data.success) showToast(data.message || "网络异常");
// //回调
// callback && callback(data.success, data);
// resolve(data);
// console.log(
// `\n%c[ mock ]\n` +
// `NAME : ${netName} \n` +
// `STATE : %o \n` +
// `PARAM : %o \n` +
// `%cDATA : %o \n`,
// `${data.success ? "color:green" : "color:red"}`,
// data.success,
// parameter,
// `${data.success ? "color:green" : "color:red"}`,
// data
// );
// },
// () => {}
// );
// return;
// }
let fun = function (e: { type: string; data: dataOut }) {
//移除事件
GDispatcher.removeEventListener(netName, fun);
var d = e.data;
//记录数据
dataRecord[netName] = d;
//统一错误信息提示,d.data为了区分网络超时
if (!hideMsg && !d.success) showToast(d.message || "网络异常");
//执行回调
callback && callback(d.success, d);
resolve(d);
console.log(
`\n%c[ mock11 ]\n` +
`NAME : ${netName} \n` +
`STATE : %o \n` +
`PARAM : %o \n` +
`%cDATA : %o \n`,
`${d.success ? "color:green" : "color:red"}`,
d.success,
parameter,
`${d.success ? "color:green" : "color:red"}`,
d
);
console.log(JSON.stringify(d));
};
//添加事件接收接口返回信息
GDispatcher.addEventListener(netName, fun);
//用事件方式吧,派发事件发接口,,,,注意很多独有的事件名别重了,onHide,onShow,onMessage等
GDispatcher.dispatchEvent({ type: "onMessage" }, { netName, parameter });
});
}
/**
* 获取数据
* @param netName
*/
export function getTbData(netName: TbNetName): dataOut {
return dataRecord[netName] || null;
}
//销毁数据
export function destroyNetData() {
dataRecord = {};
}
async function fetchAsync(url: string) {
// await response of fetch call
let response = await fetch(url);
// only proceed once promise is resolved
let data = await response.json();
// only proceed once second promise is resolved
return data;
}
import { RES } from "../module/RES";
/**
* 定制,记录一些全局量和方法
*/
export class Tool {
/**
* 状态,1为正常流程,2为注册返回页,3为分享落地页,4为喜哥链接返回
*/
public static status;
/**
* 是否第一次
*/
public static isFirst: boolean;
/**
* 缓存key
*/
public static cacheKey: string = "hadCompleteHaokelai";
/**
* 初始化一些数据,比如环境参数等
*/
public static init() {
//是否第一次
// if (GTool.readCache(this.cacheKey)) {
// this.isFirst = true
// }
}
public static getSprite(imageName: string, x: number = 0, y: number = 0) {
var sprite = new FYGE.Sprite(RES.getRes(imageName));
sprite.x = x;
sprite.y = y;
return sprite;
}
/**
*
* @param txt
* @param size
* @param color
* @param textWidth
* @param align
* @param x
* @param y
*/
public static getText(
txt: string,
size: number,
color: string = "#000000",
align: FYGE.TEXT_ALIGN = FYGE.TEXT_ALIGN.LEFT,
textWidth: number = 0,
x: number = 0,
y: number = 0
): FYGE.TextField {
var text = new FYGE.TextField();
text.fillColor = color;
text.size = size;
text.textWidth = textWidth;
text.textAlign = align;
text.x = x;
text.y = y;
text.text = txt;
return text;
}
/**
* 左上角原点
* @param width
* @param height
* @param color
* @param alpha
* @param radius
* @param x
* @param y
*/
public static getRect(
width: number,
height: number,
color: number = 0xff0000,
alpha: number = 1,
radius: number = 0,
x: number = 0,
y: number = 0
): FYGE.Graphics {
var g = new FYGE.Graphics();
g.beginFill(color);
g.alpha = alpha;
if (!radius) {
g.drawRect(0, 0, width, height);
} else {
g.drawRoundedRect(0, 0, width, height, radius);
}
g.endFill();
g.position.set(x, y);
return g;
}
public static getCircle(
radius: number = 10,
color: number = 0xff0000,
alpha: number = 1,
x: number = 0,
y: number = 0
): FYGE.Graphics {
var g = new FYGE.Graphics();
g.beginFill(color);
g.alpha = alpha;
g.drawCircle(0, 0, radius);
g.endFill();
g.position.set(x, y);
return g;
}
/**
* 总行数
*/
public static rowNum = 4;
/**
* 总列数
*/
public static colNum = 4;
/**
* 格子宽度
*/
public static width = 125;
/**
* 格子高度
*/
public static height = 125;
//整体偏移X,
public static offsetX = 106;
//整体偏移Y
public static offsetY = 600;
/**
* row和col转换到index的hashMap
*/
private static rcToIndexMap = {};
/**
* index到row和col的hashMap
*/
private static indexToRcMap: [number, number][] = [];
/**
* 行列位置,记录每个格子中心点的位置吧
*/
private static rowColPositions = {};
/**
* 索引位置
*/
private static indexPositions: [number, number][] = [];
/**
* 初始化数据
* 提前的缓存数据,千万别修改,因为给出的数据都没有深拷贝过
*/
public static initLatData() {
//位置信息
var spaceX = this.width + 11,
spaceY = this.height + 11,
offsetX = this.offsetX + this.width / 2,
offsetY = this.offsetY + this.height / 2;
for (var i = 0; i < this.rowNum; i++) {
for (var j = 0; j < this.colNum; j++) {
this.rcToIndexMap["" + i + j] = i * this.colNum + j;
this.indexToRcMap[i * this.colNum + j] = [i, j];
this.rowColPositions["" + i + j] = [
offsetX + j * spaceX,
offsetY + i * spaceY,
];
this.indexPositions[i * this.colNum + j] = [
offsetX + j * spaceX,
offsetY + i * spaceY,
];
}
}
}
/**
* row和col获得index值
* @param row
* @param col
*/
public static rcToIndex(row: number, col: number): number {
var key = "" + row + col;
return this.rcToIndexMap[key];
}
/**
* index获得row和col,返回的是数组,0是row,1是col
* @param index
*/
public static indexToRc(index: number): [number, number] {
return this.indexToRcMap[index];
}
/**
* 根据row,col得到位置信息
* @param row
* @param col
* @return 类似数组[111,222],0是x坐标,1是y坐标
*/
public static getPositionByRc(row: number, col: number): [number, number] {
var key = "" + row + col;
return this.rowColPositions[key];
}
/**
* 根据index得到位置信息
* @param index
* @return 类似数组[111,222],0是x坐标,1是y坐标
*/
public static getPositionByIndex(index: number): [number, number] {
return this.indexPositions[index];
}
}
/* type AltaData = {
key: string,
frameRate: number,
frames: {
x: number, //x,y,w,h为图集上的切图位置数据
y: number,
w: number,
h: number
}[]
} */
import GameMgr from "../Mgr/GameMgr";
import { RES } from "../../module/RES";
import { DataMgr } from "../Mgr/DataMgr";
interface Frame {
x: number,
y: number,
texture: FYGE.Texture
}
export class FrameAnimationMgr extends GameMgr {
constructor() { super("FrameAnimationMgr") }
public playingAnimations: FrameAnimation[] = [];
protected onUpdate() {
if (this.pause) return;
const filters: FrameAnimation[] = [];
let anim: FrameAnimation = null;
for (let i = 0; i < this.playingAnimations.length; i++) {
anim = this.playingAnimations[i];
anim.onUpdate();
if (anim.curPos >= anim.frameCount) {
anim.onCompleted && anim.onCompleted();
} else {
filters.push(anim);
}
}
this.playingAnimations = filters;
}
}
export default class FrameAnimation extends FYGE.Container {
private frames: Frame[] = [];
public frameCount: number = 0;
public curPos: number = 0;
private frameTimer: number = 0;
private frameRate: number = 60;
private sprite: FYGE.Sprite = new FYGE.Sprite;
private static caches: {
[key: string]: {
frameCount: number,
frameRate: number,
frames: Frame[]
}
} = {};
public static loadRes(texture: FYGE.Texture, egretData: any) {
let name: string = null;
const mc = egretData.mc;
for (let key in mc) { name = key; break; }
if (!FrameAnimation.caches[name]) {
let altaData = {};
for (let i in egretData.res) {
altaData[name + "_" + i] = egretData.res[i];
}
const textures = FYGE.createTextureSheet(texture.baseTexture, altaData);
let frames: Frame[] = [];
const framesData = mc[name].frames;
for (let i in framesData) {
frames[i] = {
x: framesData[i].x,
y: framesData[i].y,
texture: textures[name + "_" + framesData[i].res]
}
}
FrameAnimation.caches[name] = {
frameRate: mc[name].frameRate,
frameCount: Object.keys(altaData).length,
frames: frames
}
}
}
constructor(key: string) {
super();
if (!FrameAnimation.caches[key]) {
console.error("unloaded animation:" + key);
return;
}
this.frames = FrameAnimation.caches[key].frames;
this.frameCount = Object.keys(this.frames).length;
this.frameRate = FrameAnimation.caches[key].frameRate;
this.addChild(this.sprite);
}
onUpdate() {
if (this.frameTimer >= 60 / this.frameRate) {
if (this.curPos >= this.frameCount) {
return;
} else {
const frameData = this.frames[this.curPos];
this.sprite.texture = frameData.texture;
this.sprite.x = frameData.x;
this.sprite.y = frameData.y;
}
this.curPos++;
this.frameTimer = 0;
} else {
this.frameTimer++;
}
}
play() {
DataMgr.game._animationMgr.playingAnimations.push(this);
}
onCompleted: () => void;
}
\ No newline at end of file
interface MEventData<T> {
callback: T,
thisObj: any,
bindFunc?: any
}
export default class MEvent<T extends Function>{
private list: MEventData<T>[] = [];
private isTraversing = false;
private deleteList: MEventData<T>[] = [];
public add(callback: T, thisObj?: any) {
this.list.push({
callback: callback,
thisObj: thisObj,
bindFunc: thisObj ? callback.bind(thisObj) : undefined
});
}
public clear() {
if (this.isTraversing) {
this.deleteList.concat(this.list);
} else {
this.list = [];
}
}
public remove(callback: T, thisObj?: any) {
if (this.isTraversing) {
this.deleteList.push({
callback: callback,
thisObj: thisObj
});
} else {
this.list = this.list.filter(e => e.callback !== callback || e.thisObj !== thisObj);
}
}
public call(...args: any[]) {
this.isTraversing = true;
let item: MEventData<T> = null;
for (let i = 0; i < this.list.length; i++) {
item = this.list[i];
if (item.bindFunc) {
item.bindFunc(...args);
} else {
item.callback(...args);
}
}
for (let i = 0; i < this.deleteList.length; i++) {
this.list = this.list.filter(e => e.callback !== this.deleteList[i].callback || e.thisObj !== this.deleteList[i].thisObj);
}
this.deleteList = [];
this.isTraversing = false;
}
}
\ No newline at end of file
export abstract class PoolGroup<T extends PoolElement>{
constructor(protected layer: FYGE.Container) { }
protected data: { [key: string]: Pool<T> } = {}
public recycle(key: string, element: T) {
this.data[key].recycle(element);
}
public abstract spwan(...args: any[]): T;
}
export abstract class Pool<T extends PoolElement>{
constructor(protected layer: FYGE.Container) { }
protected data: T[] = [];
public recycle(element: T) {
element.onElementRecycle();
this.data.push(element);
}
public abstract spwan(...args: any[]): T;
}
export interface PoolElement {
/**回收元素时的调用 */
onElementRecycle(): void;
onElementInit(): void;
poolKey?: string;
}
\ No newline at end of file
import { MConst } from "../Global/MConst";
export default class UILayer extends FYGE.Container {
constructor() {
super();
this.width = MConst.DesignResolution.width;
this.height = MConst.DesignResolution.height;
}
}
\ No newline at end of file
import { sendTbNet, TbNetName, getTbData } from "../TaoBaoNet"
export default async (score: number) => {
const params = {
score: score,
};
return await sendTbNet(TbNetName.submitFinal, params)
}
\ No newline at end of file
import GameComponent from "../Game/GameComponent";
import GameObject from "../Game/GameObject";
import PhycicsSystem from "./PhycicsSystem";
import Physics from "./Physics";
import { DataMgr } from "../Mgr/DataMgr";
export default abstract class Collider extends GameComponent {
public physics: Physics = null;
private _group: ColliderGroup = null;
set group(group: ColliderGroup) {
if (this._group == null) {
this._group = group;
DataMgr.game._phycicsSystem.addCollider(this);
} else {
this._group = group;
}
}
get group() {
return this._group;
}
public type: ColliderType = null;
setData(...ags: any[]): void {
this.physics && this.physics.onColliderResize(this);
}
onEnabled() {
//自动设置物理组件
if (this.group)
DataMgr.game._phycicsSystem.addCollider(this);
let physics = this.owner.getComponent<Physics>(Physics);
if (physics) {
this.physics = physics;
physics.collider = this;
}
}
protected worldPos: FYGE.Point = new FYGE.Point();
abstract getWorldPosition(out: number[]): void;
onDisabled() {
DataMgr.game._phycicsSystem.removeCollider(this);
}
/**获取碰撞器的中心的节点坐标 */
abstract getCenter(): number[];
}
export class CircleCollider extends Collider {
public radius: number = 0
public center: number[] = []
constructor(owner: GameObject) {
super(owner);
this.type = ColliderType.Circle;
}
setData(x: number, y: number, radius: number) {
this.radius = radius;
this.center[0] = x;
this.center[1] = y;
super.setData();
}
getCenter() {
return this.center;
}
private t = {
x: 0,
y: 0
};
getWorldPosition(out: number[]) {
out[0] = this.owner.x + this.center[0];
out[1] = this.owner.y + this.center[1];
}
}
export class RectCollider extends Collider {
public rect: FYGE.Rectangle = new FYGE.Rectangle();
constructor(owner: GameObject) {
super(owner);
this.type = ColliderType.Rect;
}
setData(x: number, y: number, width: number, height: number) {
this.rect.x = x;
this.rect.y = y;
this.rect.width = width;
this.rect.height = height;
super.setData();
}
getCenter() {
return [this.rect.x + this.rect.width / 2, this.rect.y + this.rect.height / 2];
}
getWorldPosition(out: number[]) {
out[0] = this.owner.x + this.rect.left;
out[1] = this.owner.y + this.rect.top;
}
}
export class PointCollider extends Collider {
public center: number[] = [];
constructor(owner: GameObject) {
super(owner);
this.type = ColliderType.Point;
}
setData(x: number, y: number) {
this.center[0] = x;
this.center[1] = y;
super.setData();
}
getCenter() {
return this.center;
}
getWorldPosition(out: number[]) {
let owner = this.owner;
out[0] = this.owner.x + this.center[0];
out[1] = this.owner.y + this.center[1];
}
}
export enum ColliderGroup {
none = 0,
Food = 1,
Pot = 2
}
export enum ColliderType {
Circle = 0,
Rect = 1,
Point = 2
}
import MoveObjcet from "./MoveObject";
import { PoolElement } from "../Component/Pool";
import Collider, { RectCollider, ColliderGroup } from "./Collider";
import { RES } from "../../module/RES";
import { MConst } from "../Global/MConst";
import PrizeFell from "./PrizeFell";
import { MUtils } from "../Global/MUtils";
import { dirname } from "path";
import { layers } from "../../module/views/layers";
import { DataMgr } from "../Mgr/DataMgr";
import GameMgr from "../Mgr/GameMgr";
import MTimer from "../Global/MTimer";
const foodType = {
BBBall: "bangbangBall.png",
CowItem: "cowItem.png",
LZBall: "lizhiBall.png",
MRoom: "mushRoom.png",
Penguin: "penguin.png",
IceBlock: "iceBlock.png",
Boom: "boom.png",
};
export default class Food extends MoveObjcet implements PoolElement {
public poolKey: string = null;
public foodName: string = "Penguin"; //球名称
private score: number = 0; //球分数
private id: number = 0; //球类型标识
private bitmap: FYGE.Sprite = null; //位图
public collider: RectCollider = null;
constructor(id: number) {
super();
this.id = id;
this.bitmap = new FYGE.Sprite();
// this.bitmap.texture = RES.getRes(foodType["Boom"]);
// this.bitmap.width = 200;
// this.bitmap.height = 200;
this.addChild(this.bitmap);
//初始化碰撞器
let collider = this.addComponent(RectCollider) as RectCollider;
collider.group = ColliderGroup.Food;
this.collider = collider;
//TO ADD 碰撞器宽高
// this.collider.setData(0, 0, 100, 100);
}
/**
* 初始化食材
* @param foodName 食材名字
* @param score 分数
*/
init(foodName: string, score: number): Food {
this.foodName = foodName;
this.score = score;
this.bitmap.texture = RES.getRes(foodType[foodName]);
this.anchorX = this.bitmap.width / 2;
this.anchorY = this.bitmap.height / 2;
this.bitmap.x = -this.bitmap.width / 2;
this.bitmap.y = -this.bitmap.height / 2;
this.collider.setData(0, 0, this.bitmap.width / 2, this.bitmap.height / 2);
return this;
}
startShow() {
this.x = (750 - 120) * Math.random() + 30;
this.y = MConst.FoodInitPosY + PrizeFell.OFFSET_Y;
//是否加速度
this.physics.acceleration.y = MConst.Gravity;
}
/**
* 掉落
*/
public drop() {
this.y += MConst.FoodSplitVelocityY;
if (this.y > 1324) {
DataMgr.game.foodPool.recycle(this);
}
}
/** 接住食物 */
private doubleObj = { t: 0 };
getFood() {
if (!this.foodName) return;
switch (this.foodName) {
case "BBBall":
break;
case "CowItem":
break;
case "LZBall":
break;
case "MRoom":
//无敌5秒
DataMgr.game.pot.getInvincible();
break;
case "Penguin":
//5秒内双倍积分
DataMgr.game.scoreMultiple = 2;
DataMgr.game.getDoubleScore(this.x, this.y);
FYGE.Tween.removeTweens(this.doubleObj);
this.doubleObj.t += MConst.doubleTimer * 1000;
FYGE.Tween.get(this.doubleObj)
.to({ t: 0 }, this.doubleObj.t)
.call(() => {
//双倍结束
DataMgr.game.scoreMultiple = 1;
});
break;
case "IceBlock":
//冰冻3秒
DataMgr.game.pot.getIce();
break;
case "Boom":
//玩家死亡
DataMgr.game.pot.playerDead();
break;
default:
break;
}
}
onCollisionEnter(other: Collider) {
if (other.group == ColliderGroup.Pot) {
DataMgr.game.score += this.score * DataMgr.game.scoreMultiple;
DataMgr.game.foodPool.recycle(this);
//积分数字
// this.addScore();
if (this.score > 0) {
DataMgr.game.addScore(
this.x,
this.y,
this.score * DataMgr.game.scoreMultiple
);
}
this.getFood();
}
}
onCollisionStay(other: Collider) {
// console.log("999");
}
/**@inheritdoc */
onElementRecycle() {
this.visible = false;
this.physics.velocity.y = 0;
this.physics.velocity.x = 0;
this.physics.acceleration.y = 0;
this.physics.acceleration.x = 0;
this.disableAllComponents();
}
onElementInit() {
this.visible = true;
this.enableAllComponents();
}
}
import GameObject from "./GameObject";
export default abstract class GameComponent {
public get enabled(): boolean {
return this._enabled;
}
public set enabled(v: boolean) {
if (v == true && this._enabled == false) {
this.onEnabled();
this._enabled = v;
} else if (v == false && this._enabled == true) {
this.onDisabled();
this._enabled = v;
}
}
private _enabled: boolean = false;
public get owner(): GameObject {
return this._owner;
}
private _owner: GameObject = null;
constructor(owner: GameObject) {
this._owner = owner;
}
protected abstract onEnabled(): void;
protected abstract onDisabled(): void;
}
\ No newline at end of file
import GameComponent from "./GameComponent";
import Collider from "./Collider";
export default class GameObject extends FYGE.Container {
public name: string = "";
public addComponent<T extends GameComponent>(cls: any): T {
if (this.getComponent(cls) != null) {
console.error("component is existent");
return;
}
let ins = new cls(this);
ins.enabled = true;
this.componentList.push(ins);
return ins;
}
public getComponent<T extends GameComponent>(cls: any): T {
for (let i of this.componentList) {
if (i instanceof cls) {
return i as T;
}
}
return null;
}
public removeComponent(cls: any) {
for (let i of this.componentList) {
if (i instanceof cls) {
i.enabled = false;
this.componentList = this.componentList.filter(e => e != i);
return;
}
}
}
private _anchorOffsetX: number = 0;
public get anchorOffsetX(): number {
return this._anchorOffsetX;
}
public set anchorOffsetX(v: number) {
this._anchorOffsetX = v;
}
private _anchorOffsetY: number = 0;
public get anchorOffsetY(): number {
return this._anchorOffsetY;
}
public set anchorOffsetY(v: number) {
this._anchorOffsetY = v;
}
private componentList: GameComponent[] = [];
constructor() {
super();
// this.addEventListener(engine.Event.REMOVED_FROM_STAGE, this.disableAllComponents, this);
this.mouseEnable = false;
this.mouseChildren = false;
}
/**销毁时禁用所有组件 */
dispose() {
this.destroy();
this.disableAllComponents();
}
protected disableAllComponents() {
Object.keys(this.componentList).forEach(e => this.componentList[e].enabled = false);
}
protected enableAllComponents() {
Object.keys(this.componentList).forEach(e => this.componentList[e].enabled = true);
}
public onCollisionEnter(other: Collider) {
}
public onCollisionStay(other: Collider) {
}
public onCollisionExit(other: Collider) {
}
}
\ No newline at end of file
import { MConfigs } from "../Global/MConfigs";
import { MConst } from "../Global/MConst";
import { RES } from "../../module/RES";
import { Tool } from "../Tools";
import { DataMgr } from "../Mgr/DataMgr";
import { layers } from "../../module/views/layers";
import Food from "./Food";
export default class GuideMask extends FYGE.Container {
gameOffsetY: number;
constructor() {
super();
var gameOffsetY = (1624 - layers.stageHeight) / 2;
this.gameOffsetY = gameOffsetY;
// const config = MConfigs.guide[index];
this.addEventListener(
FYGE.MouseEvent.MOUSE_DOWN,
() => {
this.onClick && this.onClick(this);
},
this
);
}
//first -- 第一步
drawFirst() {
var pot = DataMgr.game.pot;
//一般来说shape公用,clear掉重用
var shape = new FYGE.Shape();
shape.clear();
shape.beginFill(0x000000, 0.7);
//顺时针画方
shape.moveTo(0, 0);
shape.lineTo(750, 0);
shape.lineTo(750, 1624);
shape.lineTo(0, 1624);
shape.lineTo(0, 0);
//逆时针画椭圆
BezierEllipse1(
shape,
pot.x + pot.width / 2,
pot.y + pot.height / 2 - 10,
140,
70
);
/** 画椭圆 */
function BezierEllipse1(shape, x, y, a, b) {
//0.5和0.6是两个关键系数(在本函数中为试验而得)
var ox = 0.5 * a,
oy = 0.6 * b;
//从椭圆纵轴下端开始逆时针方向绘制
shape.moveTo(0 + x, b + y);
shape.bezierCurveTo(ox + x, b + y, a + x, oy + y, a + x, 0 + y);
shape.bezierCurveTo(a + x, -oy + y, ox + x, -b + y, 0 + x, -b + y);
shape.bezierCurveTo(-ox + x, -b + y, -a + x, -oy + y, -a + x, 0 + y);
shape.bezierCurveTo(-a + x, oy + y, -ox + x, b + y, 0 + x, b + y);
}
shape.endFill();
this.addChild(shape);
let desc = Tool.getText(
"左右移动火锅去接不同的食材\n获取不同的分数哦~",
38,
"#ffdbac",
FYGE.TEXT_ALIGN.CENTER,
750
);
desc.lineSpacing = 30;
desc.position.set(0, 750 + this.gameOffsetY + 100);
shape.addChild(desc);
//按钮-下一步
let next = new FYGE.Sprite(RES.getRes("next.png"));
next.position.set(250, 920 + this.gameOffsetY + 100);
shape.addChild(next);
//手势
let pointer = new FYGE.Sprite(RES.getRes("point.png"));
pointer.anchorX = pointer.width / 2;
pointer.anchorY = pointer.height / 2 - 10;
pointer.position.set(460, 1140 + this.gameOffsetY + 100);
shape.addChild(pointer);
//手势动效 -- TODO
FYGE.Tween.get(pointer, { loop: true })
.to({ scaleX: 0.8, scaleY: 0.8, rotation: -11 }, 400)
.to({ scaleX: 1, scaleY: 1, rotation: 0 }, 200);
//左右标志
let leftImg = new FYGE.Sprite(RES.getRes("left.png"));
leftImg.anchorY = leftImg.height / 2;
leftImg.anchorX = leftImg.width / 2 + 40;
leftImg.position.set(160, 1110 + this.gameOffsetY + 100);
shape.addChild(leftImg);
let rightImg = new FYGE.Sprite(RES.getRes("right.png"));
rightImg.anchorY = rightImg.height / 2;
rightImg.anchorX = rightImg.width / 2 - 40;
rightImg.position.set(540, 1110 + this.gameOffsetY + 100);
shape.addChild(rightImg);
//左右箭头动效 -- TODO
FYGE.Tween.get(leftImg, { loop: true })
.to({ scaleX: 1.2 }, 400)
.to({ scaleX: 1 }, 400);
FYGE.Tween.get(rightImg, { loop: true })
.to({ scaleX: 1.2 }, 400)
.to({ scaleX: 1 }, 400);
}
//second -- 第二步
drawSecond(foods: Array<Food>) {
//一般来说shape公用,clear掉重用
var shape = new FYGE.Shape();
shape.clear();
shape.beginFill(0x000000, 0.7);
//逆时针画方
shape.moveTo(0, 0);
shape.lineTo(0, 1624);
shape.lineTo(750, 1624);
shape.lineTo(750, 0);
shape.lineTo(0, 0);
//顺时针画洞
let count = 0;
for (var i = 0; i < foods.length; i++) {
var p = foods[i];
if (
(p.foodName === "MRoom" ||
p.foodName === "Penguin" ||
p.foodName === "IceBlock" ||
p.foodName === "Boom") &&
count < 4
) {
count++;
shape.moveTo(p.x + 50, p.y);
shape.drawCircle(p.x, p.y, 70, false);
// console.log("66666", p.foodName);
}
}
shape.endFill();
this.addChild(shape);
let desc = Tool.getText(
"接到企鹅——5s的双倍积分\n接到冰块——暂停3s不能移动锅\n接到蘑菇——锅无敌5s\n接到炸弹则游戏结束",
38,
"#ffdbac",
FYGE.TEXT_ALIGN.CENTER,
750
);
desc.lineSpacing = 30;
desc.position.set(0, 800 + this.gameOffsetY + 100);
shape.addChild(desc);
//按钮-我知道了
let next = new FYGE.Sprite(RES.getRes("iknowbtn.png"));
next.position.set(250, 1100 + this.gameOffsetY + 100);
shape.addChild(next);
//手势
let pointer = new FYGE.Sprite(RES.getRes("point.png"));
pointer.anchorX = pointer.width / 2;
pointer.anchorY = pointer.height / 2 - 10;
pointer.position.set(448, 1120 + this.gameOffsetY + 100);
shape.addChild(pointer);
//手势动效 -- TODO
FYGE.Tween.get(pointer, { loop: true })
.to({ scaleX: 0.8, scaleY: 0.8, rotation: -11 }, 400)
.to({ scaleX: 1, scaleY: 1, rotation: 0 }, 200);
}
onClick: (context: GuideMask) => void;
}
import GameObject from "./GameObject";
import Physics from "./Physics";
export default class MoveObjcet extends GameObject {
public physics: Physics = null;
constructor() {
super();
this.physics = this.addComponent(Physics);
}
}
\ No newline at end of file
import Physics from "./Physics";
import Collider, { CircleCollider, RectCollider, ColliderType, ColliderGroup, PointCollider } from "./Collider";
import { arrayRemove } from "../Global/GUtils";
import MTimer from "../Global/MTimer";
import GameMgr from "../Mgr/GameMgr";
import DebugMgr from "../Mgr/DebugMgr";
let instanceId1: number = null;
let instanceId2: number = null;
export default class PhycicsSystem extends GameMgr {
/* private _enabled: boolean = false;
public set enabled(v: boolean) {
this._enabled = v;
if (this._enabled == true)
this.pause = false;
this.clear();
}
public get enabled() {
return this._enabled;
} */
constructor() { super("PhycicsSystem"); }
private phycicsList: Physics[] = [];
onInit() {
super.onInit();
for (let i = 0; i <= GroupMaxIndex; i++) {
this.colliderList[i] = [];
}
}
public onDestroy() {
super.onDestroy();
for (let i = 0; i <= GroupMaxIndex; i++) {
this.colliderList[i] = [];
}
this.phycicsList = [];
}
protected onUpdate() {
if (this.pause) return;
for (let i of this.phycicsList) {
i.onFixedUpdate(MTimer.dtFactor);
}
this.detectCollision();
return false;
}
public add(phycics: Physics) {
this.phycicsList.push(phycics);
}
public remove(phycics: Physics) {
this.phycicsList = arrayRemove(this.phycicsList, phycics);
}
private colliderList: Collider[][] = [];
private collisions: number[][] = [];
/**
* 判断两个碰撞器之前是否发生过碰撞
* @returns 未找到返回-1
*/
private getCollisionIndex(collider1: number, collider2: number): number {
for (let i = 0; i < this.collisions.length; i++) {
if ((this.collisions[i][0] == collider1 && this.collisions[i][1] == collider2) || (this.collisions[i][0] == collider2 && this.collisions[i][1] == collider1)) {
return i;
}
}
//未碰撞
return -1;
}
public addCollider(collider: Collider) {
if (typeof this.colliderList[collider.group] == "undefined") {
this.colliderList[collider.group] = [];
}
this.colliderList[collider.group].push(collider);
}
public removeCollider(collider: Collider) {
this.collisions = this.collisions.filter(e => {
if (e[0] != collider.owner.instanceId && e[1] != collider.owner.instanceId) {
return true;
} else
return false;
});
// DebugMgr.instance.clearShape(collider.owner.instanceId.toString());
this.colliderList[collider.group] = arrayRemove(this.colliderList[collider.group], collider);
}
/**检测碰撞 */
public detectCollision() {
/* for (let i of this.colliderList) {
for (let j of i) {
this.drawCollider(j);
}
} */
//查找所有碰撞
let i = 0,
j = 0,
m = 0,
n = 0,
length = this.colliderList.length,
group1: Collider[] = null,
group2: Collider[] = null;
for (i = 0; i <= length - 1; i++) {
for (j = i + 1; j <= length - 1; j++) {
if (CollisionMap[i] & 1 << j) {
group1 = this.colliderList[i];
group2 = this.colliderList[j];
for (m = 0; m <= group1.length - 1; m++) {
for (n = 0; n <= group2.length - 1; n++) {
this.detectTraverse(group1[m], group2[n]);
}
}
}
}
}
}
private detectTraverse(collider1: Collider, collider2: Collider) {
instanceId1 = collider1.owner.instanceId;
instanceId2 = collider2.owner.instanceId;
let collisionIndex = this.getCollisionIndex(instanceId1, instanceId2);
if (callDetectFunc(collider1, collider2)) { //发生碰撞
if (collisionIndex >= 0) { //之前就发生了碰撞
collider1.owner.onCollisionStay(collider2);
collider2.owner.onCollisionStay(collider1);
} else { //之前没有碰撞
//添加到索引表
this.collisions.push([instanceId1, instanceId2]);
collider1.owner.onCollisionEnter(collider2);
collider2.owner.onCollisionEnter(collider1);
}
} else { //未发生碰撞
//碰撞退出
if (collisionIndex >= 0) { //之前有发生碰撞
//在碰撞列表中删除这一对碰撞
this.collisions.splice(collisionIndex, 1);
collider1.owner.onCollisionExit(collider2);
collider2.owner.onCollisionExit(collider1);
}
}
}
private drawCollider(collider: Collider) {
switch (collider.type) {
case ColliderType.Circle:
let circleCollider = collider as CircleCollider;
let worldCenter = [];
collider.getWorldPosition(worldCenter)
DebugMgr.instance.updateCircle(collider.owner.instanceId.toString(), worldCenter[0], worldCenter[1], circleCollider.radius);
break;
case ColliderType.Rect:
let rectCollider = collider as RectCollider;
let worldPos = [];
rectCollider.getWorldPosition(worldPos);
DebugMgr.instance.updateRect(rectCollider.owner.instanceId.toString(), new FYGE.Rectangle(worldPos[0], worldPos[1], rectCollider.rect.width, rectCollider.rect.height));
break;
}
}
}
function callDetectFunc(collider1: Collider, collider2: Collider): boolean {
if (collider1.type == ColliderType.Circle) {
if (collider2.type == ColliderType.Circle) {
return circleToCircle(collider1 as CircleCollider, collider2 as CircleCollider);
} else if (collider2.type == ColliderType.Rect) {
return circleToRect(collider1 as CircleCollider, collider2 as RectCollider);
} else if (collider2.type == ColliderType.Point) {
return circleToPoint(collider1 as CircleCollider, collider2 as PointCollider)
}
} else if (collider1.type == ColliderType.Rect) {
if (collider2.type == ColliderType.Circle) {
return circleToRect(collider2 as CircleCollider, collider1 as RectCollider);
} else if (collider2.type == ColliderType.Rect) {
return rectToRect(collider1 as RectCollider, collider2 as RectCollider);
} else if (collider2.type == ColliderType.Point) {
return pointToRect(collider2 as PointCollider, collider1 as RectCollider);
}
} else if (collider1.type == ColliderType.Point) {
if (collider2.type == ColliderType.Circle) {
return circleToPoint(collider2 as CircleCollider, collider1 as PointCollider);
} else if (collider2.type == ColliderType.Rect) {
return pointToRect(collider1 as PointCollider, collider2 as RectCollider);
}
}
return false;
}
let tempPoint1: number[] = [];
let tempPoint2: number[] = [];
function distance(p1: number[], p2: number[]) {
return Math.sqrt((p1[0] - p2[0]) * (p1[0] - p2[0]) + (p1[1] - p2[1]) * (p1[1] - p2[1]));
}
function circleToCircle(collider1: CircleCollider, collider2: CircleCollider): boolean {
collider1.getWorldPosition(tempPoint1);
collider2.getWorldPosition(tempPoint2);
return distance(tempPoint1, tempPoint2) < (collider1.radius + collider2.radius);
}
function circleToRect(circleCollider: CircleCollider, rectCollider: RectCollider) {
circleCollider.getWorldPosition(tempPoint1);
rectCollider.getWorldPosition(tempPoint2);
let closestPoint = new FYGE.Point();
if (tempPoint1[1] < tempPoint2[1]) {
closestPoint.y = tempPoint2[1];
} else if (tempPoint1[1] > tempPoint2[1] + rectCollider.rect.height) {
closestPoint.y = tempPoint2[1] + rectCollider.rect.height;
} else {
closestPoint.y = tempPoint1[1];
}
if (tempPoint1[0] < tempPoint2[0]) {
closestPoint.x = tempPoint2[0];
} else if (tempPoint1[0] > tempPoint2[0] + rectCollider.rect.width) {
closestPoint.x = tempPoint2[0] + rectCollider.rect.width;
} else {
closestPoint.x = tempPoint1[0];
}
return distance([closestPoint.x, closestPoint.y], tempPoint1) < circleCollider.radius;
}
function rectToRect(collider1: RectCollider, collider2: RectCollider) {
let rect1 = collider1.rect,
rect2 = collider2.rect;
collider1.getWorldPosition(tempPoint1);
collider2.getWorldPosition(tempPoint2);
let rectW1 = tempPoint1[0] + rect1.width,
rectW2 = tempPoint2[0] + rect2.width,
rectH1 = rect1.height + tempPoint1[1],
rectH2 = tempPoint2[1] + rect2.height;
if (tempPoint1[0] <= rectW2 &&
rectW1 >= tempPoint2[0] &&
tempPoint1[1] <= rectH2 &&
rectH1 >= tempPoint2[1]) { //发生碰撞
return true;
} else
return false;
}
function circleToPoint(circle: CircleCollider, point: PointCollider) {
circle.getWorldPosition(tempPoint1);
point.getWorldPosition(tempPoint2);
if (distance(tempPoint1, tempPoint2) < circle.radius) {
return true;
} else {
return false;
}
}
function pointToRect(point: PointCollider, rect: RectCollider) {
rect.getWorldPosition(tempPoint1);
point.getWorldPosition(tempPoint2);
if (tempPoint2[1] < tempPoint1[1] + rect.rect.height
&& tempPoint2[1] > tempPoint1[1]
&& tempPoint2[0] > tempPoint1[0]
&& tempPoint2[0] < tempPoint1[0] + rect.rect.width
) {
return true;
} else {
return false;
}
}
const CollisionMap = {
0: 0b00000000,
1: 0b01011100,
2: 0b10000010,
3: 0b01100010,
4: 0b00100010,
5: 0b01011000,
6: 0b00101010,
7: 0b00000010
}
const GroupMaxIndex = 7
\ No newline at end of file
import GameComponent from "../Game/GameComponent";
import GameObject from "../Game/GameObject";
import PhycicsSystem from "./PhycicsSystem";
import Collider from "./Collider";
import { DataMgr } from "../Mgr/DataMgr";
export default class Physics extends GameComponent {
/**旋转速度
* @单位 (弧度制)度/帧
* @方向 正值表示顺时针旋转,负表示逆时针旋转
**/
public rotateVelocity: number = 0;
/**每帧速率的增量
* x坐标表示对应坐标轴方向上速率的增量(标量)
* @单位 像素/帧
**/
public acceleration: FYGE.Point = new FYGE.Point();
/**速度 单位:像素/帧 */
public velocity: FYGE.Point = new FYGE.Point();
public get collider() {
return this._collider;
}
public set collider(v: Collider) {
this._collider = v;
v.physics = this;
}
public _collider: Collider = null;
public onFixedUpdate(dtFactor: number) {
this.velocity.x += this.acceleration.x * dtFactor;
this.velocity.y += this.acceleration.y * dtFactor;
if (Math.sqrt(this.velocity.x * this.velocity.x + this.velocity.y * this.velocity.y) > 0) {
this.moveTo(
this.owner.x += this.velocity.x * dtFactor,
this.owner.y += this.velocity.y * dtFactor
);
}
//旋转
if (this.rotateVelocity != 0) {
this.owner.rotation += this.rotateVelocity * dtFactor;
}
}
public moveTo(x: number | FYGE.Point, y?: number) {
if (typeof x == "number") {
if (!y) {
console.error("invalid param");
return;
}
this.owner.x = x;
this.owner.y = y;
} else {
this.owner.x = x.x;
this.owner.y = x.y;
}
this.onMoved && this.onMoved(this.owner);
}
public onMoved: (owner: GameObject) => void;
protected onDisabled() {
DataMgr.game._phycicsSystem.remove(this);
}
protected onEnabled() {
DataMgr.game._phycicsSystem.add(this);
}
public onColliderResize(collider: Collider) {
let center = collider.getCenter();
this.owner.anchorX = center[0];
this.owner.anchorY = center[1];
}
}
\ No newline at end of file
import { MConst } from "../Global/MConst";
import { MConfigs } from "../Global/MConfigs";
export default class PlayerController extends FYGE.Container {
public onTouchMove: (deltaX: number) => void = null;
private touchId: number = null;
private lastX: number = null;
constructor() {
super();
this.width = MConst.DesignResolution.width;
this.height = MConst.DesignResolution.height;
this.addEventListener(FYGE.MouseEvent.MOUSE_DOWN, (e: FYGE.MouseEvent) => {
this.touchId = e.instanceId;
this.lastX = e.clientX;
}, this);
this.addEventListener(FYGE.MouseEvent.MOUSE_MOVE, (e: FYGE.MouseEvent) => {
if (e.instanceId != this.touchId || this.touchId == null || this.lastX == null) return;
this.onTouchMove && this.onTouchMove(e.clientX - this.lastX)
this.lastX = e.clientX;
}, this);
this.addEventListener(FYGE.MouseEvent.MOUSE_UP, (e: FYGE.MouseEvent) => {
if (e.instanceId != this.touchId) return;
this.touchId = null;
this.lastX = null;
}, this);
let graphics = new FYGE.Graphics();
const rect = graphics
.beginFill(0xffffff,0)
.drawRect(0, 0, 750, 1624)
.endFill()
this.addChild(rect);
}
}
\ No newline at end of file
import { RES } from "../../module/RES";
import { MConst } from "../Global/MConst";
import MTimer from "../Global/MTimer";
import { DataMgr } from "../Mgr/DataMgr";
import Collider, { ColliderGroup, RectCollider } from "./Collider";
import GameObject from "./GameObject";
import { SoundMgr } from "../Mgr/SoundMgr";
export default class Pot extends GameObject {
private collider: RectCollider;
public touchWall: 1 | -1 | 0 = 0;
globalcarCollidePaddingX = 0;
globalcarCollidePaddingY = 0;
public onDead: () => void;
private iceBlock: FYGE.Sprite;
private invincibleBlock: FYGE.Sprite;
public iceFlag: boolean = false;
public invincibleFlag: boolean = false;
constructor() {
super();
const carCollidePaddingX = this.globalcarCollidePaddingX,
carCollidePaddingY = this.globalcarCollidePaddingY;
//锅
let pot = new FYGE.Sprite(RES.getRes("pot.png"));
pot.anchorX = pot.width / 2;
pot.anchorY = pot.height / 2;
pot.x = 0;
pot.y = 0;
this.addChild(pot);
//冰冻
let ice = (this.iceBlock = new FYGE.Sprite(RES.getRes("getIce.png")));
ice.x = -20;
ice.y = -10;
this.addChild(ice);
ice.visible = false;
//无敌
let invincible = (this.invincibleBlock = new FYGE.Sprite(
RES.getRes("baohuzhao.png")
));
invincible.x = -40;
invincible.y = -50;
this.addChild(invincible);
invincible.visible = false;
//碰撞盒
let collider = (this.collider = this.addComponent<RectCollider>(
RectCollider
));
collider.setData(carCollidePaddingX, carCollidePaddingY, 244, 63);
collider.group = ColliderGroup.Pot;
}
onCollisionEnter(other: Collider) {
if (other.group == ColliderGroup.Food) {
if (this.invincibleFlag) {
FYGE.Tween.get(this.invincibleBlock)
.to({ alpha: 0.8 }, 100)
.to({ alpha: 1 }, 100)
.to({ alpha: 0.8 }, 100)
.to({ alpha: 1 }, 100)
.call(() => {
FYGE.Tween.removeTweens(this.invincibleBlock);
});
}
if (this.iceFlag) {
FYGE.Tween.get(this.iceBlock)
.to({ alpha: 0.8 }, 100)
.to({ alpha: 1 }, 100)
.to({ alpha: 0.8 }, 100)
.to({ alpha: 1 }, 100)
.call(() => {
FYGE.Tween.removeTweens(this.iceBlock);
});
}
}
}
onCollisionStay(other: Collider) {
if (other.group == ColliderGroup.Food) {
console.log("锅和实物碰撞22");
}
}
onCollisionExit(other: Collider) {
if (other.group == ColliderGroup.Pot) {
this.touchWall = 0;
}
}
/** 玩家移动 */
move(deltaX: number) {
if (this.iceFlag) return;
if (this.touchWall == 1 && deltaX <= 0) {
return;
} else if (this.touchWall == -1 && deltaX >= 0) {
return;
}
//自定义
const carCollidePaddingX = this.globalcarCollidePaddingX;
const { x, width } = this.collider.rect;
this.x = Math.max(
-x,
Math.min(750 - width - carCollidePaddingX, this.x + deltaX)
);
}
/** 无敌状态 */
private objInvincible = { t: 0 };
getInvincible() {
if (this.iceFlag) {
//冰冻结束
this.iceBlock.visible = false;
this.iceFlag = false;
}
this.invincibleBlock.visible = true;
this.invincibleFlag = true;
let self = this;
// console.log("无敌开始+++", this.objInvincible.t);
FYGE.Tween.removeTweens(this.objInvincible);
this.objInvincible.t += MConst.invincibleTimer * 1000;
FYGE.Tween.get(this.objInvincible)
.to({ t: 0 }, this.objInvincible.t)
.call(() => {
//无敌结束
self.invincibleBlock.visible = false;
self.invincibleFlag = false;
});
}
/** 冰冻状态 */
private iceTimer = { t: 0 };
getIce() {
if (this.invincibleFlag) return;
// console.log("冰冻");
this.iceBlock.visible = true;
this.iceFlag = true;
let self = this;
FYGE.Tween.removeTweens(this.iceTimer);
this.iceTimer.t += MConst.iceTimer * 1000;
FYGE.Tween.get(this.iceTimer)
.to({ t: 0 }, this.iceTimer.t)
.call(() => {
//无敌结束
self.iceBlock.visible = false;
self.iceFlag = false;
});
}
/** 玩家死亡 */
playerDead() {
if (this.invincibleFlag) return;
this.onDead && this.onDead();
}
}
import { props } from "../props";
import { Scene } from "../../module/views/Scene";
import { layers } from "../../module/views/layers";
import { DataMgr } from "../Mgr/DataMgr";
import { GDispatcher } from "../MainPrizeFell";
import GuideMgr from "../Mgr/GuideMgr";
import { MConst } from "../Global/MConst";
import { RES } from "../../module/RES";
import { FrameAnimationMgr } from "../component/FrameAnimation";
import PhycicsSystem from "./PhycicsSystem";
import Pot from "./Pot";
import Physics from "./Physics";
import PlayerController from "./PlayerController";
import { FoodPool } from "../Pools/FoodPool";
import Food from "./Food";
import MTimer from "../Global/MTimer";
import { MUtils } from "../Global/MUtils";
import { GameFun } from "../global/GameFun";
import { MConfigs } from "../Global/MConfigs";
import { Tool } from "../Tools";
import { showPanel, showToast } from "../../module/ctrls";
import { GameOverPanel } from "../panels/GameOverPanel";
import submitGame from "../ctrls/submitGame";
import { SoundMgr } from "../Mgr/SoundMgr";
export default class PrizeFell extends FYGE.Container {
public _animationMgr: FrameAnimationMgr = new FrameAnimationMgr();
public _phycicsSystem: PhycicsSystem = new PhycicsSystem();
//ADD
private node: FYGE.Container = new FYGE.Container();
static OFFSET_Y: number;
public pot: Pot = null;
public food = new FYGE.Container();
public foodPool: FoodPool;
public _foodList: Food[] = [];
private createFoodCD: number = 0;
public totalScoreLabel: FYGE.BitmapText;
private cdline: FYGE.Sprite;
private timeLabel: FYGE.TextField;
private timing = false;
public timer: number = MConst.countDown * 1000;
openMusic: FYGE.Sprite;
closeMusic: FYGE.Sprite;
constructor(parent: Scene) {
super();
this.timer = MConst.tickSeconds * 1000;
PrizeFell.OFFSET_Y = (1624 - layers.stageHeight) / 2;
DataMgr.game = this;
this._phycicsSystem.onInit();
this.pause = false;
GDispatcher.once("gameDead", this.gameDead, this);
//弹窗测试
// showPanel(GameOverPanel);
//引导
GuideMgr.instance.container = parent;
parent.addChild(this.node);
this.node.width = MConst.DesignResolution.width;
this.node.height = MConst.DesignResolution.height;
this.node.x = 0;
this.node.y = 0;
//背景
let bg = new FYGE.Sprite(RES.getRes("gameBg.jpg"));
this.node.addChild(bg);
//食材
this.node.addChild(this.food);
//倒计时
let cdbg = new FYGE.Sprite(RES.getRes("main_countdown.png"));
cdbg.position.set(642, 208);
cdbg.y = 212
this.node.addChild(cdbg);
let cdbg2 = new FYGE.Sprite(RES.getRes("main_countdown2.png"));
cdbg2.position.set(672, 218);
cdbg2.anchorX = 2.5;
cdbg2.anchorY = 20;
this.node.addChild(cdbg2);
this.cdline = cdbg2;
this.timeLabel = Tool.getText(
"00s",
30,
"#ffffff",
FYGE.TEXT_ALIGN.CENTER,
100
);
this.timeLabel.position.set(630, 290);
this.node.addChild(this.timeLabel);
//得分标题
let scoreTitle = new FYGE.Sprite(RES.getRes("scoreTitle.png"));
scoreTitle.position.set(282, 208);
this.node.addChild(scoreTitle);
//得分
var textures = {};
for (var i = 0; i < 10; i++) textures[i] = RES.getRes(`score_num_${i}.png`);
var labelScore = new FYGE.BitmapText(textures);
labelScore.textAlign = FYGE.TEXT_ALIGN.CENTER;
labelScore.y = 264;
this.totalScoreLabel = labelScore;
this.totalScoreLabel.text = "0";
this.node.addChild(this.totalScoreLabel);
//锅
let pot = new Pot();
pot.x = this.node.width / 2 - pot.width / 2;
pot.y = MConst.GroundLine - pot.height;
this.node.addChild(pot);
pot.addComponent(Physics);
pot.onDead = () => {
this.gameOver();
};
this.pot = pot;
// GuideMgr.instance.drawFirstGuide(true);
//玩家控制器
let playerController = new PlayerController();
playerController.onTouchMove = (deltaX) => {
if (!this.pause) {
this.pot.move(deltaX);
}
};
this.node.addChild(playerController);
//创建食材池子
this.foodPool = new FoodPool(this.food);
//音乐按钮
let openMusic = new FYGE.Sprite(RES.getRes("openMusic.png"));
openMusic.position.set(560, 208);
this.node.addChild(openMusic);
openMusic.visible = true;
this.openMusic = openMusic;
let closeMusic = new FYGE.Sprite(RES.getRes("closeMusic.png"));
closeMusic.position.set(560, 208);
this.node.addChild(closeMusic);
closeMusic.visible = false;
this.closeMusic = closeMusic;
//音乐控制
openMusic.mouseEnable = true;
openMusic.addEventListener(
FYGE.MouseEvent.CLICK,
() => {
openMusic.visible = false;
closeMusic.visible = true;
SoundMgr.instance.isMusic = false;
},
this
);
closeMusic.addEventListener(
FYGE.MouseEvent.CLICK,
() => {
closeMusic.visible = false;
openMusic.visible = true;
SoundMgr.instance.isMusic = true;
},
this
);
//添加监听器
MTimer.onFrame("Game", this.onUpdate, this);
//开始倒计时
this.timing = true;
if (!this.pause) {
FYGE.Tween.get(this.cdline, { loop: !!1 }).to({ rotation: 360 }, 500);
this.cdline["hasTween"] = 1;
}
}
/** 积分倍数 */
public scoreMultiple: number = 1;
/**
* 当前得分
* @readonly
*/
private _score: number = 0;
public set score(v: number) {
this._score = v;
}
public get score(): number {
return this._score;
}
/**设置游戏暂停状态 */
private _pause: boolean = false;
public set pause(v: boolean) {
this._pause = v;
this.timing = !this._pause;
this._phycicsSystem.pause = this._pause;
this.cdline && FYGE.Tween.removeTweens(this.cdline);
if (this.pause) {
console.log("音乐关闭++")
SoundMgr.instance.isMusic = false;
this.cdline && (this.cdline["hasTween"] = 0);
this.cdline.rotation = 0;
} else if (this.cdline && !this.cdline["hasTween"]) {
SoundMgr.instance.isMusic = true;
this.cdline["hasTween"] = 1;
FYGE.Tween.get(this.cdline, { loop: !!1 }).to({ rotation: 360 }, 500);
}
}
public get pause() {
return this._pause;
}
/** 游戏结束 */
private gameDead() {
GDispatcher.dispatchEvent("game-destroy");
}
/** 游戏进行 */
private onUpdate() {
// console.log("000", this._foodList);
if (this.pause) {
// MTimer.removeOnFrame("Game");
return;
}
this.updateScore();
for (let i = 0; i < this._foodList.length; i++) {
this._foodList[i].drop();
}
if (this.createFoodCD > 0) {
this.createFoodCD -= MTimer.deltaTime;
}
if (this._foodList.length < MConst.CurMaxFoodNum) {
if (this.createFoodCD <= 0) {
this.createFoods();
}
}
//倒计时
this.downTimer();
}
/** 得分更新 */
updateScore() {
this.totalScoreLabel.text = this.score + "";
this.totalScoreLabel.x = 750 / 2;
}
/** 倒计时 */
downTimer() {
if (this.timing) {
if (this.timer > 0) {
if (MTimer.deltaTime > 0) {
this.timer -= MTimer.deltaTime;
}
} else {
this.timer = 0;
this.timing = false;
//时间到
this.gameOver();
}
let temp = Math.ceil(this.timer / 1000);
this.timeLabel.text = temp + "s";
}
}
/** 创建食材出现 */
private foodGuide: Array<number> = [0, 1, 2, 3, 4, 5, 6];
private foods: Array<Food> = [];
private createFoods() {
// console.log("44");
let id = MUtils.randomInt(0, 8);
let food = this.foodPool.spwan(id);
let foodType;
//TODO 新手引导
if (GuideMgr.instance.guideFlag && this.foodGuide.length >= 1) {
let index = GameFun.randomArr(this.foodGuide);
let _index = this.foodGuide.indexOf(index);
if (_index > -1) {
this.foodGuide.splice(_index, 1);
}
foodType = GameFun.getFoodTypeGuid(index);
this.foods.length <= 7 && this.foods.push(food);
if (this.foods.length == 7) {
console.log("新手引导的食材+++++", this.foods);
//出现新手引导
this.pause = true;
if (GuideMgr.instance.guideFlag == true) {
GuideMgr.instance.drawSecondGuide(this.foods, true);
}
return;
}
this.createFoodCD = MConst.FoodAppearSpaceGuide;
} else {
foodType = GameFun.getFoodType();
//不出现同时获得效果
if (this.pot.invincibleFlag && foodType.name === "MRoom") {
foodType = GameFun.getFoodTypeNoRepeat("MRoom");
}
if (this.pot.iceFlag && foodType.name === "IceBlock") {
foodType = GameFun.getFoodTypeNoRepeat("IceBlock");
}
if (this.scoreMultiple === 2 && foodType.name === "Penguin") {
foodType = GameFun.getFoodTypeNoRepeat("Penguin");
}
this.createFoodCD = MConst.FoodAppearSpace;
}
food.init(foodType.name, foodType.score);
food.startShow();
}
/** add 数字上飘 */
public addScore(addNumX: number, addNumY: number, score: number) {
var textures = {};
for (var i = 0; i < 10; i++) textures[i] = RES.getRes(`add_score_${i}.png`);
var addScoreText = new FYGE.BitmapText(textures);
addScoreText.textAlign = FYGE.TEXT_ALIGN.CENTER;
addScoreText.x = addNumX;
addScoreText.y = addNumY;
this.node.addChild(addScoreText);
addScoreText.text = score + "";
//数字上飘
FYGE.Tween.get(addScoreText)
.to({ y: addNumY - 80, alpha: 0.4 }, 500)
.call(() => {
FYGE.Tween.removeTweens(addScoreText);
addScoreText && this.node.removeChild(addScoreText);
addScoreText = null;
});
}
/** 获得双倍 */
public getDoubleScore(doubleX: number, doubleY: number) {
let doubleImg = new FYGE.Sprite(RES.getRes("double.png"));
doubleImg.x = this.pot.x + this.pot.width / 2 - doubleImg.width / 2;
doubleImg.y = this.pot.y - this.pot.height / 2;
doubleImg.anchorX = doubleImg.width / 2;
doubleImg.anchorY = doubleImg.height / 2;
this.node.addChild(doubleImg);
doubleImg.alpha = 0;
//双倍动效
FYGE.Tween.get(doubleImg)
.set({ scaleX: 0, scaleY: 0, alpha: 0 })
.to({ scaleX: 1.3, scaleY: 1.3, alpha: 1 }, 300)
.to({ scaleX: 1.2, scaleY: 1.2, alpha: 1 }, 100)
.wait(300)
.call(() => {
FYGE.Tween.removeTweens(doubleImg);
doubleImg && this.node.removeChild(doubleImg);
doubleImg = null;
});
}
/** 游戏暂停 */
gamePause() {
this.pause = true;
this.timing = false;
}
/** 游戏结束 */
async gameOver() {
console.log("游戏结束");
this.timer = 0;
this.gamePause();
//ADDTO 弹窗
const result = await submitGame(this.score);
if(result.success){
console.log("弹出弹窗+++",result);
showPanel(GameOverPanel, result.data);
GDispatcher.dispatchEvent("showBuried");
}else{
console.log("099009")
showToast(result.message);
setTimeout(() => {
this.gameDead();
}, 3000);
}
}
/**销毁游戏 */
public destroy() {
//@ts-ignore
this.node.dispose();
this._phycicsSystem.onDestroy();
MTimer.removeOnFrame("Game");
}
}
import { MUtils } from "./MUtils";
import { MConst } from "./MConst";
import { MConfigs } from "./MConfigs";
export function getBallScore(bulletScore: number, powerScore: number, colorIndex: number): any {
let getScoreFromRange = ([a, b]) => {
a = Math.ceil(a * 0.1);
b = Math.ceil(b * 0.1);
let n = Math.abs(b - a) + 1;
n = Math.floor(n / 6);
const m = [];
for (let i = 0; i < 5; i++) {
m.push([a + n * i, a + n * i + n - 1]);
}
m.push([a + n * 4 + n, b])
const [a0, b0] = m[colorIndex]; //1-10
let result = Math.ceil(Math.random() * (b0 - a0 + 1)) + a0
return result;
}
if (bulletScore <= 20)
return getScoreFromRange([0.01 * powerScore, 0.2 * powerScore]);
if (bulletScore > 20 && bulletScore <= 40) {
return getScoreFromRange([0.2 * powerScore, 0.6 * powerScore]);
}
let getRange = (list: any[], props: any[]) => {
return getScoreFromRange(getProp(list, props)[0]);
}
if (bulletScore > 40 && bulletScore <= 60) {
const list = [
[0.2 * powerScore, 0.6 * powerScore],
[0.6 * powerScore, 0.8 * powerScore],
[0.8 * powerScore, 1.5 * powerScore],
]
return getRange(list, [3, 5, 2]);
}
if (bulletScore > 60 && bulletScore <= 80) {
const list = [
[0.6 * powerScore, 0.8 * powerScore],
[0.8 * powerScore, 1.5 * powerScore],
[1.5 * powerScore, 2.2 * powerScore],
]
return getRange(list, [2, 5, 2]);
}
if (bulletScore > 80 && bulletScore <= 100) {
const list = [
[1.5 * powerScore, 2.2 * powerScore],
[2.2 * powerScore, 3.2 * powerScore],
[3.2 * powerScore, 4.2 * powerScore],
]
return getRange(list, [1, 5, 4]);
}
if (bulletScore > 100 && bulletScore <= 120) {
const list = [
[2.2 * powerScore, 3.2 * powerScore],
[3.2 * powerScore, 4.2 * powerScore],
[4.2 * powerScore, 5.2 * powerScore],
]
return getRange(list, [1, 4, 5]);
}
const list = [
[2.2 * powerScore, 3.2 * powerScore],
[3.2 * powerScore, 4.2 * powerScore],
[4.2 * powerScore, 5.2 * powerScore],
]
return getRange(list, [1, 3, 6]);
}
export function getProp(items: any[], props: number[], n = 1) {
let pool = [];
for (let i in items) {
for (let j = 0; j < props[i]; j++) {
pool.push(items[i]);
}
}
const result = [];
for (let i = 0; i < n; i++) {
result.push(pool[MUtils.randomInt(0, pool.length)]);
}
return result;
}
export function arrayRemove(array: any[], target: any): any[] {
let newArray = [];
for (let i = 0; i < array.length; i++) {
if (array[i] !== target) {
newArray.push(array[i]);
}
}
return newArray;
}
/**
* 游戏配置
*/
export namespace GameFun {
//概率总和 1
export const foodType = {
BBBall: {
rol: 0.25,
score: 3,
},
CowItem: {
rol: 0.25,
score: 3,
},
LZBall: {
rol: 0.25,
score: 3,
},
MRoom: {
rol: 0.05,
score: 2,
},
Penguin: {
rol: 0.05,
score: 2,
},
IceBlock: {
rol: 0.1,
score: 0,
},
Boom: {
rol: 0.05,
score: 0,
},
};
//获取食材及对应分数 -- 常态
export function getFoodType(): any {
let currentRol = Math.random();
let rolMin: number = 0,
rolMax: number = 0;
for (let item in foodType) {
rolMax += foodType[item].rol;
if (currentRol >= rolMin && currentRol < rolMax) {
let foodNow = { name: item, score: foodType[item].score };
return foodNow;
}
rolMin += foodType[item].rol;
}
}
//获取食材及分数 -- 新手引导
export const foodNames = [
"CowItem",
"LZBall",
"MRoom",
"Penguin",
"IceBlock",
"Boom",
"BBBall",
];
//获取新手引导的食材
export function getFoodTypeGuid(index: number): any {
let foodNow = {
name: foodNames[index],
score: foodType[foodNames[index]].score,
};
return foodNow;
}
//随机从数组中取一个
export function randomArr(arr: any[]): any {
return arr[0]; //取第一个
return arr[(Math.random() * arr.length) | 0];
}
//获得没有锅具有的效果的食材
export function getFoodTypeNoRepeat(name: string) {
var newFoodNames = foodNames.slice(0, foodNames.length);
var index = newFoodNames.indexOf(name);
if (index > -1) {
newFoodNames.splice(index, 1);
}
var newName = newFoodNames[(Math.random() * newFoodNames.length) | 0];
return { name: newName, score: foodType[newName].score };
}
}
// export const MConfigs: any = window;
export namespace MConfigs {
export function updateConfig() {
let mconfig = window["mconfig"];
if (typeof mconfig != "object") return;
Object.keys(mconfig).forEach((e) => {
MConfigs[e] = mconfig[e];
});
}
}
export namespace MConst {
/** 设计宽高 */
export const DesignResolution = {
width: 750,
height: 1624
};
export const GroundLine = 1400;//地平线
export const Gravity = 0.015;//食材加速度
export const FoodSplitVelocityY = 5.8;//每帧下落距离
export const FoodInitPosY = 1206 * 0.2;//食材初始位置——Y
export const CurMaxFoodNum = 8;//界面最多存在食材数
export const FoodAppearSpaceGuide = 300;//新手引导食材出现间隔
export const FoodAppearSpace = 500;//食材出现间隔
export const countDown = 1 * 60;//倒计时时间
export const doubleTimer = 5;//双倍持续时间
export const invincibleTimer = 5;//无敌持续时间
export const iceTimer = 3;//冰冻持续时间
export let tickSeconds = 60;
}
\ No newline at end of file
import MEvent from "../Component/MEvent";
import { GDispatcher } from "../MainPrizeFell";
export default class MTimer {
public static init() {
startTime = Date.now();
//@ts-ignore
FYGE.gameStage.addEventListener(FYGE.Event.ENTER_FRAME, onUpdate, MTimer);
if (document) {
document.addEventListener("visibilitychange", onVisibilityChange);
} else {
GDispatcher.addEventListener("onShow", onVisibilityChange, MTimer);
}
}
public static destroy() {
_onFrame.clear();
//@ts-ignore
FYGE.gameStage.removeEventListener(FYGE.Event.ENTER_FRAME, onUpdate, MTimer);
if (document) {
document.removeEventListener("visibilitychange", onVisibilityChange);
} else {
GDispatcher.addEventListener("onShow", onVisibilityChange, MTimer);
}
}
/**
* 帧间隔
*/
public static get deltaTime(): number {
return _deltaTime;
}
/**
* 帧间隔系数:当前帧间隔与标准帧间隔(60帧)的比值
*/
public static get dtFactor() {
return MTimer.deltaTime / DefaultDeltaTime;
}
/**
* 注册帧回调函数
*/
/* public static get onFrame(): MEvent<(dt: number) => void> {
return _onFrame;
} */
public static onFrame(key: string, callback: (dt: number) => void, thisObj?: any) {
if (key) {
if (onFrameCaches[key]) {
_onFrame.remove(onFrameCaches[key].callback, onFrameCaches[key].thisObj);
delete onFrameCaches[key];
}
onFrameCaches[key] = {
callback: callback,
thisObj: thisObj
};
}
_onFrame.add(callback, thisObj);
}
public static removeOnFrame(key: string) {
if (onFrameCaches[key]) {
_onFrame.remove(onFrameCaches[key].callback, onFrameCaches[key].thisObj);
delete onFrameCaches[key];
}
}
/**
* 设置帧计时器
*/
public static setFrameTimer(frame: number, onTimeOut: () => void) {
let count = 0;
const callback = () => {
if (count >= frame) {
onTimeOut();
timerTickEvent.remove(callback);
} else {
count += MTimer.dtFactor;
}
}
timerTickEvent.add(callback);
}
}
const onFrameCaches: {
[key: string]: {
callback: (dt: number) => void,
thisObj?: any
}
} = {};
const _onFrame: MEvent<(dt: number) => void> = new MEvent();
const timerTickEvent: MEvent<() => void> = new MEvent();
const DefaultDeltaTime = 1000 / 60;
let _deltaTime: number = 0;
let startTime = 0;
let lastTime = 0;
let curTime = 0;
function updateDeltaTime() {
lastTime = curTime;
curTime = Date.now() - startTime;
_deltaTime = curTime - lastTime;
_deltaTime = _deltaTime < 0 ? 0 : _deltaTime
}
function onVisibilityChange() {
curTime = Date.now() - startTime;
}
function onUpdate() {
updateDeltaTime();
_onFrame.call(MTimer.deltaTime);
timerTickEvent.call();
}
export namespace MUtils {
/**左闭右开 */
export function random(min: number, max: number) {
return Math.random() * (max - min) + min;
}
/**左闭右开 */
export function randomInt(min: number, max: number) {
return Math.floor(Math.random() * (max - min) + min);
}
export function toRadians(degrees: number) {
return degrees / 180 * Math.PI;
}
export function toDegress(radians: number) {
return radians / Math.PI * 180;
}
export function degreesAngelAdd(a: number, b: number) {
return (a + b) % 360;
}
export function dot(vec1: FYGE.Point, vec2: FYGE.Point): number {
return vec1.x * vec2.x + vec1.y * vec2.y;
}
export function getAngle(point: FYGE.Point) {
let radians = Math.acos(point.x / (Math.sqrt(point.x*point.x+point.y*point.y)));
radians = point.y > 0 ? radians : -radians;
return toDegress(radians);
}
/**
* 根据角度创建单位向量
* @param angle 角度制的角度
*/
export function getVector(angle: number) {
angle = toRadians(angle);
return new FYGE.Point(Math.cos(angle), Math.sin(angle));
}
export function stringOverEllipsis(str: string, limit: number) {
str = str || "";
if (str.length > limit) {
return str.substring(0, limit) + "...";
} else {
return str;
}
}
export function getClassName(cls: any) {
return cls["prototype"]["constructor"]["name"];
}
export function getInstanceClassName(instance: any) {
return getClassName(instance["constructor"]);
}
export function setColorFilter(image: FYGE.DisplayObject, color: number) {
//TODO 颜色滤镜实现
// 将16进制颜色分割成rgb值
let spliceColor = (color: number) => {
let result = { r: -1, g: -1, b: -1 };
result.b = color % 256;
result.g = Math.floor((color / 256)) % 256;
result.r = Math.floor((color / 256) / 256);
return result;
}
let result = spliceColor(color);
let colorMatrix = [
1, 0, 0, 0, 0,
0, 1, 0, 0, 0,
0, 0, 1, 0, 0,
0, 0, 0, 1, 0
];
colorMatrix[0] = result.r / 255;
colorMatrix[6] = result.g / 255;
colorMatrix[12] = result.b / 255;
let colorFilter = new FYGE.ColorMatrixFilter(colorMatrix);
image.filters = [colorFilter];
}
}
\ No newline at end of file
import { MUtils } from "./MUtils";
import { duiba_md5 } from "../../module/tools/security";
export namespace NetUtils {
export function createSgin(ticketId: number, score: number, gameData: any, submitToken: string): string {
return duiba_md5(ticketId + '' + score + '' + gameData + '' + submitToken);
}
export function encryptSeq(seq: number) {
return Math.round(5 * seq - MUtils.random(0, 4));
}
export function md5(str: string) {
return duiba_md5(str);
}
export function getTimestamp() {
return Date.now();
}
}
\ No newline at end of file
import { RES } from "../../module/RES";
import { Panel } from "../../module/views/Panel";
// import transRank from "../datas/transRank";
import { Tool } from "../Tools";
import { getTbData, TbNetName } from "../TaoBaoNet";
import { layers } from "../../module/views/layers";
import { GDispatcher } from "../MainPrizeFell";
export const centerImage = (img: FYGE.Sprite) => {
img.x = 750 / 2 - img.width / 2
img.y = 1624 / 2 - img.height / 2
}
export const posImage = (img: FYGE.Sprite, right: any, top: number) => {
if (right == 'center') {
img.x = img.parent.width / 2 - img.width / 2;
} else
img.x = img.parent.width - img.width - right;
img.y = top;
}
export class GameOverPanel extends Panel {
closeBtn: FYGE.Button;
scoreText: FYGE.BitmapText;
againBtn: FYGE.Button;
initUi() {
var bg = Tool.getSprite("gameOverBg1.png");
this.addChild(bg);
centerImage(bg);
//数据
const { score } = this.data;
//本局分数
var textures = {};
for (var i = 0; i < 10; i++) textures[i] = RES.getRes(`score_${i}.png`);
textures["f"] = RES.getRes(`score_f.png`);
var scoreNum = new FYGE.BitmapText(textures);
scoreNum.textAlign = FYGE.TEXT_ALIGN.CENTER;
this.scoreText = scoreNum;
this.addChild(this.scoreText);
this.scoreText.text = `${score}f`;
this.scoreText.x = 375;
this.scoreText.y = 800;
this.closeBtn = new FYGE.Button(RES.getRes("closeBtn1.png"));
bg.addChild(this.closeBtn);
posImage(this.closeBtn, 75, 20);
//再来一局
this.againBtn = new FYGE.Button(RES.getRes("gameAgain.png"));
bg.addChild(this.againBtn);
posImage(this.againBtn, "center", 350);
}
hidePanel() {
GDispatcher.dispatchEvent("gameDead");
super.hidePanel();
}
//点击再来一局
onClickAgain(){
GDispatcher.dispatchEvent("clickBuried");
this.hidePanel();
}
initEvents(){
super.initEvents();
this.againBtn.addEventListener(FYGE.MouseEvent.CLICK,this.onClickAgain,this);
}
removeEvents(){
super.initEvents();
this.againBtn.removeEventListener(FYGE.MouseEvent.CLICK,this.onClickAgain,this);
}
protected get closeBtns(): any[] {
return [this["closeBtn"]];
}
get groupNames() {
return ["gameOverPanel", "dialogScore"];
}
}
function operString(str: string): string {
//非空判断
if (!str || typeof str != "string" || !str.length) return "****";
//只有一个字符时
if (str.length == 1) return str[0] + "***";
//保留首尾,中间***
return str[0] + "***" + str[str.length - 1];
}
import { RES } from "../../module/RES";
import { Tool } from "../Tools";
export class GameEle extends FYGE.Sprite {
private _type: number
get type() {
return this._type
}
set type(value: number) {
this._type = value;
this.texture = RES.getRes("ele" + value + ".png")
}
private _tempType: number = null;
get tempType() {
return this._tempType;
}
set tempType(value) {
this._tempType = value;
}
index: number;
get row() {
return Tool.indexToRc(this.index)[0]
}
get col() {
return Tool.indexToRc(this.index)[1]
}
constructor(type: number) {
super();
this.type = type;
this.anchorTexture.set(0.5, 0.5);
}
reset(type) {
this.type = type;
this.scale.set(1, 1)
}
}
\ No newline at end of file
import { RES } from "../../module/RES";
/**
* 旋转光
*/
export class Light extends FYGE.Sprite {
get groupNames(){
return ["outerPanel"]
}
constructor() {
super();
this.texture = RES.getRes("light_bg.png");
this.anchorTexture.set(0.5, 0.5);
this.addEventListener(FYGE.Event.ENTER_FRAME, () => {
this.rotation += 1;
}, this)
}
}
\ No newline at end of file
import { GameEle } from "./GameEle";
import { Tool } from "../Tools";
import { RES } from "../../module/RES";
import { GPool } from "../../module/tools/GPool";
export interface MoveAniInt {
startEle1: GameEle,
startEle2?: GameEle,
endIndex: number,
}
/**
* 偷懒先用fun的试下,不然就动画独立
* @param callback 回调里计数完成用
* @param startEle1
* @param endIndex
* @param startEle2
*/
export function moveAni(
callback: () => void,
startEle1: GameEle,
endIndex: number,
startEle2?: GameEle,
) {
var endType: number = startEle1.type * 2;
var endP = Tool.getPositionByIndex(endIndex);
//移动动画
FYGE.Tween.get(startEle1)
.to({ x: endP[0], y: endP[1] }, 200)
.call(() => {
callback();
if (!startEle2) return;
//添加动画
// startEle1.parent.addChild(playDisAni(endType, startEle1.x, startEle1.y))
//第一个缩小
FYGE.Tween.get(startEle1)
.to({ scaleX: 0.1, scaleY: 0.1 }, 100)
.call(() => {
startEle1.type = endType;
startEle1.tempType = null;
})
.to({ scaleX: 1, scaleY: 1 }, 100, FYGE.Ease.backOut)
// .call(() => { callback() })
})
if (startEle2) {
FYGE.Tween.get(startEle2)
.to({ x: endP[0], y: endP[1] }, 200)
.call(() => {
//移除第二个
startEle2.parent.removeChild(startEle2);
GPool.recover("gameEle", startEle2)
})
}
}
// const disAniName = "disAniName"
// function playDisAni(type: number, x, y) {
// let mv: FYGE.MovieClip = GPool.takeOut(disAniName + type)
// if (!mv) {
// mv = new FYGE.MovieClip(RES.getRes("create" + type + ".svga"))
// }
// mv.position.set(x - 125, y - 125);
// mv.startAniRange(1, mv.totalFrames, 1, () => {
// if (mv.parent) {
// mv.parent.removeChild(mv);
// GPool.recover(disAniName + type, mv);
// }
// })
// return mv
// }
/**
* Created by rockyl on 2020-01-21.
*/
export let props: any = {};
// export function prepareProps() {
// let metaProps = getProps();
// engine.injectProp(props, metaProps);
// }
// export function injectProps(p) {
// engine.injectProp(props, p);
// }
import { Scene } from "../../module/views/Scene";
import PrizeFell from "../game/PrizeFell";
import MTimer from "../Global/MTimer";
import GuideMgr from "../Mgr/GuideMgr";
import { layers } from "../../module/views/layers";
import { GDispatcher } from "../MainPrizeFell";
import { SoundMgr } from "../Mgr/SoundMgr";
export class GameScenes extends Scene {
public game: PrizeFell = null;
get groupNames() {
return ["PrizeFell", "animation"];
}
initUi() {
this.customProperty();
this.width = 750;
this.height = 1624;
// this.y = -(1624 - layers.stageHeight) / 2;
this.awake();
setTimeout(() => {
this.onActive();
});
GDispatcher.addEventListener("game-create", this.onActive, this);
GDispatcher.addEventListener("game-destroy", this.onSleep, this);
GDispatcher.addEventListener("game-pause", this.onPause, this);
GDispatcher.addEventListener("game-resume", this.onResume, this);
}
public onActive() {
if (!this.game) {
this.game = new PrizeFell(this);
}
if (GuideMgr.instance.guideFlag == true) {
const pot = this.game.pot;
GuideMgr.instance.drawFirstGuide(false);
}
//设置隐藏属性和改变可见属性的事件的名称
let hidden: string, visibilityChange: string,self = this;
if (typeof document.hidden !== "undefined") {
hidden = "hidden";
visibilityChange = "visibilitychange";
} else if (typeof document["msHidden"] !== "undefined") {
hidden = "msHidden";
visibilityChange = "msvisibilitychange";
} else if (typeof document["webkitHidden"] !== "undefined") {
hidden = "webkitHidden";
visibilityChange = "webkitvisibilitychange";
}
const handleVisibilityChange = (e) => {
if (document.visibilityState == "visible") {
self.game.openMusic.visible && (SoundMgr.instance.isMusic = true);
self.game.closeMusic.visible && (SoundMgr.instance.isMusic = false);
console.log("网页显示");
} else if (document.visibilityState == "hidden") {
SoundMgr.instance.isMusic = false
console.log("网页隐藏");
}
};
document.addEventListener(visibilityChange, handleVisibilityChange, false);
}
public onSleep() {
MTimer.destroy();
this.game.destroy();
this.game = null;
}
public onPause() {
SoundMgr.instance.isMusic = false;
this.game.pause = true;
}
public onResume() {
this.game.pause = false;
}
private awake() {
MTimer.init();
}
private customProperty() {
//@ts-ignore
FYGE.DisplayObject.prototype.dispose = function () {
this.parent.removeChild(this);
};
}
removeEvents() {
GDispatcher.removeEventListener("game-create", this.onActive, this);
GDispatcher.removeEventListener("game-destroy", this.onSleep, this);
GDispatcher.removeEventListener("game-pause", this.onPause, this);
GDispatcher.removeEventListener("game-resume", this.onResume, this);
}
}
{
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"noImplicitAny": false,
"sourceMap": true,
"removeComments": true,
"noEmitOnError":true,
"outDir":"dist",
/*"outFile": "./index.js",*/
"lib": [
"es5",
"dom",
"es2015.promise"
]
},
"exclude": [
"node_modules"
]
}
\ No newline at end of file
const path = require('path');
module.exports = {
entry: './src/MainPrizeFell.ts',
module: {
rules: [
{
test: /\.tsx?$/,
use: 'ts-loader',
exclude: /node_modules/
}
]
},
resolve: {
extensions: ['.tsx', '.ts', '.js']
},
output: {
filename: 'output.js',
path: __dirname,
libraryTarget: 'umd',
}
};
\ No newline at end of file
const merge = require('webpack-merge');
const common = require('./webpack.common.js');
const webpack = require('webpack');
const MockWebpackPlugin = require('mock-webpack-plugin');
const mockConfig = require('./mock/config.js');
module.exports = merge(common, {
devtool: 'eval-source-map',
devServer: {
contentBase: '.',
proxy: {
'/plugin/*':'http://localhost:3000',
'/ngapi/*': 'http://localhost:3000',
'/ngame/*': 'http://localhost:3000',
}
},
plugins: [
new MockWebpackPlugin({
config: mockConfig,
port: 3000
})
]
});
\ No newline at end of file
const merge = require('webpack-merge');
const common = require('./webpack.common.js');
const UglifyJSPlugin = require('uglifyjs-webpack-plugin');
const webpack = require('webpack');
module.exports = merge(common, {
mode: "development",
devtool: 'source-map',
plugins: [
// new UglifyJSPlugin(
// { sourceMap: false }
// ),
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('production')
})
]
});
\ No newline at end of file
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