Skip to content

Commit 051a4f9

Browse files
feat: counting score
1 parent f08c513 commit 051a4f9

File tree

6 files changed

+117
-40
lines changed

6 files changed

+117
-40
lines changed
Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,32 @@
11
<!doctype html>
22
<html lang="en">
3-
<head>
4-
<meta charset="UTF-8" />
5-
<link rel="stylesheet" href="/src/style.css" >
6-
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
7-
<title>Running Ball (Babylon.js)</title>
8-
</head>
9-
<body>
10-
<main class="app">
11-
<canvas id="game-canvas" class="game-canvas"></canvas>
12-
<div class="user-ui">
13-
<button id="restart-btn" class="ui-btn">
14-
<img src="/assets/images/restart.png" width="30px"/>
15-
</button>
3+
4+
<head>
5+
<meta charset="UTF-8" />
6+
<link rel="preconnect" href="https://fonts.googleapis.com">
7+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
8+
<link href="https://fonts.googleapis.com/css2?family=Black+Ops+One&display=swap" rel="stylesheet">
9+
<link rel="stylesheet" href="/src/style.css">
10+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
11+
<title>Running Ball (Babylon.js)</title>
12+
</head>
13+
14+
<body>
15+
<main class="app">
16+
<canvas id="game-canvas" class="game-canvas"></canvas>
17+
<div class="user-ui user-ui__top">
18+
<div class="score">
19+
<span class="game-score" id="game-score">0</span>
20+
<img src="/assets/images/coin.png" class="coin-img" />
1621
</div>
1722
</div>
23+
24+
<div class="user-ui user-ui__bottom">
25+
<button id="restart-btn" class="ui-btn">
26+
<img src="/assets/images/restart.png" width="30px" />
27+
</button>
28+
</div>
1829
<script type="module" src="/src/main.ts"></script>
19-
</body>
20-
</html>
30+
</body>
31+
32+
</html>
9.09 KB
Loading

games/running-ball-babylonjs/src/Game.ts

Lines changed: 50 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,13 @@ import {
2121
import '@babylonjs/loaders/glTF'
2222
//@ts-ignore
2323
import * as CANNON from 'cannon';
24-
import type { Size3D } from './types';
24+
import type { GameArgs, Size3D } from './types';
2525
import { notRepeatedRandomFreeSpacePositionGenerator } from './utils';
2626

2727

2828
export class Game {
2929
private static readonly SinglePlatformSize: Size3D = Object.freeze({ height: 0.6, depth: 6, width: 8 });
30-
private static readonly SingleWallSize: Size3D = Object.freeze({ height: Game.SinglePlatformSize.width / 3, depth: Game.SinglePlatformSize.width / 6, width: Game.SinglePlatformSize.width / 3 });
30+
private static readonly SingleWallSize: Size3D = Object.freeze({ height: Game.SinglePlatformSize.width / 3, depth: Game.SinglePlatformSize.width / 8, width: Game.SinglePlatformSize.width / 3 });
3131
private static readonly ZeroVector = new Vector3(0, 0, 0);
3232
private static readonly SpeedOfMovingStraight = 6;
3333
private static readonly SpeedOfMovingAside = 2;
@@ -47,12 +47,18 @@ export class Game {
4747
private readonly platforms: Mesh[];
4848
private readonly walls: Mesh[];
4949
private readonly ball: Mesh;
50-
private coinModel: Mesh = {} as Mesh;
50+
private readonly coins: Mesh[] = [];
5151
private readonly shadowGenerator: ShadowGenerator;
52+
private coinScore = 0;
53+
private readonly canvasRef: HTMLCanvasElement;
54+
private readonly scoreTextRef: HTMLElement;
5255

5356

54-
public constructor(private readonly canvas: HTMLCanvasElement) {
55-
this.engine = new Engine(this.canvas);
57+
public constructor(args: GameArgs) {
58+
this.scoreTextRef = args.scoreTextRef;
59+
this.canvasRef = args.canvasRef;
60+
61+
this.engine = new Engine(this.canvasRef);
5662
this.scene = this.configureScene();
5763
this.light = this.configureLight();
5864
this.camera = this.configureCamera();
@@ -72,18 +78,18 @@ export class Game {
7278

7379
this.initControls();
7480

75-
this.loadCoinModel();
76-
void this.coinModel;
77-
78-
this.scene.registerBeforeRender(this.checkSphereBoxCollision.bind(this));
81+
this.scene.registerBeforeRender(() => {
82+
this.checkSphereBoxCollision();
83+
this.checkCoinEarned();
84+
});
7985

8086
this.engine.runRenderLoop(() => {
8187
this.updateCameraAndLight();
8288
this.scene.render();
8389
});
8490
}
8591

86-
private loadCoinModel() {
92+
private createCoin(position: Vector3) {
8793
// I see, that deprecated, but Babylon is so strange, that the fastest way to load this
8894
// is just to use deprecated SceneLoader sync import
8995
SceneLoader.ImportMesh(
@@ -95,10 +101,10 @@ export class Game {
95101
console.log(m)
96102
const meshArray = m as unknown as Mesh[];
97103
const coin = meshArray[0];
98-
coin.scaling = new Vector3(0.07, 0.07, 0.07);
99-
coin.position = new Vector3(2, 1, 0);
104+
coin.scaling = new Vector3(0.05, 0.05, 0.05);
105+
coin.position = position;
100106

101-
this.coinModel = coin;
107+
this.coins.push(coin);
102108

103109
this.shadowGenerator.addShadowCaster(coin);
104110
coin.receiveShadows = true;
@@ -163,15 +169,17 @@ export class Game {
163169

164170
private updateCameraAndLight(): void {
165171
this.camera.position.z = this.ball.getAbsolutePosition().z - 12;
166-
this.camera.position.y = this.ball.getAbsolutePosition().y + 5;
172+
this.camera.position.y = this.ball.getAbsolutePosition().y + 6;
173+
//this.camera.setTarget(this.ball.getAbsolutePosition());
174+
167175
this.light.position.z = this.ball.getAbsolutePosition().z + 10;
168176
this.light.position.y = this.ball.getAbsolutePosition().y + 10;
169177
this.light.position.z = this.ball.getAbsolutePosition().z + 10;
170178
}
171179

172180
private shrinkCanvas() {
173-
this.canvas.width = this.canvas.clientWidth;
174-
this.canvas.height = this.canvas.clientHeight;
181+
this.canvasRef.width = this.canvasRef.clientWidth;
182+
this.canvasRef.height = this.canvasRef.clientHeight;
175183
this.engine.resize();
176184
}
177185

@@ -200,7 +208,7 @@ export class Game {
200208
}
201209

202210
private configureCamera(): Camera {
203-
const camera = new FreeCamera('camera', new Vector3(-1, 5, -10), this.scene);
211+
const camera = new FreeCamera('camera', new Vector3(-2, 5, -10), this.scene);
204212
camera.setTarget(Game.ZeroVector);
205213
///camera.attachControl(this.canvas)
206214

@@ -290,6 +298,14 @@ export class Game {
290298
const walls: Mesh[] = []
291299
for (let counter = 0; counter < 3; ++counter) {
292300
if (counter === skipPartIndex) {
301+
// here probably must be coin with probability of ~70%
302+
if (Math.random() < 0.6) {
303+
this.createCoin(new Vector3(
304+
counter * oneThirdOfWidth - oneThirdOfWidth,
305+
1,
306+
3 + z
307+
))
308+
}
293309
continue;
294310
}
295311

@@ -309,7 +325,7 @@ export class Game {
309325

310326
for (let counter = 0; counter < 20; ++counter) {
311327
const skippingPart = notRepeatedFreeSpaceGenerator();
312-
const row = this.createWallRow(counter * (Game.SingleWallSize.depth * 7) + offset, skippingPart);
328+
const row = this.createWallRow(counter * (Game.SingleWallSize.depth * 10) + offset, skippingPart);
313329
walls.push(...row);
314330
}
315331

@@ -345,4 +361,20 @@ export class Game {
345361
}
346362
}
347363
}
364+
private updateScoreText() {
365+
this.scoreTextRef.innerText = String(this.coinScore);
366+
}
367+
368+
private checkCoinEarned(): void {
369+
for (let i = 0; i < this.coins.length; ++i) {
370+
if (this.ball.intersectsMesh(this.coins[i], true)) {
371+
++this.coinScore;
372+
this.updateScoreText();
373+
this.scene.removeMesh(this.coins[i]);
374+
this.coins[i].dispose();
375+
this.coins.splice(i, 1);
376+
break;
377+
}
378+
}
379+
}
348380
}

games/running-ball-babylonjs/src/main.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@ import { Game } from './Game';
22

33

44
async function main() {
5-
const appCanvas = document.getElementById('game-canvas') as HTMLCanvasElement;
5+
const canvasRef = document.getElementById('game-canvas') as HTMLCanvasElement;
6+
const scoreTextRef = document.getElementById('game-score') as HTMLCanvasElement;
67

7-
new Game(appCanvas);
8+
new Game({ canvasRef, scoreTextRef });
89
}
910

1011

games/running-ball-babylonjs/src/style.css

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@
88

99
body {
1010
overflow-y: hidden;
11+
12+
font-family: "Black Ops One", system-ui;
13+
font-weight: 400;
14+
font-style: normal;
1115
}
1216

1317
.app {
@@ -17,19 +21,42 @@ body {
1721
}
1822

1923
.user-ui {
20-
position: absolute;
21-
bottom: 25px;
22-
left: 50%;
23-
transform: translateX(-50%);
2424
padding: 10px 30px;
2525
background-color: white;
2626
border-radius: 10px;
27-
box-shadow: 0 0 10px rgba(0 , 0, 0, 0.1);
27+
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
2828
width: 100%;
2929
max-width: 300px;
3030
z-index: 9999;
3131
}
3232

33+
.user-ui__bottom {
34+
position: absolute;
35+
bottom: 25px;
36+
left: 50%;
37+
transform: translateX(-50%);
38+
}
39+
40+
.user-ui__top {
41+
position: absolute;
42+
top: 25px;
43+
right: 25px;
44+
}
45+
46+
.coin-img {
47+
width: 5vh;
48+
}
49+
50+
.score {
51+
display: flex;
52+
width: 100%;
53+
justify-content: flex-end;
54+
align-items: center;
55+
column-gap: 5px;
56+
color: black;
57+
font-size: 5vh;
58+
}
59+
3360
.ui-btn {
3461
background-color: #e6e6e6;
3562
box-shadow: inset 0 0 0 rgba(0, 0, 0, 0.12);

games/running-ball-babylonjs/src/types.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,9 @@ export interface Size3D {
22
width: number;
33
height: number;
44
depth: number;
5+
}
6+
7+
export interface GameArgs {
8+
canvasRef: HTMLCanvasElement;
9+
scoreTextRef: HTMLElement;
510
}

0 commit comments

Comments
 (0)