278 lines
8.2 KiB
TypeScript
278 lines
8.2 KiB
TypeScript
import { _decorator, assetManager, Component, director, Label, Node, PhysicsSystem, Vec3, Animation, Prefab, instantiate, tween } from 'cc';
|
|
import { RoundBall } from './RoundBall';
|
|
import { PlayerController } from './PlayerController';
|
|
import { resLoader } from 'db://assets/core_tgx/base/utils/ResLoader';
|
|
import { ModuleDef } from 'db://assets/scripts/ModuleDef';
|
|
import { tgxUIAlert } from 'db://assets/core_tgx/tgx';
|
|
import { AreanNetMgr } from '../../scripts/AreanNetMgr';
|
|
const { ccclass, property } = _decorator;
|
|
|
|
enum GameState {
|
|
Playing,
|
|
Paused,
|
|
GameOver
|
|
}
|
|
|
|
@ccclass('BallGame')
|
|
export class BallGame extends Component {
|
|
|
|
/**
|
|
* 游戏结束
|
|
*/
|
|
private _isGameOver: boolean = false;
|
|
|
|
@property({ type: Node })
|
|
guiNode: Node | null = null;
|
|
|
|
public get isGameOver(): boolean {
|
|
return this._isGameOver;
|
|
}
|
|
|
|
myBallNum: number = 10;
|
|
opBallNum: number = 10;
|
|
deadBallNum: number = 0;
|
|
rndBallNum: number = 0;
|
|
|
|
@property({
|
|
type: PlayerController,
|
|
displayName: "角色控制"
|
|
})
|
|
playerCtrl: PlayerController | null = null;
|
|
@property({
|
|
type: RoundBall,
|
|
displayName: "球控制"
|
|
})
|
|
ballCtrl: RoundBall | null = null;
|
|
|
|
|
|
|
|
@property({
|
|
type: Label,
|
|
displayName: "我方弹珠数量"
|
|
})
|
|
myBallNumLabel: Label | null = null;
|
|
|
|
@property({
|
|
type: Label,
|
|
displayName: "对方弹珠数量"
|
|
})
|
|
opBallNumLabel: Label | null = null;
|
|
|
|
@property({
|
|
type: Label,
|
|
displayName: "放置弹珠数量"
|
|
})
|
|
rndBallNumLabel: Label | null = null;
|
|
|
|
@property({
|
|
type: Label,
|
|
displayName: "击中弹珠数量"
|
|
})
|
|
deadBallNumLabel: Label | null = null;
|
|
|
|
|
|
@property(Node)
|
|
PlaneNode: Node = null;
|
|
|
|
@property(Animation)
|
|
startAnim: Animation = null!;
|
|
|
|
private gameState: GameState = GameState.Playing;
|
|
|
|
start() {
|
|
this.initPhysics();
|
|
this.initGameState();
|
|
this.playStartAnimation();
|
|
}
|
|
|
|
private initPhysics() {
|
|
const physics = PhysicsSystem.instance;
|
|
physics.enable = true;
|
|
physics.gravity = new Vec3(0, -10, 0);
|
|
physics.allowSleep = false;
|
|
}
|
|
|
|
private initGameState() {
|
|
this.myBallNum = 10;
|
|
this.opBallNum = 10;
|
|
this.deadBallNum = 0;
|
|
this.rndBallNum = 0;
|
|
this.PlaneNode.active = false;
|
|
}
|
|
|
|
private playStartAnimation() {
|
|
if (this.startAnim) {
|
|
this.startAnim.play("camera1");
|
|
this.startAnim.once(Animation.EventType.FINISHED, this.onStartAnimFinished, this);
|
|
}
|
|
}
|
|
|
|
private onStartAnimFinished() {
|
|
this.PlaneNode.active = true;
|
|
}
|
|
|
|
AddBall() {
|
|
console.log("添加球");
|
|
if (this.playerCtrl) {
|
|
this.playerCtrl.AddBall();
|
|
}
|
|
}
|
|
public setGameOver(isWin: boolean) {
|
|
|
|
|
|
if (!isWin) {
|
|
resLoader.load(ModuleDef.Arean, 'common/prefabs/settlement', (err: Error | null, prefab: Prefab) => {
|
|
if (!err && prefab) {
|
|
const n = instantiate(prefab);
|
|
this.guiNode.addChild(n);
|
|
n.getComponent(Animation).play("showLose");
|
|
|
|
}
|
|
});
|
|
}
|
|
else {
|
|
resLoader.load(ModuleDef.Arean, 'common/prefabs/settlement', (err: Error | null, prefab: Prefab) => {
|
|
if (!err && prefab) {
|
|
const n = instantiate(prefab);
|
|
this.guiNode.addChild(n);
|
|
n.getComponent(Animation).play("showWin");
|
|
|
|
}
|
|
});
|
|
}
|
|
|
|
this.scheduleOnce(() => {
|
|
resLoader.load(ModuleDef.Arean, 'common/prefabs/settlement', (err: Error | null, prefab: Prefab) => {
|
|
if (!err && prefab) {
|
|
const n = instantiate(prefab);
|
|
this.guiNode.addChild(n);
|
|
n.getComponent(Animation).play("showSettlement");
|
|
// Lives从10滚动到8
|
|
const livesLabel = n.getChildByPath("settlementNode/Node/lives").getComponent(Label);
|
|
let lives = { value: 4 };
|
|
tween(lives)
|
|
.to(1, { value: 2 }, {
|
|
easing: 'linear',
|
|
onUpdate: () => {
|
|
livesLabel.string = Math.floor(lives.value).toString();
|
|
}
|
|
})
|
|
.start();
|
|
|
|
// Money从400w滚动到480w
|
|
const moneyLabel = n.getChildByPath("settlementNode/Node/money").getComponent(Label);
|
|
let money = { value: 452 };
|
|
tween(money)
|
|
.to(1, { value: 454 }, {
|
|
easing: 'linear',
|
|
onUpdate: () => {
|
|
moneyLabel.string = Math.floor(money.value) + "w";
|
|
}
|
|
})
|
|
.start();
|
|
|
|
n.getChildByPath("settlementNode/btnOK/label").getComponent(Label).string = "Coming Soon";
|
|
n.getChildByPath("settlementNode/btnOK").on(Node.EventType.TOUCH_START, () => {
|
|
|
|
if (isWin) {
|
|
director.loadScene("lobby_arean");
|
|
}
|
|
else {
|
|
director.loadScene("lobby_arean");
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}, 3);
|
|
}
|
|
|
|
public RestartGame() {
|
|
this.myBallNum = 10;
|
|
this.opBallNum = 10;
|
|
this.deadBallNum = 0;
|
|
this.rndBallNum = 0;
|
|
this.refreshBallNum();
|
|
|
|
if (this.playerCtrl) {
|
|
this.playerCtrl.resetGame();
|
|
}
|
|
if (this.ballCtrl) {
|
|
this.ballCtrl.resetGame();
|
|
}
|
|
}
|
|
|
|
// update(deltaTime: number) {
|
|
// if (this.playerCtrl) {
|
|
// if (this.playerCtrl.IsMoveEnd()) {
|
|
// if (this.ballCtrl && this.ballCtrl.isMoveEnd()) {
|
|
// console.log("球移动结束");
|
|
// if (this.playerCtrl.AddBallEnd()) {
|
|
// this.setGameOver(this.ballCtrl.isbegin);
|
|
// this.RestGame();
|
|
// } else {
|
|
// if (this.ballCtrl.isbegin) {
|
|
// this.setGameOver(this.ballCtrl.isbegin);
|
|
// this.RestGame();
|
|
// }
|
|
// }
|
|
// }
|
|
// }
|
|
// }
|
|
// }
|
|
|
|
public refreshBallNum() {
|
|
scrollLabelToNumber(this.myBallNumLabel!, this.myBallNum);
|
|
scrollLabelToNumber(this.opBallNumLabel!, this.opBallNum);
|
|
scrollLabelToNumber(this.deadBallNumLabel!, this.deadBallNum);
|
|
scrollLabelToNumber(this.rndBallNumLabel!, this.rndBallNum);
|
|
}
|
|
|
|
changeGameScene() {
|
|
var bundle = assetManager.getBundle('level1');
|
|
if (bundle) {
|
|
director.loadScene("scene/level1Scene");
|
|
} else {
|
|
assetManager.loadBundle("level1", () => {
|
|
director.loadScene("scene/level1Scene");
|
|
})
|
|
}
|
|
}
|
|
|
|
onClickBtnQuit() {
|
|
tgxUIAlert.show(`是否确认退出 ? `, true).onClick(async b => {
|
|
if (b) {
|
|
AreanNetMgr.inst.sendMsg_exit();
|
|
}
|
|
});
|
|
}
|
|
|
|
}
|
|
|
|
function scrollLabelToNumber(label: Label, targetNumber: number, duration: number = 0.3) {
|
|
const startNumber = parseInt(label.string); // 获取当前 Label 上的数字
|
|
const startTime = Date.now(); // 记录开始时间
|
|
|
|
const updateNumber = () => {
|
|
// 计算已经过去的时间比例
|
|
const elapsedTime = (Date.now() - startTime) / (duration * 1000);
|
|
const progress = Math.min(elapsedTime, 1); // 限制在 [0, 1] 范围内
|
|
|
|
// 计算当前数字
|
|
const currentNumber = Math.round(startNumber + (targetNumber - startNumber) * progress);
|
|
|
|
// 更新显示的数字
|
|
label.string = currentNumber.toString();
|
|
|
|
// 如果动画未结束,继续更新数字
|
|
if (progress < 1) {
|
|
requestAnimationFrame(updateNumber);
|
|
}
|
|
};
|
|
|
|
// 开始更新数字
|
|
updateNumber();
|
|
}
|
|
|
|
|
|
|