core2d 2.10.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/Input.mjs ADDED
@@ -0,0 +1,123 @@
1
+ "use strict";
2
+
3
+ import { Controller } from "./Controller.mjs";
4
+ import { GamePad } from "./GamePad.mjs";
5
+ import { Keyboard } from "./Keyboard.mjs";
6
+ import { Mouse } from "./Mouse.mjs";
7
+ import { Pointer } from "./Pointer.mjs";
8
+ import { Static } from "./Static.mjs";
9
+ import { Touch } from "./Touch.mjs";
10
+
11
+ export class Input {
12
+ constructor() {
13
+ this._controllers = [];
14
+ this._controllerQueue = [];
15
+ this._controllerRequestQueue = [];
16
+ this._pointers = [];
17
+ this._pointerQueue = [];
18
+ this._pointerRequestQueue = [];
19
+ this._gamePads = 0;
20
+
21
+ const ON_KEYBOARD = (event) => {
22
+ removeEventListener("keydown", ON_KEYBOARD);
23
+ console.log("Keyboard detected.");
24
+ this.addController(new Keyboard(event));
25
+ };
26
+
27
+ const ON_MOUSE = (event) => {
28
+ removeEventListener("mousemove", ON_MOUSE);
29
+ console.log("Mouse detected.");
30
+ this.addPointer(new Mouse(event));
31
+ };
32
+
33
+ const ON_TOUCH = (event) => {
34
+ removeEventListener("touchstart", ON_TOUCH);
35
+ console.log("Touch detected.");
36
+ this.addPointer(new Touch(event));
37
+ };
38
+
39
+ addEventListener("keydown", ON_KEYBOARD, false);
40
+ addEventListener("mousemove", ON_MOUSE, false);
41
+ addEventListener("touchstart", ON_TOUCH, false);
42
+ }
43
+
44
+ static getGamePadAxes(id) {
45
+ if (Static.getGamepads()[id]) {
46
+ return Static.getGamepads()[id].axes;
47
+ }
48
+
49
+ return [];
50
+ }
51
+
52
+ static getGamePadButtons(id) {
53
+ const GAMEPAD = Static.getGamepads()[id];
54
+ return GAMEPAD && GAMEPAD.buttons || [];
55
+ }
56
+
57
+ addController(device) {
58
+ this._controllerQueue.push(device);
59
+ this.checkControllerQueues();
60
+ }
61
+
62
+ addPointer(device) {
63
+ this._pointerQueue.push(device);
64
+ this.checkPointerQueues();
65
+ }
66
+
67
+ checkGamePads() {
68
+ if (Static.getGamepads()[this._gamePads]) {
69
+ console.log("Game pad detected.");
70
+ this.addController(new GamePad(this._gamePads++));
71
+ }
72
+ }
73
+
74
+ checkControllerQueues() {
75
+ if (this._controllerRequestQueue.length > 0 && this._controllerQueue.length > 0) {
76
+ const REQUESTER = this._controllerRequestQueue.shift();
77
+ const DEVICE = this._controllerQueue.shift();
78
+ REQUESTER.setDevice(DEVICE);
79
+ }
80
+ }
81
+
82
+ checkPointerQueues() {
83
+ if (this._pointerRequestQueue.length > 0 && this._pointerQueue.length > 0) {
84
+ const REQUESTER = this._pointerRequestQueue.shift();
85
+ const DEVICE = this._pointerQueue.shift();
86
+ REQUESTER.setDevice(DEVICE);
87
+ }
88
+ }
89
+
90
+ getController(id = 0) {
91
+ if (this._controllers.length < id + 1) {
92
+ const CONTROLLER = new Controller();
93
+ this._controllers.push(CONTROLLER);
94
+ this._controllerRequestQueue.push(CONTROLLER);
95
+ this.checkControllerQueues();
96
+ }
97
+
98
+ return this._controllers[id];
99
+ }
100
+
101
+ getPointer(id = 0) {
102
+ if (this._pointers.length < id + 1) {
103
+ const POINTER = new Pointer();
104
+ this._pointers.push(POINTER);
105
+ this._pointerRequestQueue.push(POINTER);
106
+ this.checkPointerQueues();
107
+ }
108
+
109
+ return this._pointers[id];
110
+ }
111
+
112
+ update() {
113
+ this.checkGamePads();
114
+
115
+ for (let i in this._controllers) {
116
+ this._controllers[i].update();
117
+ }
118
+
119
+ for (let j in this._pointers) {
120
+ this._pointers[j].update();
121
+ }
122
+ }
123
+ }
package/src/Key.mjs ADDED
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+
3
+ export const Key = {
4
+ BACK: 8,
5
+ ENTER: 13,
6
+ SHIFT: 16,
7
+ CTRL: 17,
8
+ ALT: 18,
9
+ SPACE: 32,
10
+ LEFT: 37,
11
+ UP: 38,
12
+ RIGHT: 39,
13
+ DOWN: 40,
14
+ D: 68,
15
+ E: 69,
16
+ F: 70,
17
+ I: 73,
18
+ J: 74,
19
+ K: 75,
20
+ L: 76,
21
+ S: 83
22
+ };
package/src/KeyMap.mjs ADDED
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+
3
+ import { Command } from "./Command.mjs";
4
+ import { Key } from "./Key.mjs";
5
+
6
+ export const KeyMap = {
7
+ [Key.UP]: Command.UP,
8
+ [Key.E]: Command.UP,
9
+ [Key.I]: Command.UP,
10
+ [Key.DOWN]: Command.DOWN,
11
+ [Key.D]: Command.DOWN,
12
+ [Key.K]: Command.DOWN,
13
+ [Key.LEFT]: Command.LEFT,
14
+ [Key.S]: Command.LEFT,
15
+ [Key.J]: Command.LEFT,
16
+ [Key.RIGHT]: Command.RIGHT,
17
+ [Key.F]: Command.RIGHT,
18
+ [Key.L]: Command.RIGHT,
19
+ [Key.SPACE]: Command.A,
20
+ [Key.ALT]: Command.B,
21
+ [Key.CTRL]: Command.X,
22
+ [Key.SHIFT]: Command.Y,
23
+ [Key.ENTER]: Command.START,
24
+ [Key.BACK]: Command.SELECT,
25
+ };
@@ -0,0 +1,34 @@
1
+ "use sttrict";
2
+
3
+ import { KeyMap } from "./KeyMap.mjs";
4
+
5
+ export class Keyboard {
6
+ constructor(event) {
7
+ this._buffer = {};
8
+
9
+ this.onKey(event, true);
10
+ addEventListener("keydown", event => this.onKey(event, true), false);
11
+ addEventListener("keyup", event => this.onKey(event, false), false);
12
+ }
13
+
14
+ get commands() {
15
+ const RESULT = {};
16
+
17
+ for (let i in this._buffer) {
18
+ if (this._buffer[i]) {
19
+ RESULT[i] = true;
20
+ }
21
+ }
22
+
23
+ return RESULT;
24
+ }
25
+
26
+ onKey(event, isDown) {
27
+ const COMMAND = KeyMap[event.keyCode];
28
+ this._buffer[COMMAND] = isDown;
29
+
30
+ if (isDown && "number" == typeof(COMMAND)) {
31
+ event.preventDefault();
32
+ }
33
+ }
34
+ }
package/src/Mouse.mjs ADDED
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+
3
+ import { Point } from "./Point.mjs";
4
+
5
+ export class Mouse extends Point {
6
+ constructor(event) {
7
+ super();
8
+ this.updateCoordinates(event);
9
+
10
+ addEventListener("mousedown", (event) => {
11
+ event.preventDefault();
12
+ this._isDown = true;
13
+ }, false);
14
+
15
+ addEventListener("mousemove", (event) => {
16
+ this.updateCoordinates(event);
17
+ }, false);
18
+
19
+ addEventListener("mouseup", (event) => {
20
+ event.preventDefault();
21
+ this._isDown = false;
22
+ }, false);
23
+ }
24
+
25
+ get command() {
26
+ return this._isDown;
27
+ }
28
+
29
+ updateCoordinates(event) {
30
+ event.preventDefault();
31
+ this.x = event.x ?? event.clientX ?? 0;
32
+ this.y = event.y ?? event.clientY ?? 0;
33
+ }
34
+ }
package/src/Point.mjs ADDED
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+
3
+ export class Point {
4
+ constructor(x = 0, y = 0) {
5
+ this.x = x;
6
+ this.y = y;
7
+ }
8
+
9
+ get position() {
10
+ return this;
11
+ }
12
+
13
+ setX(x) {
14
+ this.x = x;
15
+ return this;
16
+ }
17
+
18
+ setY(y) {
19
+ this.y = y;
20
+ return this;
21
+ }
22
+
23
+ setPosition(point) {
24
+ this.x = point.x;
25
+ this.y = point.y;
26
+ return this;
27
+ }
28
+
29
+ set position(point) {
30
+ this.setPosition(point);
31
+ }
32
+
33
+ distance(point) {
34
+ const dx = point.x - this.x;
35
+ const dy = point.y - this.y;
36
+ return Math.sqrt(dx * dx + dy * dy);
37
+ }
38
+ }
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+
3
+ import { Engine } from "./Engine.mjs";
4
+ import { Point } from "./Point.mjs";
5
+
6
+ export class Pointer extends Point {
7
+ constructor() {
8
+ super();
9
+ this._active = false;
10
+ this._device = null;
11
+ this._hold = false;
12
+ }
13
+
14
+ get down() {
15
+ return this._active;
16
+ }
17
+
18
+ get push() {
19
+ return this._active && !this._hold;
20
+ }
21
+
22
+ setDevice(device) {
23
+ this._device = device;
24
+ }
25
+
26
+ update() {
27
+ if (!this._device) {
28
+ return;
29
+ }
30
+
31
+ this._hold = false;
32
+ const LAST = this._active;
33
+ this._active = this._device.command;
34
+
35
+ if (this._active && LAST) {
36
+ this._hold = true;
37
+ }
38
+
39
+ const REAL_X = this._device.x - Engine.offsetLeft;
40
+ const REAL_Y = this._device.y - Engine.offsetTop;
41
+ this.x = Math.floor(REAL_X * Engine.width / Engine.realWidth);
42
+ this.y = Math.floor(REAL_Y * Engine.height / Engine.realHeight);
43
+ }
44
+ }
package/src/Rect.mjs ADDED
@@ -0,0 +1,127 @@
1
+ "use strict";
2
+
3
+ import { Point } from "./Point.mjs";
4
+
5
+ export class Rect extends Point {
6
+ constructor(x, y, width = 0, height = 0) {
7
+ super(x, y);
8
+ this.width = width;
9
+ this.height = height;
10
+ }
11
+
12
+ get left() {
13
+ return this.x;
14
+ }
15
+
16
+ get right() {
17
+ return this.x + this.width - 1;
18
+ }
19
+
20
+ get top() {
21
+ return this.y;
22
+ }
23
+
24
+ get bottom() {
25
+ return this.y + this.height - 1;
26
+ }
27
+
28
+ get centerX() {
29
+ return this.x + Math.floor(this.width / 2);
30
+ }
31
+
32
+ get centerY() {
33
+ return this.y + Math.floor(this.height / 2);
34
+ }
35
+
36
+ get center() {
37
+ return new Point(this.centerX, this.centerY);
38
+ }
39
+
40
+ setWidth(width) {
41
+ this.width = width;
42
+ return this;
43
+ }
44
+
45
+ setHeight(height) {
46
+ this.height = height;
47
+ return this;
48
+ }
49
+
50
+ setSize(rect) {
51
+ this.setWidth(rect.width);
52
+ this.setHeight(rect.height);
53
+ return this;
54
+ }
55
+
56
+ setLeft(x) {
57
+ this.x = x;
58
+ return this;
59
+ }
60
+
61
+ setRight(x) {
62
+ this.x = x - this.width + 1;
63
+ return this;
64
+ }
65
+
66
+ setTop(y) {
67
+ this.y = y;
68
+ return this;
69
+ }
70
+
71
+ setBottom(y) {
72
+ this.y = y - this.height + 1;
73
+ return this;
74
+ }
75
+
76
+ setCenterX(x) {
77
+ this.x = x - Math.floor(this.width / 2);
78
+ return this;
79
+ }
80
+
81
+ setCenterY(y) {
82
+ this.y = y - Math.floor(this.height / 2);
83
+ return this;
84
+ }
85
+
86
+ setCenter(point) {
87
+ this.setCenterX(point.x);
88
+ this.setCenterY(point.y);
89
+ return this;
90
+ }
91
+
92
+ set left(x) {
93
+ this.setLeft(x);
94
+ }
95
+
96
+ set right(x) {
97
+ this.setRight(x);
98
+ }
99
+
100
+ set top(y) {
101
+ this.setTop(y);
102
+ }
103
+
104
+ set bottom(y) {
105
+ this.setBottom(y);
106
+ }
107
+
108
+ set centerX(x) {
109
+ this.setCenterX(x);
110
+ }
111
+
112
+ set centerY(y) {
113
+ this.setCenterY(y);
114
+ }
115
+
116
+ set center(point) {
117
+ this.setCenter(point);
118
+ }
119
+
120
+ makeUnion(rect) {
121
+ const RECT = new Rect(Math.min(this.x, rect.x), Math.min(this.y, rect.y));
122
+
123
+ return RECT
124
+ .setWidth(Math.max(this.right, rect.right) - RECT.x + 1)
125
+ .setHeight(Math.max(this.bottom, rect.bottom) - RECT.y + 1);
126
+ }
127
+ }
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+
3
+ export class RenderableList {
4
+ constructor() {
5
+ this._elements = [];
6
+ }
7
+
8
+ add(renderable) {
9
+ this._elements.push(renderable);
10
+ }
11
+
12
+ render(context) {
13
+ for (let i = 0; i < this._elements.length; ++i) {
14
+ this._elements[i].render(context);
15
+ }
16
+
17
+ this._elements.length = 0;
18
+ }
19
+ }
package/src/Scene.mjs ADDED
@@ -0,0 +1,108 @@
1
+ "use strict";
2
+
3
+ import { Engine } from "./Engine.mjs";
4
+ import { Sprite } from "./Sprite.mjs";
5
+ import { Static } from "./Static.mjs";
6
+
7
+ 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
+ }
108
+ }
package/src/Sound.mjs ADDED
@@ -0,0 +1,138 @@
1
+ "use strict";
2
+
3
+ import { Static } from "./Static.mjs";
4
+
5
+ const DEFAULT_PLAY_VOLUME = 0.3;
6
+
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
+ }
138
+ }