create-lagom-game 0.0.1-beta.1
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/LICENSE +21 -0
- package/bin/create-lagom-game.js +29 -0
- package/package.json +19 -0
- package/template/index.html +13 -0
- package/template/package.json +19 -0
- package/template/src/GameTemplate.ts +84 -0
- package/template/src/Platformer.ts +132 -0
- package/template/src/Pong.ts +258 -0
- package/template/src/art/level.json +359 -0
- package/template/src/assets/flip_0.1.wav +0 -0
- package/template/src/assets/mute_button_16x16.png +0 -0
- package/template/src/assets/pixeloid.ttf +0 -0
- package/template/src/assets/retro.ttf +0 -0
- package/template/src/main.css +4 -0
- package/template/src/main.ts +17 -0
- package/template/src/util/SoundManager.ts +102 -0
- package/template/src/vite-env.d.ts +1 -0
- package/template/tsconfig.json +15 -0
- package/template/vite.config.ts +6 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2020 Peter Mandile
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import path from "path";
|
|
3
|
+
import fs from "fs-extra";
|
|
4
|
+
import { fileURLToPath } from "url";
|
|
5
|
+
import prompts from "prompts";
|
|
6
|
+
|
|
7
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
8
|
+
|
|
9
|
+
async function main() {
|
|
10
|
+
const { projectName } = await prompts({
|
|
11
|
+
type: "text",
|
|
12
|
+
name: "projectName",
|
|
13
|
+
message: "Project name",
|
|
14
|
+
initial: "my-lagom-game"
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
const target = path.resolve(process.cwd(), projectName);
|
|
18
|
+
const template = path.resolve(__dirname, "../template");
|
|
19
|
+
|
|
20
|
+
await fs.copy(template, target);
|
|
21
|
+
|
|
22
|
+
console.log(`\nCreated ${projectName}`);
|
|
23
|
+
console.log(`\nNext steps:`);
|
|
24
|
+
console.log(` cd ${projectName}`);
|
|
25
|
+
console.log(` pnpm install`);
|
|
26
|
+
console.log(` pnpm dev`);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
main();
|
package/package.json
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "create-lagom-game",
|
|
3
|
+
"version": "0.0.1-beta.1",
|
|
4
|
+
"bin": {
|
|
5
|
+
"create-lagom-game": "bin/create-lagom-game.js"
|
|
6
|
+
},
|
|
7
|
+
"files": [
|
|
8
|
+
"bin",
|
|
9
|
+
"template"
|
|
10
|
+
],
|
|
11
|
+
"dependencies": {
|
|
12
|
+
"prompts": "^2.4.2",
|
|
13
|
+
"fs-extra": "^11.3.3"
|
|
14
|
+
},
|
|
15
|
+
"devDependencies": {
|
|
16
|
+
"typescript": "^5.6.2",
|
|
17
|
+
"vite": "7.1.11"
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
|
+
<title>Lagom</title>
|
|
8
|
+
</head>
|
|
9
|
+
<body>
|
|
10
|
+
<div id="app"></div>
|
|
11
|
+
<script type="module" src="/src/main.ts"></script>
|
|
12
|
+
</body>
|
|
13
|
+
</html>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "lagom-game-template",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"scripts": {
|
|
6
|
+
"dev": "vite",
|
|
7
|
+
"build": "tsc && vite build",
|
|
8
|
+
"preview": "vite preview",
|
|
9
|
+
"deploy": "tsc && vite build && butler push dist USERNAME/GAMENAME:html5"
|
|
10
|
+
},
|
|
11
|
+
"dependencies": {
|
|
12
|
+
"lagom-engine": "workspace:^"
|
|
13
|
+
},
|
|
14
|
+
"devDependencies": {
|
|
15
|
+
"typescript": "^5.6.2",
|
|
16
|
+
"vite": "7.1.11"
|
|
17
|
+
},
|
|
18
|
+
"packageManager": "pnpm@10.15.1"
|
|
19
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { ActionOnPress, AudioAtlas, Entity, FrameTriggerSystem, Game, Log, LogLevel, Scene, TextDisp, TimerSystem } from "lagom-engine";
|
|
2
|
+
import { SoundManager } from "./util/SoundManager";
|
|
3
|
+
|
|
4
|
+
class TitleScene extends Scene {
|
|
5
|
+
onAdded() {
|
|
6
|
+
super.onAdded();
|
|
7
|
+
|
|
8
|
+
this.addGUIEntity(new SoundManager());
|
|
9
|
+
this.addGlobalSystem(new TimerSystem());
|
|
10
|
+
this.addGlobalSystem(new FrameTriggerSystem());
|
|
11
|
+
|
|
12
|
+
this.addGUIEntity(new Entity("title")).addComponent(
|
|
13
|
+
new TextDisp(100, 10, "GAME NAME", {
|
|
14
|
+
fontFamily: "retro",
|
|
15
|
+
fill: 0xffffff,
|
|
16
|
+
}),
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
this.addSystem(
|
|
20
|
+
new ActionOnPress(() => {
|
|
21
|
+
this.game.setScene(new MainScene(this.game));
|
|
22
|
+
}),
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
class MainScene extends Scene {
|
|
28
|
+
onAdded() {
|
|
29
|
+
super.onAdded();
|
|
30
|
+
|
|
31
|
+
this.addGUIEntity(new SoundManager());
|
|
32
|
+
this.addGlobalSystem(new TimerSystem());
|
|
33
|
+
this.addGlobalSystem(new FrameTriggerSystem());
|
|
34
|
+
|
|
35
|
+
this.addGUIEntity(new Entity("main scene")).addComponent(
|
|
36
|
+
new TextDisp(100, 10, "MAIN SCENE", {
|
|
37
|
+
fontFamily: "pixeloid",
|
|
38
|
+
fill: 0xffffff,
|
|
39
|
+
}),
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export class GameTemplate extends Game {
|
|
45
|
+
startScene = () => new TitleScene(this);
|
|
46
|
+
resourceLoad = async () => {
|
|
47
|
+
await this.resourceLoader.autoLoad();
|
|
48
|
+
|
|
49
|
+
this.resourceLoader.getSound("flip").play();
|
|
50
|
+
console.log("loaded all resources");
|
|
51
|
+
// await this.resourceLoader.addResource("mute_button", muteButtonSpr, {
|
|
52
|
+
// tileHeight: 16,
|
|
53
|
+
// tileWidth: 16,
|
|
54
|
+
// });
|
|
55
|
+
};
|
|
56
|
+
static GAME_WIDTH = 512;
|
|
57
|
+
static GAME_HEIGHT = 512;
|
|
58
|
+
|
|
59
|
+
static muted = false;
|
|
60
|
+
static musicPlaying = false;
|
|
61
|
+
static audioAtlas: AudioAtlas = new AudioAtlas();
|
|
62
|
+
|
|
63
|
+
constructor() {
|
|
64
|
+
super({
|
|
65
|
+
width: GameTemplate.GAME_WIDTH,
|
|
66
|
+
height: GameTemplate.GAME_HEIGHT,
|
|
67
|
+
resolution: 1,
|
|
68
|
+
backgroundColor: 0x200140,
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
// Set the global log level
|
|
72
|
+
Log.logLevel = LogLevel.INFO;
|
|
73
|
+
|
|
74
|
+
// Load an empty scene while we async load the resources for the main one
|
|
75
|
+
// this.setScene(new Scene(this));
|
|
76
|
+
|
|
77
|
+
// TODO sound loader and font loader need to go in the actual loader
|
|
78
|
+
// Import sounds and set their properties
|
|
79
|
+
// const music = GameTemplate.audioAtlas.load("music", "src/assets/ADD_ME")
|
|
80
|
+
// .loop(true)
|
|
81
|
+
// .volume(0.3);
|
|
82
|
+
|
|
83
|
+
}
|
|
84
|
+
}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CircleSatCollider,
|
|
3
|
+
CollisionMatrix,
|
|
4
|
+
Component,
|
|
5
|
+
Entity,
|
|
6
|
+
Game,
|
|
7
|
+
Key,
|
|
8
|
+
Log,
|
|
9
|
+
LogLevel,
|
|
10
|
+
newSystem,
|
|
11
|
+
RectSatCollider,
|
|
12
|
+
RenderCircle,
|
|
13
|
+
RenderRect,
|
|
14
|
+
SatCollisionSystem,
|
|
15
|
+
Scene,
|
|
16
|
+
types,
|
|
17
|
+
} from "lagom-engine";
|
|
18
|
+
|
|
19
|
+
enum Layers {
|
|
20
|
+
Guy,
|
|
21
|
+
Wall,
|
|
22
|
+
WallCheck,
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
class MoveMe extends Component {
|
|
26
|
+
constructor(public vel: number = 0) {
|
|
27
|
+
super();
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
class Gravity extends Component {}
|
|
32
|
+
|
|
33
|
+
class Grounded extends Component {
|
|
34
|
+
constructor(public onGround: boolean = false) {
|
|
35
|
+
super();
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
class MainScene extends Scene {
|
|
40
|
+
onAdded() {
|
|
41
|
+
super.onAdded();
|
|
42
|
+
|
|
43
|
+
const matrix = new CollisionMatrix();
|
|
44
|
+
matrix.addCollision(Layers.Guy, Layers.Wall);
|
|
45
|
+
matrix.addCollision(Layers.Wall, Layers.WallCheck);
|
|
46
|
+
this.addGlobalSystem(new SatCollisionSystem(matrix));
|
|
47
|
+
|
|
48
|
+
const e2 = this.addEntity(new Entity("", 105, 100));
|
|
49
|
+
e2.addComponent(new CircleSatCollider({ layer: Layers.Guy, radius: 10 })).onTrigger.register((caller, data) => {
|
|
50
|
+
if (data.other.layer == Layers.Wall) {
|
|
51
|
+
// console.log("hit")
|
|
52
|
+
caller.parent.transform.x -= data.result.overlapV.x;
|
|
53
|
+
caller.parent.transform.y -= data.result.overlapV.y;
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
const grounded = e2.addComponent(new Grounded());
|
|
57
|
+
const groundChild = e2.addChild(new Entity("groundCheck", 0, 12));
|
|
58
|
+
const groundCheck = groundChild.addComponent(
|
|
59
|
+
new CircleSatCollider({
|
|
60
|
+
layer: Layers.WallCheck,
|
|
61
|
+
radius: 12,
|
|
62
|
+
}),
|
|
63
|
+
);
|
|
64
|
+
groundCheck.onTriggerEnter.register((caller, data) => {
|
|
65
|
+
console.log("grounded");
|
|
66
|
+
if (data.other.layer == Layers.Wall) {
|
|
67
|
+
grounded.onGround = true;
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
groundCheck.onTriggerExit.register((caller, data) => {
|
|
72
|
+
console.log("no grounded");
|
|
73
|
+
if (data.other.layer == Layers.Wall) {
|
|
74
|
+
grounded.onGround = false;
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
groundChild.addComponent(new RenderCircle({ radius: 2 }, 0x00ffff, undefined));
|
|
78
|
+
|
|
79
|
+
e2.addComponent(new RenderCircle({ radius: 10 }));
|
|
80
|
+
|
|
81
|
+
e2.addComponent(new MoveMe());
|
|
82
|
+
e2.addComponent(new Gravity());
|
|
83
|
+
|
|
84
|
+
const floor = this.addEntity(new Entity("floor", 0, 150));
|
|
85
|
+
floor.addComponent(new RectSatCollider({ layer: Layers.Wall, height: 10, width: 200 }));
|
|
86
|
+
floor.addComponent(new RenderRect({ width: 200, height: 10 }));
|
|
87
|
+
|
|
88
|
+
this.addFnSystem(
|
|
89
|
+
newSystem([MoveMe], (d, e, moveme) => {
|
|
90
|
+
if (this.game.keyboard.isKeyDown(Key.KeyA)) {
|
|
91
|
+
e.transform.position.x -= d * 0.1;
|
|
92
|
+
}
|
|
93
|
+
if (this.game.keyboard.isKeyDown(Key.KeyD)) {
|
|
94
|
+
e.transform.position.x += d * 0.1;
|
|
95
|
+
}
|
|
96
|
+
if (this.game.keyboard.isKeyPressed(Key.KeyW) && grounded.onGround) {
|
|
97
|
+
moveme.vel = -50;
|
|
98
|
+
}
|
|
99
|
+
}),
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
this.addFixedFnSystem(
|
|
103
|
+
newSystem(types(MoveMe, Gravity), (delta, entity, moveme, gravity) => {
|
|
104
|
+
moveme.vel += delta * 0.2;
|
|
105
|
+
if (moveme.vel > 20) {
|
|
106
|
+
moveme.vel = 20;
|
|
107
|
+
}
|
|
108
|
+
entity.transform.y += moveme.vel * delta * 0.01;
|
|
109
|
+
}),
|
|
110
|
+
);
|
|
111
|
+
|
|
112
|
+
// this.addFnSystem(newSystem([MoveMe, MoveMeToo], (d, e) => {}))
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export class Platformer extends Game {
|
|
117
|
+
resourceLoad = async () => {};
|
|
118
|
+
startScene = () => new MainScene(this);
|
|
119
|
+
static GAME_WIDTH = 512;
|
|
120
|
+
static GAME_HEIGHT = 512;
|
|
121
|
+
|
|
122
|
+
constructor() {
|
|
123
|
+
super({
|
|
124
|
+
width: Platformer.GAME_WIDTH,
|
|
125
|
+
height: Platformer.GAME_HEIGHT,
|
|
126
|
+
resolution: 1,
|
|
127
|
+
backgroundColor: 0x200140,
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
Log.logLevel = LogLevel.INFO;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
// import {
|
|
2
|
+
// CollisionMatrix,
|
|
3
|
+
// CollisionSystem,
|
|
4
|
+
// Component,
|
|
5
|
+
// CType,
|
|
6
|
+
// Diagnostics,
|
|
7
|
+
// DiscreteCollisionSystem,
|
|
8
|
+
// Entity,
|
|
9
|
+
// Game,
|
|
10
|
+
// Key,
|
|
11
|
+
// Observable,
|
|
12
|
+
// RectCollider,
|
|
13
|
+
// RenderRect,
|
|
14
|
+
// Scene,
|
|
15
|
+
// System,
|
|
16
|
+
// TextDisp
|
|
17
|
+
// } from "lagom-engine";
|
|
18
|
+
//
|
|
19
|
+
// enum Layers {
|
|
20
|
+
// leftpaddle,
|
|
21
|
+
// ball,
|
|
22
|
+
// rightpaddle
|
|
23
|
+
// }
|
|
24
|
+
//
|
|
25
|
+
// enum PaddleSide {
|
|
26
|
+
// left,
|
|
27
|
+
// right
|
|
28
|
+
// }
|
|
29
|
+
//
|
|
30
|
+
// export class Pong extends Game {
|
|
31
|
+
// constructor() {
|
|
32
|
+
// super({width: 800, height: 600, resolution: 1, backgroundColor: 0x000000});
|
|
33
|
+
// this.setScene(new MainScene(this));
|
|
34
|
+
// }
|
|
35
|
+
// }
|
|
36
|
+
//
|
|
37
|
+
// class MainScene extends Scene {
|
|
38
|
+
// onAdded() {
|
|
39
|
+
// super.onAdded();
|
|
40
|
+
//
|
|
41
|
+
// const collisionMatrix = new CollisionMatrix();
|
|
42
|
+
// collisionMatrix.addCollision(Layers.leftpaddle, Layers.ball);
|
|
43
|
+
// collisionMatrix.addCollision(Layers.rightpaddle, Layers.ball);
|
|
44
|
+
//
|
|
45
|
+
// this.addGlobalSystem(new DiscreteCollisionSystem(collisionMatrix));
|
|
46
|
+
//
|
|
47
|
+
// this.addEntity(new Paddle(30, 300, PaddleSide.left));
|
|
48
|
+
// this.addEntity(new Paddle(740, 300, PaddleSide.right));
|
|
49
|
+
// this.addEntity(new Ball(400, 200));
|
|
50
|
+
// const scoreboard = new Scoreboard(400, 50);
|
|
51
|
+
// this.addEntity(scoreboard);
|
|
52
|
+
// this.addEntity(new Diagnostics("red"));
|
|
53
|
+
//
|
|
54
|
+
// this.addSystem(new PlayerMover());
|
|
55
|
+
// this.addSystem(new BallMover());
|
|
56
|
+
// this.addSystem(new ScoreSystem(scoreboard.score));
|
|
57
|
+
// }
|
|
58
|
+
// }
|
|
59
|
+
//
|
|
60
|
+
// class Paddle extends Entity {
|
|
61
|
+
// private static width = 30;
|
|
62
|
+
// private static height = 80;
|
|
63
|
+
//
|
|
64
|
+
// constructor(x: number, y: number, private side: PaddleSide) {
|
|
65
|
+
// super("paddle", x, y);
|
|
66
|
+
// }
|
|
67
|
+
//
|
|
68
|
+
// onAdded() {
|
|
69
|
+
// super.onAdded();
|
|
70
|
+
//
|
|
71
|
+
// if (this.side === PaddleSide.left) {
|
|
72
|
+
// this.addComponent(new PlayerControlled(Key.KeyW, Key.KeyS));
|
|
73
|
+
// } else {
|
|
74
|
+
// this.addComponent(new PlayerControlled(Key.ArrowUp, Key.ArrowDown));
|
|
75
|
+
// }
|
|
76
|
+
//
|
|
77
|
+
// this.addComponent(new RenderRect(0, 0, Paddle.width, Paddle.height, 0xffffff, 0xffffff));
|
|
78
|
+
//
|
|
79
|
+
// this.addComponent(
|
|
80
|
+
// new RectCollider(<CollisionSystem<any>>this.getScene().getGlobalSystem<CollisionSystem<any>>(CollisionSystem),
|
|
81
|
+
// {
|
|
82
|
+
// layer: Layers.leftpaddle,
|
|
83
|
+
// height: Paddle.height, width: Paddle.width
|
|
84
|
+
// }));
|
|
85
|
+
// }
|
|
86
|
+
// }
|
|
87
|
+
//
|
|
88
|
+
// class PlayerControlled extends Component {
|
|
89
|
+
// constructor(public upKey: Key, public downKey: Key) {
|
|
90
|
+
// super();
|
|
91
|
+
// }
|
|
92
|
+
// }
|
|
93
|
+
//
|
|
94
|
+
// class PlayerMover extends System<[PlayerControlled]> {
|
|
95
|
+
// types: [CType<PlayerControlled>] = [PlayerControlled];
|
|
96
|
+
//
|
|
97
|
+
// private readonly moveSpeed = 40;
|
|
98
|
+
//
|
|
99
|
+
// runOnEntities(delta: number, entity: Entity, playerControlled: PlayerControlled): void {
|
|
100
|
+
//
|
|
101
|
+
// if (this.scene.game.keyboard.isKeyDown(playerControlled.upKey) && entity.transform.position.y > 0) {
|
|
102
|
+
// entity.transform.position.y += this.moveSpeed * -1 * (delta / 100);
|
|
103
|
+
// }
|
|
104
|
+
// if (this.scene.game.keyboard.isKeyDown(playerControlled.downKey)
|
|
105
|
+
// && entity.transform.position.y + entity.transform.height < entity.getScene().getGame().renderer.height) {
|
|
106
|
+
// entity.transform.position.y += this.moveSpeed * (delta / 100);
|
|
107
|
+
// }
|
|
108
|
+
// }
|
|
109
|
+
// }
|
|
110
|
+
//
|
|
111
|
+
//
|
|
112
|
+
// class BallMovement extends Component {
|
|
113
|
+
// xSpeed: number;
|
|
114
|
+
// ySpeed: number;
|
|
115
|
+
//
|
|
116
|
+
// constructor() {
|
|
117
|
+
// super();
|
|
118
|
+
// this.xSpeed = -30;
|
|
119
|
+
// this.ySpeed = 30;
|
|
120
|
+
// }
|
|
121
|
+
// }
|
|
122
|
+
//
|
|
123
|
+
//
|
|
124
|
+
// class BallMover extends System<[BallMovement]> {
|
|
125
|
+
// types: [CType<BallMovement>] = [BallMovement];
|
|
126
|
+
//
|
|
127
|
+
// topBounce: number;
|
|
128
|
+
// bottomBounce: number;
|
|
129
|
+
//
|
|
130
|
+
// constructor() {
|
|
131
|
+
// super();
|
|
132
|
+
// this.topBounce = 10;
|
|
133
|
+
// this.bottomBounce = 600 - 10;
|
|
134
|
+
// }
|
|
135
|
+
//
|
|
136
|
+
// runOnEntities(delta: number, entity: Entity, ball: BallMovement): void {
|
|
137
|
+
//
|
|
138
|
+
// const bodyY = entity.transform.y;
|
|
139
|
+
// if (bodyY > this.bottomBounce || bodyY < this.topBounce) {
|
|
140
|
+
// ball.ySpeed *= -1;
|
|
141
|
+
// }
|
|
142
|
+
// entity.transform.x += ball.xSpeed * (delta / 100);
|
|
143
|
+
// entity.transform.y += ball.ySpeed * (delta / 100);
|
|
144
|
+
// }
|
|
145
|
+
// }
|
|
146
|
+
//
|
|
147
|
+
// class Ball extends Entity {
|
|
148
|
+
// constructor(x: number, y: number) {
|
|
149
|
+
// super("ball", x, y);
|
|
150
|
+
// }
|
|
151
|
+
//
|
|
152
|
+
// onAdded(): void {
|
|
153
|
+
// super.onAdded();
|
|
154
|
+
//
|
|
155
|
+
// const rect = new RenderRect(0, 0, 10, 10, 0xffffff, 0xffffff);
|
|
156
|
+
// this.addComponent(rect);
|
|
157
|
+
// this.addComponent(new BallMovement());
|
|
158
|
+
//
|
|
159
|
+
// const collider = this.addComponent(
|
|
160
|
+
// new RectCollider(<CollisionSystem<any>>this.getScene().getGlobalSystem<CollisionSystem<any>>(CollisionSystem),
|
|
161
|
+
// {
|
|
162
|
+
// xOff: 0, yOff: 0, layer: Layers.ball, rotation: 0,
|
|
163
|
+
// height: 10, width: 10
|
|
164
|
+
// }));
|
|
165
|
+
//
|
|
166
|
+
// collider.onTriggerEnter.register(() => {
|
|
167
|
+
// const movement = this.getComponent<BallMovement>(BallMovement);
|
|
168
|
+
// if (movement !== null) {
|
|
169
|
+
// movement.xSpeed *= -1;
|
|
170
|
+
// }
|
|
171
|
+
// });
|
|
172
|
+
// }
|
|
173
|
+
// }
|
|
174
|
+
//
|
|
175
|
+
// class Scoreboard extends Entity {
|
|
176
|
+
// score: Score;
|
|
177
|
+
//
|
|
178
|
+
// constructor(x: number, y: number) {
|
|
179
|
+
// super("scoreboard", x, y);
|
|
180
|
+
// this.score = new Score();
|
|
181
|
+
// }
|
|
182
|
+
//
|
|
183
|
+
// onAdded() {
|
|
184
|
+
// super.onAdded();
|
|
185
|
+
//
|
|
186
|
+
// const p1Label = new TextDisp(-30, 0, this.score.player1Score.toString(), {fill: 0x777777});
|
|
187
|
+
// this.addComponent(p1Label);
|
|
188
|
+
// this.score.onP1Score.register((_, num) => {
|
|
189
|
+
// p1Label.pixiObj.text = num.toString();
|
|
190
|
+
// });
|
|
191
|
+
//
|
|
192
|
+
// const p2Label = new TextDisp(30, 0, this.score.player2Score.toString(), {fill: 0x777777});
|
|
193
|
+
// this.addComponent(p2Label);
|
|
194
|
+
// this.score.onP2Score.register((_, num) => {
|
|
195
|
+
// p2Label.pixiObj.text = num.toString();
|
|
196
|
+
// });
|
|
197
|
+
// }
|
|
198
|
+
// }
|
|
199
|
+
//
|
|
200
|
+
// class Score extends Component {
|
|
201
|
+
// private _player1Score: number;
|
|
202
|
+
// private _player2Score: number;
|
|
203
|
+
//
|
|
204
|
+
// constructor() {
|
|
205
|
+
// super();
|
|
206
|
+
// this._player1Score = 0;
|
|
207
|
+
// this._player2Score = 0;
|
|
208
|
+
// }
|
|
209
|
+
//
|
|
210
|
+
// player1Scored(): void {
|
|
211
|
+
// this._player1Score++;
|
|
212
|
+
// this.onP1Score.trigger(this, this._player1Score);
|
|
213
|
+
// }
|
|
214
|
+
//
|
|
215
|
+
// get player1Score(): number {
|
|
216
|
+
// return this._player1Score;
|
|
217
|
+
// }
|
|
218
|
+
//
|
|
219
|
+
// player2Scored(): void {
|
|
220
|
+
// this._player2Score++;
|
|
221
|
+
// this.onP2Score.trigger(this, this._player2Score);
|
|
222
|
+
// }
|
|
223
|
+
//
|
|
224
|
+
// get player2Score(): number {
|
|
225
|
+
// return this._player2Score;
|
|
226
|
+
// }
|
|
227
|
+
//
|
|
228
|
+
// readonly onP1Score: Observable<Score, number> = new Observable();
|
|
229
|
+
// readonly onP2Score: Observable<Score, number> = new Observable();
|
|
230
|
+
//
|
|
231
|
+
// onRemoved(): void {
|
|
232
|
+
// super.onRemoved();
|
|
233
|
+
//
|
|
234
|
+
// this.onP1Score.releaseAll();
|
|
235
|
+
// this.onP2Score.releaseAll();
|
|
236
|
+
// }
|
|
237
|
+
// }
|
|
238
|
+
//
|
|
239
|
+
// class ScoreSystem extends System<[BallMovement]> {
|
|
240
|
+
// types: [CType<BallMovement>] = [BallMovement];
|
|
241
|
+
//
|
|
242
|
+
// constructor(private score: Score) {
|
|
243
|
+
// super();
|
|
244
|
+
// }
|
|
245
|
+
//
|
|
246
|
+
// runOnEntities(delta: number, entity: Entity, args_0: BallMovement): void {
|
|
247
|
+
// if (entity.transform.x < 0) {
|
|
248
|
+
// this.score.player2Scored();
|
|
249
|
+
// entity.destroy();
|
|
250
|
+
// this.getScene().addEntity(new Ball(400, 200));
|
|
251
|
+
// }
|
|
252
|
+
// if (entity.transform.x > 800) {
|
|
253
|
+
// this.score.player1Scored();
|
|
254
|
+
// entity.destroy();
|
|
255
|
+
// this.getScene().addEntity(new Ball(400, 200));
|
|
256
|
+
// }
|
|
257
|
+
// }
|
|
258
|
+
// }
|
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "1",
|
|
3
|
+
"name": "Untitled",
|
|
4
|
+
"description": "No description",
|
|
5
|
+
"tileSize": 12,
|
|
6
|
+
"spriteSheets": {
|
|
7
|
+
"600d29ce-27cb-48ed-b91d-13f8c07e6c2a": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJAAAAAwCAYAAAD+WvNWAAAAAXNSR0IArs4c6QAAAt1JREFUeJztncFt3DAQRb+C+OoefHEBPtiNpIzAgCsxYLiMNGIfXIAv7iHXHJRDwICrHXFJzgxFUf8BCwjaNYcSPz+H4i49AZjRH5NTufG1esXwItS9q3pP8BVQuNiaGNY3aq0OXTWIwLLezev76+5uBoAfHx9nsb85xp1WjnOxFHaqrNk4lhWu9Xp4fTQp+7tFIQKSYGrcbl4pq7SMks9t7UhF9+jP7/uzz19dv5tdQ3CfcLx0IQ8HSlW+tRPV/O1WjlQcVxKPJbF4gnDic4C9gHIE0kpE2pvbSkhN4jy8Ps5rw5Z0Xsp7vHOgEmF4i8g6f/Jo4KZO9/bzRbznqVxIEgxw6kJWAqoRhJeIvBrFqsE3TdolwayJKyZ2pFhYFtP4VkluTsyWDVN63VZ1+x+3JoHWCMhjCLPI9q2cqHWvznWSJo5zdf0+5cy+lmLJEU8KjYAsp7taEW35HGdNIO7CCaIpnbaXimY581oyV7y8qKnL0V7NSQmodhz3XqsqKX9L97Fg6weXKjyXMsgB0PR078XOHlxIsxhcUv5uoQMRFb0IqIdpeQoPp9i9+wD5AmIDE5EeHCglxFFFOow4exAQ2TE5PeGSC2h6U67D5MYwX29yiDGM+wB0IKJkSwGV9ORRcqGh3AegAxEll3qEdY5SWm5NnFY5Smmc4dwHoAMRJVsISOMQe82FhnQfIC0gJrnkIq0dyEJoexPr0KJkDkRUWP+6wfMJbkmsmngeT9SHdh+ADkSUtBKQR97Sey40vPsAsoA4zSbZtHAg758B9YJ2P6RdwhyIqFj2lBbfp2mN5/eZDo/XDmVkAL6ebsXOd/P8ebI7RwwdiAD4J55YKPH5cHzz/DnRgcgZa84DnLoPcJpEW85oep0dlbx3aCT3kaADEZGc/AeggMgKuQ4UhjAuNZAq+CCRiHw93c6pZDpwpO1LvLenGQ5JQMuhzfufrYQYveC9w9rh4BBGVPwF3wE0x+ESvQkAAAAASUVORK5CYII="
|
|
8
|
+
},
|
|
9
|
+
"layers": [
|
|
10
|
+
{
|
|
11
|
+
"id": "b2cce924-1569-4bd3-87b4-628d278a97d9",
|
|
12
|
+
"name": "Layer_0",
|
|
13
|
+
"description": "",
|
|
14
|
+
"tiles": [
|
|
15
|
+
{
|
|
16
|
+
"id": "0",
|
|
17
|
+
"x": 216,
|
|
18
|
+
"y": -72,
|
|
19
|
+
"spriteSheetId": "600d29ce-27cb-48ed-b91d-13f8c07e6c2a",
|
|
20
|
+
"scaleX": 1
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"id": "0",
|
|
24
|
+
"x": 216,
|
|
25
|
+
"y": -60,
|
|
26
|
+
"spriteSheetId": "600d29ce-27cb-48ed-b91d-13f8c07e6c2a",
|
|
27
|
+
"scaleX": 1
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"id": "0",
|
|
31
|
+
"x": 216,
|
|
32
|
+
"y": -48,
|
|
33
|
+
"spriteSheetId": "600d29ce-27cb-48ed-b91d-13f8c07e6c2a",
|
|
34
|
+
"scaleX": 1
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"id": "0",
|
|
38
|
+
"x": 216,
|
|
39
|
+
"y": -36,
|
|
40
|
+
"spriteSheetId": "600d29ce-27cb-48ed-b91d-13f8c07e6c2a",
|
|
41
|
+
"scaleX": 1
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"id": "0",
|
|
45
|
+
"x": 216,
|
|
46
|
+
"y": -24,
|
|
47
|
+
"spriteSheetId": "600d29ce-27cb-48ed-b91d-13f8c07e6c2a",
|
|
48
|
+
"scaleX": 1
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
"id": "47",
|
|
52
|
+
"x": 216,
|
|
53
|
+
"y": 0,
|
|
54
|
+
"spriteSheetId": "600d29ce-27cb-48ed-b91d-13f8c07e6c2a",
|
|
55
|
+
"scaleX": 1
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
"id": "0",
|
|
59
|
+
"x": 312,
|
|
60
|
+
"y": -48,
|
|
61
|
+
"spriteSheetId": "600d29ce-27cb-48ed-b91d-13f8c07e6c2a",
|
|
62
|
+
"scaleX": 1
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"id": "0",
|
|
66
|
+
"x": 312,
|
|
67
|
+
"y": -24,
|
|
68
|
+
"spriteSheetId": "600d29ce-27cb-48ed-b91d-13f8c07e6c2a",
|
|
69
|
+
"scaleX": 1
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
"id": "14",
|
|
73
|
+
"x": 264,
|
|
74
|
+
"y": -36,
|
|
75
|
+
"spriteSheetId": "600d29ce-27cb-48ed-b91d-13f8c07e6c2a",
|
|
76
|
+
"scaleX": 1
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
"id": "15",
|
|
80
|
+
"x": 276,
|
|
81
|
+
"y": -36,
|
|
82
|
+
"spriteSheetId": "600d29ce-27cb-48ed-b91d-13f8c07e6c2a",
|
|
83
|
+
"scaleX": 1
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
"id": "26",
|
|
87
|
+
"x": 264,
|
|
88
|
+
"y": -24,
|
|
89
|
+
"spriteSheetId": "600d29ce-27cb-48ed-b91d-13f8c07e6c2a",
|
|
90
|
+
"scaleX": 1
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
"id": "27",
|
|
94
|
+
"x": 276,
|
|
95
|
+
"y": -24,
|
|
96
|
+
"spriteSheetId": "600d29ce-27cb-48ed-b91d-13f8c07e6c2a",
|
|
97
|
+
"scaleX": 1
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
"id": "16",
|
|
101
|
+
"x": 216,
|
|
102
|
+
"y": 24,
|
|
103
|
+
"spriteSheetId": "600d29ce-27cb-48ed-b91d-13f8c07e6c2a",
|
|
104
|
+
"scaleX": 1
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
"id": "17",
|
|
108
|
+
"x": 228,
|
|
109
|
+
"y": 24,
|
|
110
|
+
"spriteSheetId": "600d29ce-27cb-48ed-b91d-13f8c07e6c2a",
|
|
111
|
+
"scaleX": 1
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
"id": "28",
|
|
115
|
+
"x": 216,
|
|
116
|
+
"y": 36,
|
|
117
|
+
"spriteSheetId": "600d29ce-27cb-48ed-b91d-13f8c07e6c2a",
|
|
118
|
+
"scaleX": 1
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
"id": "29",
|
|
122
|
+
"x": 228,
|
|
123
|
+
"y": 36,
|
|
124
|
+
"spriteSheetId": "600d29ce-27cb-48ed-b91d-13f8c07e6c2a",
|
|
125
|
+
"scaleX": 1
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
"id": "40",
|
|
129
|
+
"x": 216,
|
|
130
|
+
"y": 48,
|
|
131
|
+
"spriteSheetId": "600d29ce-27cb-48ed-b91d-13f8c07e6c2a",
|
|
132
|
+
"scaleX": 1
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
"id": "41",
|
|
136
|
+
"x": 228,
|
|
137
|
+
"y": 48,
|
|
138
|
+
"spriteSheetId": "600d29ce-27cb-48ed-b91d-13f8c07e6c2a",
|
|
139
|
+
"scaleX": 1
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
"id": "16",
|
|
143
|
+
"x": 300,
|
|
144
|
+
"y": 24,
|
|
145
|
+
"spriteSheetId": "600d29ce-27cb-48ed-b91d-13f8c07e6c2a",
|
|
146
|
+
"scaleX": 1
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
"id": "17",
|
|
150
|
+
"x": 312,
|
|
151
|
+
"y": 24,
|
|
152
|
+
"spriteSheetId": "600d29ce-27cb-48ed-b91d-13f8c07e6c2a",
|
|
153
|
+
"scaleX": 1
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
"id": "28",
|
|
157
|
+
"x": 300,
|
|
158
|
+
"y": 36,
|
|
159
|
+
"spriteSheetId": "600d29ce-27cb-48ed-b91d-13f8c07e6c2a",
|
|
160
|
+
"scaleX": 1
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
"id": "29",
|
|
164
|
+
"x": 312,
|
|
165
|
+
"y": 36,
|
|
166
|
+
"spriteSheetId": "600d29ce-27cb-48ed-b91d-13f8c07e6c2a",
|
|
167
|
+
"scaleX": 1
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
"id": "40",
|
|
171
|
+
"x": 300,
|
|
172
|
+
"y": 48,
|
|
173
|
+
"spriteSheetId": "600d29ce-27cb-48ed-b91d-13f8c07e6c2a",
|
|
174
|
+
"scaleX": 1
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
"id": "41",
|
|
178
|
+
"x": 312,
|
|
179
|
+
"y": 48,
|
|
180
|
+
"spriteSheetId": "600d29ce-27cb-48ed-b91d-13f8c07e6c2a",
|
|
181
|
+
"scaleX": 1
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
"id": "16",
|
|
185
|
+
"x": 264,
|
|
186
|
+
"y": 72,
|
|
187
|
+
"spriteSheetId": "600d29ce-27cb-48ed-b91d-13f8c07e6c2a",
|
|
188
|
+
"scaleX": 1
|
|
189
|
+
},
|
|
190
|
+
{
|
|
191
|
+
"id": "17",
|
|
192
|
+
"x": 276,
|
|
193
|
+
"y": 72,
|
|
194
|
+
"spriteSheetId": "600d29ce-27cb-48ed-b91d-13f8c07e6c2a",
|
|
195
|
+
"scaleX": 1
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
"id": "28",
|
|
199
|
+
"x": 264,
|
|
200
|
+
"y": 84,
|
|
201
|
+
"spriteSheetId": "600d29ce-27cb-48ed-b91d-13f8c07e6c2a",
|
|
202
|
+
"scaleX": 1
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
"id": "29",
|
|
206
|
+
"x": 276,
|
|
207
|
+
"y": 84,
|
|
208
|
+
"spriteSheetId": "600d29ce-27cb-48ed-b91d-13f8c07e6c2a",
|
|
209
|
+
"scaleX": 1
|
|
210
|
+
},
|
|
211
|
+
{
|
|
212
|
+
"id": "40",
|
|
213
|
+
"x": 264,
|
|
214
|
+
"y": 96,
|
|
215
|
+
"spriteSheetId": "600d29ce-27cb-48ed-b91d-13f8c07e6c2a",
|
|
216
|
+
"scaleX": 1
|
|
217
|
+
},
|
|
218
|
+
{
|
|
219
|
+
"id": "41",
|
|
220
|
+
"x": 276,
|
|
221
|
+
"y": 96,
|
|
222
|
+
"spriteSheetId": "600d29ce-27cb-48ed-b91d-13f8c07e6c2a",
|
|
223
|
+
"scaleX": 1
|
|
224
|
+
},
|
|
225
|
+
{
|
|
226
|
+
"id": "9",
|
|
227
|
+
"x": 240,
|
|
228
|
+
"y": -60,
|
|
229
|
+
"spriteSheetId": "600d29ce-27cb-48ed-b91d-13f8c07e6c2a",
|
|
230
|
+
"scaleX": 1
|
|
231
|
+
},
|
|
232
|
+
{
|
|
233
|
+
"id": "9",
|
|
234
|
+
"x": 252,
|
|
235
|
+
"y": -36,
|
|
236
|
+
"spriteSheetId": "600d29ce-27cb-48ed-b91d-13f8c07e6c2a",
|
|
237
|
+
"scaleX": 1
|
|
238
|
+
},
|
|
239
|
+
{
|
|
240
|
+
"id": "9",
|
|
241
|
+
"x": 264,
|
|
242
|
+
"y": 48,
|
|
243
|
+
"spriteSheetId": "600d29ce-27cb-48ed-b91d-13f8c07e6c2a",
|
|
244
|
+
"scaleX": 1
|
|
245
|
+
},
|
|
246
|
+
{
|
|
247
|
+
"id": "9",
|
|
248
|
+
"x": 240,
|
|
249
|
+
"y": 72,
|
|
250
|
+
"spriteSheetId": "600d29ce-27cb-48ed-b91d-13f8c07e6c2a",
|
|
251
|
+
"scaleX": 1
|
|
252
|
+
},
|
|
253
|
+
{
|
|
254
|
+
"id": "9",
|
|
255
|
+
"x": 300,
|
|
256
|
+
"y": 72,
|
|
257
|
+
"spriteSheetId": "600d29ce-27cb-48ed-b91d-13f8c07e6c2a",
|
|
258
|
+
"scaleX": 1
|
|
259
|
+
},
|
|
260
|
+
{
|
|
261
|
+
"id": "11",
|
|
262
|
+
"x": 276,
|
|
263
|
+
"y": 24,
|
|
264
|
+
"spriteSheetId": "600d29ce-27cb-48ed-b91d-13f8c07e6c2a",
|
|
265
|
+
"scaleX": 1
|
|
266
|
+
},
|
|
267
|
+
{
|
|
268
|
+
"id": "11",
|
|
269
|
+
"x": 276,
|
|
270
|
+
"y": 36,
|
|
271
|
+
"spriteSheetId": "600d29ce-27cb-48ed-b91d-13f8c07e6c2a",
|
|
272
|
+
"scaleX": 1
|
|
273
|
+
},
|
|
274
|
+
{
|
|
275
|
+
"id": "11",
|
|
276
|
+
"x": 264,
|
|
277
|
+
"y": 36,
|
|
278
|
+
"spriteSheetId": "600d29ce-27cb-48ed-b91d-13f8c07e6c2a",
|
|
279
|
+
"scaleX": 1
|
|
280
|
+
},
|
|
281
|
+
{
|
|
282
|
+
"id": "11",
|
|
283
|
+
"x": 264,
|
|
284
|
+
"y": 24,
|
|
285
|
+
"spriteSheetId": "600d29ce-27cb-48ed-b91d-13f8c07e6c2a",
|
|
286
|
+
"scaleX": 1
|
|
287
|
+
},
|
|
288
|
+
{
|
|
289
|
+
"id": "10",
|
|
290
|
+
"x": 300,
|
|
291
|
+
"y": -48,
|
|
292
|
+
"spriteSheetId": "600d29ce-27cb-48ed-b91d-13f8c07e6c2a",
|
|
293
|
+
"scaleX": 1
|
|
294
|
+
},
|
|
295
|
+
{
|
|
296
|
+
"id": "10",
|
|
297
|
+
"x": 288,
|
|
298
|
+
"y": -48,
|
|
299
|
+
"spriteSheetId": "600d29ce-27cb-48ed-b91d-13f8c07e6c2a",
|
|
300
|
+
"scaleX": 1
|
|
301
|
+
},
|
|
302
|
+
{
|
|
303
|
+
"id": "10",
|
|
304
|
+
"x": 288,
|
|
305
|
+
"y": -36,
|
|
306
|
+
"spriteSheetId": "600d29ce-27cb-48ed-b91d-13f8c07e6c2a",
|
|
307
|
+
"scaleX": 1
|
|
308
|
+
},
|
|
309
|
+
{
|
|
310
|
+
"id": "10",
|
|
311
|
+
"x": 288,
|
|
312
|
+
"y": -24,
|
|
313
|
+
"spriteSheetId": "600d29ce-27cb-48ed-b91d-13f8c07e6c2a",
|
|
314
|
+
"scaleX": 1
|
|
315
|
+
},
|
|
316
|
+
{
|
|
317
|
+
"id": "10",
|
|
318
|
+
"x": 300,
|
|
319
|
+
"y": -24,
|
|
320
|
+
"spriteSheetId": "600d29ce-27cb-48ed-b91d-13f8c07e6c2a",
|
|
321
|
+
"scaleX": 1
|
|
322
|
+
},
|
|
323
|
+
{
|
|
324
|
+
"id": "10",
|
|
325
|
+
"x": 300,
|
|
326
|
+
"y": -36,
|
|
327
|
+
"spriteSheetId": "600d29ce-27cb-48ed-b91d-13f8c07e6c2a",
|
|
328
|
+
"scaleX": 1
|
|
329
|
+
},
|
|
330
|
+
{
|
|
331
|
+
"id": "10",
|
|
332
|
+
"x": 312,
|
|
333
|
+
"y": -36,
|
|
334
|
+
"spriteSheetId": "600d29ce-27cb-48ed-b91d-13f8c07e6c2a",
|
|
335
|
+
"scaleX": 1
|
|
336
|
+
},
|
|
337
|
+
{
|
|
338
|
+
"id": "47",
|
|
339
|
+
"x": 216,
|
|
340
|
+
"y": 120,
|
|
341
|
+
"spriteSheetId": "600d29ce-27cb-48ed-b91d-13f8c07e6c2a",
|
|
342
|
+
"scaleX": 1
|
|
343
|
+
}
|
|
344
|
+
],
|
|
345
|
+
"collider": false,
|
|
346
|
+
"isAutoTile": false,
|
|
347
|
+
"rules": []
|
|
348
|
+
}
|
|
349
|
+
],
|
|
350
|
+
"settings": {
|
|
351
|
+
"showGrid": true,
|
|
352
|
+
"GBStudioMode": false,
|
|
353
|
+
"backgroundColor": "#FFFFFF"
|
|
354
|
+
},
|
|
355
|
+
"exports": {
|
|
356
|
+
"spritesheet": "",
|
|
357
|
+
"tiles": []
|
|
358
|
+
}
|
|
359
|
+
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import "./main.css";
|
|
2
|
+
import { Platformer } from "./Platformer";
|
|
3
|
+
import { GameTemplate } from "./GameTemplate";
|
|
4
|
+
|
|
5
|
+
document.querySelector<HTMLDivElement>("#app")!.innerHTML = `
|
|
6
|
+
<div id="main" style="align-items: center; justify-content: center; height: 100%; display: flex">
|
|
7
|
+
</div>
|
|
8
|
+
<!-- <canvas id="detect-render" width="768" height="768""></canvas>-->
|
|
9
|
+
`;
|
|
10
|
+
const main = document.querySelector<HTMLDivElement>("#main")!;
|
|
11
|
+
const game = new Platformer();
|
|
12
|
+
// const game = new GameTemplate();
|
|
13
|
+
|
|
14
|
+
game.start().then(() => {
|
|
15
|
+
main.appendChild(game.application.canvas);
|
|
16
|
+
game.application.canvas.focus();
|
|
17
|
+
});
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { AnimatedSpriteController, Button, Component, CType, Entity, Key, System, Timer } from "lagom-engine";
|
|
2
|
+
|
|
3
|
+
import { GameTemplate } from "../GameTemplate";
|
|
4
|
+
|
|
5
|
+
class MuteComp extends Component {}
|
|
6
|
+
|
|
7
|
+
class MuteListener extends System<[AnimatedSpriteController, MuteComp]> {
|
|
8
|
+
types: [CType<AnimatedSpriteController>, CType<MuteComp>] = [AnimatedSpriteController, MuteComp];
|
|
9
|
+
|
|
10
|
+
runOnEntities(delta: number, e: Entity, spr: AnimatedSpriteController, args_1: MuteComp): void {
|
|
11
|
+
if (this.scene.game.mouse.isButtonPressed(Button.LEFT)) {
|
|
12
|
+
// TODO this is a bit cheeky, how can I do it now?
|
|
13
|
+
// const pos = e.scene.game.canvas.plugins.interaction.mouse.global;
|
|
14
|
+
// if (pos.x >= GameTemplate.GAME_WIDTH - 24 && pos.x <= GameTemplate.GAME_WIDTH - 8 && pos.y >= GameTemplate.GAME_HEIGHT - 24 && pos.y <= GameTemplate.GAME_HEIGHT - 8) {
|
|
15
|
+
// (e.scene.getEntityWithName("audio") as SoundManager).toggleMute();
|
|
16
|
+
// spr.setAnimation(Number(GameTemplate.muted));
|
|
17
|
+
// }
|
|
18
|
+
} else if (this.scene.game.keyboard.isKeyPressed(Key.KeyM)) {
|
|
19
|
+
(e.scene.getEntityWithName("audio") as SoundManager).toggleMute();
|
|
20
|
+
spr.setAnimation(Number(GameTemplate.muted));
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export class SoundManager extends Entity {
|
|
26
|
+
constructor() {
|
|
27
|
+
super("audio", GameTemplate.GAME_WIDTH - 16 - 8, GameTemplate.GAME_HEIGHT - 24, 0);
|
|
28
|
+
this.startMusic();
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
onAdded(): void {
|
|
32
|
+
super.onAdded();
|
|
33
|
+
|
|
34
|
+
this.addComponent(new MuteComp());
|
|
35
|
+
const spr = this.addComponent(
|
|
36
|
+
new AnimatedSpriteController(Number(GameTemplate.muted), [
|
|
37
|
+
{
|
|
38
|
+
id: 0,
|
|
39
|
+
textures: [this.scene.game.getResource("mute_button").tileAt(0, 0)],
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
id: 1,
|
|
43
|
+
textures: [this.scene.game.getResource("mute_button").tileAt(1, 0)],
|
|
44
|
+
},
|
|
45
|
+
]),
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
this.addComponent(new Timer(50, spr, false)).onTrigger.register((caller, data) => {
|
|
49
|
+
data.setAnimation(Number(GameTemplate.muted));
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
this.scene.addSystem(new MuteListener());
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
toggleMute() {
|
|
56
|
+
GameTemplate.muted = !GameTemplate.muted;
|
|
57
|
+
|
|
58
|
+
if (GameTemplate.muted) {
|
|
59
|
+
this.stopAllSounds();
|
|
60
|
+
} else {
|
|
61
|
+
this.startMusic();
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
startMusic() {
|
|
66
|
+
if (!GameTemplate.muted && !GameTemplate.musicPlaying) {
|
|
67
|
+
GameTemplate.audioAtlas.play("music");
|
|
68
|
+
GameTemplate.musicPlaying = true;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
stopAllSounds(music = true) {
|
|
73
|
+
if (music) {
|
|
74
|
+
GameTemplate.audioAtlas.sounds.forEach((v: any, k: string) => v.stop());
|
|
75
|
+
GameTemplate.musicPlaying = false;
|
|
76
|
+
} else {
|
|
77
|
+
GameTemplate.audioAtlas.sounds.forEach((v: any, k: string) => {
|
|
78
|
+
if (k !== "music") v.stop();
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
onRemoved(): void {
|
|
84
|
+
super.onRemoved();
|
|
85
|
+
this.stopAllSounds(false);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
playSound(name: string, restart = false) {
|
|
89
|
+
if (!GameTemplate.muted) {
|
|
90
|
+
if (GameTemplate.audioAtlas.sounds.get(name)?.isPlaying && !restart) return;
|
|
91
|
+
GameTemplate.audioAtlas.play(name);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
stopSound(name: string) {
|
|
96
|
+
GameTemplate.audioAtlas.sounds.forEach((value, key) => {
|
|
97
|
+
if (key === name) {
|
|
98
|
+
value.stop();
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/// <reference types="vite/client" />
|