feat: update 0.1.1

main
tiendat3699 2024-03-12 15:50:54 +07:00
parent d0f3716a8c
commit 4d858855c9
20 changed files with 1705 additions and 1142 deletions

View File

@ -86,7 +86,7 @@
"__type__": "cc.RealCurve",
"_times": [
0,
0.16666666666666666
0.1666666716337204
],
"_values": [
{
@ -105,7 +105,7 @@
"__type__": "cc.RealKeyframeValue",
"interpolationMode": 0,
"tangentWeightMode": 0,
"value": -30,
"value": -25,
"rightTangent": 0,
"rightTangentWeight": 1,
"leftTangent": 0,
@ -204,10 +204,10 @@
"__type__": "cc.RealCurve",
"_times": [
0,
0.08333333333333333,
0.18333333333333332,
0.2833333333333333,
0.3333333333333333
0.0833333358168602,
0.18333333730697632,
0.28333333134651184,
0.3333333432674408
],
"_values": [
{

View File

@ -240,7 +240,7 @@
{
"__type__": "cc.CurveRange",
"mode": 0,
"constant": 0.5,
"constant": 0.4,
"multiplier": 1
},
{
@ -295,13 +295,13 @@
{
"__type__": "cc.CurveRange",
"mode": 0,
"constant": -20,
"constant": -10,
"multiplier": 1
},
{
"__type__": "cc.CurveRange",
"mode": 0,
"constant": 50,
"constant": 40,
"multiplier": 1
},
{

View File

@ -0,0 +1,372 @@
[
{
"__type__": "cc.Prefab",
"_name": "Clock",
"_objFlags": 0,
"_native": "",
"data": {
"__id__": 1
},
"optimizationPolicy": 0,
"persistent": false
},
{
"__type__": "cc.Node",
"_name": "Clock",
"_objFlags": 0,
"__editorExtras__": {},
"_parent": null,
"_children": [
{
"__id__": 2
}
],
"_active": true,
"_components": [
{
"__id__": 8
},
{
"__id__": 10
},
{
"__id__": 12
},
{
"__id__": 14
},
{
"__id__": 16
}
],
"_prefab": {
"__id__": 18
},
"_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": 33554432,
"_euler": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
},
"_id": ""
},
{
"__type__": "cc.Node",
"_name": "Sprite",
"_objFlags": 0,
"_parent": {
"__id__": 1
},
"_children": [],
"_active": true,
"_components": [
{
"__id__": 3
},
{
"__id__": 5
}
],
"_prefab": {
"__id__": 7
},
"_lpos": {
"__type__": "cc.Vec3",
"x": 0,
"y": -25,
"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": 33554432,
"_euler": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
},
"_id": ""
},
{
"__type__": "cc.UITransform",
"_name": "",
"_objFlags": 0,
"node": {
"__id__": 2
},
"_enabled": true,
"__prefab": {
"__id__": 4
},
"_contentSize": {
"__type__": "cc.Size",
"width": 50,
"height": 50
},
"_anchorPoint": {
"__type__": "cc.Vec2",
"x": 0.5,
"y": 0
},
"_id": ""
},
{
"__type__": "cc.CompPrefabInfo",
"fileId": "7eQbUjrCxCdqX0lbHJJf5m"
},
{
"__type__": "cc.Sprite",
"_name": "",
"_objFlags": 0,
"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__": "cdb1ff8a-065e-4d3f-8b28-3bede38d9b1f@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": "8f4n9BtRRP+4F8ppzXIOAb"
},
{
"__type__": "cc.PrefabInfo",
"root": {
"__id__": 1
},
"asset": {
"__id__": 0
},
"fileId": "58e2t45HZDcaGTymn9uf1N",
"instance": null,
"targetOverrides": null,
"nestedPrefabInstanceRoots": null
},
{
"__type__": "cc.UITransform",
"_name": "",
"_objFlags": 0,
"node": {
"__id__": 1
},
"_enabled": true,
"__prefab": {
"__id__": 9
},
"_contentSize": {
"__type__": "cc.Size",
"width": 50,
"height": 50
},
"_anchorPoint": {
"__type__": "cc.Vec2",
"x": 0.5,
"y": 0.5
},
"_id": ""
},
{
"__type__": "cc.CompPrefabInfo",
"fileId": "dd1k5yz/9Jw7Y3h/ln7e+D"
},
{
"__type__": "cc.BoxCollider2D",
"_name": "",
"_objFlags": 0,
"node": {
"__id__": 1
},
"_enabled": true,
"__prefab": {
"__id__": 11
},
"tag": 0,
"_group": 2,
"_density": 1,
"_sensor": true,
"_friction": 0.2,
"_restitution": 0,
"_offset": {
"__type__": "cc.Vec2",
"x": 0,
"y": 0
},
"_size": {
"__type__": "cc.Size",
"width": 100,
"height": 100
},
"_id": ""
},
{
"__type__": "cc.CompPrefabInfo",
"fileId": "e3xI5cN0VBUb2QzjmBNBDQ"
},
{
"__type__": "cc.RigidBody2D",
"_name": "",
"_objFlags": 0,
"node": {
"__id__": 1
},
"_enabled": true,
"__prefab": {
"__id__": 13
},
"enabledContactListener": true,
"bullet": false,
"awakeOnLoad": true,
"_group": 2,
"_type": 1,
"_allowSleep": true,
"_gravityScale": 1,
"_linearDamping": 0,
"_angularDamping": 0,
"_linearVelocity": {
"__type__": "cc.Vec2",
"x": 0,
"y": 0
},
"_angularVelocity": 0,
"_fixedRotation": false,
"_id": ""
},
{
"__type__": "cc.CompPrefabInfo",
"fileId": "bbOXJ9GJVHppWgt0OjwEBK"
},
{
"__type__": "3bd17tsjpdMZqOLOE4CWMkE",
"_name": "",
"_objFlags": 0,
"node": {
"__id__": 1
},
"_enabled": true,
"__prefab": {
"__id__": 15
},
"_collider": {
"__id__": 10
},
"_sprite": {
"__id__": 5
},
"_spawnAnimation": {
"__id__": 16
},
"_hitSound": {
"__uuid__": "1f602e14-2769-4903-b4d2-b0977eeaf36b",
"__expectedType__": "cc.AudioClip"
},
"_score": 0,
"_bonusTime": 5,
"_id": ""
},
{
"__type__": "cc.CompPrefabInfo",
"fileId": "f3W6S5U0BKM6/Fx3RiEC8W"
},
{
"__type__": "cc.Animation",
"_name": "",
"_objFlags": 0,
"node": {
"__id__": 1
},
"_enabled": true,
"__prefab": {
"__id__": 17
},
"playOnLoad": false,
"_clips": [
{
"__uuid__": "cfd9afd6-9345-446c-bf56-b7ac3dbf2c1e",
"__expectedType__": "cc.AnimationClip"
}
],
"_defaultClip": {
"__uuid__": "cfd9afd6-9345-446c-bf56-b7ac3dbf2c1e",
"__expectedType__": "cc.AnimationClip"
},
"_id": ""
},
{
"__type__": "cc.CompPrefabInfo",
"fileId": "9cExf3IzxEa53jorYVyMdR"
},
{
"__type__": "cc.PrefabInfo",
"root": {
"__id__": 1
},
"asset": {
"__id__": 0
},
"fileId": "31K2tUn39G47RitJdKcKW+",
"instance": null,
"targetOverrides": null
}
]

View File

@ -0,0 +1,13 @@
{
"ver": "1.1.43",
"importer": "prefab",
"imported": true,
"uuid": "c32eb90e-312b-4fb1-bbdb-dab9e9b14691",
"files": [
".json"
],
"subMetas": {},
"userData": {
"syncNodeName": "Clock"
}
}

View File

@ -1,7 +1,7 @@
[
{
"__type__": "cc.Prefab",
"_name": "box",
"_name": "Box",
"_objFlags": 0,
"_native": "",
"data": {
@ -12,7 +12,7 @@
},
{
"__type__": "cc.Node",
"_name": "box",
"_name": "Box",
"_objFlags": 0,
"__editorExtras__": {},
"_parent": null,
@ -317,11 +317,12 @@
"_spawnAnimation": {
"__id__": 16
},
"_score": 10,
"_hitSound": {
"__uuid__": "1f602e14-2769-4903-b4d2-b0977eeaf36b",
"__expectedType__": "cc.AudioClip"
},
"_score": 5,
"_bonusTime": 0,
"_id": ""
},
{

View File

@ -8,6 +8,6 @@
],
"subMetas": {},
"userData": {
"syncNodeName": "box"
"syncNodeName": "Box"
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,9 @@
enum TimeConfig {
DelayPLay = 1,
DelayMultiBall = 2,
DelayGoal = 2,
DelayCannonFire = 1,
DelayCannonDone = 0.5,
}
export default TimeConfig;

View File

@ -0,0 +1,9 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "f1afd1fe-5a78-46ce-ac86-2fe0d970f737",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@ -2,7 +2,6 @@ import {
_decorator,
Animation,
AudioClip,
CCFloat,
CCInteger,
Collider2D,
Color,
@ -20,7 +19,7 @@ import Utilities from '../Utilities';
import { EventManger } from '../Manager/EventManger';
import GameEvent from '../Events/GameEvent';
import { SoundManager } from '../Manager/SoundManager';
const { ccclass, property, float } = _decorator;
const { ccclass, property } = _decorator;
@ccclass('ScoreObject')
export class ScoreObject extends Component implements IPoolable {
@ -34,6 +33,8 @@ export class ScoreObject extends Component implements IPoolable {
private _hitSound: AudioClip;
@property({ type: CCInteger, visible: true })
private _score: number;
@property({ type: CCInteger, visible: true })
private _bonusTime: number;
private _flySpeed: number;
private _flyDirection: Vec3;
@ -82,14 +83,12 @@ export class ScoreObject extends Component implements IPoolable {
this._targetColor.a = 0;
this._flySpeed = otherCollider.getComponent(RigidBody2D).linearVelocity.length();
this.node.setSiblingIndex(this.node.parent.children.length - 1);
if (this._score > 0) {
GameManager.instance.destroyEnvironmentObject(this._score, this.node.getWorldPosition());
}
GameManager.instance.destroyEnvironmentObject(this._score, this.node.getWorldPosition(), this._bonusTime);
}
public async onGet() {
this._spawnAnimation.play();
await Utilities.delay(this._spawnAnimation.defaultClip.duration * 1000);
await Utilities.delay(this._spawnAnimation.defaultClip.duration);
this._collider.enabled = true;
}

View File

@ -6,22 +6,25 @@ enum GameEvent {
Score,
BallOut,
MultiBall,
TimeUpdate,
GameStateChange,
ScoreObjectRelease,
}
export interface GameEventCallbackMap {
[GameEvent.Score]: (score: number, type?: ScoreType) => void;
[GameEvent.BallOut]: (ball: number) => void;
[GameEvent.BallOut]: () => void;
[GameEvent.MultiBall]: (active: boolean) => void;
[GameEvent.TimeUpdate]: (time: number) => void;
[GameEvent.GameStateChange]: (state: GameState) => void;
[GameEvent.ScoreObjectRelease]: (obj: Node) => void;
}
export interface GameEventArgMap {
[GameEvent.Score]: [number, ScoreType];
[GameEvent.BallOut]: number;
[GameEvent.BallOut]: null;
[GameEvent.MultiBall]: boolean;
[GameEvent.TimeUpdate]: number;
[GameEvent.GameStateChange]: GameState;
[GameEvent.ScoreObjectRelease]: Node;
}

View File

@ -1,6 +1,7 @@
import { _decorator, CCInteger, Collider2D, Component, Contact2DType, EventHandler, tween, Vec2 } from 'cc';
import Utilities from '../Utilities';
import { Ball } from './Ball';
import TimeConfig from '../Enum/TimeConfig';
const { ccclass, property } = _decorator;
@ccclass('Cannon')
@ -22,10 +23,10 @@ export class Cannon extends Component {
if (ball) {
ball.setActiveRigi(false);
tween(ball.node).to(0.1, { worldPosition: this.node.worldPosition }).start();
await Utilities.delay(1000);
await Utilities.delay(TimeConfig.DelayCannonFire);
ball.setActiveRigi(true);
ball.throwBall(new Vec2(0, this._force));
await Utilities.delay(500);
await Utilities.delay(TimeConfig.DelayCannonDone);
this._collider.enabled = true;
EventHandler.emitEvents(this.onDone, ball);
}

View File

@ -14,6 +14,7 @@ import Utilities from '../Utilities';
import ObjectPool from '../Pool/ObjectPool';
import { Ball } from './Ball';
import { SoundManager } from '../Manager/SoundManager';
import TimeConfig from '../Enum/TimeConfig';
const { ccclass, property } = _decorator;
@ccclass('Goal')
@ -45,7 +46,7 @@ export class Goal extends Component {
fx.node.setWorldPosition(pos);
fx.play();
SoundManager.instance.playSfx(this._goalSound);
await Utilities.delay(1000);
await Utilities.delay(TimeConfig.DelayPLay);
ObjectPool.release(ball.node);
await Utilities.waitUntil(() => fx.isStopped);
this._goalFxPool.release(fx.node);

View File

@ -2,6 +2,7 @@ import { _decorator, Collider2D, Component, Contact2DType, Vec2, Node } from 'cc
import { GameManager } from '../Manager/GameManager';
import Utilities from '../Utilities';
import { Ball } from './Ball';
import TimeConfig from '../Enum/TimeConfig';
const { ccclass, property } = _decorator;
@ccclass('MultiBall')
@ -13,16 +14,17 @@ export class MultiBall extends Component {
@property({ type: Node, visible: true })
private _portRight;
private originBall: Ball;
private trigged = false;
private _originBall: Ball;
private _trigged = false;
protected onLoad(): void {
this._collider.on(Contact2DType.BEGIN_CONTACT, this.onBeginContact, this);
}
protected lateUpdate(dt: number): void {
if (this.trigged) {
const ball1 = this.originBall;
if (this._trigged) {
this._originBall.setActiveRigi(true);
const ball1 = this._originBall;
const ball2 = GameManager.instance.spawnBall(false);
ball1.node.setWorldPosition(this._portRight.worldPosition);
ball1.addForce(new Vec2(10, 0));
@ -30,16 +32,17 @@ export class MultiBall extends Component {
ball2.node.setWorldPosition(this._portLeft.worldPosition);
ball2.addForce(new Vec2(-10, 0));
this.trigged = false;
this._trigged = false;
}
}
private async onBeginContact(selfCollider: Collider2D, otherCollider: Collider2D) {
if (this.trigged) return;
if (this._trigged) return;
this._collider.enabled = false;
this.originBall = otherCollider.getComponent(Ball);
this.trigged = true;
await Utilities.delay(500);
this._originBall = otherCollider.getComponent(Ball);
this._originBall.setActiveRigi(false);
this._trigged = true;
await Utilities.delay(TimeConfig.DelayMultiBall);
this._collider.enabled = true;
}
}

View File

@ -1,17 +1,4 @@
import {
_decorator,
Component,
Node,
Prefab,
Vec2,
Vec3,
randomRangeInt,
CCInteger,
Director,
director,
AudioClip,
Label,
} from 'cc';
import { _decorator, Component, Node, Prefab, Vec2, Vec3, randomRangeInt, CCInteger, AudioClip } from 'cc';
import ObjectPool from '../Pool/ObjectPool';
import { Ball } from '../GamePlay/Ball';
import Utilities from '../Utilities';
@ -21,6 +8,7 @@ import GameEvent from '../Events/GameEvent';
import ScoreType from '../Enum/ScoreType';
import { FloatingText } from '../Environments/FloatingText';
import { SoundManager } from './SoundManager';
import TimeConfig from '../Enum/TimeConfig';
const { ccclass, property } = _decorator;
@ccclass('GameManager')
@ -40,7 +28,7 @@ export class GameManager extends Component {
@property({ visible: true })
private _ballSpawnPosition: Vec3;
@property({ type: CCInteger, visible: true })
private readonly _ballsInit = 3;
private readonly _timePlay = 3;
@property({ type: AudioClip, visible: true })
private _startSound: AudioClip;
@property({ type: AudioClip, visible: true })
@ -49,11 +37,7 @@ export class GameManager extends Component {
private _ballPool: ObjectPool;
private _FloatingScorePool: ObjectPool;
private _gameState: GameState;
private _balls: number;
public get balls() {
return this._ballsInit;
}
private _timer: number;
private _score = 0;
private _isMultiBall = false;
@ -73,12 +57,24 @@ export class GameManager extends Component {
this.changeGameState(GameState.Init);
}
protected update(dt: number): void {
if (this._gameState != GameState.Playing) return;
this._timer -= dt;
if (this._timer <= 0) {
this._timer = 0;
this.gameOver();
}
EventManger.instance.emit(GameEvent.TimeUpdate, this._timer);
}
private changeGameState(state: GameState) {
this._gameState = state;
EventManger.instance.emit(GameEvent.GameStateChange, this._gameState);
}
private addScore(score: number, type: ScoreType, position: Vec3) {
score = this._isMultiBall ? score * 2 : score;
this._score += score;
const floatingScore = this._FloatingScorePool.get(this._floatingTextContainer, FloatingText);
floatingScore.show(`+${score}`, position, score >= 100 ? 1.5 : 1, score >= 100 ? 1 : 0.7);
@ -90,7 +86,7 @@ export class GameManager extends Component {
if (this._currentBallInGame >= 2) {
if (!this._isMultiBall) {
this._isMultiBall = true;
EventManger.instance.emit(GameEvent.MultiBall, false);
EventManger.instance.emit(GameEvent.MultiBall, true);
}
}
@ -103,6 +99,7 @@ export class GameManager extends Component {
}
public spawnBall(throwBall: boolean): Ball {
if (this._gameState != GameState.Playing) return;
SoundManager.instance.playSfx(this._startSound);
this.setCurrentBallInGame(1);
const ball = this._ballPool.get(this.node, Ball);
@ -120,46 +117,50 @@ export class GameManager extends Component {
public async ballOut() {
this.setCurrentBallInGame(-1);
if (this._currentBallInGame <= 0) {
this._balls--;
EventManger.instance.emit(GameEvent.BallOut, this._balls);
if (this._balls === 0) {
await Utilities.delay(1000);
this.changeGameState(GameState.GameOver);
return;
}
await Utilities.delay(1000);
EventManger.instance.emit(GameEvent.BallOut, null);
await Utilities.delay(TimeConfig.DelayPLay);
this.spawnBall(true);
}
}
public async goal(bonusScore: number, position: Vec3) {
this.addScore(bonusScore, ScoreType.Goal, position);
this.setCurrentBallInGame(-1);
this.addScore(this._isMultiBall ? bonusScore * 2 : bonusScore, ScoreType.Goal, position);
if (this._currentBallInGame <= 0) {
await Utilities.delay(2000);
await Utilities.delay(TimeConfig.DelayGoal);
this.spawnBall(true);
}
}
public destroyEnvironmentObject(bonusScore: number, position: Vec3) {
this.addScore(bonusScore, ScoreType.DestroyObject, position);
public async destroyEnvironmentObject(bonusScore: number, position: Vec3, bonusTime?: number) {
if (bonusScore) {
this.addScore(bonusScore, ScoreType.DestroyObject, position);
await Utilities.delay(0.3);
}
if (bonusTime) {
this.addTime(bonusTime);
const floatingScore = this._FloatingScorePool.get(this._floatingTextContainer, FloatingText);
floatingScore.show(`+${bonusTime}`, position, 0.7);
}
}
public addTime(time: number) {
this._timer += time;
}
private gameOver() {
this._ballPool.releaseAll();
this.changeGameState(GameState.GameOver);
}
public async play() {
this._balls = this._ballsInit;
SoundManager.instance.playBGM(this._backgroundMusic, 0.5);
this.changeGameState(GameState.Playing);
await Utilities.delay(1000);
this.spawnBall(true);
}
public async restart() {
this._balls = this._ballsInit;
this._timer = this._timePlay + TimeConfig.DelayPLay;
this._score = 0;
this._currentBallInGame = 0;
this._isMultiBall = false;
SoundManager.instance.playBGM(this._backgroundMusic, 0.5);
this.changeGameState(GameState.Playing);
await Utilities.delay(1000);
await Utilities.delay(TimeConfig.DelayPLay);
this.spawnBall(true);
}

View File

@ -1,12 +1,25 @@
import { _decorator, CCFloat, Component, Node, Prefab, randomRangeInt } from 'cc';
import { _decorator, CCFloat, CCInteger, Component, Node, Prefab, randomRangeInt } from 'cc';
import ObjectPool from '../Pool/ObjectPool';
import { ScoreObject } from '../Environments/ScoreObject';
import { EventManger } from './EventManger';
import GameEvent from '../Events/GameEvent';
import GameState from '../Enum/GameState';
import Utilities from '../Utilities';
import ScoreType from '../Enum/ScoreType';
const { ccclass, property } = _decorator;
@ccclass('weightedObject')
class weightedObject {
@property(Prefab)
public prefab: Prefab;
@property(CCInteger)
public weight = 0;
@property(CCInteger)
public weightStepOnGoal = 0;
@property(CCInteger)
public maxWeight = 0;
}
@ccclass('SpawnObjectManager')
export class SpawnObjectManager extends Component {
//#region singleton
@ -16,8 +29,8 @@ export class SpawnObjectManager extends Component {
}
//#endregion
@property({ type: Prefab, visible: true })
private _objects: Prefab[] = [];
@property({ type: weightedObject, visible: true })
private _objects: weightedObject[] = [];
@property({ type: Node, visible: true })
private _spawnPoints: Node[] = [];
@property({ type: CCFloat, visible: true, range: [1, 10], slide: true })
@ -27,16 +40,20 @@ export class SpawnObjectManager extends Component {
private _usedPoints: { [key: string]: Node } = {};
private _playing = false;
private _timer = 0;
private _weights: number[] = [];
protected onLoad(): void {
SpawnObjectManager._instance = this;
EventManger.instance.on(GameEvent.ScoreObjectRelease, this.onObjectRelease, this);
EventManger.instance.on(GameEvent.GameStateChange, this.onGameStateChange, this);
EventManger.instance.on(GameEvent.Score, this.onScore, this);
for (let i = 0; i < this._objects.length; i++) {
const prefab = this._objects[i];
const prefab = this._objects[i].prefab;
this._pools[i] = new ObjectPool(prefab, 10, true, ScoreObject);
}
this._weights = this._objects.map((obj) => obj.weight);
}
protected update(dt: number): void {
@ -50,7 +67,7 @@ export class SpawnObjectManager extends Component {
private spawn() {
if (Object.keys(this._usedPoints).length == this._spawnPoints.length) return;
var randomPool = this._pools[randomRangeInt(0, this._pools.length)];
var randomPool = Utilities.weightedRandom(this._pools, this._weights);
do {
var randomPoint = this._spawnPoints[randomRangeInt(0, this._spawnPoints.length)];
} while (Object.values(this._usedPoints).indexOf(randomPoint) != -1);
@ -63,6 +80,20 @@ export class SpawnObjectManager extends Component {
delete this._usedPoints[obj.uuid];
}
private onScore(score: number, type: ScoreType) {
if (type == ScoreType.Goal) {
this._objects.forEach((object) => {
if (object.weight >= object.maxWeight) {
object.weight = object.maxWeight;
return;
}
object.weight += object.weightStepOnGoal;
});
this._weights = this._objects.map((obj) => obj.weight);
}
}
private onGameStateChange(state: GameState) {
switch (state) {
case GameState.Init:

View File

@ -4,7 +4,6 @@ import GameEvent from '../Events/GameEvent';
import ScoreType from '../Enum/ScoreType';
import Utilities from '../Utilities';
import GameState from '../Enum/GameState';
import { GameManager } from '../Manager/GameManager';
const { ccclass, property } = _decorator;
@ccclass('UIController')
@ -12,8 +11,6 @@ export class UIController extends Component {
@property({ type: Label, visible: true })
private _scoreLabel: Label;
@property({ type: Label, visible: true })
private _ballLabel: Label;
@property({ type: Label, visible: true })
private _goalLabel: Label;
@property({ type: Label, visible: true })
private _resultLabel: Label;
@ -35,29 +32,26 @@ export class UIController extends Component {
EventManger.instance.on(GameEvent.BallOut, this.onBallOut, this);
EventManger.instance.on(GameEvent.GameStateChange, this.onGameStateChange, this);
EventManger.instance.on(GameEvent.MultiBall, this.onMultiBall, this);
EventManger.instance.on(GameEvent.TimeUpdate, this.onTimeUpdate, this);
this._goalLabel.string = '';
}
protected update(dt: number): void {
if (this._playing) {
this._timer += dt;
this._timeLabe.string = this.secondsToTime(this._timer);
}
if (this._playing) this._timer += dt;
}
private async onScore(score: number, type: ScoreType) {
this._scoreLabel.string = `Score: ${score}`;
if (type == ScoreType.Goal) {
this._goalLabel.string = 'Goal!!';
await Utilities.delay(1000);
await Utilities.delay(1);
this._goalLabel.string = '';
}
}
private async onBallOut(balls: number) {
this._ballLabel.string = `Ball ${balls}`;
private async onBallOut() {
this._goalLabel.string = 'Ball Out!!';
await Utilities.delay(1000);
await Utilities.delay(1);
this._goalLabel.string = '';
}
@ -67,9 +61,9 @@ export class UIController extends Component {
this._startPanel.active = true;
break;
case GameState.Playing:
this._timer = 0;
this._playing = true;
this._scoreLabel.string = 'Score: 0';
this._ballLabel.string = `Ball: ${GameManager.instance.balls}`;
this._startPanel.active = false;
this._overPanel.active = false;
break;
@ -77,8 +71,7 @@ export class UIController extends Component {
this._playing = false;
this._overPanel.active = true;
this._resultLabel.string = this._scoreLabel.string;
this._timeResult.string = this._timeLabe.string;
this._timer = 0;
this._timeResult.string = this.secondsToTime(this._timer);
break;
}
}
@ -88,6 +81,10 @@ export class UIController extends Component {
else this._buffFx.stop();
}
private onTimeUpdate(time: number) {
this._timeLabe.string = this.secondsToTime(time);
}
private secondsToTime(second: number) {
const h = Math.floor(second / 3600)
.toString()

View File

@ -1,19 +1,19 @@
export default class Utilities {
/**
*
* @param time (ms)
* @param time (s)
* @returns
*/
public static delay(time: number): Promise<any> {
return new Promise((resolve) => setTimeout(resolve, time));
return new Promise((resolve) => setTimeout(resolve, time * 1000));
}
/**
*@param predicate
* @param time (ms)
* @param time (s)
* @returns
*/
public static async waitUntil(predicate: () => boolean, timeCheck = 10) {
public static async waitUntil(predicate: () => boolean, timeCheck = 0.01) {
while (!predicate()) {
await this.delay(timeCheck);
}
@ -26,4 +26,19 @@ export default class Utilities {
return false;
}
}
public static weightedRandom<T>(items: T[], weights: number[]): T {
let i = 0;
const weightsClone = [...weights];
for (i = 1; i < weightsClone.length; i++) {
weightsClone[i] += weights[i - 1];
}
let random = Math.random() * weightsClone[weightsClone.length - 1];
for (i = 0; i < weightsClone.length; i++) {
if (weightsClone[i] > random) break;
}
return items[i];
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

View File

@ -0,0 +1,134 @@
{
"ver": "1.0.25",
"importer": "image",
"imported": true,
"uuid": "cdb1ff8a-065e-4d3f-8b28-3bede38d9b1f",
"files": [
".json",
".png"
],
"subMetas": {
"6c48a": {
"importer": "texture",
"uuid": "cdb1ff8a-065e-4d3f-8b28-3bede38d9b1f@6c48a",
"displayName": "clock",
"id": "6c48a",
"name": "texture",
"userData": {
"wrapModeS": "clamp-to-edge",
"wrapModeT": "clamp-to-edge",
"imageUuidOrDatabaseUri": "cdb1ff8a-065e-4d3f-8b28-3bede38d9b1f",
"isUuid": true,
"visible": false,
"minfilter": "linear",
"magfilter": "linear",
"mipfilter": "none",
"anisotropy": 0
},
"ver": "1.0.22",
"imported": true,
"files": [
".json"
],
"subMetas": {}
},
"f9941": {
"importer": "sprite-frame",
"uuid": "cdb1ff8a-065e-4d3f-8b28-3bede38d9b1f@f9941",
"displayName": "clock",
"id": "f9941",
"name": "spriteFrame",
"userData": {
"trimType": "auto",
"trimThreshold": 1,
"rotated": false,
"offsetX": 0,
"offsetY": 0,
"trimX": 0,
"trimY": 0,
"width": 512,
"height": 512,
"rawWidth": 512,
"rawHeight": 512,
"borderTop": 0,
"borderBottom": 0,
"borderLeft": 0,
"borderRight": 0,
"packable": true,
"pixelsToUnit": 100,
"pivotX": 0.5,
"pivotY": 0.5,
"meshType": 0,
"vertices": {
"rawPosition": [
-256,
-256,
0,
256,
-256,
0,
-256,
256,
0,
256,
256,
0
],
"indexes": [
0,
1,
2,
2,
1,
3
],
"uv": [
0,
512,
512,
512,
0,
0,
512,
0
],
"nuv": [
0,
0,
1,
0,
0,
1,
1,
1
],
"minPos": [
-256,
-256,
0
],
"maxPos": [
256,
256,
0
]
},
"isUuid": true,
"imageUuidOrDatabaseUri": "cdb1ff8a-065e-4d3f-8b28-3bede38d9b1f@6c48a",
"atlasUuid": ""
},
"ver": "1.0.11",
"imported": true,
"files": [
".json"
],
"subMetas": {}
}
},
"userData": {
"type": "sprite-frame",
"fixAlphaTransparencyArtifacts": true,
"hasAlpha": true,
"redirect": "cdb1ff8a-065e-4d3f-8b28-3bede38d9b1f@f9941"
}
}