brick-engine-cli 1.0.8 → 1.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +1 -1
- package/package.json +2 -2
- package/src/index.ts +2 -1
- package/templates/src/index.ts +125 -56
package/dist/index.js
CHANGED
|
@@ -12,7 +12,7 @@ function run() {
|
|
|
12
12
|
commander_1.program
|
|
13
13
|
.name("brick-engine-cli")
|
|
14
14
|
.description("CLI to scaffold Brick Engine projects")
|
|
15
|
-
.version("1.0.
|
|
15
|
+
.version("1.0.8");
|
|
16
16
|
commander_1.program
|
|
17
17
|
.command("init <name>")
|
|
18
18
|
.description("Initialize a new Brick Engine project")
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "brick-engine-cli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.10",
|
|
4
4
|
"description": "CLI to scaffold Brick Game projects",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
15
15
|
"@types/inquirer": "^8.2.12",
|
|
16
|
-
"brick-engine-js": "^1.0.
|
|
16
|
+
"brick-engine-js": "^1.0.22",
|
|
17
17
|
"chalk": "^4.1.2",
|
|
18
18
|
"commander": "^11.1.0",
|
|
19
19
|
"dotenv": "^17.3.1",
|
package/src/index.ts
CHANGED
|
@@ -2,12 +2,13 @@ import { program } from "commander";
|
|
|
2
2
|
import { initCommand } from "./commands/init";
|
|
3
3
|
import { publishCommand } from "./commands/publish";
|
|
4
4
|
import chalk from "chalk";
|
|
5
|
+
import { readFileSync } from "fs";
|
|
5
6
|
|
|
6
7
|
export function run() {
|
|
7
8
|
program
|
|
8
9
|
.name("brick-engine-cli")
|
|
9
10
|
.description("CLI to scaffold Brick Engine projects")
|
|
10
|
-
.version("1.0.
|
|
11
|
+
.version("1.0.8");
|
|
11
12
|
|
|
12
13
|
program
|
|
13
14
|
.command("init <name>")
|
package/templates/src/index.ts
CHANGED
|
@@ -1,100 +1,169 @@
|
|
|
1
|
-
import { Game, FontSize, ControlKey, ControlEventType, Sound, FontAlign, FontVerticalAlign, Color } from 'brick-engine-js';
|
|
1
|
+
import { Game, FontSize, ControlKey, ControlEventType, Sound, FontAlign, FontVerticalAlign, Color, Coordinate, StateProperty } from 'brick-engine-js';
|
|
2
2
|
|
|
3
3
|
export default class MyGame extends Game {
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
private playerX = 5;
|
|
5
|
+
private enemies: Coordinate[] = [];
|
|
6
|
+
private spawnRate = 5; // Ticks between spawns
|
|
7
|
+
private initTickInterval = 200;
|
|
6
8
|
|
|
7
9
|
/**
|
|
8
10
|
* Called once after the engine and its modules are fully initialized.
|
|
9
|
-
* Ideal for setting initial state, text sizes, and subscribing to controls.
|
|
10
11
|
*/
|
|
11
12
|
setupGame(): void {
|
|
12
|
-
const {
|
|
13
|
-
|
|
14
|
-
//
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
this.modules.session.register({
|
|
27
|
-
serialId: 'coords',
|
|
28
|
-
deserialize: data => {
|
|
29
|
-
const { x, y } = JSON.parse(data);
|
|
30
|
-
this.x = x;
|
|
31
|
-
this.y = y;
|
|
13
|
+
const { control, session } = this.modules;
|
|
14
|
+
|
|
15
|
+
// Register how game data should be serialized and deserialized for the session
|
|
16
|
+
session.register({
|
|
17
|
+
// Unique identifier for the session data
|
|
18
|
+
serialId: 'game-data',
|
|
19
|
+
// Recieves from LocalStorage and restore the game state
|
|
20
|
+
deserialize: (data: string) => {
|
|
21
|
+
if (!data) return;
|
|
22
|
+
const { playerX, enemies } = JSON.parse(data);
|
|
23
|
+
this.playerX = playerX;
|
|
24
|
+
this.enemies = enemies;
|
|
32
25
|
},
|
|
26
|
+
// Prepare data to be saved to LocalStorage
|
|
33
27
|
serialize: () => {
|
|
34
|
-
return JSON.stringify({
|
|
28
|
+
return JSON.stringify({
|
|
29
|
+
playerX: this.playerX,
|
|
30
|
+
enemies: this.enemies,
|
|
31
|
+
});
|
|
35
32
|
},
|
|
36
33
|
});
|
|
34
|
+
|
|
35
|
+
this.onStart();
|
|
36
|
+
|
|
37
|
+
// Move Left
|
|
38
|
+
control.subscribeForPlayingScreen(ControlKey.LEFT, ControlEventType.PRESSED, () => {
|
|
39
|
+
this.movePlayer(-1);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
// Move Right
|
|
43
|
+
control.subscribeForPlayingScreen(ControlKey.RIGHT, ControlEventType.PRESSED, () => {
|
|
44
|
+
this.movePlayer(1);
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
private movePlayer(dx: number): void {
|
|
49
|
+
const { grid, sound } = this.modules;
|
|
50
|
+
|
|
51
|
+
const newX = this.playerX + dx;
|
|
52
|
+
|
|
53
|
+
if (grid.isCoordinateValid({ x: newX, y: grid.bottomRow })) {
|
|
54
|
+
this.playerX = newX;
|
|
55
|
+
sound.play(Sound.KEY_PRESS);
|
|
56
|
+
}
|
|
37
57
|
}
|
|
38
58
|
|
|
39
59
|
/**
|
|
40
|
-
*
|
|
41
|
-
* This is where movement, collision, and state updates should happen.
|
|
42
|
-
* Logic here ONLY runs when the game is in the PLAYING state.
|
|
60
|
+
* Logic update on every game "tick".
|
|
43
61
|
*/
|
|
44
|
-
update(
|
|
45
|
-
const
|
|
62
|
+
update(): void {
|
|
63
|
+
const { grid, state, score, sound, time } = this.modules;
|
|
64
|
+
|
|
65
|
+
// 1. Move enemies down
|
|
66
|
+
this.enemies = this.enemies.map(enemy => ({ x: enemy.x, y: enemy.y + 1 })).filter(enemy => grid.isCoordinateValid({ x: enemy.x, y: enemy.y }));
|
|
46
67
|
|
|
47
|
-
|
|
48
|
-
|
|
68
|
+
// 2. Spawn new enemy
|
|
69
|
+
if (time.isTickEvery(this.spawnRate)) {
|
|
70
|
+
const spawnX = Math.floor(Math.random() * grid.width);
|
|
71
|
+
this.enemies.push({ x: spawnX, y: grid.topRow });
|
|
49
72
|
}
|
|
50
73
|
|
|
51
|
-
|
|
74
|
+
// 3. Check collisions
|
|
75
|
+
const playerY = grid.bottomRow;
|
|
76
|
+
const collision = this.enemies.find(enemy => enemy.x === this.playerX && enemy.y === playerY);
|
|
77
|
+
|
|
78
|
+
if (collision) {
|
|
79
|
+
sound.play(Sound.EXPLOSION);
|
|
80
|
+
state.triggerGameOver();
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// 4. Update Grid
|
|
85
|
+
grid.resetGrid();
|
|
86
|
+
|
|
87
|
+
// Draw Player
|
|
88
|
+
grid.stampCell({
|
|
89
|
+
coordinate: { x: this.playerX, y: playerY },
|
|
90
|
+
color: Color.CYAN,
|
|
91
|
+
value: 1,
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
// Draw Enemies
|
|
95
|
+
this.enemies.forEach(enemy => {
|
|
96
|
+
grid.stampCell({
|
|
97
|
+
coordinate: enemy,
|
|
98
|
+
color: Color.RED,
|
|
99
|
+
value: 2,
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
// 5. Increase score and difficulty
|
|
104
|
+
score.increaseScore(1);
|
|
105
|
+
|
|
106
|
+
// Increase speed every 50 points
|
|
107
|
+
if (score.score > 0 && score.score % 50 === 0 && score.level < score.maxLevel) {
|
|
108
|
+
time.setTickInterval(this.initTickInterval - 15 * score.level);
|
|
109
|
+
|
|
110
|
+
score.increaseLevel(1);
|
|
111
|
+
|
|
112
|
+
if (score.level < 6) {
|
|
113
|
+
sound.play(Sound.SCORE_2);
|
|
114
|
+
} else {
|
|
115
|
+
sound.play(Sound.SCORE_3);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
52
118
|
}
|
|
53
119
|
|
|
54
120
|
/**
|
|
55
|
-
*
|
|
56
|
-
* Used for visual-only effects that don't impact game state (e.g. animations).
|
|
57
|
-
* Runs during PLAYING and PAUSED states.
|
|
121
|
+
* Visual-only rendering (HUD elements).
|
|
58
122
|
*/
|
|
59
|
-
render(): void {
|
|
60
|
-
const { text } = this.modules;
|
|
61
|
-
|
|
62
|
-
text.setTextSize(FontSize.EXTRA_SMALL);
|
|
63
|
-
text.setTextAlign(FontAlign.LEFT, FontVerticalAlign.TOP);
|
|
64
|
-
text.textOnDisplay('press', { x: 0.05, y: 0.05 });
|
|
65
|
-
text.textOnDisplay('action', { x: 0.05, y: 0.1 });
|
|
66
|
-
}
|
|
123
|
+
render(): void {}
|
|
67
124
|
|
|
68
125
|
/**
|
|
69
|
-
*
|
|
70
|
-
* Usually displays the title and "Press Start" instructions.
|
|
126
|
+
* Title Screen Layout.
|
|
71
127
|
*/
|
|
72
128
|
drawTitleScreen(): void {
|
|
73
129
|
const { text } = this.modules;
|
|
74
130
|
|
|
75
131
|
text.setTextSize(FontSize.MEDIUM);
|
|
76
132
|
text.setTextAlign(FontAlign.CENTER, FontVerticalAlign.CENTER);
|
|
77
|
-
text.textOnDisplay('
|
|
133
|
+
text.textOnDisplay('DODGE BRICK', { x: 0.5, y: 0.3 });
|
|
78
134
|
|
|
79
135
|
text.setTextSize(FontSize.SMALL);
|
|
80
|
-
text.textOnDisplay('
|
|
81
|
-
text.textOnDisplay('drawTitleScreen', { x: 0.5, y: 0.55 });
|
|
136
|
+
text.textOnDisplay('USE ARROWS TO MOVE', { x: 0.5, y: 0.5 });
|
|
82
137
|
|
|
83
138
|
text.setTextSize(FontSize.MEDIUM);
|
|
84
139
|
text.textOnDisplay('PRESS START', { x: 0.5, y: 0.8 });
|
|
85
140
|
}
|
|
86
141
|
|
|
87
142
|
/**
|
|
88
|
-
*
|
|
89
|
-
* Replaces standard `render()` calls to show scores or restart messages.
|
|
90
|
-
* Usually displays the game over message and "Press START to restart" instructions, and the final score.
|
|
143
|
+
* Game Over Screen Layout.
|
|
91
144
|
*/
|
|
92
145
|
drawGameOverScreen(): void {
|
|
93
|
-
|
|
146
|
+
const { text, score } = this.modules;
|
|
94
147
|
|
|
95
|
-
|
|
148
|
+
text.setTextAlign(FontAlign.CENTER, FontVerticalAlign.CENTER);
|
|
149
|
+
text.setTextSize(FontSize.MEDIUM);
|
|
150
|
+
text.textOnDisplay('GAME OVER', { x: 0.5, y: 0.4 });
|
|
151
|
+
|
|
152
|
+
text.setTextSize(FontSize.SMALL);
|
|
153
|
+
text.textOnDisplay(`FINAL SCORE: ${score.score}`, { x: 0.5, y: 0.55 });
|
|
154
|
+
|
|
155
|
+
text.setTextSize(FontSize.MEDIUM);
|
|
156
|
+
text.textOnDisplay('PRESS START', { x: 0.5, y: 0.8 });
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Reset game local state when starting/restarting.
|
|
161
|
+
*/
|
|
162
|
+
onStart(): void {
|
|
163
|
+
const { score, time } = this.modules;
|
|
96
164
|
|
|
97
|
-
this.
|
|
98
|
-
this.
|
|
165
|
+
this.playerX = 5;
|
|
166
|
+
this.enemies = [];
|
|
167
|
+
time.setTickInterval(this.initTickInterval - 15 * score.level);
|
|
99
168
|
}
|
|
100
169
|
}
|