Skip to content

Commit b9fbe01

Browse files
committed
update
1 parent f2dc094 commit b9fbe01

File tree

13 files changed

+83
-85
lines changed

13 files changed

+83
-85
lines changed

.prettierrc.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"printWidth": 120,
3+
"quoteProps": "preserve"
4+
}

README.md

Lines changed: 38 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -70,38 +70,46 @@ To use a middleware in another middleware we use the `use` method:
7070
this.use(new AnotherMiddleware());
7171
```
7272

73-
### Watermelon: Middlewares
73+
### 8-Ball: Middlewares
7474

75-
In the Watermelon game we will develop the following middlewares:
75+
In this game we will develop the following middlewares:
7676
- Main: Entry point of the application
77-
- Gameplay: Implements game logic
78-
- Physics: Implements physics simulation
79-
- Terminal: Implements user-interface
8077
- FrameLoop: Implements game loop
78+
- Terminal: Implements rendering and user-input
79+
- BilliardsPhysics: Billiards table physics simulation
80+
- PoolTable: Pool table geometrical configuration (table, pockets, etc.)
81+
- Cue: Implements cue sticks
82+
- EightBall: 8-ball game logic
8183

82-
Game objects such as fruits and score are stored in the context. Gameplay middleware manages game objects and state, and receives events such as drop-next-fruit, move-next-fruit from Terminal, and collide-fruits, collide-top from Physics.
84+
Game data such as balls and score are stored in the application context, and are used by all middlewares. Middlewares communicate via events, and don't have direct access to each other.
8385

84-
Terminal middleware accesses game objects and state from the context. and renders them on screen using SVG. Terminal also collects user pointer input and then sends drop-next-fruit and move-next-fruit, which are used by Gameplay.
85-
86-
Physics middleware also accesses game objects and state from the context. Physics adds fruits to physics simulation, updates fruits position, and collect collision events from simulation and sends collide-fruits, collide-fruit-top to gameplay.
87-
88-
FrameLoop middleware implements the game loop. It sends frame-loop event to all middlewares in each frame.
89-
90-
We will discuss each middleware further in the following sections.
86+
Here is how our Main class looks like:
9187

9288
```ts
9389
class Main extends Middleware {
9490
constructor() {
9591
super();
96-
this.use(new Gameplay());
97-
this.use(new Physics());
98-
this.use(new Terminal());
9992
this.use(new FrameLoop());
93+
this.use(new EightBall());
94+
this.use(new PoolTable());
95+
this.use(new Cue());
96+
this.use(new BilliardsPhysics());
97+
this.use(new Terminal());
10098
}
10199
}
102-
```
100+
```
103101

104-
### Watermelon: FrameLoop
102+
We will discuss each middleware further in the following sections. By breaking down the application into loosely-coupled middlewares we can reduce complexity of the application, and make it easier to maintain and extend.
103+
104+
Terminal middleware accesses game objects and state from the context. and renders them on screen using SVG. Terminal also collects user pointer input and then sends drop-next-fruit and move-next-fruit, which are used by Gameplay.
105+
106+
Physics middleware also accesses game objects and state from the context. Physics adds fruits to physics simulation, updates fruits position, and collect collision events from simulation and sends collide-fruits, collide-fruit-top to gameplay.
107+
108+
FrameLoop middleware implements the game loop. It sends frame-loop event to all middlewares in each frame.
109+
110+
EightBall middleware manages game state, and receives events such as drop-next-fruit, move-next-fruit from Terminal, and collide-fruits, collide-top from Physics.
111+
112+
### FrameLoop Middleware
105113

106114
Polymatic does not implement game loop, or any other game specific functions. However, it's very simple to use a middlewares to implement a game loop.
107115

@@ -137,11 +145,11 @@ class Physics extends Middleware {
137145
}
138146
```
139147

140-
Please note that here we used a fixed frame loop. In this repository source code we implemented a variable frame loop which is slightly more complicated.
148+
Please note that here we implemented a fixed frame loop. In this repository source code there is a variable frame loop which is slightly more complicated.
141149

142-
### Watermelon: Gameplay
150+
### EightBall Middleware
143151

144-
Next, let's implement the gameplay. In the gameplay we implement the logic for dropping new fruits, merging them, and increasing user score.
152+
Next, let's implement the 8-ball gameplay. In the EightBall middleware we implement the logic, such as when player pockets a ball.
145153

146154
We store all objects in the context so that they can be accessed by all middlewares, and we listen to events from other middlewares.
147155

@@ -175,11 +183,15 @@ class Gameplay extends Middleware {
175183
}
176184
```
177185

186+
### Cue Middleware
187+
Cue middleware implements the cue stick. Cue middleware receives user pointer input events from Terminal, and sends move-cue, and shot-cue events, to BilliardsPhysic middleware.
188+
189+
178190
### Data Driver
179191

180-
Middlewares shares game object via context. In some middlewares we need to assign new components to game objects. For example in this project in the Terminal middleware we need to add a new svg element for each fruit, and add new bodies to the physics simulation in the Physics middleware. Data drivers are used by middlewares to dynamically add new components to game objects.
192+
Middlewares share game objects in context. In some middlewares we need to assign new components to game objects. For example for each ball we need to create an SVG element in the Terminal middleware, and add a new physics simulation body int the Physics middleware. Data drivers are used by middlewares to dynamically add new components to game objects.
181193

182-
To use data-drivers we first create a Dataset, and then add Drivers to the dataset.
194+
To use data-drivers we first create a Dataset to track entities, and then add Drivers to the dataset to manage components.
183195

184196
Dataset needs to uniquely identify objects between updates, so it requires a key function. We can create a dataset by extending the Dataset class, or using the `Dataset.create` method:
185197

@@ -224,9 +236,9 @@ const driver = Driver.create<Fruit, Element>({
224236
dataset.addDriver(driver);
225237
```
226238

227-
### Watermelon: Physics with Planck/Box2D
239+
### BilliardsPhysics with Planck/Box2D
228240

229-
Physics middleware adds physics simulation to fruits and detects collisions. When two similar fruits collide, physics middleware emits an event to informs gameplay middleware about the collision to merge two fruits.
241+
Physics middleware adds movement and collision detection to balls and table. When two similar fruits collide, physics middleware emits an event to informs gameplay middleware about the collision to merge two fruits.
230242

231243
```ts
232244
export class Physics extends Middleware<MainContext> {
@@ -293,7 +305,7 @@ export class Physics extends Middleware<MainContext> {
293305

294306
```
295307
296-
### Watermelon: Terminal with SVG
308+
### Terminal with SVG
297309
298310
Now we need to implement the game Terminal (i.e. user-interface). Terminal renders game objects and score, and collects user input such as pointer events.
299311

docs/assets/index-Chi0c8Qx.css

Lines changed: 0 additions & 1 deletion
This file was deleted.

docs/assets/index-B9yXfPCS.js renamed to docs/assets/index-DUu6bOcc.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/assets/index-L93qdzHF.css

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/index.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@
77
content="user-scalable=no, width=device-width, height=device-height, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0" />
88
<meta name="theme-color" content="#323130" />
99
<meta name="color-scheme" content="dark" />
10-
<script type="module" crossorigin src="/polymatic-example-eight-ball/assets/index-B9yXfPCS.js"></script>
11-
<link rel="stylesheet" crossorigin href="/polymatic-example-eight-ball/assets/index-Chi0c8Qx.css">
10+
<script type="module" crossorigin src="/polymatic-example-eight-ball/assets/index-DUu6bOcc.js"></script>
11+
<link rel="stylesheet" crossorigin href="/polymatic-example-eight-ball/assets/index-L93qdzHF.css">
1212
</head>
1313

1414
<body>
15-
<svg id="polymatic-watermelon" class="terminal" viewBox="-2.5 -5 5 10"></svg>
15+
<svg id="polymatic-eight-ball" class="terminal" viewBox="-2.5 -5 5 10"></svg>
1616
</body>
1717

1818
</html>

index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
</head>
1212

1313
<body>
14-
<svg id="polymatic-watermelon" class="terminal" viewBox="-2.5 -5 5 10"></svg>
14+
<svg id="polymatic-eight-ball" class="terminal" viewBox="-2.5 -5 5 10"></svg>
1515
<script type="module" src="./index"></script>
1616
</body>
1717

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"name": "polymatic-billiard",
2+
"name": "polymatic-eight-ball",
33
"private": true,
44
"version": "0.0.0",
55
"type": "module",

src/Cue.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ class Point {
88
y: number;
99
}
1010

11-
export class Cue0 {
11+
export class CueStick {
1212
key = "cue-" + Date.now();
1313
type = "cue" as const;
1414
ball: Ball;
@@ -24,6 +24,7 @@ export class Cue extends Middleware<MainContext> {
2424
this.on("user-pointer-end", this.handlePointerUp);
2525
this.on("frame-loop", this.handleFrameLoop);
2626
}
27+
2728
handleFrameLoop() {
2829
if (!this.context.cue) return;
2930
const cue = this.context.cue;
@@ -34,7 +35,7 @@ export class Cue extends Middleware<MainContext> {
3435
handlePointerStart(point: Point) {
3536
const ball = this.context.balls.find((ball) => ball.color === "white");
3637
if (!ball) return;
37-
this.context.cue = new Cue0();
38+
this.context.cue = new CueStick();
3839
this.context.cue.ball = ball;
3940
this.context.cue.start.x = ball.position.x;
4041
this.context.cue.start.y = ball.position.y;

src/Main.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@ import { Middleware } from "polymatic";
55
import { Ball, Physics, Pocket, Rail, Table } from "./Physics";
66
import { PoolTable } from "./PoolTable";
77
import { EightBall } from "./EightBall";
8-
import { TerminalSvg } from "./TerminalSvg";
8+
import { Terminal } from "./Terminal";
99
import { FrameLoop } from "./FrameLoop";
10-
import { Cue, Cue0 } from "./Cue";
10+
import { Cue, CueStick } from "./Cue";
1111

1212
export class MainContext {
13-
cue: Cue0 | null;
13+
cue: CueStick | null;
1414
balls: Ball[];
1515
rails: Rail[];
1616
pockets: Pocket[];
@@ -34,6 +34,6 @@ export class Main extends Middleware<MainContext> {
3434
this.use(new EightBall());
3535
this.use(new Physics());
3636
this.use(new Cue());
37-
this.use(new TerminalSvg());
37+
this.use(new Terminal());
3838
}
3939
}

0 commit comments

Comments
 (0)