Commit 5a93cefd authored by haiyoucuv's avatar haiyoucuv

1

parents
Pipeline #257427 failed with stages
in 0 seconds
# project ignores
node_modules
./released
.DS_Store
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="JavaScriptSettings">
<option name="languageLevel" value="ES6" />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/qiaqia_qx.iml" filepath="$PROJECT_DIR$/.idea/qiaqia_qx.iml" />
</modules>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
<excludeFolder url="file://$MODULE_DIR$/temp" />
<excludeFolder url="file://$MODULE_DIR$/tmp" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="PropertiesComponent">
<property name="nodejs_interpreter_path.stuck_in_default_project" value="undefined stuck path" />
<property name="nodejs_npm_path_reset_for_default_project" value="true" />
<property name="settings.editor.selected.configurable" value="editor.preferences.fonts.default" />
</component>
</project>
\ No newline at end of file
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</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 Main(canvas);
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);
})
</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 diff is collapsed.
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 diff is collapsed.
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 = {
'/ngame/new/datapash': {
data: './json/datapash.json'
}
}
for (let item in config) {
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": "1111",
"data": {}
}
\ No newline at end of file
This diff is collapsed.
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 { 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 = () => {
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) => {
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.msg.x = (this.bg.width - this.msg.textWidth) / 2//(layers.stageWidth - this.msg.textWidth) / 2;
//是否需要根据文本宽度缩放背景
// this.bg.width = Math.min(this.msg.textWidth + this.PADDING * 2, 523);
//背景居中适配,由于上面一行注释,那这行就构造函数里只执行一次吧
// 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
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 {
this.data = null;//看情况吧,有时候hidePanel后用了data,注意
//移除事件
this.removeEvents();
//派发销毁事件,主要用于场景及弹框控制
this.dispatchEvent("onDestroy");
super.destroy();
}
}
\ 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();
}
}
\ 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]]);
}
//初始化场景层级
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 diff is collapsed.
This diff is collapsed.
{
"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": "^8.0.0",
"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": {},
"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 --host 0.0.0.0",
"buildTS": "webpack --config webpack.prod.js && node scripts/mergeJs",
"copyJs": "node scripts/copyJs"
},
"author": "MrKwon",
"license": "ISC"
}
\ No newline at end of file
{
"type": "activity",
"name": "anything"
}
\ No newline at end of file
{
"comCloseBtn.png": {
"x": 646,
"y": 60,
"w": 48,
"h": 48,
"ox": 0,
"oy": 0,
"sw": 48,
"sh": 48,
"ro": false
},
"toastBg.png": {
"x": 184,
"y": 2,
"w": 460,
"h": 130,
"ox": 0,
"oy": 0,
"sw": 460,
"sh": 130,
"ro": false
},
"waitingBg.png": {
"x": 2,
"y": 2,
"w": 160,
"h": 180,
"ox": 0,
"oy": 0,
"sw": 160,
"sh": 180,
"ro": true
},
"waitingRot.png": {
"x": 646,
"y": 2,
"w": 56,
"h": 56,
"ox": 0,
"oy": 0,
"sw": 56,
"sh": 56,
"ro": false
}
}
\ No newline at end of file
{
"btn_浠撳簱.png": {
"x": 1964,
"y": 2,
"w": 121,
"h": 133,
"ox": 0,
"oy": 0,
"sw": 121,
"sh": 133,
"ro": false
},
"btn_鍏戞崲璁板綍.png": {
"x": 2960,
"y": 2,
"w": 100,
"h": 104,
"ox": 0,
"oy": 0,
"sw": 100,
"sh": 104,
"ro": false
},
"btn_鍟嗗簵.png": {
"x": 2208,
"y": 2,
"w": 119,
"h": 133,
"ox": 0,
"oy": 0,
"sw": 119,
"sh": 133,
"ro": false
},
"btn_瑙勫垯.png": {
"x": 2765,
"y": 2,
"w": 99,
"h": 107,
"ox": 0,
"oy": 0,
"sw": 99,
"sh": 107,
"ro": false
},
"btn_棰嗘按婊�.png": {
"x": 2087,
"y": 2,
"w": 119,
"h": 133,
"ox": 0,
"oy": 0,
"sw": 119,
"sh": 133,
"ro": false
},
"game_鏀惰幏.png": {
"x": 3246,
"y": 97,
"w": 82,
"h": 93,
"ox": 0,
"oy": 0,
"sw": 82,
"sh": 93,
"ro": true
},
"game_娴囨按.png": {
"x": 3154,
"y": 2,
"w": 90,
"h": 101,
"ox": 0,
"oy": 0,
"sw": 90,
"sh": 101,
"ro": false
},
"game_绉嶆.png": {
"x": 3062,
"y": 2,
"w": 90,
"h": 101,
"ox": 0,
"oy": 0,
"sw": 90,
"sh": 101,
"ro": false
},
"骞垮憡.png": {
"x": 1828,
"y": 2,
"w": 103,
"h": 156,
"ox": 0,
"oy": 0,
"sw": 103,
"sh": 156,
"ro": false
},
"鐢ㄦ埛_bg.png": {
"x": 2329,
"y": 2,
"w": 434,
"h": 129,
"ox": 0,
"oy": 0,
"sw": 434,
"sh": 129,
"ro": false
},
"鐢ㄦ埛_澶村儚.png": {
"x": 3246,
"y": 2,
"w": 93,
"h": 93,
"ox": 0,
"oy": 0,
"sw": 93,
"sh": 93,
"ro": false
},
"鐢ㄦ埛_姘�.png": {
"x": 2024,
"y": 137,
"w": 39,
"h": 48,
"ox": 0,
"oy": 0,
"sw": 39,
"sh": 48,
"ro": true
},
"鐢癬鍒濆.png": {
"x": 812,
"y": 2,
"w": 403,
"h": 177,
"ox": 0,
"oy": 0,
"sw": 403,
"sh": 177,
"ro": false
},
"鐢癬绉嶆.png": {
"x": 407,
"y": 2,
"w": 403,
"h": 177,
"ox": 0,
"oy": 0,
"sw": 403,
"sh": 177,
"ro": false
},
"鐢癬閫夋嫨.png": {
"x": 2,
"y": 2,
"w": 403,
"h": 177,
"ox": 0,
"oy": 0,
"sw": 403,
"sh": 177,
"ro": false
},
"绉嶆妗哶bg.png": {
"x": 1217,
"y": 2,
"w": 609,
"h": 160,
"ox": 0,
"oy": 0,
"sw": 609,
"sh": 160,
"ro": false
},
"绉嶆妗哶left.png": {
"x": 1828,
"y": 160,
"w": 19,
"h": 34,
"ox": 0,
"oy": 0,
"sw": 19,
"sh": 34,
"ro": true
},
"绉嶆妗哶right.png": {
"x": 1864,
"y": 160,
"w": 18,
"h": 34,
"ox": 0,
"oy": 0,
"sw": 18,
"sh": 34,
"ro": true
},
"绉嶆妗哶灞辨牳妗�.png": {
"x": 2119,
"y": 137,
"w": 35,
"h": 44,
"ox": 0,
"oy": 0,
"sw": 35,
"sh": 44,
"ro": true
},
"绉嶆妗哶寮€蹇冩灉.png": {
"x": 1933,
"y": 143,
"w": 35,
"h": 46,
"ox": 0,
"oy": 0,
"sw": 35,
"sh": 46,
"ro": true
},
"绉嶆妗哶鏉挎牀.png": {
"x": 1981,
"y": 137,
"w": 42,
"h": 41,
"ox": 0,
"oy": 0,
"sw": 42,
"sh": 41,
"ro": true
},
"绉嶆妗哶鐡滃瓙.png": {
"x": 2414,
"y": 133,
"w": 26,
"h": 48,
"ox": 0,
"oy": 0,
"sw": 26,
"sh": 48,
"ro": true
},
"绉嶆妗哶鑵版灉.png": {
"x": 2074,
"y": 137,
"w": 38,
"h": 43,
"ox": 0,
"oy": 0,
"sw": 38,
"sh": 43,
"ro": true
},
"绉嶆妗哶鑺辩敓.png": {
"x": 2363,
"y": 133,
"w": 26,
"h": 49,
"ox": 0,
"oy": 0,
"sw": 26,
"sh": 49,
"ro": true
},
"绉嶆妗哶琚嬪瓙.png": {
"x": 2866,
"y": 2,
"w": 107,
"h": 92,
"ox": 0,
"oy": 0,
"sw": 107,
"sh": 92,
"ro": true
},
"杩涘害_bg.png": {
"x": 2165,
"y": 137,
"w": 196,
"h": 31,
"ox": 0,
"oy": 0,
"sw": 196,
"sh": 31,
"ro": false
},
"杩涘害_fill.png": {
"x": 1933,
"y": 2,
"w": 139,
"h": 29,
"ox": 0,
"oy": 0,
"sw": 139,
"sh": 29,
"ro": true
}
}
\ No newline at end of file
{
"groups": [
{
"keys": "comCloseBtn.png,toastBg.png,waitingBg.png,waitingRot.png",
"name": "common",
"atlas": "common.json"
},
{
"keys": "btn_仓库.png,btn_兑换记录.png,btn_商店.png,btn_规则.png,btn_领水滴.png,game_bg.jpg,game_收获.png,game_浇水.png,game_种植.png,广告.png,用户_bg.png,用户_头像.png,用户_水.png,田_初始.png,田_种植.png,田_选择.png,种植框_bg.png,种植框_left.png,种植框_right.png,种植框_山核桃.png,种植框_开心果.png,种植框_板栗.png,种植框_瓜子.png,种植框_腰果.png,种植框_花生.png,种植框_袋子.png,进度_bg.png,进度_fill.png",
"name": "gameScene",
"atlas": "gameScene.json"
}
],
"path": "./resource/"
}
\ No newline at end of file
{
"groups": [
{
"keys": "comCloseBtn.png,toastBg.png,waitingBg.png,waitingRot.png",
"name": "common"
},
{
"keys": "btn_仓库.png,btn_兑换记录.png,btn_商店.png,btn_规则.png,btn_领水滴.png,game_bg.jpg,game_收获.png,game_浇水.png,game_种植.png,广告.png,用户_bg.png,用户_头像.png,用户_水.png,田_初始.png,田_种植.png,田_选择.png,种植框_bg.png,种植框_left.png,种植框_right.png,种植框_山核桃.png,种植框_开心果.png,种植框_板栗.png,种植框_瓜子.png,种植框_腰果.png,种植框_花生.png,种植框_袋子.png,进度_bg.png,进度_fill.png",
"name": "gameScene"
}
],
"path": "./resource/"
}
\ No newline at end of file
var fs = require("fs");
// fs.writeFileSync(
// "./released/output.js",
// fs.readFileSync("./output.js")
// )
var endPath = 'D:/duibaGame/测试项目0527/taobaominiTest/client/pages/index1/';
var version = Math.round(new Date().getTime() / 1000);
fs.writeFileSync(endPath + "output." + version + ".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");
//反序列化
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" })
sonFiles = sonFiles.filter((f) => { return jsons.indexOf(f.substring(0, f.length - 4) + ".json") == -1 })
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);
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"), "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 {
//遍历
for (var i = 0; i < files.length; i++) {
let filename = files[i];
if (filename.indexOf(".json") == -1) continue
//获取当前文件的绝对路径
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();
}
//序列化,不格式化,节省内存
}
})
} 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), "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"), "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 { Tool } from "./Tools";
import { layers, destroyLayers } from "../module/views/layers";
import { RES } from "../module/RES";
import { changeScene, showWaiting, destroyAllCtrls } from "../module/ctrls";
import { ResJson } from "./ResJson";
import { destroyNetData, sendTbNet, TbNetName } from "./TaoBaoNet";
import { GameScene } from "./scenes/GameScene";
/**
* 全局事件,为了和小程序交互
* 有可能多处页面用到,所以单开
*/
export const GDispatcher = new FYGE.EventDispatcher();
export class Main {
//主舞台
stage: FYGE.Stage;
private requestID;
private _pause: boolean;
constructor(canvas: HTMLCanvasElement) {
var sysInfo;
//@ts-ignore 存在my就初始化
if (my) {
FYGE.initedByCanvas(canvas)
//@ts-ignore 存在my就初始化
sysInfo = my.getSystemInfoSync()
}
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;
//开始循环
// 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 async onAddToStage() {
//初始化层级
layers.init(this.stage);
console.log("初始化层级完成")
//初始化资源配置
RES.loadConfig(ResJson);
console.log("初始化资源配置完成")
//加载通用资源
await RES.loadGroup("common");
console.log("通用资源加载完成")
//隐藏加载中
// if (document.getElementById("__loading__")) document.getElementById("__loading__").style.display = "none";
//打开开始场景
changeScene(GameScene);
//测试
// sendTbNet(TbNetName.aaa, {}, (s, res) => {
// console.log(res)
// })
//获取数据,,必成功
// showWaiting();
// sendTbNet(TbNetName.getAppData, {}, (s, res) => {
// hideWaiting();
// Tool.globalData = res.data;
// changeScene(PlayScene);
// //先去获取下任务列表的商品信息吧
// sendTbNet(TbNetName.getTaskList, { activityId: Tool.globalData.activityId }, (s, res) => {
// if (s) Tool.browseItems = res.data.browseItemIds.content;
// })
// })
}
//在小程序显示时调用onShow
run() {
this._pause = false
}
//在小程序隐藏时调用onHide
pause() {
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() {
//Tween都移除,注意吧,可能原先的也被移除
FYGE.Tween.removeAllTweens()
// removeAllTimeoutId();//这个再看,尽量用tween的修改
//停掉计时器
FYGE.getCancelAnimationFrame()(this.requestID);
//层级销毁
destroyLayers()
//销毁控制器
destroyAllCtrls();
//舞台销毁
this.stage.destroy();
//全局事件置空
GDispatcher.removeAllEventListener();
//网络数据记录清空
destroyNetData();
}
}
export const ResJson = {
"groups": [
{
"keys": "comCloseBtn.png,toastBg.png,waitingBg.png,waitingRot.png",
"name": "common"
},
{
"keys": "btn_仓库.png,btn_兑换记录.png,btn_商店.png,btn_规则.png,btn_领水滴.png,game_bg.jpg,game_收获.png,game_浇水.png,game_种植.png,广告.png,用户_bg.png,用户_头像.png,用户_水.png,田_初始.png,田_种植.png,田_选择.png,种植框_bg.png,种植框_left.png,种植框_right.png,种植框_山核桃.png,种植框_开心果.png,种植框_板栗.png,种植框_瓜子.png,种植框_腰果.png,种植框_花生.png,种植框_袋子.png,进度_bg.png,进度_fill.png",
"name": "gameScene"
}
],
"path": "./resource/"
}
\ No newline at end of file
import { showToast, wait, clearWait } from "../module/ctrls";
//接口枚举,包括需要调用淘宝的api,用是否含有兑吧区分,或者单独区分
export enum TbNetName {
aaa = "aaa",
/**
* 查询积分
* activityId
*/
getCredits = "getCredits",
/**
* 开始接口
* activityId,nickName
*/
startGame = "startGame",
/**
* 提交分数接口
* activityId,grade,score,type(0:解锁 1:提交), playId
*/
submit = "submit",
/**
* 查询道具数量
* actitvityId
*/
getTools = "getTools",
/**
* 获取任务列表
* activityId
*/
getTaskList = "getTaskList",
/**
* 领取道具
* activityId,taskName
*/
getToolsByType = "getToolsByType",
/**
* 消耗道具
* activityId,type,playId
*/
useTools = "useTools",
}
//返回数据类型,到时再调整
interface dataIn {
netName: TbNetName
data: any
}
//返回数据类型
interface dataOut {
success: boolean,
data?: any
code?: string,
message?: string
}
//记录数据
let dataRecord: {
[name: string]: any
} = {};
//云函数
let fc;
/**
* 发送接口
* @param netName
* @param parameter
* @param callback
*/
export function sendTbNet(netName: TbNetName, parameter: any, callback: Function, hideMsg: boolean = false) {
//网络超时
let waitObj = wait(() => {
if (!hideMsg) showToast("网络超时")
callback(false)
}, 5000)
//@ts-ignore 本地开发,直接取数据
if (!my) {
var url = "../../mock/miniTb/" + netName + ".json";
fetchAsync(url)
.then((data) => {
//清除超时
clearWait(waitObj)
//记录数据
dataRecord[name] = data;
//统一错误信息提示
if (!hideMsg && !data.success) showToast(data.message || "网络异常")
//回调
callback(data.success, data);
}, () => { })
return
}
//@ts-ignore
if (!fc) fc = getApp().cloud.function;
//第一个参数视项目而定
fc.invoke("becheery", parameter, netName)
.then((res: dataOut) => {
clearWait(waitObj);
//记录数据
dataRecord[netName] = res;
// console.log("返回数据" + JSON.stringify(res));
//统一错误信息提示
if (!hideMsg && !res.success) showToast(codeMsg[res.code] || res.message || "网络异常")
//回调
callback(res.success, res);
})
}
/**
* 获取数据
* @param netName
*/
export function getTbData(netName: TbNetName): dataOut {
return dataRecord[netName] || null;
}
//销毁数据
export function destroyNetData() {
dataRecord = {}
}
//webview里调用无效,用postMessage去调
// export const navigateToOutside = (url) => {
// my.call("navigateToOutside", {
// url
// }, (res) => {
// // my.alert({ content: "success - " + JSON.stringify(res)})
// });
// }
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;
}
// const { cloud } = window["getApp"]();
// const { function: fc } = cloud;
// fc.invoke("duiba.sign.doJoin", { signActivityId: 1 })
// .then(res => {
// console.log(res);
// })
/**
* 错误码列表,字段不设枚举了
*/
const codeMsg = {
"210001": "服务器异常",
"210002": "用户不存在",
"210003": "邀请已达上限",
"210004": "无法邀请自己",
"210006": "该活动ID无效",
"210009": "该活动暂未开始",
"210010": "该分享ID不存在",
"210012": "该用户暂未获奖",
"210013": "领取失败",
"210015": "该活动已删除",
"210016": "该活动已经结束",
"210017": "该奖品已达领取上线",
"210018": "请先分享好友",
"210019": "暂有奖品未领取",
"210020": "暂有奖品未完成",
"210021": "请先玩一局游戏",
"210022": "请先选择奖品",
"210023": "领取失败,库存不足",
"210024": "请先成为会员",
"210025": "奖品已经过期",
"210026": "不能重复助力",
"210028": "请至我的奖品页重新领取",//重新领取
}
\ No newline at end of file
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",
textWidth: number = 0,
align: FYGE.TEXT_ALIGN = FYGE.TEXT_ALIGN.CENTER,
x: number = 0,
y: number = 0
) {
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,
) {
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 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]
}
}
\ No newline at end of file
import { layers } from "../../module/views/layers";
export function getAdjustBottomHeight(target, percent: number) {
return layers.stageHeight - layers.stageHeight * percent - target.height + layers.stageOffsetY;
}
export function getAdjustTopHeight(target, percent: number) {
return layers.stageHeight * percent + layers.stageOffsetY;
}
export enum PLANT {
'NONE' = 'NONE',
'Chestnut' = 'Chestnut', // 板栗
'Pecan' = 'Pecan', // 山核桃
'Peanut' = 'Peanut', // 花生
'Sunflower' = 'Sunflower', // 瓜子
'Pistachio' = 'Pistachio', // 开心果
'Cashew' = 'Cashew', // 腰果
}
export const s_PlantData = {
Chestnut: {
name: '板栗',
time: 1,
},
Pecan: {
name: '山核桃',
time: 2,
},
Peanut: {
name: '花生',
time: 3,
},
Sunflower: {
name: '瓜子',
time: 4,
},
Pistachio: {
name: '开心果',
time: 5,
},
Cashew: {
name: '腰果',
time: 6,
},
}
import { Tool } from "../Tools";
import { Panel } from "../../module/views/Panel";
import { RES } from "../../module/RES";
import { Light } from "../parts/Light";
const foodData: {
[key: number]: { name: string, des: string }
} = {
8: { name: "爆浆麻薯150g*2袋", des: "" },
16: { name: "面筋卷120g*2袋", des: "" },
32: { name: "岩焗乳酪吐司500g", des: "" },
64: { name: "鱼豆腐170g", des: "" },
128: { name: "猪肉脯200g", des: "解锁后可在首页领取奖励哦~" },
256: { name: "卤藕168g*2袋", des: "解锁后可在首页领取奖励哦~" },
512: { name: "手撕面包1050g", des: "解锁后可在首页领取奖励哦~" },
1024: { name: "枣夹核桃700g", des: "解锁后可在首页领取奖励哦~" },
2048: { name: "甜辣鸭脖190g", des: "解锁后可在首页领取奖励哦~" },
}
/**
* 解锁弹框
*/
export class UnlockPanel extends Panel {
get groupNames() { return ["unlockPanel"] }
closeBtn:FYGE. Button;
data: {
grade: number,
closeFun:Function
}
initUi() {
//加光
this.addChild(new Light()).position.set(375, 735);
//背景
this.addChild(Tool.getSprite("unlockPanelBg.png"));
//关闭按钮
this.closeBtn = new FYGE.Button(RES.getRes("comCloseBtn.png"));
this.closeBtn.position.set(614, 460);
this.addChild(this.closeBtn);
//继续游戏
this.addChild(new FYGE.Button(RES.getRes("zailaiyiju.png")))
.once(FYGE.MouseEvent.CLICK, this.onClick_closeBtn, this)
.position.set((750 - 233) / 2, 938)
//标题文案
// this.addChild(new Title(this.data.grade))
//奖品图片 246;
this.addChild(new FYGE.Sprite(RES.getRes("unlock" + this.data.grade + ".png")))
.position.set((750 - 449) / 2-20, 580+20)
//名字
// this.addChild(Tool.addText(
// foodData[this.data.grade].name,
// 28,
// "#ffffff",
// undefined,
// 560,
// (750 - 560) / 2,
// 890
// ))
//描述
// this.addChild(Tool.addText(
// foodData[this.data.grade].des,
// 22,
// "#dac5fc",
// undefined,
// 560,
// (750 - 560) / 2,
// 931
// ))
}
start(data) {
super.start();
}
initEvents() {
this.closeBtn.addEventListener(FYGE.MouseEvent.CLICK,this.onClick_closeBtn, this)
}
onClick_closeBtn() {
this.data.closeFun()
this.hidePanel();
}
removeEvents() {
this.closeBtn.removeEventListener(FYGE.MouseEvent.CLICK,this.onClick_closeBtn, this)
}
}
class Title extends FYGE.Container {
grade: number
constructor(grade: number) {
super();
var msg = new FYGE.Sprite(RES.getRes("unlockMsg.png"))
this.addChild(msg);
var textures = {}
for (var i = 0; i < 10; i++)textures[i] = RES.getRes("n" + i + ".png");
var num = new FYGE.BitmapText(textures);
num.textAlign = FYGE.TEXT_ALIGN.LEFT;
num.text = grade + "";
this.addChild(num);
var w = msg.width + num.width;
msg.position.set((750 - w) / 2, 548);
num.position.set(msg.x + msg.width, 548 + 4)
}
}
\ No newline at end of file
import Container = FYGE.Container;
export default class GameLayer extends Container{
constructor() {
super();
}
}
import Container = FYGE.Container;
class Land extends Container {
constructor() {
super();
}
}
import { PLANT, s_PlantData } from "../../const/staticData";
import { Tool } from "../../Tools";
import Container = FYGE.Container;
import IScrollListItem = FYGE.IScrollListItem;
import ScrollList = FYGE.ScrollList;
import TextField = FYGE.TextField;
import TEXT_ALIGN = FYGE.TEXT_ALIGN;
import VERTICAL_ALIGN = FYGE.VERTICAL_ALIGN;
import Sprite = FYGE.Sprite;
import { RES } from "../../../module/RES";
class ListPlant extends Container implements IScrollListItem {
id: number;
data: number;
/**
* 数据更新
* @param {number} id
* @param data
*/
public initData(id: number, data: any) {
if (!data || data == PLANT.NONE) return;
this.key = data;
this.img.texture = RES.getRes(`种植框_${s_PlantData[data].name}.png`);
this.img.position.set((this.width - this.img.width) / 2 - 5, (this.height - this.img.height) / 2 + 20);
}
private _key: PLANT = PLANT.NONE;
public get key() {
return this._key;
}
public set key(key: PLANT) {
this._key = key;
if (this._key == PLANT.NONE) return;
this.nameLabel.text = s_PlantData[key].name;
this.timeLabel.text = s_PlantData[key].time + 'h';
this.nameLabel.x = (this.width - this.nameLabel.textWidth) / 2;
this.timeLabel.x = 72 + (35 - this.timeLabel.textWidth) / 2;
}
private nameLabel: TextField;
private timeLabel: TextField;
private img: Sprite;
constructor() {
super();
this.width = 108;
this.height = 160;
this.addChild(Tool.getSprite('种植框_袋子.png'))
.position.set(0, 21);
// 名字的label
this.nameLabel = this.addChild(new TextField());
this.nameLabel.position.set(0, 125);
this.nameLabel.size = 22;
this.nameLabel.textAlign = TEXT_ALIGN.CENTER;
// 需要时间的label
this.timeLabel = this.addChild(new TextField());
this.timeLabel.position.set(75, 85);
this.timeLabel.size = 17;
this.timeLabel.textAlign = TEXT_ALIGN.CENTER;
this.timeLabel.verticalAlign = VERTICAL_ALIGN.MIDDLE;
this.img = this.addChild(new Sprite());
this.addEventListener(FYGE.MouseEvent.CLICK, () => {
console.log(`点到了: ${this.key} ${s_PlantData[this.key].name}`);
});
}
}
export default class PlantList extends Container {
private scrollList: ScrollList;
constructor() {
super();
this.width = 609;
this.height = 106;
// bg
this.addChild(Tool.getSprite('种植框_bg.png'));
// tip: left and right
this.addChild(Tool.getSprite('种植框_left.png'))
.position.set(15, (this.height - 34) / 2);
this.addChild(Tool.getSprite('种植框_right.png'))
.position.set(this.width - 33, (this.height - 34) / 2);
// 列表
this.scrollList = this.addChild(new ScrollList(ListPlant, 128, 160, 500, 160, false));
let data = [];
for (let k in PLANT) {
if (k == PLANT.NONE) continue;
data.push(PLANT[k]);
}
this.scrollList.updateData(data);
this.scrollList.x = (this.width - 500) / 2;
this.x = 100;
this.y = 400;
}
}
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 {
constructor() {
super();
this.texture = RES.getRes("light.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
// }
import Container = FYGE.Container;
import { Tool } from "../../Tools";
import Sprite = FYGE.Sprite;
import TextField = FYGE.TextField;
import Graphics = FYGE.Graphics;
import Texture = FYGE.Texture;
export class UserInfoGroup extends Container {
private avatar: Sprite;
private nickName: TextField;
private numLabel: TextField;
constructor(userInfo?) {
super();
// 背景
this.addChild(Tool.getSprite('用户_bg.png'));
// 头像
// this.avatar = this.addChild(new Sprite());
this.avatar = this.addChild(Tool.getSprite('用户_头像.png'));
this.avatar.position.set(35, 13);
this.avatar.width = this.avatar.height = 93;
// 头像mask
// let mask = new Graphics();
// mask.position.set(35, 13);
let r = 93 / 2;
// mask.drawCircle(35 + r, 13 + r, r);
// this.avatar.mask = this.addChild(mask);
this.avatar.mask = this.addChild(new Graphics().drawCircle(35 + r, 13 + r, r));
// 昵称
this.nickName = this.addChild(new TextField());
this.nickName.position.set(150, 20);
this.nickName.size = 28;
this.nickName.fillColor = '#a65310';
// 数量
this.numLabel = this.addChild(new TextField());
this.numLabel.position.set(200, 68);
this.numLabel.size = 28;
this.numLabel.fillColor = '#a65310';
// 更新信息
userInfo && this.updateInfo(userInfo);
}
/**
* 更新用户信息
* @param userInfo
*/
public updateInfo(userInfo) {
this.avatar.texture = Texture.fromUrl(userInfo.avatar);
if (userInfo.nickName.length >= 3) {
userInfo.nickName = userInfo.nickName.slice(0, 3) + '...';
}
this.nickName.text = userInfo.nickName + '的坚果庄园';
this.numLabel.text = ${userInfo.waterNum}`;
}
}
import { Scene } from "../../module/views/Scene";
import { Tool } from "../Tools";
import PlantList from "../parts/Game/PlantList";
import Container = FYGE.Container;
import { getAdjustBottomHeight, getAdjustTopHeight } from "../const/myLab";
import { UserInfoGroup } from "../parts/UI/UserInfoGroup";
import Sprite = FYGE.Sprite;
import MouseEvent = FYGE.MouseEvent;
export class GameScene extends Scene {
get groupNames() {
return ['gameScene']
}
private plantList: PlantList; // 种植列表
// 顶部
private userInfoGroup: UserInfoGroup; // 用户信息
private ruleBtn: Sprite; // 规则按钮
// 底部
private taskBtn: Sprite; // 任务按钮
private wareHouseBtn: Sprite; // 仓库按钮
private storeBtn: Sprite; // 商店按钮
// 广告
private adBtn: Sprite;// 广告
initUi() {
this.addChild(Tool.getSprite('game_bg.jpg'));
// 底部
let bottomGroup = this.addChild(new Container());
this.taskBtn = bottomGroup.addChild(Tool.getSprite('btn_领水滴.png'))
this.taskBtn.x = 750 / 6 - this.taskBtn.width / 2;
this.taskBtn.name = '任务';
this.wareHouseBtn = bottomGroup.addChild(Tool.getSprite('btn_仓库.png'))
this.wareHouseBtn.x = 750 / 2 - this.wareHouseBtn.width / 2;
this.wareHouseBtn.name = '仓库';
this.storeBtn = bottomGroup.addChild(Tool.getSprite('btn_商店.png'))
this.storeBtn.x = 750 / 6 * 5 - this.storeBtn.width / 2;
this.storeBtn.name = '商店';
bottomGroup.y = getAdjustBottomHeight(bottomGroup, (1624 - 1382 - 133) / 1624);
// 顶部
let topGroup = this.addChild(new Container());
this.userInfoGroup = topGroup.addChild(new UserInfoGroup({
avatar: 'https://source.unsplash.com/collection/collectionid/100x100',
nickName: '哈哈哈哈',
waterNum: '666'
}));
this.ruleBtn = topGroup.addChild(Tool.getSprite('btn_规则.png'));
this.ruleBtn.position.set(622, 0);
this.ruleBtn.name = '规则';
topGroup.y = getAdjustTopHeight(topGroup, 117 / 1624);
this.adBtn = this.addChild(Tool.getSprite('广告.png'));
this.adBtn.position.set(30, (this.height - this.adBtn.height) / 2);
this.adBtn.name = '广告';
// 种植列表
this.plantList = this.addChild(new PlantList());
// this.plantList.visible = false;
}
start() {
super.start();
}
/**
* 按钮的点击事件
* @param e
*/
private touchBtn(e) {
console.log(e.target.name);
switch (e.target) {
case this.taskBtn:
console.log('点击了任务');
break;
case this.wareHouseBtn:
console.log('点击了仓库');
break;
case this.storeBtn:
console.log('点击了商店');
break;
case this.ruleBtn:
console.log('点击了规则');
break;
case this.adBtn:
console.log('点击了广告');
break;
}
}
initEvents() {
super.initEvents();
[this.ruleBtn, this.taskBtn, this.wareHouseBtn, this.storeBtn, this.adBtn].forEach((v) => {
v.addEventListener(MouseEvent.CLICK, this.touchBtn, this);
});
}
removeEvents() {
super.removeEvents();
[this.ruleBtn, this.taskBtn, this.wareHouseBtn, this.storeBtn, this.adBtn].forEach((v) => {
v.removeEventListener(MouseEvent.CLICK, this.touchBtn, 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
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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