core2d 2.10.4 → 2.11.2

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/src/Scene.mjs CHANGED
@@ -4,105 +4,146 @@ import { Engine } from "./Engine.mjs";
4
4
  import { Sprite } from "./Sprite.mjs";
5
5
  import { Static } from "./Static.mjs";
6
6
 
7
+ /**
8
+ * Represents a scene, which is a collection of sprites that are rendered together.
9
+ * @extends Sprite
10
+ */
7
11
  export class Scene extends Sprite {
8
- constructor() {
9
- super();
10
- this.height = Engine.height;
11
- this.width = Engine.width;
12
- this._sprites = [];
13
- this._spritesQueue = [];
14
- }
15
-
16
- init() {
17
- // no default behavior
18
- }
19
-
20
- add(sprite) {
21
- this._spritesQueue.push(sprite);
22
- sprite.scene = this;
23
- sprite.init();
24
- sprite.x -= sprite.speedX;
25
- sprite.y -= sprite.speedY;
26
- return this;
27
- }
28
-
29
- build(map, tileFactory = null, offsetX = 0, offsetY = 0, x = 0, y = 0) {
30
- tileFactory = tileFactory ?? function baseTileFactory(id) {
31
- return new Sprite().addTag("tile").setImage(id);
32
- };
33
-
34
- for (let i = 0; i < map.length; ++i) {
35
- const LINE = map[i];
36
-
37
- for (let j = 0; j < LINE.length; ++j) {
38
- const ID = map[i][j];
39
-
40
- if (!ID || "" == ID.trim()) {
41
- continue;
42
- }
43
-
44
- const TILE = tileFactory(ID);
45
-
46
- if (TILE) {
47
- const X = offsetX || TILE.width;
48
- const Y = offsetY || TILE.height;
49
- TILE.x = x + j * X;
50
- TILE.y = y + i * Y;
51
- this.add(TILE);
52
- }
53
- }
54
- }
55
-
56
- return this;
57
- }
58
-
59
- sync() {
60
- Engine.paint(this, this.layerIndex);
61
- let sprites = [];
62
- const solidSprites = [];
63
-
64
- for (let i = 0; i < this._sprites.length; ++i) {
65
- const sprite = this._sprites[i];
66
-
67
- if (sprite.sync()) {
68
- if (sprite.essential) {
69
- this.setExpired();
70
- }
71
- } else {
72
- if (sprite.solid) {
73
- solidSprites.push(sprite);
74
- }
75
-
76
- sprites.push(sprite);
77
- Engine.paint(sprite, sprite.layerIndex);
78
- }
79
-
80
- sprite.collided = false;
81
- }
82
-
83
- Static.checkCollisions(solidSprites);
84
- this._sprites = sprites.concat(this._spritesQueue);
85
- this._spritesQueue = [];
86
- return Sprite.prototype.sync.call(this);
87
- }
88
-
89
- getObjectsWithTag(tag) {
90
- const RESULT = [];
91
- const SPRITES = this._sprites.concat(this._spritesQueue);
92
-
93
- for (let i = 0; i < SPRITES.length; ++i) {
94
- const SPRITE = SPRITES[i];
95
-
96
- if (SPRITE.hasTag(tag)) {
97
- RESULT.push(SPRITE);
98
- }
99
- }
100
-
101
- return RESULT;
102
- }
103
-
104
- setTransition(transition) {
105
- this.transition = transition;
106
- return this;
107
- }
12
+ /**
13
+ * Creates a new Scene.
14
+ */
15
+ constructor() {
16
+ super();
17
+ this.height = Engine.height;
18
+ this.width = Engine.width;
19
+ this._sprites = [];
20
+ this._spritesQueue = [];
21
+ }
22
+
23
+ /**
24
+ * Initializes the scene.
25
+ */
26
+ init() {
27
+ // no default behavior
28
+ }
29
+
30
+ /**
31
+ * Adds a sprite to the scene.
32
+ * @param {Sprite} sprite The sprite to add.
33
+ * @returns {Scene} This scene.
34
+ */
35
+ add(sprite) {
36
+ this._spritesQueue.push(sprite);
37
+ sprite.scene = this;
38
+ sprite.init();
39
+ sprite.x -= sprite.speedX;
40
+ sprite.y -= sprite.speedY;
41
+ return this;
42
+ }
43
+
44
+ /**
45
+ * Builds a tilemap from a map.
46
+ * @param {string[][]} map The map.
47
+ * @param {function(string): Sprite} [tileFactory=null] A function that creates a tile from an ID.
48
+ * @param {number} [offsetX=0] The horizontal offset between tiles.
49
+ * @param {number} [offsetY=0] The vertical offset between tiles.
50
+ * @param {number} [x=0] The horizontal position of the tilemap.
51
+ * @param {number} [y=0] The vertical position of the tilemap.
52
+ * @returns {Scene} This scene.
53
+ */
54
+ build(map, tileFactory = null, offsetX = 0, offsetY = 0, x = 0, y = 0) {
55
+ tileFactory =
56
+ tileFactory ??
57
+ function baseTileFactory(id) {
58
+ return new Sprite().addTag("tile").setImage(id);
59
+ };
60
+
61
+ for (let i = 0; i < map.length; ++i) {
62
+ const LINE = map[i];
63
+
64
+ for (let j = 0; j < LINE.length; ++j) {
65
+ const ID = map[i][j];
66
+
67
+ if (!ID || "" == ID.trim()) {
68
+ continue;
69
+ }
70
+
71
+ const TILE = tileFactory(ID);
72
+
73
+ if (TILE) {
74
+ const X = offsetX || TILE.width;
75
+ const Y = offsetY || TILE.height;
76
+ TILE.x = x + j * X;
77
+ TILE.y = y + i * Y;
78
+ this.add(TILE);
79
+ }
80
+ }
81
+ }
82
+
83
+ return this;
84
+ }
85
+
86
+ /**
87
+ * Synchronizes the scene.
88
+ * @returns {boolean} Whether the scene has expired.
89
+ */
90
+ sync() {
91
+ Engine.paint(this, this.layerIndex);
92
+ let sprites = [];
93
+ const solidSprites = [];
94
+
95
+ for (let i = 0; i < this._sprites.length; ++i) {
96
+ const sprite = this._sprites[i];
97
+
98
+ if (sprite.sync()) {
99
+ if (sprite.essential) {
100
+ this.setExpired();
101
+ }
102
+ } else {
103
+ if (sprite.solid) {
104
+ solidSprites.push(sprite);
105
+ }
106
+
107
+ sprites.push(sprite);
108
+ Engine.paint(sprite, sprite.layerIndex);
109
+ }
110
+
111
+ sprite.collided = false;
112
+ }
113
+
114
+ Static.checkCollisions(solidSprites);
115
+ this._sprites = sprites.concat(this._spritesQueue);
116
+ this._spritesQueue = [];
117
+ return Sprite.prototype.sync.call(this);
118
+ }
119
+
120
+ /**
121
+ * Gets all sprites with a specific tag.
122
+ * @param {string} tag The tag.
123
+ * @returns {Sprite[]} The sprites with the tag.
124
+ */
125
+ getObjectsWithTag(tag) {
126
+ const RESULT = [];
127
+ const SPRITES = this._sprites.concat(this._spritesQueue);
128
+
129
+ for (let i = 0; i < SPRITES.length; ++i) {
130
+ const SPRITE = SPRITES[i];
131
+
132
+ if (SPRITE.hasTag(tag)) {
133
+ RESULT.push(SPRITE);
134
+ }
135
+ }
136
+
137
+ return RESULT;
138
+ }
139
+
140
+ /**
141
+ * Sets the transition to the next scene.
142
+ * @param {Transition} transition The transition.
143
+ * @returns {Scene} This scene.
144
+ */
145
+ setTransition(transition) {
146
+ this.transition = transition;
147
+ return this;
148
+ }
108
149
  }
package/src/Sound.mjs CHANGED
@@ -5,134 +5,138 @@ import { Static } from "./Static.mjs";
5
5
  const DEFAULT_PLAY_VOLUME = 0.3;
6
6
 
7
7
  export class Sound {
8
- constructor() {
9
- this._isFading = false;
10
- this._isMute = false;
11
- this._nextThemeName = null;
12
- this._queue = {};
13
- this._theme = null;
14
- this._themeId = null;
15
- this._volume = 100;
16
- }
17
-
18
- fadeOut() {
19
- if (!this._theme) {
20
- return;
21
- }
22
-
23
- this._isFading = true;
24
- this._volume = 100;
25
- }
26
-
27
- mute() {
28
- this._isMute = !this._isMute;
29
-
30
- if (!this._isMute) {
31
- this._theme.play();
32
- } else {
33
- this._theme.pause();
34
- }
35
- }
36
-
37
- pause() {
38
- if (this._theme) {
39
- this._theme.pause();
40
- }
41
- }
42
-
43
- play(id, volume = DEFAULT_PLAY_VOLUME) {
44
- if (this._isMute) {
45
- return;
46
- }
47
-
48
- this._queue[id] = volume;
49
- }
50
-
51
- playTheme(id) {
52
- if (id == this._themeId) {
53
- return;
54
- }
55
-
56
- if (this._theme && this._theme.currentTime > 0) {
57
- this._nextThemeName = id;
58
-
59
- if (!this._isFading) {
60
- this.fadeOut();
61
- }
62
-
63
- return;
64
- }
65
-
66
- this.stopTheme();
67
- this._theme = Static.getElement(id);
68
- this._themeId = id;
69
-
70
- if (this._theme.currentTime > 0) {
71
- this._theme.currentTime = 0;
72
- }
73
-
74
- if (this._isMute) {
75
- return;
76
- }
77
-
78
- this._theme.volume = 1;
79
- this._theme.play();
80
- }
81
-
82
- resume() {
83
- if (this._isMute) {
84
- return;
85
- }
86
-
87
- if (this._theme.paused) {
88
- this._theme.play();
89
- }
90
- }
91
-
92
- stopTheme() {
93
- this._isFading = false;
94
-
95
- if (this._theme) {
96
- this._theme.pause();
97
- this._theme.currentTime = 0;
98
- this._themeId = null;
99
- }
100
- }
101
-
102
- update() {
103
- for (let id in this._queue) {
104
- const SOUND = Static.getElement(id);
105
-
106
- if (!SOUND?.pause) {
107
- console.warn(`Could not find audio with id: ${id}`);
108
- }
109
-
110
- SOUND.pause();
111
-
112
- if (SOUND.currentTime > 0) {
113
- SOUND.currentTime = 0;
114
- }
115
-
116
- SOUND.volume = this._queue[id];
117
- SOUND.play();
118
- }
119
-
120
- this._queue = {};
121
-
122
- if (this._isFading) {
123
- if (--this._volume > 0) {
124
- this._theme.volume = this._volume / 100;
125
- } else {
126
- this.stopTheme();
127
- this._isFading = false;
128
- this._theme = null;
129
-
130
- if (this._nextThemeName) {
131
- this.playTheme(this._nextThemeName);
132
- this._themeId = this._nextThemeName;
133
- this._nextThemeName = null;
134
- }
135
- }
136
- }
137
- }
8
+ constructor() {
9
+ this._isFading = false;
10
+ this._isMute = false;
11
+ this._nextThemeName = null;
12
+ this._queue = {};
13
+ this._theme = null;
14
+ this._themeId = null;
15
+ this._volume = 100;
16
+ }
17
+
18
+ fadeOut() {
19
+ if (!this._theme) {
20
+ return;
21
+ }
22
+
23
+ this._isFading = true;
24
+ this._volume = 100;
25
+ }
26
+
27
+ mute() {
28
+ this._isMute = !this._isMute;
29
+
30
+ if (!this._theme) {
31
+ return;
32
+ }
33
+
34
+ if (!this._isMute) {
35
+ this._theme.play();
36
+ } else {
37
+ this._theme.pause();
38
+ }
39
+ }
40
+
41
+ pause() {
42
+ if (this._theme) {
43
+ this._theme.pause();
44
+ }
45
+ }
46
+
47
+ play(id, volume = DEFAULT_PLAY_VOLUME) {
48
+ if (this._isMute) {
49
+ return;
50
+ }
51
+
52
+ this._queue[id] = volume;
53
+ }
54
+
55
+ playTheme(id) {
56
+ if (id == this._themeId) {
57
+ return;
58
+ }
59
+
60
+ if (this._theme && this._theme.currentTime > 0) {
61
+ this._nextThemeName = id;
62
+
63
+ if (!this._isFading) {
64
+ this.fadeOut();
65
+ }
66
+
67
+ return;
68
+ }
69
+
70
+ this.stopTheme();
71
+ this._theme = Static.getElement(id);
72
+ this._themeId = id;
73
+
74
+ if (this._theme.currentTime > 0) {
75
+ this._theme.currentTime = 0;
76
+ }
77
+
78
+ if (this._isMute) {
79
+ return;
80
+ }
81
+
82
+ this._theme.volume = 1;
83
+ this._theme.play();
84
+ }
85
+
86
+ resume() {
87
+ if (this._isMute) {
88
+ return;
89
+ }
90
+
91
+ if (this._theme.paused) {
92
+ this._theme.play();
93
+ }
94
+ }
95
+
96
+ stopTheme() {
97
+ this._isFading = false;
98
+
99
+ if (this._theme) {
100
+ this._theme.pause();
101
+ this._theme.currentTime = 0;
102
+ this._themeId = null;
103
+ }
104
+ }
105
+
106
+ update() {
107
+ for (let id in this._queue) {
108
+ const SOUND = Static.getElement(id);
109
+
110
+ if (!SOUND?.pause) {
111
+ console.warn(`Could not find audio with id: ${id}`);
112
+ }
113
+
114
+ SOUND.pause();
115
+
116
+ if (SOUND.currentTime > 0) {
117
+ SOUND.currentTime = 0;
118
+ }
119
+
120
+ SOUND.volume = this._queue[id];
121
+ SOUND.play();
122
+ }
123
+
124
+ this._queue = {};
125
+
126
+ if (this._isFading) {
127
+ if (--this._volume > 0) {
128
+ this._theme.volume = this._volume / 100;
129
+ } else {
130
+ this.stopTheme();
131
+ this._isFading = false;
132
+ this._theme = null;
133
+
134
+ if (this._nextThemeName) {
135
+ this.playTheme(this._nextThemeName);
136
+ this._themeId = this._nextThemeName;
137
+ this._nextThemeName = null;
138
+ }
139
+ }
140
+ }
141
+ }
138
142
  }