angry-pixel 1.2.17 → 2.0.0

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/README.md CHANGED
@@ -1,148 +1,168 @@
1
- # Introduction
1
+ # Angry Pixel Engine
2
2
 
3
- ## What is Angry Pixel?
3
+ ## What is Angry Pixel Engine?
4
4
 
5
- Angry Pixel is a 2D engine for browser games written in Typescript.
5
+ It is a 2D engine for browser games written in Typescript.
6
6
 
7
7
  Main features:
8
8
 
9
- - Sprites and animations
10
- - Tilemaps (csv and Tiled)
9
+ - Entity-Component-System based architecture
11
10
  - WebGL rendering
12
- - Polygonal collisions and static physics resolution
13
- - Input (keyboard, mouse, gamepad, touch)
14
- - Scene-Object-Component based architecture
11
+ - Sprite-based graphics and frame-by-frame animations
12
+ - Text rendering based on bitmap fonts
13
+ - Shadow/Lights rendering
14
+ - Polygonal collisions and static/dynamic physical responses
15
+ - Keyboard, mouse, gamepad and touch screen input support
16
+ - Dependency Injection
15
17
 
16
18
  ## Getting Started
17
19
 
20
+ Let's create a scene where the Angry Pixel logo bounces off the edges of the screen in a DVD screensaver fashion.
21
+
18
22
  ### Installation
19
23
 
20
24
  ```bash
21
25
  npm i angry-pixel
22
26
  ```
23
27
 
28
+ or
29
+
30
+ ```bash
31
+ yarn add angry-pixel
32
+ ```
33
+
24
34
  ### Initialize
25
35
 
26
- Create and configure a new Game instance.
36
+ First we create an instance of the Game class:
27
37
 
28
38
  ```typescript
29
39
  import { Game, GameConfig } from "angry-pixel";
30
40
 
31
41
  const config: GameConfig = {
32
- containerNode: document.getElementById("app"),
33
- gameWidth: 1920,
34
- gameHeight: 1080,
42
+ containerNode: document.querySelector("#app"),
43
+ width: 1920,
44
+ height: 1080,
35
45
  canvasColor: "#00D9D9",
36
46
  };
37
47
 
38
- // create the game
39
48
  const game = new Game(config);
40
49
  ```
41
50
 
42
51
  ### Create a Scene
43
52
 
44
- Crear la clase MainScene que extiende Scene and load an image that will be used as a Sprite.
53
+ Then we will create the MainScene class, which extends the Scene base class. This class represents a scene in our game, and has three main functions:
54
+
55
+ - To load assets.
56
+ - To create the initial entities.
57
+ - To know which are the necessary systems.
58
+
59
+ For the moment we only implement the function loadAssets to load an image that we will use later:
45
60
 
46
61
  ```typescript
47
62
  import { Scene } from "angry-pixel";
48
63
 
49
64
  class MainScene extends Scene {
50
- protected init(): void {
65
+ // within this method we load the assets
66
+ public loadAssets(): void {
51
67
  this.assetManager.loadImage("logo.png");
52
68
  }
53
69
  }
54
70
  ```
55
71
 
56
- Add the scene to the game.
72
+ And we add this scene to our game:
57
73
 
58
74
  ```typescript
59
- const config: GameConfig = {
60
- containerNode: document.getElementById("app"),
61
- gameWidth: 1920,
62
- gameHeight: 1080,
63
- canvasColor: "#00D9D9",
64
- };
75
+ // arguments: the scene class, the scene name, and true because is the opening scene
76
+ game.addScene(MainScene, "MainScene", true);
77
+ ```
65
78
 
66
- // create the game
67
- const game = new Game(config);
68
- // add scene
69
- game.addScene(MainScene, "MainScene");
79
+ ### Create a Component
80
+
81
+ Then we will create the MoveAndBounce component which has the necessary attributes to define the movement of our entity.
82
+
83
+ ```typescript
84
+ import { Vector2 } from "angry-pixel";
85
+
86
+ class MoveAndBounce {
87
+ boundaries: number[] = [476, -476, 896, -896]; // top, bottom, left, right
88
+ direction: Vector2 = new Vector2(1, 1); // the direction in wich the entity will move
89
+ speed: number = 200; // pixels per second
90
+ }
70
91
  ```
71
92
 
72
- ### Create a Game Object
93
+ ### Create a System
73
94
 
74
- Create the Logo class extending GameObject and add the image using the native SpriteRenderer component.
95
+ Once we have created our component, we will need a system that executes the business logic. Extending the base class GameSystem, we will create our MoveAndBounceSystem, which, using the EntityManager, obtains all the entities that have the MoveAndBounce component, and executes the business logic necessary for the entity to move by bouncing on the edges of the screen:
75
96
 
76
97
  ```typescript
77
- import { GameObject, Sprite, SpriteRenderer } from "angry-pixel";
98
+ import { GameSystem, Transform } from "angry-pixel";
78
99
 
79
- class Logo extends GameObject {
80
- protected init(): void {
81
- this.addComponent(SpriteRenderer, {
82
- sprite: new Sprite({
83
- image: this.assetManager.getImage("logo.png"),
84
- }),
100
+ class MoveAndBounceSystem extends GameSystem {
101
+ public onUpdate(): void {
102
+ this.entityManager.search(MoveAndBounce).forEach(({ component, entity }) => {
103
+ const transform = this.entityManager.getComponent(entity, Transform);
104
+ const { boundaries, direction, speed } = component;
105
+
106
+ if (transform.position.y >= boundaries[0] || transform.position.y <= boundaries[1]) {
107
+ direction.y *= -1;
108
+ }
109
+
110
+ if (transform.position.x >= boundaries[2] || transform.position.x <= boundaries[3]) {
111
+ direction.x *= -1;
112
+ }
113
+
114
+ transform.position.x += direction.x * speed * this.timeManager.deltaTime;
115
+ transform.position.y += direction.y * speed * this.timeManager.deltaTime;
85
116
  });
86
117
  }
87
118
  }
88
119
  ```
89
120
 
90
- Add the object to the scene.
121
+ Once the system is created, we can add it to the scene
91
122
 
92
123
  ```typescript
124
+ import { Scene } from "angry-pixel";
125
+
93
126
  class MainScene extends Scene {
94
- protected init(): void {
127
+ // in this attribute we load the systems of the scene
128
+ public systems: SystemType<System>[] = [MoveAndBounceSystem];
129
+
130
+ public loadAssets(): void {
95
131
  this.assetManager.loadImage("logo.png");
96
- this.addGameObject(Logo);
97
132
  }
98
133
  }
99
134
  ```
100
135
 
101
- ### Create a Component
136
+ ### Create the entities
102
137
 
103
- Create the MoveAndBounce class that extends Component and contains the logic for object movement, using the native Transform component (natively included in the GameObject), vectors and delta time.
138
+ Finally, we need two entities, one that represents our logo, which we want to move, and another one that represents the camera of our game. To do this we will create the entities in the following way:
104
139
 
105
140
  ```typescript
106
- import { Component, Transform, Vector2 } from "angry-pixel";
141
+ import { Camera, Component, Scene, SpriteRenderer, Transform } from "angry-pixel";
107
142
 
108
- class MoveAndBounce extends Component {
109
- private transform: Transform;
110
- private direction: Vector2;
111
- private speed: number;
143
+ class MainScene extends Scene {
144
+ public systems: SystemType<System>[] = [MoveAndBounceSystem];
112
145
 
113
- protected init(): void {
114
- this.transform = this.gameObject.transform;
115
- this.direction = new Vector2(1, 1);
116
- this.speed = 200; // pixels per second
146
+ public loadAssets(): void {
147
+ this.assetManager.loadImage("logo.png");
117
148
  }
118
149
 
119
- // this method is called once per frame
120
- protected update(): void {
121
- if (this.transform.position.y >= 476 || this.transform.position.y <= -476) {
122
- this.direction.y *= -1;
123
- }
124
- if (this.transform.position.x >= 896 || this.transform.position.x <= -896) {
125
- this.direction.x *= -1;
126
- }
127
-
128
- this.transform.position.x += this.direction.x * this.speed * this.timeManager.deltaTime;
129
- this.transform.position.y += this.direction.y * this.speed * this.timeManager.deltaTime;
130
- }
131
- }
132
- ```
133
-
134
- Add the component to the object.
135
-
136
- ```typescript
137
- class Logo extends GameObject {
138
- protected init(): void {
139
- this.addComponent(SpriteRenderer, {
140
- sprite: new Sprite({
150
+ // within this method we create the entities
151
+ public setup(): void {
152
+ // camera
153
+ const cameraArchetype: Component[] = [new Transform(), new Camera({ layers: ["Logo"] })];
154
+ this.entityManager.createEntity(cameraArchetype);
155
+
156
+ // logo
157
+ const logoArchetype: Component[] = [
158
+ new Transform(),
159
+ new SpriteRenderer({
160
+ layer: "Logo",
141
161
  image: this.assetManager.getImage("logo.png"),
142
162
  }),
143
- });
144
-
145
- this.addComponent(MoveAndBounce);
163
+ new MoveAndBounce(),
164
+ ];
165
+ this.entityManager.createEntity(logoArchetype);
146
166
  }
147
167
  }
148
168
  ```
@@ -150,18 +170,6 @@ class Logo extends GameObject {
150
170
  ### Run the game
151
171
 
152
172
  ```typescript
153
- const config: GameConfig = {
154
- containerNode: document.getElementById("app"),
155
- gameWidth: 1920,
156
- gameHeight: 1080,
157
- canvasColor: "#00D9D9",
158
- };
159
-
160
- // create the game
161
- const game = new Game(config);
162
- // add scene
163
- game.addScene(MainScene, "MainScene");
164
- // run the game
165
173
  game.run();
166
174
  ```
167
175