提交版本

This commit is contained in:
MushrooMagician 2025-03-23 02:31:54 +08:00
parent 88190b579b
commit 174d284e22
13 changed files with 2043 additions and 819 deletions

View File

@ -0,0 +1,403 @@
[
{
"__type__": "cc.Prefab",
"_name": "timerNode",
"_objFlags": 0,
"__editorExtras__": {},
"_native": "",
"data": {
"__id__": 1
},
"optimizationPolicy": 0,
"persistent": false
},
{
"__type__": "cc.Node",
"_name": "timerNode",
"_objFlags": 0,
"__editorExtras__": {},
"_parent": null,
"_children": [
{
"__id__": 2
},
{
"__id__": 8
}
],
"_active": true,
"_components": [
{
"__id__": 14
}
],
"_prefab": {
"__id__": 16
},
"_lpos": {
"__type__": "cc.Vec3",
"x": -600,
"y": 154,
"z": 0
},
"_lrot": {
"__type__": "cc.Quat",
"x": 0,
"y": 0,
"z": 0,
"w": 1
},
"_lscale": {
"__type__": "cc.Vec3",
"x": 1,
"y": 1,
"z": 1
},
"_mobility": 0,
"_layer": 1073741824,
"_euler": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
},
"_id": ""
},
{
"__type__": "cc.Node",
"_name": "combtn1",
"_objFlags": 0,
"__editorExtras__": {},
"_parent": {
"__id__": 1
},
"_children": [],
"_active": true,
"_components": [
{
"__id__": 3
},
{
"__id__": 5
}
],
"_prefab": {
"__id__": 7
},
"_lpos": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
},
"_lrot": {
"__type__": "cc.Quat",
"x": 0,
"y": 0,
"z": 0,
"w": 1
},
"_lscale": {
"__type__": "cc.Vec3",
"x": 1,
"y": 1,
"z": 1
},
"_mobility": 0,
"_layer": 1073741824,
"_euler": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
},
"_id": ""
},
{
"__type__": "cc.UITransform",
"_name": "",
"_objFlags": 0,
"__editorExtras__": {},
"node": {
"__id__": 2
},
"_enabled": true,
"__prefab": {
"__id__": 4
},
"_contentSize": {
"__type__": "cc.Size",
"width": 184.59799999999998,
"height": 66.78595302783627
},
"_anchorPoint": {
"__type__": "cc.Vec2",
"x": 0.5,
"y": 0.5
},
"_id": ""
},
{
"__type__": "cc.CompPrefabInfo",
"fileId": "7fwmu/a1VFRbVNDt+FBl5b"
},
{
"__type__": "cc.Sprite",
"_name": "",
"_objFlags": 0,
"__editorExtras__": {},
"node": {
"__id__": 2
},
"_enabled": true,
"__prefab": {
"__id__": 6
},
"_customMaterial": null,
"_srcBlendFactor": 2,
"_dstBlendFactor": 4,
"_color": {
"__type__": "cc.Color",
"r": 255,
"g": 255,
"b": 255,
"a": 255
},
"_spriteFrame": {
"__uuid__": "21c4e332-eafb-448b-a8fb-7f078bfa9c22@f9941",
"__expectedType__": "cc.SpriteFrame"
},
"_type": 0,
"_fillType": 0,
"_sizeMode": 0,
"_fillCenter": {
"__type__": "cc.Vec2",
"x": 0,
"y": 0
},
"_fillStart": 0,
"_fillRange": 0,
"_isTrimmedMode": true,
"_useGrayscale": false,
"_atlas": null,
"_id": ""
},
{
"__type__": "cc.CompPrefabInfo",
"fileId": "ab7N5x5xFOAYunjD4A1qsK"
},
{
"__type__": "cc.PrefabInfo",
"root": {
"__id__": 1
},
"asset": {
"__id__": 0
},
"fileId": "11ITMjcD1BjI9dKjatbFMA",
"instance": null,
"targetOverrides": null,
"nestedPrefabInstanceRoots": null
},
{
"__type__": "cc.Node",
"_name": "timer",
"_objFlags": 0,
"__editorExtras__": {},
"_parent": {
"__id__": 1
},
"_children": [],
"_active": true,
"_components": [
{
"__id__": 9
},
{
"__id__": 11
}
],
"_prefab": {
"__id__": 13
},
"_lpos": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
},
"_lrot": {
"__type__": "cc.Quat",
"x": 0,
"y": 0,
"z": 0,
"w": 1
},
"_lscale": {
"__type__": "cc.Vec3",
"x": 1,
"y": 1,
"z": 1
},
"_mobility": 0,
"_layer": 1073741824,
"_euler": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
},
"_id": ""
},
{
"__type__": "cc.UITransform",
"_name": "",
"_objFlags": 0,
"__editorExtras__": {},
"node": {
"__id__": 8
},
"_enabled": true,
"__prefab": {
"__id__": 10
},
"_contentSize": {
"__type__": "cc.Size",
"width": 107.5,
"height": 50.4
},
"_anchorPoint": {
"__type__": "cc.Vec2",
"x": 0.5,
"y": 0.5
},
"_id": ""
},
{
"__type__": "cc.CompPrefabInfo",
"fileId": "f0UMy7wylJZZdkvBPwoWrg"
},
{
"__type__": "cc.Label",
"_name": "",
"_objFlags": 0,
"__editorExtras__": {},
"node": {
"__id__": 8
},
"_enabled": true,
"__prefab": {
"__id__": 12
},
"_customMaterial": null,
"_srcBlendFactor": 2,
"_dstBlendFactor": 4,
"_color": {
"__type__": "cc.Color",
"r": 39,
"g": 39,
"b": 39,
"a": 255
},
"_string": "03:00",
"_horizontalAlign": 1,
"_verticalAlign": 1,
"_actualFontSize": 40,
"_fontSize": 40,
"_fontFamily": "Arial",
"_lineHeight": 40,
"_overflow": 0,
"_enableWrapText": true,
"_font": {
"__uuid__": "f40babd5-d5a5-4df0-ae5c-6d5c04f6f25b",
"__expectedType__": "cc.TTFFont"
},
"_isSystemFontUsed": false,
"_spacingX": 0,
"_isItalic": false,
"_isBold": false,
"_isUnderline": false,
"_underlineHeight": 2,
"_cacheMode": 0,
"_enableOutline": false,
"_outlineColor": {
"__type__": "cc.Color",
"r": 0,
"g": 0,
"b": 0,
"a": 255
},
"_outlineWidth": 2,
"_enableShadow": false,
"_shadowColor": {
"__type__": "cc.Color",
"r": 0,
"g": 0,
"b": 0,
"a": 255
},
"_shadowOffset": {
"__type__": "cc.Vec2",
"x": 2,
"y": -2
},
"_shadowBlur": 2,
"_id": ""
},
{
"__type__": "cc.CompPrefabInfo",
"fileId": "15R0OIE3tBfLBVlO7Mkd8W"
},
{
"__type__": "cc.PrefabInfo",
"root": {
"__id__": 1
},
"asset": {
"__id__": 0
},
"fileId": "f5SpsjSWJEbqADlm7ULGEf",
"instance": null,
"targetOverrides": null,
"nestedPrefabInstanceRoots": null
},
{
"__type__": "cc.UITransform",
"_name": "",
"_objFlags": 0,
"__editorExtras__": {},
"node": {
"__id__": 1
},
"_enabled": true,
"__prefab": {
"__id__": 15
},
"_contentSize": {
"__type__": "cc.Size",
"width": 196.315,
"height": 90.053
},
"_anchorPoint": {
"__type__": "cc.Vec2",
"x": 0.5,
"y": 0.5
},
"_id": ""
},
{
"__type__": "cc.CompPrefabInfo",
"fileId": "90cie1v9NBpYrDMuqJ6qtA"
},
{
"__type__": "cc.PrefabInfo",
"root": {
"__id__": 1
},
"asset": {
"__id__": 0
},
"fileId": "36/YoP/aJHo5U6akto3lXB",
"targetOverrides": null
}
]

View File

@ -0,0 +1,13 @@
{
"ver": "1.1.50",
"importer": "prefab",
"imported": true,
"uuid": "e0258a83-5ef1-470b-abcf-9e10180d864e",
"files": [
".json"
],
"subMetas": {},
"userData": {
"syncNodeName": "timerNode"
}
}

View File

@ -33,6 +33,8 @@ export class WoodenManGame extends Component {
@property(Node)
guiNode: Node = null; // ui节点
@property(Label)
timerLabel: Label = null!; // 倒计时文本显示
private turnAnimationDuration: number = 0.3; // 转身动画持续时间
private readonly TURN_BACK_DELAY = 2; // 转回正面的延迟时间
@ -45,8 +47,10 @@ export class WoodenManGame extends Component {
readonly maxRoleId: number = 5;
readonly REQUIRED_QUALIFIED = 10; // 需要晋级的人数
qualifiedCount: number = 0; // 已晋级人数
gameTimer: number = 180; // 游戏时间3分钟)
gameTimer: number = 120; // 游戏时间2分钟)
isGameOver: boolean = false; // 游戏是否结束
private isCountdownStarted: boolean = false; // 是否已开始倒计时
private startDelay: number = 0; // 延迟多久开始倒计时
@property(Node)
warningLightsNode: Node = null; // 三个警示灯的父节点
@ -78,7 +82,6 @@ export class WoodenManGame extends Component {
async start() {
await this.initPlayers();
this.schedule(this.updateGameTimer, 1);
this.updateWinCount();
tgxAudioMgr.inst.play(EMusicDefine.MUSIC_BGM_BATTLE, 1, ModuleDef.BASIC);
// 修改按钮事件监听
@ -89,12 +92,22 @@ export class WoodenManGame extends Component {
this.stopButton.on(Node.EventType.TOUCH_CANCEL, this.onStopButtonRelease, this);
}
// 初始化计时器显示
if (this.timerLabel) {
this.updateTimerDisplay();
}
// 延迟3秒后开始第一次转身
this.scheduleOnce(() => {
this.isGameStarted = true; // 标记游戏开始
// 显示停止按钮
this.guiNode.getComponent(Animation).play("showUI");
this.executeTurnBackPhase(true);
// 开始倒计时
this.scheduleOnce(() => {
this.startCountdown();
}, this.startDelay);
}, 12); // 延长等待时间,等摄像机序列播放完
}
@ -379,6 +392,7 @@ export class WoodenManGame extends Component {
if (this.isGameOver) return;
this.isGameOver = true;
this.isCountdownStarted = false;
this.unscheduleAllCallbacks(); // 停止所有定时器
@ -536,9 +550,11 @@ export class WoodenManGame extends Component {
// 更新游戏时间
private updateGameTimer() {
if (this.isGameOver) return;
if (this.isGameOver || !this.isCountdownStarted) return;
this.gameTimer--;
this.updateTimerDisplay();
if (this.gameTimer <= 0) {
this.endGame('时间到!游戏结束');
}
@ -585,4 +601,23 @@ export class WoodenManGame extends Component {
// 开始点亮第一个灯
lightInterval();
}
// 开始倒计时
private startCountdown() {
this.isCountdownStarted = true;
this.unschedule(this.updateGameTimer); // 确保不会重复计时
this.schedule(this.updateGameTimer, 1);
this.updateTimerDisplay();
}
// 更新计时器显示
private updateTimerDisplay() {
if (!this.timerLabel) return;
const minutes = Math.floor(this.gameTimer / 60);
const seconds = this.gameTimer % 60;
// 格式化为 "xx:xx"
this.timerLabel.string = `${minutes < 10 ? '0' + minutes : minutes}:${seconds < 10 ? '0' + seconds : seconds}`;
}
}

View File

@ -28,13 +28,16 @@
},
{
"__id__": 39
},
{
"__id__": 51
}
],
"_exoticAnimation": null,
"_events": [],
"_embeddedPlayers": [],
"_additiveSettings": {
"__id__": 51
"__id__": 62
},
"_auxiliaryCurveEntries": []
},
@ -811,6 +814,192 @@
"preExtrapolation": 1,
"postExtrapolation": 1
},
{
"__type__": "cc.animation.VectorTrack",
"_binding": {
"__type__": "cc.animation.TrackBinding",
"path": {
"__id__": 52
},
"proxy": null
},
"_channels": [
{
"__id__": 54
},
{
"__id__": 56
},
{
"__id__": 58
},
{
"__id__": 60
}
],
"_nComponents": 3
},
{
"__type__": "cc.animation.TrackPath",
"_paths": [
{
"__id__": 53
},
"position"
]
},
{
"__type__": "cc.animation.HierarchyPath",
"path": "topUI/timerNode"
},
{
"__type__": "cc.animation.Channel",
"_curve": {
"__id__": 55
}
},
{
"__type__": "cc.RealCurve",
"_times": [
0,
0.08333333333333333
],
"_values": [
{
"__type__": "cc.RealKeyframeValue",
"interpolationMode": 0,
"tangentWeightMode": 0,
"value": -600,
"rightTangent": 0,
"rightTangentWeight": 1,
"leftTangent": 0,
"leftTangentWeight": 1,
"easingMethod": 0,
"__editorExtras__": {
"tangentMode": 0
}
},
{
"__type__": "cc.RealKeyframeValue",
"interpolationMode": 0,
"tangentWeightMode": 0,
"value": -600,
"rightTangent": 0,
"rightTangentWeight": 1,
"leftTangent": 0,
"leftTangentWeight": 1,
"easingMethod": 0,
"__editorExtras__": {
"tangentMode": 0
}
}
],
"preExtrapolation": 1,
"postExtrapolation": 1
},
{
"__type__": "cc.animation.Channel",
"_curve": {
"__id__": 57
}
},
{
"__type__": "cc.RealCurve",
"_times": [
0,
0.08333333333333333
],
"_values": [
{
"__type__": "cc.RealKeyframeValue",
"interpolationMode": 0,
"tangentWeightMode": 0,
"value": 801.88,
"rightTangent": 0,
"rightTangentWeight": 1,
"leftTangent": 0,
"leftTangentWeight": 1,
"easingMethod": 0,
"__editorExtras__": {
"tangentMode": 0
}
},
{
"__type__": "cc.RealKeyframeValue",
"interpolationMode": 0,
"tangentWeightMode": 0,
"value": 656.97,
"rightTangent": 0,
"rightTangentWeight": 1,
"leftTangent": 0,
"leftTangentWeight": 1,
"easingMethod": 0,
"__editorExtras__": {
"tangentMode": 0
}
}
],
"preExtrapolation": 1,
"postExtrapolation": 1
},
{
"__type__": "cc.animation.Channel",
"_curve": {
"__id__": 59
}
},
{
"__type__": "cc.RealCurve",
"_times": [
0,
0.08333333333333333
],
"_values": [
{
"__type__": "cc.RealKeyframeValue",
"interpolationMode": 0,
"tangentWeightMode": 0,
"value": 0,
"rightTangent": 0,
"rightTangentWeight": 1,
"leftTangent": 0,
"leftTangentWeight": 1,
"easingMethod": 0,
"__editorExtras__": {
"tangentMode": 0
}
},
{
"__type__": "cc.RealKeyframeValue",
"interpolationMode": 0,
"tangentWeightMode": 0,
"value": 0,
"rightTangent": 0,
"rightTangentWeight": 1,
"leftTangent": 0,
"leftTangentWeight": 1,
"easingMethod": 0,
"__editorExtras__": {
"tangentMode": 0
}
}
],
"preExtrapolation": 1,
"postExtrapolation": 1
},
{
"__type__": "cc.animation.Channel",
"_curve": {
"__id__": 61
}
},
{
"__type__": "cc.RealCurve",
"_times": [],
"_values": [],
"preExtrapolation": 1,
"postExtrapolation": 1
},
{
"__type__": "cc.AnimationClipAdditiveSettings",
"enabled": false,

View File

@ -1,20 +1,114 @@
import { _decorator, Component, Node, Animation } from 'cc';
import { _decorator, Component, Node, Animation, Label, director } from 'cc';
const { ccclass, property } = _decorator;
enum GameState {
Playing,
Paused,
GameOver
}
@ccclass('GameManager')
export class GameManager extends Component {
@property({type: Animation})
cameraAnim: Animation = null!;
@property(Label)
timerLabel: Label = null!; // 倒计时文本显示
@property(Node)
guiNode: Node = null!; // UI节点
private gameState: GameState = GameState.Playing;
private countdownDuration: number = 120; // 3分钟 = 180秒
private countdownRemaining: number = 120;
private isCountdownStarted: boolean = false;
private startDelay: number = 6; // 开场动画结束后延迟1.5秒开始
private isGameOver: boolean = false;
start() {
// 游戏开始时播放相机动画
if (this.cameraAnim) {
this.cameraAnim.play('camera1');
this.initGame();
}
private initGame() {
// 初始化游戏状态
this.gameState = GameState.Playing;
this.countdownRemaining = this.countdownDuration;
this.isCountdownStarted = false;
this.isGameOver = false;
// 初始化计时器显示
this.updateTimerDisplay();
this.scheduleOnce(() => {
this.startCountdown();
}, this.startDelay);
}
private startCountdown() {
this.isCountdownStarted = true;
this.countdownRemaining = this.countdownDuration;
this.updateTimerDisplay();
// 每秒更新一次
this.schedule(this.updateCountdown, 1);
}
private updateCountdown() {
if (!this.isCountdownStarted || this.gameState !== GameState.Playing) return;
this.countdownRemaining--;
this.updateTimerDisplay();
if (this.countdownRemaining <= 0) {
// 时间到,结束游戏
this.unschedule(this.updateCountdown);
this.setGameOver(false); // 时间到算失败
}
}
update(deltaTime: number) {
private updateTimerDisplay() {
if (!this.timerLabel) return;
const minutes = Math.floor(this.countdownRemaining / 60);
const seconds = this.countdownRemaining % 60;
// 格式化为 "xx:xx"
this.timerLabel.string = `${minutes < 10 ? '0' + minutes : minutes}:${seconds < 10 ? '0' + seconds : seconds}`;
}
public setGameOver(isWin: boolean) {
if (this.isGameOver) return;
this.isGameOver = true;
this.isCountdownStarted = false;
this.unschedule(this.updateCountdown);
this.gameState = GameState.GameOver;
// 这里可以添加游戏结算逻辑
console.log(`游戏结束,${isWin ? '胜利' : '失败'},剩余时间: ${this.countdownRemaining}`);
// 这里可以添加显示结算界面的代码
}
// 可以添加其他游戏相关方法
public pauseGame() {
if (this.gameState === GameState.Playing) {
this.gameState = GameState.Paused;
this.unschedule(this.updateCountdown);
}
}
public resumeGame() {
if (this.gameState === GameState.Paused) {
this.gameState = GameState.Playing;
this.schedule(this.updateCountdown, 1);
}
}
onDestroy() {
// 清理定时器
this.unscheduleAllCallbacks();
}
}

View File

@ -0,0 +1,9 @@
{
"ver": "1.2.0",
"importer": "directory",
"imported": true,
"uuid": "e15fc82a-cf6b-411a-b13a-f48806e54313",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@ -78,8 +78,16 @@ export class BallGame extends Component {
@property(Animation)
startAnim: Animation = null!;
@property(Label)
timerLabel: Label = null!; // 挂载到 timerNode 下的 Label 组件
private gameState: GameState = GameState.Playing;
private countdownDuration: number = 180; // 3分钟 = 180秒
private countdownRemaining: number = 180;
private isCountdownStarted: boolean = false;
private startDelay: number = 5; // 开场动画结束后延迟1.5秒开始
start() {
this.initPhysics();
this.initGameState();
@ -110,6 +118,43 @@ export class BallGame extends Component {
private onStartAnimFinished() {
this.PlaneNode.active = true;
// 延迟指定秒数后开始倒计时
this.scheduleOnce(() => {
this.startCountdown();
}, this.startDelay);
}
private startCountdown() {
this.isCountdownStarted = true;
this.countdownRemaining = this.countdownDuration;
this.updateTimerDisplay();
// 每秒更新一次
this.schedule(this.updateCountdown, 1);
}
private updateCountdown() {
if (!this.isCountdownStarted || this.gameState !== GameState.Playing) return;
this.countdownRemaining--;
this.updateTimerDisplay();
if (this.countdownRemaining <= 0) {
// 时间到,结束游戏
this.unschedule(this.updateCountdown);
this.setGameOver(false); // 时间到算失败
}
}
private updateTimerDisplay() {
if (!this.timerLabel) return;
const minutes = Math.floor(this.countdownRemaining / 60);
const seconds = this.countdownRemaining % 60;
// 格式化为 "xx:xx"
this.timerLabel.string = `${minutes < 10 ? '0' + minutes : minutes}:${seconds < 10 ? '0' + seconds : seconds}`;
}
AddBall() {
@ -119,7 +164,8 @@ export class BallGame extends Component {
}
}
public setGameOver(isWin: boolean) {
this.isCountdownStarted = false; // 停止倒计时
this.unschedule(this.updateCountdown);
if (!isWin) {
resLoader.load(ModuleDef.Arean, 'common/prefabs/settlement', (err: Error | null, prefab: Prefab) => {
@ -214,6 +260,10 @@ export class BallGame extends Component {
if (this.ballCtrl) {
this.ballCtrl.resetGame();
}
this.countdownRemaining = this.countdownDuration;
this.isCountdownStarted = false;
this.updateTimerDisplay();
}
// update(deltaTime: number) {

View File

@ -15,7 +15,8 @@ export const GameServerListFileURL = ""; //'http://192.168.0.104:7456/web-mobile
*/
export const GameServerURLs = [
// 'wss://chengchennet.cn:15005',//wss远程链接
"ws://150.158.100.241:8092", //ws远程链接
//"ws://150.158.100.241:8092", //ws远程链接
"ws://52.221.198.126:8023", //亚马逊 ws远程链接
// "ws://127.0.0.1:8092", //ws本地连接
// 'wss://squidgameserver.gryphon.fun'
];

Binary file not shown.

Before

Width:  |  Height:  |  Size: 877 KiB

After

Width:  |  Height:  |  Size: 134 KiB

View File

@ -46,10 +46,10 @@
"offsetY": 0,
"trimX": 0,
"trimY": 0,
"width": 2160,
"height": 1080,
"rawWidth": 2160,
"rawHeight": 1080,
"width": 1353,
"height": 675,
"rawWidth": 1353,
"rawHeight": 675,
"borderTop": 0,
"borderBottom": 0,
"borderLeft": 0,
@ -61,17 +61,17 @@
"meshType": 0,
"vertices": {
"rawPosition": [
-1080,
-540,
-676.5,
-337.5,
0,
1080,
-540,
676.5,
-337.5,
0,
-1080,
540,
-676.5,
337.5,
0,
1080,
540,
676.5,
337.5,
0
],
"indexes": [
@ -84,12 +84,12 @@
],
"uv": [
0,
1080,
2160,
1080,
675,
1353,
675,
0,
0,
2160,
1353,
0
],
"nuv": [
@ -103,13 +103,13 @@
1
],
"minPos": [
-1080,
-540,
-676.5,
-337.5,
0
],
"maxPos": [
1080,
540,
676.5,
337.5,
0
]
},