Skip to content

Commit

Permalink
[FEAT] Handle Game Over and Restart (#5)
Browse files Browse the repository at this point in the history
* restart game after death && show particles
* build gh-pages && adjust factory amount
  • Loading branch information
saacostam-zaga authored Dec 28, 2023
1 parent f7df420 commit 301bf7f
Show file tree
Hide file tree
Showing 10 changed files with 669 additions and 514 deletions.
1,008 changes: 504 additions & 504 deletions docs/assets/index-BqF0neoc.js → docs/assets/index-v7LhaIZJ.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<link rel="icon" type="image/svg+xml" href="./vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Crossy Road</title>
<script type="module" crossorigin src="./assets/index-BqF0neoc.js"></script>
<script type="module" crossorigin src="./assets/index-v7LhaIZJ.js"></script>
<link rel="stylesheet" crossorigin href="./assets/index-0wMWXa16.css">
</head>
<body>
Expand Down
30 changes: 25 additions & 5 deletions src/object/actor/player/player.actor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@ import { Entity } from "../..";
import { Game } from "../../../app";
import { BASE_SIZE } from "../../../config";
import { TiledSceneNavigator } from "../../../handler";
import { BaseScene, HomeScene } from "../../../scene";
import { HomeScene } from "../../../scene";
import { Direction, StateMachine } from "../../../types";
import { Curve, CurveUtil, DirectionUtil } from "../../../util";

import { PlayerStateMachineState, PlayerStateMachineTransition, getPlayerStateMachine } from "./player.state-machine";
import { DeathParticlesGroup } from "../../particles-group";

type PlayerOptions = {
size?: number,
Expand All @@ -34,9 +35,9 @@ export class Player extends Entity{
private platformCenterOffset: Vector3 | undefined;
private tiledSceneNavigator: TiledSceneNavigator | undefined;

public scene: BaseScene;
public scene: HomeScene;

constructor(scene: BaseScene, options?: PlayerOptions){
constructor(scene: HomeScene, options?: PlayerOptions){
super(scene);
this.scene = scene;

Expand Down Expand Up @@ -190,14 +191,14 @@ export class Player extends Entity{

private handleIdle(_game: Game, _delta: number){
const metaTile = this.tiledSceneNavigator?.getClosestTile(this._mesh.position._x, this.depth);
if (metaTile?.tile.collisionType === 'dynamic' && metaTile.x > 0) _game.engine.stopRenderLoop();
if (metaTile?.tile.collisionType === 'dynamic' && metaTile.x > 0) this.handleDeath();
}

public onCollision(_other: Entity, _game: Game): void {
if (_game.engine.getFps() === Infinity) return;

if (_other.collisionType === 'static') this.stateMachine.transition('move-back');
if (_other.collisionType === 'dynamic') _game.engine.stopRenderLoop();
if (_other.collisionType === 'dynamic' && this.scene) this.handleDeath();
if (_other.collisionType === 'platform') {
if (this.stateMachine.state() === 'idle'){
this.platform = _other;
Expand All @@ -224,6 +225,23 @@ export class Player extends Entity{
)
}

private handleDeath(){
if (this.stateMachine.state() === 'dead') return;
this.stateMachine.transition('die');

if (this.mesh.material) this.mesh.material.alpha = 0;
this.meshChildren.forEach(child => {
if (child.mesh.material) child.mesh.material.alpha = 0;
});

const start = this._mesh.position.clone();
const particlesGroup = new DeathParticlesGroup(this.scene, {
start: start,
});

this.scene.addEntity(particlesGroup);
}

public update(_game: Game, _delta: number): void {
if (_game.engine.getFps() === Infinity) return;

Expand Down Expand Up @@ -257,6 +275,8 @@ export class Player extends Entity{
case 'moving-back':
this.updateJump(_game, _delta);
break;
case 'dead':
break;
}

this.updateMesh(_game, _delta)
Expand Down
19 changes: 17 additions & 2 deletions src/object/actor/player/player.state-machine.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { IndependentCallback, StateMachine } from "../../../types";

export type PlayerStateMachineState = 'moving' | 'idle' | 'moving-back' | 'on-platform';
export type PlayerStateMachineTransition = 'move' | 'stop' | 'move-back' | 'bind-to-platform';
export type PlayerStateMachineState = 'moving' | 'idle' | 'moving-back' | 'on-platform' | 'dead';
export type PlayerStateMachineTransition = 'move' | 'stop' | 'move-back' | 'bind-to-platform' | 'die';

export const getPlayerStateMachine = (): StateMachine<
PlayerStateMachineState,
Expand All @@ -28,6 +28,9 @@ export const getPlayerStateMachine = (): StateMachine<
break;
case 'move-back':
break;
case 'die':
currentState = 'dead';
break;
}
break;
case 'moving':
Expand All @@ -43,6 +46,9 @@ export const getPlayerStateMachine = (): StateMachine<
break;
case 'bind-to-platform':
break;
case 'die':
currentState = 'dead';
break;
}
break;
case 'moving-back':
Expand All @@ -56,6 +62,9 @@ export const getPlayerStateMachine = (): StateMachine<
case 'move':
case 'bind-to-platform':
break;
case 'die':
currentState = 'dead';
break;
}
break;
case 'on-platform':
Expand All @@ -69,7 +78,13 @@ export const getPlayerStateMachine = (): StateMachine<
case 'move-back':
case 'bind-to-platform':
break;
case 'die':
currentState = 'dead';
break;
}
break;
case 'dead':
break;
}

const CURR_STATE = currentState;
Expand Down
2 changes: 1 addition & 1 deletion src/object/enviroment/tile/tile.object.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ export class Tile extends Entity{
}

public onEnterScene(_scene: BaseScene): void {
const N_ENTITIES_TO_ADD = 1 + Math.floor(2 * Math.random());
const N_ENTITIES_TO_ADD = 1 + Math.floor(3 * Math.random());

const TileFactory = this.isEmpty
? EmptyTileFactory
Expand Down
1 change: 1 addition & 0 deletions src/object/enviroment/tile/track.factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export const TrackTileFactory: TileFactory = (scene: BaseScene, amount: number,

const direction: Direction = Math.random() < 0.5 ? 'right' : 'left';

amount = Math.min(2, amount);
const MIN = tile._mesh.position.z - tile.depth/2;
const MAX = tile._mesh.position.z + tile.depth/2;

Expand Down
49 changes: 49 additions & 0 deletions src/object/particles-group/death-particles.group.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { Vector3 } from "@babylonjs/core";
import { Particle } from ".";
import { Entity } from "..";
import { Game } from "../../app";
import { HomeScene } from "../../scene";

type DeathParticlesGroupOptions = {
start: Vector3;
}

export class DeathParticlesGroup extends Entity{
public static TTL = 1000;
public scene: HomeScene;

private particles: Entity[] = [];
private life = 0;

constructor(scene: HomeScene, options: DeathParticlesGroupOptions){
super(scene);

const NUMBER_OF_PARTICLES = 20;
for (let i = 0; i < NUMBER_OF_PARTICLES; i++){
const particle = new Particle(scene, {
start: options.start,
TTL: DeathParticlesGroup.TTL,
});

this.particles.push(particle);
scene.addEntity(particle);
}

this.scene = scene;
}

public update(_game: Game, _delta: number): void {
if (this.life > DeathParticlesGroup.TTL) {
this.kill();
this.scene.restart();
return;
}

this.life += _delta;
}

kill(): void {
super.kill();
this.particles.forEach(particle => particle.kill());
}
}
2 changes: 2 additions & 0 deletions src/object/particles-group/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './death-particles.group';
export * from './particle';
45 changes: 45 additions & 0 deletions src/object/particles-group/particle.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { Color3, MeshBuilder, StandardMaterial, Vector3 } from "@babylonjs/core";
import { Entity } from "..";

import { Game } from "../../app";
import { HomeScene } from "../../scene";
import { BASE_SIZE } from "../../config";

type ParticleOptions = {
start: Vector3;
TTL: number;
}

export class Particle extends Entity{
private pointingTo: Vector3;

private ttl: number;
private life: number = 0;

constructor(scene: HomeScene, options: ParticleOptions){
super(scene);
this._mesh = MeshBuilder.CreateBox('PARTICLE-MESH', {
size: BASE_SIZE/16,
}, scene);
this.mesh.material = new StandardMaterial('PLAYER-MESH-MATERIAL', scene);
if (this.mesh.material instanceof StandardMaterial) this.mesh.material.diffuseColor = Math.random() < 0.5 ? Color3.White() : Color3.Red();

this.mesh.position = options.start;
this.ttl = options.TTL;

const getNormalizedComponent = () => (-1 + Math.floor(3 * Math.random()));

this.pointingTo = new Vector3(
getNormalizedComponent(),
getNormalizedComponent(),
getNormalizedComponent(),
);
}

public update(_game: Game, _delta: number): void {
this.life += _delta;
this.mesh.position = this.mesh.position.add(this.pointingTo.scale(0.01*_delta));

if (this.mesh.material) this.mesh.material.alpha = 1 - (this.life / this.ttl);
}
}
25 changes: 24 additions & 1 deletion src/scene/home.scene.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { BASE_SIZE } from "../config";
type HomeSceneOptions = BaseSceneOptions;

export class HomeScene extends BaseScene{
private player: Player;
private player!: Player;
public tiles: MetaTile[] = [];

private static TILE_DEPTH = BASE_SIZE * 20;
Expand All @@ -25,6 +25,10 @@ export class HomeScene extends BaseScene{
super(app, options);
this.clearColor = new Color4(0.5, 0.75, 0.85);

this.setup();
}

private setup(){
this.player = new Player(this, {
position: new Vector3(-BASE_SIZE, BASE_SIZE/4, 0),
size: BASE_SIZE/4,
Expand All @@ -46,6 +50,25 @@ export class HomeScene extends BaseScene{
)
}

public restart(){
this.cleanup();
this.setup();
}

private cleanup(){
this.player.kill();
this.tiles.forEach(tile => tile.tile.kill());
this.sideLimits.forEach(limit => limit.kill());
this.gameAreaLimits.forEach(limit => limit.kill());

this.tiles = [];
this.sideLimits = [];
this.gameAreaLimits = [];
this.farthestAwayPlayerXCoordinate = 0;
this.farthestAwayTileXCoordinate = 0;
this.closestLimitXCoordinate = -10000;
}

private addTile(x: number, isEmpty: boolean = false){
const tile = new Tile(this, {
depth: HomeScene.TILE_DEPTH,
Expand Down

0 comments on commit 301bf7f

Please sign in to comment.