layaair-example

This commit is contained in:
King Wang
2021-07-21 23:11:13 +08:00
parent c3aa1f918e
commit 4bfe797a89
203 changed files with 257823 additions and 0 deletions

View File

@@ -0,0 +1,31 @@
/**This class is automatically generated by LayaAirIDE, please do not make any modifications. */
import GameUI from "./script/GameUI"
import GameControl from "./script/GameControl"
import Bullet from "./script/Bullet"
import DropBox from "./script/DropBox"
/*
* 游戏初始化配置;
*/
export default class GameConfig{
static width:number=640;
static height:number=1136;
static scaleMode:string="fixedwidth";
static screenMode:string="none";
static alignV:string="top";
static alignH:string="left";
static startScene:any="test/TestScene.scene";
static sceneRoot:string="";
static debug:boolean=false;
static stat:boolean=false;
static physicsDebug:boolean=false;
static exportSceneToJson:boolean=true;
constructor(){}
static init(){
var reg: Function = Laya.ClassUtils.regClass;
reg("script/GameUI.ts",GameUI);
reg("script/GameControl.ts",GameControl);
reg("script/Bullet.ts",Bullet);
reg("script/DropBox.ts",DropBox);
}
}
GameConfig.init();

View File

@@ -0,0 +1,54 @@
import GameConfig from "./GameConfig";
import { serviceProto } from "./shared/protocols/serviceProto";
import { HttpClient } from "./tsrpc_browser/index";
// TSRPC TEST
let client = new HttpClient(serviceProto, {
server: 'http://localhost:3000',
logger: console
});
async function test() {
await client.callApi('AddData', {
content: 'AAAAA'
})
let ret = await client.callApi('GetData', {});
console.log('ret', ret)
}
test();
class Main {
constructor() {
//根据IDE设置初始化引擎
if (window["Laya3D"]) Laya3D.init(GameConfig.width, GameConfig.height);
else Laya.init(GameConfig.width, GameConfig.height, Laya["WebGL"]);
Laya["Physics"] && Laya["Physics"].enable();
Laya["DebugPanel"] && Laya["DebugPanel"].enable();
Laya.stage.scaleMode = GameConfig.scaleMode;
Laya.stage.screenMode = GameConfig.screenMode;
Laya.stage.alignV = GameConfig.alignV;
Laya.stage.alignH = GameConfig.alignH;
//兼容微信不支持加载scene后缀场景
Laya.URL.exportSceneToJson = GameConfig.exportSceneToJson;
//打开调试面板通过IDE设置调试模式或者url地址增加debug=true参数均可打开调试面板
if (GameConfig.debug || Laya.Utils.getQueryString("debug") == "true") Laya.enableDebugPanel();
if (GameConfig.physicsDebug && Laya["PhysicsDebugDraw"]) Laya["PhysicsDebugDraw"].enable();
if (GameConfig.stat) Laya.Stat.show();
Laya.alertGlobalError(true);
//激活资源版本控制version.json由IDE发布功能自动生成如果没有也不影响后续流程
Laya.ResourceVersion.enable("version.json", Laya.Handler.create(this, this.onVersionLoaded), Laya.ResourceVersion.FILENAME_VERSION);
}
onVersionLoaded(): void {
//激活大小图映射,加载小图的时候,如果发现小图在大图合集里面,则优先加载大图合集,而不是小图
Laya.AtlasInfoManager.enable("fileconfig.json", Laya.Handler.create(this, this.onConfigLoaded));
}
onConfigLoaded(): void {
//加载IDE指定的场景
GameConfig.startScene && Laya.Scene.open(GameConfig.startScene);
}
}
//激活启动类
new Main();

View File

@@ -0,0 +1,29 @@
/**
* 子弹脚本,实现子弹飞行逻辑及对象池回收机制
*/
export default class Bullet extends Laya.Script {
constructor() { super(); }
onEnable(): void {
//设置初始速度
var rig: Laya.RigidBody = this.owner.getComponent(Laya.RigidBody);
rig.setVelocity({ x: 0, y: -10 });
}
onTriggerEnter(other: any, self: any, contact: any): void {
//如果被碰到,则移除子弹
this.owner.removeSelf();
}
onUpdate(): void {
//如果子弹超出屏幕,则移除子弹
if ((this.owner as Laya.Sprite).y < -10) {
this.owner.removeSelf();
}
}
onDisable(): void {
//子弹被移除时,回收子弹到对象池,方便下次复用,减少对象创建开销
Laya.Pool.recover("bullet", this.owner);
}
}

View File

@@ -0,0 +1,70 @@
import GameUI from "./GameUI";
/**
* 掉落盒子脚本,实现盒子碰撞及回收流程
*/
export default class DropBox extends Laya.Script {
/**盒子等级 */
level: number = 1;
/**等级文本对象引用 */
private _text: Laya.Text;
/**刚体对象引用 */
private _rig: Laya.RigidBody
constructor() { super(); }
onEnable(): void {
/**获得组件引用,避免每次获取组件带来不必要的查询开销 */
this._rig = this.owner.getComponent(Laya.RigidBody);
this.level = Math.round(Math.random() * 5) + 1;
this._text = this.owner.getChildByName("levelTxt") as Laya.Text;
this._text.text = this.level + "";
}
onUpdate(): void {
//让持续盒子旋转
(this.owner as Laya.Sprite).rotation++;
}
onTriggerEnter(other: any, self: any, contact: any): void {
var owner: Laya.Sprite = this.owner as Laya.Sprite;
if (other.label === "buttle") {
//碰撞到子弹后,增加积分,播放声音特效
if (this.level > 1) {
this.level--;
this._text.changeText(this.level + "");
owner.getComponent(Laya.RigidBody).setVelocity({ x: 0, y: -10 });
Laya.SoundManager.playSound("sound/hit.wav");
} else {
if (owner.parent) {
let effect: Laya.Animation = Laya.Pool.getItemByCreateFun("effect", this.createEffect, this);
effect.pos(owner.x, owner.y);
owner.parent.addChild(effect);
effect.play(0, true);
owner.removeSelf();
Laya.SoundManager.playSound("sound/destroy.wav");
}
}
GameUI.instance.addScore(1);
} else if (other.label === "ground") {
//只要有一个盒子碰到地板,则停止游戏
owner.removeSelf();
GameUI.instance.stopGame();
}
}
/**使用对象池创建爆炸动画 */
createEffect(): Laya.Animation {
let ani: Laya.Animation = new Laya.Animation();
ani.loadAnimation("test/TestAni.ani");
ani.on(Laya.Event.COMPLETE, null, recover);
function recover(): void {
ani.removeSelf();
Laya.Pool.recover("effect", ani);
}
return ani;
}
onDisable(): void {
//盒子被移除时,回收盒子到对象池,方便下次复用,减少对象创建开销。
Laya.Pool.recover("dropBox", this.owner);
}
}

View File

@@ -0,0 +1,69 @@
import DropBox from "./DropBox";
import Bullet from "./Bullet";
/**
* 游戏控制脚本。定义了几个dropBoxbulletcreateBoxInterval等变量能够在IDE显示及设置该变量
* 更多类型定义,请参考官方文档
*/
export default class GameControl extends Laya.Script {
/** @prop {name:dropBox,tips:"掉落容器预制体对象",type:Prefab}*/
dropBox: Laya.Prefab;
/** @prop {name:bullet,tips:"子弹预制体对象",type:Prefab}*/
bullet: Laya.Prefab;
/** @prop {name:createBoxInterval,tips:"间隔多少毫秒创建一个下跌的容器",type:int,default:1000}*/
createBoxInterval: number = 1000;
/**开始时间*/
private _time: number = 0;
/**是否已经开始游戏 */
private _started: boolean = false;
/**子弹和盒子所在的容器对象 */
private _gameBox: Laya.Sprite;
constructor() { super(); }
onEnable(): void {
this._time = Date.now();
this._gameBox = this.owner.getChildByName("gameBox") as Laya.Sprite;
}
onUpdate(): void {
//每间隔一段时间创建一个盒子
let now = Date.now();
if (now - this._time > this.createBoxInterval&&this._started) {
this._time = now;
this.createBox();
}
}
createBox(): void {
//使用对象池创建盒子
let box: Laya.Sprite = Laya.Pool.getItemByCreateFun("dropBox", this.dropBox.create, this.dropBox);
box.pos(Math.random() * (Laya.stage.width - 100), -100);
this._gameBox.addChild(box);
}
onStageClick(e: Laya.Event): void {
//停止事件冒泡,提高性能,当然也可以不要
e.stopPropagation();
//舞台被点击后,使用对象池创建子弹
let flyer: Laya.Sprite = Laya.Pool.getItemByCreateFun("bullet", this.bullet.create, this.bullet);
flyer.pos(Laya.stage.mouseX, Laya.stage.mouseY);
this._gameBox.addChild(flyer);
}
/**开始游戏,通过激活本脚本方式开始游戏*/
startGame(): void {
if (!this._started) {
this._started = true;
this.enabled = true;
}
}
/**结束游戏,通过非激活本脚本停止游戏 */
stopGame(): void {
this._started = false;
this.enabled = false;
this.createBoxInterval = 1000;
this._gameBox.removeChildren();
}
}

View File

@@ -0,0 +1,50 @@
import { ui } from "./../ui/layaMaxUI";
import GameControl from "./GameControl"
/**
* 本示例采用非脚本的方式实现而使用继承页面基类实现页面逻辑。在IDE里面设置场景的Runtime属性即可和场景进行关联
* 相比脚本方式继承式页面类可以直接使用页面定义的属性通过IDE内var属性定义比如this.tipLbllthis.scoreLbl具有代码提示效果
* 建议:如果是页面级的逻辑,需要频繁访问页面内多个元素,使用继承式写法,如果是独立小模块,功能单一,建议用脚本方式实现,比如子弹脚本。
*/
export default class GameUI extends ui.test.TestSceneUI {
/**设置单例的引用方式,方便其他类引用 */
static instance: GameUI;
/**当前游戏积分字段 */
private _score: number;
/**游戏控制脚本引用,避免每次获取组件带来不必要的性能开销 */
private _control: GameControl;
constructor() {
super();
GameUI.instance = this;
//关闭多点触控,否则就无敌了
Laya.MouseManager.multiTouchEnabled = false;
}
onEnable(): void {
this._control = this.getComponent(GameControl);
//点击提示文字,开始游戏
this.tipLbll.on(Laya.Event.CLICK, this, this.onTipClick);
}
onTipClick(e: Laya.Event): void {
this.tipLbll.visible = false;
this._score = 0;
this.scoreLbl.text = "";
this._control.startGame();
}
/**增加分数 */
addScore(value: number = 1): void {
this._score += value;
this.scoreLbl.changeText("分数:" + this._score);
//随着分数越高,难度增大
if (this._control.createBoxInterval > 600 && this._score % 20 == 0) this._control.createBoxInterval -= 20;
}
/**停止游戏 */
stopGame(): void {
this.tipLbll.visible = true;
this.tipLbll.text = "游戏结束了,点击屏幕重新开始";
this._control.stopGame();
}
}

View File

@@ -0,0 +1,10 @@
// This is a demo code file
// Feel free to delete it
export interface ReqAddData {
content: string;
}
export interface ResAddData {
time: Date
}

View File

@@ -0,0 +1,13 @@
// This is a demo code file
// Feel free to delete it
export interface ReqGetData {
}
export interface ResGetData {
data: {
content: string,
time: Date
}[]
}

View File

@@ -0,0 +1,98 @@
import { ServiceProto } from 'tsrpc-proto';
import { ReqAddData, ResAddData } from './PtlAddData';
import { ReqGetData, ResGetData } from './PtlGetData';
// This is a demo service proto file (auto generated)
// Feel free to delete it
export interface ServiceType {
api: {
"AddData": {
req: ReqAddData,
res: ResAddData
},
"GetData": {
req: ReqGetData,
res: ResGetData
}
},
msg: {
}
}
export const serviceProto: ServiceProto<ServiceType> = {
"version": 1,
"services": [
{
"id": 0,
"name": "AddData",
"type": "api"
},
{
"id": 1,
"name": "GetData",
"type": "api"
}
],
"types": {
"PtlAddData/ReqAddData": {
"type": "Interface",
"properties": [
{
"id": 0,
"name": "content",
"type": {
"type": "String"
}
}
]
},
"PtlAddData/ResAddData": {
"type": "Interface",
"properties": [
{
"id": 0,
"name": "time",
"type": {
"type": "Date"
}
}
]
},
"PtlGetData/ReqGetData": {
"type": "Interface"
},
"PtlGetData/ResGetData": {
"type": "Interface",
"properties": [
{
"id": 0,
"name": "data",
"type": {
"type": "Array",
"elementType": {
"type": "Interface",
"properties": [
{
"id": 0,
"name": "content",
"type": {
"type": "String"
}
},
{
"id": 1,
"name": "time",
"type": {
"type": "Date"
}
}
]
}
}
}
]
}
}
};

View File

@@ -0,0 +1,60 @@
/*!
* TSRPC Browser v3.0.5-dev.0
* -----------------------------------------
* Copyright (c) King Wang.
* MIT License
* https://github.com/k8w/tsrpc-browser
*/
import { ApiReturn } from 'tsrpc-proto';
import { BaseHttpClient } from 'tsrpc-base-client';
import { BaseHttpClientOptions } from 'tsrpc-base-client';
import { BaseServiceType } from 'tsrpc-proto';
import { BaseWsClient } from 'tsrpc-base-client';
import { BaseWsClientOptions } from 'tsrpc-base-client';
import { ServiceProto } from 'tsrpc-proto';
import { TransportOptions } from 'tsrpc-base-client';
import { TsrpcError } from 'tsrpc-proto';
/**
* HTTP Client for TSRPC.
* It uses XMLHttpRequest to send requests.
* @typeParam ServiceType - `ServiceType` from generated `proto.ts`
*/
export declare class HttpClient<ServiceType extends BaseServiceType = any> extends BaseHttpClient<ServiceType> {
readonly options: Readonly<HttpClientOptions>;
constructor(proto: ServiceProto<ServiceType>, options?: Partial<HttpClientOptions>);
callApi<T extends keyof ServiceType['api']>(apiName: T, req: ServiceType['api'][T]['req'], options?: HttpClientTransportOptions): Promise<ApiReturn<ServiceType['api'][T]['res']>>;
sendMsg<T extends keyof ServiceType['msg']>(msgName: T, msg: ServiceType['msg'][T], options?: HttpClientTransportOptions): Promise<{
isSucc: true;
} | {
isSucc: false;
err: TsrpcError;
}>;
}
export declare interface HttpClientOptions extends BaseHttpClientOptions {
}
export declare interface HttpClientTransportOptions extends TransportOptions {
/**
* Event when progress of data sent is changed
* @param ratio - 0~1
*/
onProgress?: (ratio: number) => void;
}
/**
* Client for TSRPC WebSocket Server.
* @typeParam ServiceType - `ServiceType` from generated `proto.ts`
*/
export declare class WsClient<ServiceType extends BaseServiceType = any> extends BaseWsClient<ServiceType> {
readonly options: Readonly<WsClientOptions>;
constructor(proto: ServiceProto<ServiceType>, options?: Partial<WsClientOptions>);
}
export declare interface WsClientOptions extends BaseWsClientOptions {
}
export * from "tsrpc-proto";
export { }

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,17 @@
/**This class is automatically generated by LayaAirIDE, please do not make any modifications. */
import View=Laya.View;
import Dialog=Laya.Dialog;
import Scene=Laya.Scene;
var REG: Function = Laya.ClassUtils.regClass;
export module ui.test {
export class TestSceneUI extends Scene {
public scoreLbl:Laya.Label;
public tipLbll:Laya.Label;
constructor(){ super()}
createChildren():void {
super.createChildren();
this.loadScene("test/TestScene");
}
}
REG("ui.test.TestSceneUI",TestSceneUI);
}