107 lines
3.3 KiB
TypeScript
107 lines
3.3 KiB
TypeScript
import {
|
|
_decorator,
|
|
Animation,
|
|
CCFloat,
|
|
Collider2D,
|
|
Component,
|
|
Contact2DType,
|
|
Director,
|
|
director,
|
|
EventTarget,
|
|
IPhysics2DContact,
|
|
ParticleSystem,
|
|
randomRangeInt,
|
|
RigidBody2D,
|
|
Vec2,
|
|
} from 'cc';
|
|
import { GameplayController } from './GameplayController';
|
|
import { SoundManager } from './SoundManager';
|
|
const { ccclass, property } = _decorator;
|
|
|
|
@ccclass('Ball')
|
|
export class Ball extends Component {
|
|
@property({ visible: true, type: CCFloat })
|
|
public maxSpeed: number;
|
|
@property({ visible: true, type: RigidBody2D })
|
|
public rigidbody: RigidBody2D;
|
|
@property(Collider2D)
|
|
public collider: Collider2D;
|
|
@property(ParticleSystem)
|
|
private trail: ParticleSystem;
|
|
public isActive: boolean;
|
|
private hitted = false;
|
|
|
|
public eventHitObstacle = new EventTarget();
|
|
public eventGoal = new EventTarget();
|
|
|
|
protected onLoad(): void {
|
|
if (this.getComponent(Collider2D)) {
|
|
this.collider.on(Contact2DType.BEGIN_CONTACT, this.onBeginContact, this);
|
|
this.collider.on(Contact2DType.END_CONTACT, this.onEndContact, this);
|
|
}
|
|
|
|
director.on(Director.EVENT_AFTER_PHYSICS, this.setMaxVelocity, this);
|
|
}
|
|
|
|
protected onEnable(): void {
|
|
let dir = randomRangeInt(-1, 2);
|
|
while (dir == 0) {
|
|
dir = randomRangeInt(-1, 2);
|
|
}
|
|
const force = new Vec2(dir, 1);
|
|
this.rigidbody.applyLinearImpulse(force.multiply2f(5, 50), Vec2.ZERO, true);
|
|
SoundManager.Instance().PlayOneShot(SoundManager.Instance().whistle);
|
|
}
|
|
|
|
private onBeginContact(selfCollider: Collider2D, otherCollider: Collider2D, contact: IPhysics2DContact | null) {
|
|
// Hit boundary
|
|
if (otherCollider.tag == 1) {
|
|
this.node.active = false;
|
|
// GameplayController.Instance().SpawnBallInTime(1);
|
|
GameplayController.Instance().LoseStreak();
|
|
SoundManager.Instance().PlayOneShot(SoundManager.Instance().hitGround);
|
|
return;
|
|
}
|
|
|
|
// Hit goal
|
|
if (otherCollider.tag == 2) {
|
|
otherCollider.getComponent(Animation)?.play();
|
|
this.node.active = false;
|
|
GameplayController.Instance().AddScore(1);
|
|
// GameplayController.Instance().SpawnBallInTime(1);
|
|
SoundManager.Instance().PlayOneShot(SoundManager.Instance().goal);
|
|
|
|
this.eventGoal.emit('Goal');
|
|
|
|
return;
|
|
}
|
|
|
|
// Hit obstacle
|
|
if (otherCollider.tag == 3) {
|
|
this.eventHitObstacle.emit('HitObstacle', otherCollider.node);
|
|
return;
|
|
}
|
|
|
|
if (!this.hitted && this.rigidbody.linearVelocity.length() >= 2) {
|
|
SoundManager.Instance().PlayOneShot(SoundManager.Instance().hitPlayer);
|
|
}
|
|
|
|
this.hitted = true;
|
|
}
|
|
|
|
private setMaxVelocity() {
|
|
if (this.rigidbody.linearVelocity.length() > this.maxSpeed) {
|
|
this.rigidbody.linearVelocity = this.rigidbody.linearVelocity.normalize().multiplyScalar(this.maxSpeed);
|
|
}
|
|
}
|
|
|
|
private onEndContact(selfCollider: Collider2D, otherCollider: Collider2D, contact: IPhysics2DContact | null) {
|
|
// console.log(otherCollider.tag, otherCollider.node.name);
|
|
this.hitted = false;
|
|
}
|
|
|
|
public resetTrail() {
|
|
this.trail.clear();
|
|
}
|
|
}
|