Skip to content

Commit

Permalink
[FEAT] Add complex meshes for entity graphics (#2)
Browse files Browse the repository at this point in the history
* add graphic to elements
* complex player model
* build gh-pages
  • Loading branch information
saacostam-zaga authored Dec 28, 2023
1 parent b89b7c5 commit 5fd3178
Show file tree
Hide file tree
Showing 15 changed files with 752 additions and 552 deletions.
1,022 changes: 511 additions & 511 deletions docs/assets/index-jtWBzQjt.js → docs/assets/index-ih74sjfz.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-jtWBzQjt.js"></script>
<script type="module" crossorigin src="./assets/index-ih74sjfz.js"></script>
<link rel="stylesheet" crossorigin href="./assets/index-0wMWXa16.css">
</head>
<body>
Expand Down
74 changes: 65 additions & 9 deletions src/object/actor/car.actor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,21 @@ export class Car extends Entity{
private end: Vector3;
private pathProgress: number;

private width: number;
private height: number;
private depth: number;

private pathMap: PathMap;

constructor(scene: BaseScene, options: CarOptions){
super(scene);

this.mesh = MeshBuilder.CreateBox('CAR-MESH',{
width: options.width,
depth: options.depth,
height: options.height,
}, scene);

this.mesh.position = options.start;
this.width = options.width;
this.height = options.height;
this.depth = options.depth;

this.mesh.material = new StandardMaterial('CAR-MESH-MATERIAL', scene);
if (this.mesh.material instanceof StandardMaterial) this.mesh.material.diffuseColor = Color3.Random();
options.start.y += this.height/8;
options.end.y += this.height/8;

this.direction = options.direction;
this.start = options.start;
Expand All @@ -41,6 +41,56 @@ export class Car extends Entity{
})

this.collisionType = 'dynamic';

// Mesh
const COLOR = Color3.Random();
const WHEEL_COLOR = new Color3(0.15, 0.15, 0.15);

this.mesh = MeshBuilder.CreateBox('CAR-MESH',{
width: this.width,
depth: this.depth,
height: this.height/2,
}, scene);
this.mesh.position = options.start;
this.mesh.material = new StandardMaterial('CAR-MESH-MATERIAL', scene);
if (this.mesh.material instanceof StandardMaterial) this.mesh.material.diffuseColor = COLOR;

// Mesh - Children
const roof = MeshBuilder.CreateBox('CAR-MESH', {
width: this.width,
depth: this.depth/2,
height: this.height/2,
}, scene);
roof.material = new StandardMaterial('CAR-MESH-MATERIAL', scene);
if (roof.material instanceof StandardMaterial) roof.material.diffuseColor = COLOR;
this.meshChildren.push({
mesh: roof,
anchorToParent: new Vector3(0, this.height/2, 0),
});

const frontWheels = MeshBuilder.CreateCylinder('CAR-MESH', {
height: this.width*1.1,
diameter: this.height*5/8,
})
frontWheels.rotation = new Vector3(0, 0, Math.PI/2);
frontWheels.material = new StandardMaterial('CAR-MESH-MATERIAL', scene);
if (frontWheels.material instanceof StandardMaterial) frontWheels.material.diffuseColor = WHEEL_COLOR;
this.meshChildren.push({
mesh: frontWheels,
anchorToParent: new Vector3(0, -this.height/6, this.depth/3),
});

const backWheels = MeshBuilder.CreateCylinder('CAR-MESH', {
height: this.width*1.1,
diameter: this.height*5/8,
})
backWheels.rotation = new Vector3(0, 0, Math.PI/2);
backWheels.material = new StandardMaterial('CAR-MESH-MATERIAL', scene);
if (backWheels.material instanceof StandardMaterial) backWheels.material.diffuseColor = WHEEL_COLOR;
this.meshChildren.push({
mesh: backWheels,
anchorToParent: new Vector3(0, -this.height/6, -this.depth/3),
});
}

public update(_game: Game, _delta: number): void {
Expand All @@ -49,5 +99,11 @@ export class Car extends Entity{
this.pathProgress = ((this.pathProgress + DELTA_MOVEMENT * MODIFIER) + 1) % 1;

this._mesh.position = this.pathMap(this.pathProgress);

this.meshChildren.forEach(
({mesh, anchorToParent}) => {
mesh.position = this._mesh.position.add(anchorToParent);
}
)
}
}
2 changes: 1 addition & 1 deletion src/object/actor/log.actor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export class Log extends Entity{
this.mesh.position = options.start;

this.mesh.material = new StandardMaterial('LOG-MESH-MATERIAL', scene);
if (this.mesh.material instanceof StandardMaterial) this.mesh.material.diffuseColor = Color3.Random();
if (this.mesh.material instanceof StandardMaterial) this.mesh.material.diffuseColor = new Color3(0.6, 0.5, 0.3);

this.direction = options.direction;
this.start = options.start;
Expand Down
108 changes: 101 additions & 7 deletions src/object/actor/player/player.actor.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { Color3, MeshBuilder, StandardMaterial, Vector3 } from "@babylonjs/core";
import { Color3, MeshBuilder, StandardMaterial, Vector3, Quaternion } from "@babylonjs/core";

import { Entity } from "../..";
import { Game } from "../../../app";
import { BASE_SIZE } from "../../../config";
import { TiledSceneNavigator } from "../../../handler";
import { BaseScene, HomeScene } from "../../../scene";
import { Direction, StateMachine } from "../../../types";
import { Curve, CurveUtil } from "../../../util";
import { Curve, CurveUtil, DirectionUtil } from "../../../util";

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

Expand All @@ -23,7 +23,10 @@ export class Player extends Entity{

private stateMachine: StateMachine<PlayerStateMachineState, PlayerStateMachineTransition>;
private jumpCurrDistance: number = 0;

private direction: Direction = 'top';

private width: number;
private depth: number;
private height: number;

Expand All @@ -38,20 +41,93 @@ export class Player extends Entity{
this.scene = scene;

const SIZE = options?.size ? options.size : BASE_SIZE;
const COLOR_RED = Color3.Red();

this.width = SIZE;
this.height = SIZE*2;
this.depth = SIZE;

this.mesh = MeshBuilder.CreateBox(
'PLAYER-MESH',
{
size: SIZE,
}
height: this.height,
depth: this.depth,
width: this.width,
},
scene,
);
this.height = SIZE;
this.depth = SIZE;

if (options?.position) this.mesh.position = options.position;

this.mesh.material = new StandardMaterial('PLAYER-MESH-MATERIAL', scene);
if (this.mesh.material instanceof StandardMaterial) this.mesh.material.diffuseColor = Color3.Blue();
if (this.mesh.material instanceof StandardMaterial) this.mesh.material.diffuseColor = Color3.White();

// Mesh - Children
const feathers = MeshBuilder.CreateBox(
'PLAYER-MESH',
{
height: this.height/2,
depth: this.depth,
width: this.width/2,
},
scene,
);
feathers.material = new StandardMaterial('PLAYER-MESH-MATERIAL', scene);
if (feathers.material instanceof StandardMaterial) feathers.material.diffuseColor = Color3.White();
this.meshChildren.push({
mesh: feathers,
anchorToParent: new Vector3(-this.width*3/4, -this.height/4, 0),
});

const comb = MeshBuilder.CreateBox(
'PLAYER-MESH',
{
height: this.height/8,
depth: this.depth/4,
width: this.width/2,
},
scene,
);
comb.material = new StandardMaterial('PLAYER-MESH-MATERIAL', scene);
if (comb.material instanceof StandardMaterial) comb.material.diffuseColor = COLOR_RED;
this.meshChildren.push({
mesh: comb,
anchorToParent: new Vector3(0, this.height*9/16, 0),
});

const beak = MeshBuilder.CreateBox(
'PLAYER-MESH',
{
height: this.height/8,
depth: this.depth/2,
width: this.width/4,
},
scene,
);
beak.material = new StandardMaterial('PLAYER-MESH-MATERIAL', scene);
if (beak.material instanceof StandardMaterial) beak.material.diffuseColor = new Color3(0.95, 0.65, 0.2);
this.meshChildren.push({
mesh: beak,
anchorToParent: new Vector3(this.width*5/8, this.height/4, 0),
});

const wattle = MeshBuilder.CreateBox(
'PLAYER-MESH',
{
height: this.height/8,
depth: this.depth/4,
width: this.width/4,
},
scene,
);
wattle.material = new StandardMaterial('PLAYER-MESH-MATERIAL', scene);
if (wattle.material instanceof StandardMaterial) wattle.material.diffuseColor = COLOR_RED;
this.meshChildren.push({
mesh: wattle,
anchorToParent: new Vector3(this.width*5/8, this.height/8, 0),
});

// State

this.stateMachine = getPlayerStateMachine();

Expand Down Expand Up @@ -127,6 +203,22 @@ export class Player extends Entity{
};
}

private updateMesh(_: Game, __: number){
const ROTATION = DirectionUtil.findRotationAngleBasedOnDirection(this.direction);
const ROTATION_VECTOR = new Vector3(0, ROTATION, 0);

this._mesh.rotation = ROTATION_VECTOR;
this.meshChildren.forEach(
({mesh, anchorToParent}) => {
mesh.rotation = ROTATION_VECTOR;

const rotationQuaternion = Quaternion.FromEulerAngles(0, ROTATION, 0);
const newAnchorToParent = anchorToParent.applyRotationQuaternion(rotationQuaternion);
mesh.position = this._mesh.position.add(newAnchorToParent);
}
)
}

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

Expand Down Expand Up @@ -161,5 +253,7 @@ export class Player extends Entity{
this.updateJump(_game, _delta);
break;
}

this.updateMesh(_game, _delta)
}
}
4 changes: 3 additions & 1 deletion src/object/base.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import { Mesh } from "@babylonjs/core";

import { Game } from "../app";
import { CollisionType } from "../types";
import { AnchoredChildMesh, CollisionType } from "../types";
import { BaseScene } from "../scene";

export class Entity {
public _mesh: Mesh;
public isAlive: boolean = true;
public collisionType: CollisionType = 'none';

public meshChildren: AnchoredChildMesh[] = [];

constructor(public scene: BaseScene){
this._mesh = new Mesh('BASE-MESH');
}
Expand Down
18 changes: 15 additions & 3 deletions src/object/enviroment/stone.object.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,28 @@ export class Stone extends Entity{
constructor(scene: BaseScene, options: StaticEntityOptions){
super(scene);

const SIZE = BASE_SIZE*(3/4);
const SIZE = BASE_SIZE/2;
const GRAY_COLOR = new Color3(0.45, 0.45, 0.45);

this.mesh = MeshBuilder.CreateBox('STONE-MESH',{
size: SIZE,
}, scene);

this.mesh.position = new Vector3(options.x, SIZE/2, options.z);

this.mesh.material = new StandardMaterial('STONE-MESH-MATERIAL', scene);
if (this.mesh.material instanceof StandardMaterial) this.mesh.material.diffuseColor = Color3.Random();
if (this.mesh.material instanceof StandardMaterial) this.mesh.material.diffuseColor = GRAY_COLOR;

// Mesh - Children
const smallerStone = MeshBuilder.CreateBox('STONE-MESH',{
size: SIZE/2,
}, scene);
smallerStone.position = new Vector3(options.x, SIZE*5/4, options.z);
smallerStone.material = new StandardMaterial('STONE-MESH-MATERIAL', scene);
if (smallerStone.material instanceof StandardMaterial) smallerStone.material.diffuseColor = GRAY_COLOR;
this.meshChildren.push({
mesh: smallerStone,
anchorToParent: Vector3.Zero(),
});

this.collisionType = 'static';
}
Expand Down
4 changes: 2 additions & 2 deletions src/object/enviroment/tile/nature.factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ export const NatureTileFactory: TileFactory = (scene: BaseScene, amount: number,
const MIN = tile._mesh.position.z - tile.depth/2;
const MAX = tile._mesh.position.z + tile.depth/2;

const z = MIN + ((MAX - MIN) * Math.random());

for (let iter = 0; iter < amount; iter++){
const z = MIN + ((MAX - MIN) * Math.random());

const NatureObjectConstructor = natureTileObjectsConstructors[Math.floor(natureTileObjectsConstructors.length * Math.random())];
const entity = new NatureObjectConstructor(scene, {
x: tile._mesh.position.x,
Expand Down
25 changes: 15 additions & 10 deletions src/object/enviroment/tile/tile.object.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,18 +31,18 @@ export class Tile extends Entity{
super(scene);

this.isEmpty = !!options.isEmpty;
if (this.isEmpty) this.tileType = 'empty';

this.width = options.width;
this.depth = options.depth;
const height = (this.tileType === 'river') ? BASE_SIZE*7/8 : BASE_SIZE;

if (this.isEmpty) this.tileType = 'empty';

if (this.tileType !== 'river'){
this.mesh = MeshBuilder.CreateBox('TILE-MESH', {
width: this.width,
height: BASE_SIZE,
depth: this.depth,
}, scene);
}
this.mesh = MeshBuilder.CreateBox('TILE-MESH', {
width: this.width,
height: height,
depth: this.depth,
}, scene);

this._mesh.position = new Vector3(
options.x,
Expand All @@ -51,13 +51,18 @@ export class Tile extends Entity{
);

this._mesh.material = new StandardMaterial('TILE-MESH-MATERIAL', scene);
if (this._mesh.material instanceof StandardMaterial) this._mesh.material.diffuseColor = Color3.Random();
if (this._mesh.material instanceof StandardMaterial) this._mesh.material.diffuseColor =
(this.tileType === 'track')
? new Color3(0.15, 0.15, 0.15)
: (this.tileType === 'river')
? new Color3(0.5, 0.75, 0.85)
: new Color3(0.6, 0.85, 0.5);

this.collisionType = (this.tileType === 'river') ? 'dynamic' : 'none';
}

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

const TileFactory = this.isEmpty
? EmptyTileFactory
Expand Down
2 changes: 1 addition & 1 deletion src/object/enviroment/tile/track.factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export const TrackTileFactory: TileFactory = (scene: BaseScene, _: number, tile:
start: start,
end: end,
width: SIZE,
depth: SIZE*2,
depth: SIZE*3,
height: HEIGHT,
});

Expand Down
Loading

0 comments on commit 5fd3178

Please sign in to comment.