malc-game-engine 1.0.1 → 1.0.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/malc.js +947 -944
- package/malc.min.js +294 -0
- package/package.json +1 -1
package/malc.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* MALC Game Engine Library
|
|
3
|
-
* Version: 1.0.
|
|
3
|
+
* Version: 1.0.2
|
|
4
4
|
* Description: A comprehensive 2D game engine for p5.js
|
|
5
5
|
*/
|
|
6
6
|
|
|
@@ -17,6 +17,9 @@
|
|
|
17
17
|
}
|
|
18
18
|
}(typeof self !== 'undefined' ? self : this, function(p5) {
|
|
19
19
|
|
|
20
|
+
// Store reference to p5 instance
|
|
21
|
+
const _p5 = p5;
|
|
22
|
+
|
|
20
23
|
// ========== GLOBAL ARRAYS ==========
|
|
21
24
|
const MALCgameObjects = [];
|
|
22
25
|
const MALCbuttons = [];
|
|
@@ -37,1121 +40,1121 @@ function generateId(prefix) {
|
|
|
37
40
|
return `${prefix}_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
38
41
|
}
|
|
39
42
|
|
|
40
|
-
// ==========
|
|
41
|
-
class
|
|
42
|
-
static
|
|
43
|
+
// ========== SCENE CLASS (DEFINED FIRST) ==========
|
|
44
|
+
class Scene {
|
|
45
|
+
static scenes = [];
|
|
46
|
+
static activeScene = "blank";
|
|
43
47
|
static started = false;
|
|
44
|
-
static
|
|
45
|
-
static
|
|
46
|
-
|
|
47
|
-
static render() {
|
|
48
|
-
MALCgameObjects.forEach(o => {
|
|
49
|
-
if (o.active) o.render();
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
|
-
|
|
48
|
+
static sceneHistory = [];
|
|
49
|
+
static historyLimit = 10;
|
|
50
|
+
|
|
53
51
|
static update() {
|
|
54
52
|
this.started = true;
|
|
55
|
-
this.
|
|
53
|
+
this.scenes = MALCScene;
|
|
56
54
|
|
|
57
|
-
|
|
58
|
-
MALCgameObjects.forEach(o => {
|
|
59
|
-
if (o.active) o.update();
|
|
60
|
-
});
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
static initialize() {
|
|
64
|
-
console.log("MALC gameObjects initialized");
|
|
55
|
+
let activeSceneFound = false;
|
|
65
56
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
57
|
+
this.scenes.forEach(S => {
|
|
58
|
+
if (S.id == this.activeScene) {
|
|
59
|
+
activeSceneFound = true;
|
|
60
|
+
|
|
61
|
+
this.scenes.forEach(s => {
|
|
62
|
+
if (s != S) {
|
|
63
|
+
s._active = false;
|
|
64
|
+
s.active = false;
|
|
65
|
+
|
|
66
|
+
s.objects.forEach(o => {
|
|
67
|
+
if (o && typeof o.active !== 'undefined') o.active = false;
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
S.active = true;
|
|
73
|
+
|
|
74
|
+
if (!S._active) {
|
|
75
|
+
S.activated = MALC.time.getTime();
|
|
76
|
+
if (typeof S.onActivate == 'function') S.onActivate();
|
|
72
77
|
}
|
|
73
|
-
|
|
78
|
+
|
|
79
|
+
S._active = true;
|
|
80
|
+
S.timeActive = MALC.time.getTime() - S.activated;
|
|
81
|
+
|
|
82
|
+
S.objects.forEach(o => {
|
|
83
|
+
if (o && typeof o.active !== 'undefined') o.active = true;
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
_p5.prototype.push();
|
|
87
|
+
if (window.camera && typeof camera.render == 'function') {
|
|
88
|
+
camera.render();
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
S.render();
|
|
92
|
+
|
|
93
|
+
_p5.prototype.pop();
|
|
94
|
+
}
|
|
74
95
|
});
|
|
96
|
+
|
|
97
|
+
if (!activeSceneFound && this.activeScene != "blank") {
|
|
98
|
+
console.warn(`Scene "${this.activeScene}" not found, switching to blank`);
|
|
99
|
+
this.activeScene = "blank";
|
|
100
|
+
}
|
|
75
101
|
}
|
|
76
102
|
|
|
77
|
-
static
|
|
78
|
-
return
|
|
103
|
+
static getSceneById(id) {
|
|
104
|
+
return MALCScene.find(scene => scene.id == id) || null;
|
|
79
105
|
}
|
|
80
106
|
|
|
81
|
-
static
|
|
82
|
-
return
|
|
107
|
+
static getActiveScene() {
|
|
108
|
+
return this.getSceneById(this.activeScene);
|
|
83
109
|
}
|
|
84
110
|
|
|
85
|
-
static
|
|
86
|
-
let scene =
|
|
87
|
-
|
|
111
|
+
static switchToScene(id, addToHistory = true) {
|
|
112
|
+
let scene = this.getSceneById(id);
|
|
113
|
+
if (scene) {
|
|
114
|
+
if (addToHistory && this.activeScene) {
|
|
115
|
+
this.sceneHistory.push(this.activeScene);
|
|
116
|
+
if (this.sceneHistory.length > this.historyLimit) {
|
|
117
|
+
this.sceneHistory.shift();
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
this.activeScene = id;
|
|
121
|
+
} else {
|
|
122
|
+
console.error(`Cannot switch to scene "${id}" - not found`);
|
|
123
|
+
}
|
|
88
124
|
}
|
|
89
125
|
|
|
90
|
-
static
|
|
91
|
-
this.
|
|
126
|
+
static goBack() {
|
|
127
|
+
if (this.sceneHistory.length > 0) {
|
|
128
|
+
let previousScene = this.sceneHistory.pop();
|
|
129
|
+
this.switchToScene(previousScene, false);
|
|
130
|
+
return true;
|
|
131
|
+
}
|
|
132
|
+
return false;
|
|
92
133
|
}
|
|
93
134
|
|
|
94
|
-
static
|
|
95
|
-
return
|
|
135
|
+
static getAllScenes() {
|
|
136
|
+
return [...MALCScene];
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
static getScenesWithObject(object) {
|
|
140
|
+
return MALCScene.filter(scene => scene.objects.includes(object));
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
static getScenesByTag(tag) {
|
|
144
|
+
return MALCScene.filter(scene => scene.hasTag(tag));
|
|
96
145
|
}
|
|
97
146
|
|
|
98
|
-
constructor(
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
this.rotation = 0;
|
|
105
|
-
this.rotationMode = "degrees";
|
|
106
|
-
this.velocity = [0, 0];
|
|
107
|
-
this.velocityMatrix = [0, 0];
|
|
108
|
-
this.velocityMode = "polar";
|
|
109
|
-
this.rvm = "unlinked";
|
|
110
|
-
|
|
111
|
-
// Gravity properties
|
|
112
|
-
this.gravity = {
|
|
113
|
-
enabled: false,
|
|
114
|
-
velocity: 0,
|
|
115
|
-
grounded: false,
|
|
116
|
-
groundTolerance: 1, // pixels
|
|
117
|
-
mass: 1,
|
|
118
|
-
bounce: 0, // 0 = no bounce, 1 = full bounce
|
|
119
|
-
friction: 0.1 // ground friction
|
|
120
|
-
};
|
|
147
|
+
constructor(id, backgroundColor, ...scripts) {
|
|
148
|
+
MALCScene.forEach(s => {
|
|
149
|
+
if (s.id == id || typeof id != "string") {
|
|
150
|
+
throw new Error(`Scenes must have unique IDs and be strings. Duplicate/Invalid ID: "${id}"`);
|
|
151
|
+
}
|
|
152
|
+
});
|
|
121
153
|
|
|
122
|
-
this.
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
};
|
|
154
|
+
this.id = id;
|
|
155
|
+
this.backColor = backgroundColor;
|
|
156
|
+
this.scripts = scripts;
|
|
126
157
|
|
|
127
|
-
this.
|
|
158
|
+
this.objects = [];
|
|
159
|
+
this.uiPlanes = [];
|
|
128
160
|
|
|
129
|
-
this.scripts = [];
|
|
130
|
-
this.scenes = scenes.length < 1 ? ["blank"] : [...new Set(scenes)];
|
|
131
161
|
this.active = false;
|
|
132
|
-
this.
|
|
133
|
-
this.
|
|
134
|
-
|
|
135
|
-
this.debug = false;
|
|
136
|
-
this.hitbox = {
|
|
137
|
-
x: 0,
|
|
138
|
-
y: 0,
|
|
139
|
-
width: 0,
|
|
140
|
-
height: 0,
|
|
141
|
-
rotation: 0,
|
|
142
|
-
parts: null,
|
|
143
|
-
outline: 1,
|
|
144
|
-
};
|
|
162
|
+
this._active = false;
|
|
163
|
+
this.activated = 0;
|
|
164
|
+
this.timeActive = -1;
|
|
145
165
|
|
|
146
|
-
this.
|
|
147
|
-
this.
|
|
166
|
+
this.tags = [];
|
|
167
|
+
this.paused = false;
|
|
168
|
+
this.transition = null;
|
|
169
|
+
this.onActivateCallbacks = [];
|
|
170
|
+
this.onDeactivateCallbacks = [];
|
|
171
|
+
this.onUpdateCallbacks = [];
|
|
148
172
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
// Enable gravity for this object
|
|
153
|
-
enableGravity() {
|
|
154
|
-
this.gravity.enabled = true;
|
|
155
|
-
return this;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
// Disable gravity for this object
|
|
159
|
-
disableGravity() {
|
|
160
|
-
this.gravity.enabled = false;
|
|
161
|
-
this.gravity.velocity = 0;
|
|
162
|
-
return this;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
// Set gravity parameters
|
|
166
|
-
setGravity(options = {}) {
|
|
167
|
-
if (options.enabled !== undefined) this.gravity.enabled = options.enabled;
|
|
168
|
-
if (options.mass !== undefined) this.gravity.mass = Math.max(0.1, options.mass);
|
|
169
|
-
if (options.bounce !== undefined) this.gravity.bounce = Math.min(1, Math.max(0, options.bounce));
|
|
170
|
-
if (options.friction !== undefined) this.gravity.friction = Math.min(1, Math.max(0, options.friction));
|
|
171
|
-
if (options.groundTolerance !== undefined) this.gravity.groundTolerance = options.groundTolerance;
|
|
172
|
-
return this;
|
|
173
|
+
this.sceneInstance = MALCScene.length;
|
|
174
|
+
MALCScene.push(this);
|
|
173
175
|
}
|
|
174
176
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
if (!this.gravity.enabled) return;
|
|
178
|
-
|
|
179
|
-
// Apply gravity acceleration (scaled by mass)
|
|
180
|
-
this.gravity.velocity += gameObject.gravity * this.gravity.mass;
|
|
177
|
+
render() {
|
|
178
|
+
if (this.paused) return;
|
|
181
179
|
|
|
182
|
-
|
|
183
|
-
|
|
180
|
+
if (this.transition) {
|
|
181
|
+
this.applyTransition();
|
|
182
|
+
}
|
|
184
183
|
|
|
185
|
-
|
|
186
|
-
let lastY = this.y;
|
|
184
|
+
_p5.prototype.background(this.backColor);
|
|
187
185
|
|
|
188
|
-
|
|
189
|
-
|
|
186
|
+
this.scripts.forEach(exe => {
|
|
187
|
+
if (typeof exe == "function") exe(this);
|
|
188
|
+
});
|
|
190
189
|
|
|
191
|
-
|
|
192
|
-
|
|
190
|
+
this.onUpdateCallbacks.forEach(cb => {
|
|
191
|
+
if (typeof cb == "function") cb(this);
|
|
192
|
+
});
|
|
193
193
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
// Apply ground friction to horizontal movement
|
|
199
|
-
if (this.gravity.friction > 0 && this.velocityMode === "polar") {
|
|
200
|
-
this.velocity[0] *= (1 - this.gravity.friction);
|
|
201
|
-
if (Math.abs(this.velocity[0]) < 0.01) this.velocity[0] = 0;
|
|
194
|
+
this.objects.forEach(o => {
|
|
195
|
+
if (o && typeof o.update == "function") {
|
|
196
|
+
o.update(true);
|
|
202
197
|
}
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
checkGroundCollision() {
|
|
208
|
-
if (!this.collition || !this.gravity.enabled) return;
|
|
209
|
-
|
|
210
|
-
let wasGrounded = this.gravity.grounded;
|
|
211
|
-
this.gravity.grounded = false;
|
|
198
|
+
if (o && typeof o.render == "function") {
|
|
199
|
+
o.render();
|
|
200
|
+
}
|
|
201
|
+
});
|
|
212
202
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
if (other.id === this.id || !other.active) return;
|
|
218
|
-
|
|
219
|
-
// Only check if gravity is enabled on this object and we're moving downward
|
|
220
|
-
if (this.gravity.velocity <= 0) return;
|
|
221
|
-
|
|
222
|
-
// Check if other object is below this one
|
|
223
|
-
let verticalDistance = (other.y - other.height/2) - (this.y + this.height/2);
|
|
224
|
-
|
|
225
|
-
// If within ground tolerance and horizontally overlapping
|
|
226
|
-
if (Math.abs(verticalDistance) <= this.gravity.groundTolerance &&
|
|
227
|
-
this.x + this.width/2 > other.x - other.width/2 &&
|
|
228
|
-
this.x - this.width/2 < other.x + other.width/2) {
|
|
229
|
-
|
|
230
|
-
this.gravity.grounded = true;
|
|
231
|
-
this.lastGroundY = other.y - other.height/2 - this.height/2;
|
|
232
|
-
|
|
233
|
-
// Apply bounce if enabled
|
|
234
|
-
if (this.gravity.bounce > 0 && wasGrounded === false) {
|
|
235
|
-
this.gravity.velocity = -this.gravity.velocity * this.gravity.bounce;
|
|
236
|
-
|
|
237
|
-
// If bounce velocity is very small, just set to zero
|
|
238
|
-
if (Math.abs(this.gravity.velocity) < 0.1) {
|
|
239
|
-
this.gravity.velocity = 0;
|
|
240
|
-
}
|
|
241
|
-
} else {
|
|
242
|
-
// Position exactly on ground
|
|
243
|
-
this.y = this.lastGroundY;
|
|
244
|
-
}
|
|
203
|
+
if (typeof UIPlanes !== 'undefined' && UIPlanes.length > 0) {
|
|
204
|
+
UIPlanes.forEach(ui => {
|
|
205
|
+
if (ui && typeof ui.belongsToScene == "function" && ui.belongsToScene(this.id)) {
|
|
206
|
+
ui.render();
|
|
245
207
|
}
|
|
246
208
|
});
|
|
247
209
|
}
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
update() {
|
|
251
|
-
if (!this.active) return;
|
|
252
|
-
|
|
253
|
-
// Apply gravity if enabled
|
|
254
|
-
this.applyGravity();
|
|
255
|
-
|
|
256
|
-
let vel = this.velocity[0];
|
|
257
|
-
let angle = this.velocity[1];
|
|
258
210
|
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
this.velocity[1] = this.rotation;
|
|
263
|
-
linked = true;
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
let rot = linked ?
|
|
267
|
-
(this.rotationMode == "degrees" ? (this.rotation) : radians(this.rotation)) :
|
|
268
|
-
(this.rotationMode == "degrees" ? (this.velocity[1]) : (this.velocity[1]));
|
|
269
|
-
|
|
270
|
-
if(isNaN(rot)){
|
|
271
|
-
vel = 0;
|
|
272
|
-
rot = 0;
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
let vx = vel * cos(rot);
|
|
276
|
-
let vy = vel * sin(rot);
|
|
277
|
-
|
|
278
|
-
this.velocityMatrix = [vx, vy];
|
|
279
|
-
|
|
280
|
-
// Don't apply horizontal movement if gravity is enabled and we're grounded with friction
|
|
281
|
-
if (!(this.gravity.enabled && this.gravity.grounded && this.gravity.friction > 0)) {
|
|
282
|
-
this.x += vx;
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
// Vertical movement is handled by gravity when enabled
|
|
286
|
-
if (!this.gravity.enabled) {
|
|
287
|
-
this.y += vy;
|
|
288
|
-
}
|
|
289
|
-
} else {
|
|
290
|
-
// Cartesian velocity mode
|
|
291
|
-
if (!(this.gravity.enabled && this.gravity.grounded && this.gravity.friction > 0)) {
|
|
292
|
-
this.x += vel;
|
|
293
|
-
}
|
|
294
|
-
if (!this.gravity.enabled) {
|
|
295
|
-
this.y += angle;
|
|
211
|
+
this.uiPlanes.forEach(ui => {
|
|
212
|
+
if (ui && typeof ui.render == "function") {
|
|
213
|
+
ui.render();
|
|
296
214
|
}
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
// Update parent scene reference
|
|
300
|
-
this.updateParentScene();
|
|
215
|
+
});
|
|
301
216
|
|
|
302
|
-
|
|
217
|
+
MALCScene[this.sceneInstance] = this;
|
|
303
218
|
}
|
|
304
219
|
|
|
305
|
-
|
|
306
|
-
if (!this.active) return;
|
|
307
|
-
|
|
308
|
-
this.scripts.forEach(s => {
|
|
309
|
-
if(typeof s == "function")s(this);
|
|
310
|
-
});
|
|
220
|
+
applyTransition() {
|
|
221
|
+
if (!this.transition || !this.transition.active) return;
|
|
311
222
|
|
|
312
|
-
|
|
313
|
-
let hb = this.hitbox;
|
|
223
|
+
this.transition.progress += 1/60;
|
|
314
224
|
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
rectMode(CENTER);
|
|
320
|
-
if (this.rotationMode == "degrees") angleMode(DEGREES);
|
|
321
|
-
rotate(this.rotation + hb.rotation);
|
|
322
|
-
|
|
323
|
-
stroke("#00FF27");
|
|
324
|
-
strokeWeight(hb.outline);
|
|
325
|
-
noFill();
|
|
326
|
-
rect(hb.x, hb.y, this.width + hb.width, this.height + hb.height);
|
|
327
|
-
|
|
328
|
-
// Draw gravity indicator if enabled
|
|
329
|
-
if (this.gravity.enabled) {
|
|
330
|
-
stroke(0, 255, 0, 100);
|
|
331
|
-
line(0, 0, 0, this.gravity.velocity * 5);
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
pop();
|
|
225
|
+
if (this.transition.progress >= this.transition.duration) {
|
|
226
|
+
this.transition.active = false;
|
|
227
|
+
this.transition = null;
|
|
228
|
+
return;
|
|
335
229
|
}
|
|
336
230
|
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
push();
|
|
340
|
-
translate(this.x, this.y);
|
|
341
|
-
rectMode(CENTER);
|
|
342
|
-
if (this.rotationMode == "degrees") angleMode(DEGREES);
|
|
343
|
-
rotate(this.rotation);
|
|
231
|
+
let t = this.transition.progress / this.transition.duration;
|
|
344
232
|
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
233
|
+
_p5.prototype.push();
|
|
234
|
+
switch(this.transition.type) {
|
|
235
|
+
case "fade":
|
|
236
|
+
_p5.prototype.fill(0, 255 * (1 - t));
|
|
237
|
+
_p5.prototype.rect(0, 0, _p5.prototype.width, _p5.prototype.height);
|
|
238
|
+
break;
|
|
239
|
+
case "slide":
|
|
240
|
+
_p5.prototype.translate(_p5.prototype.width * (1 - t), 0);
|
|
241
|
+
break;
|
|
350
242
|
}
|
|
351
|
-
|
|
352
|
-
fill(this.formatting.color);
|
|
353
|
-
rect(0, 0, this.width, this.height);
|
|
354
|
-
pop();
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
// ========== HELPFUL METHODS ==========
|
|
358
|
-
|
|
359
|
-
belongsToScene(sceneId) {
|
|
360
|
-
return this.scenes.includes(sceneId);
|
|
243
|
+
_p5.prototype.pop();
|
|
361
244
|
}
|
|
362
245
|
|
|
363
|
-
|
|
364
|
-
if (!this.
|
|
365
|
-
this.
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
scene.objects.push(this);
|
|
246
|
+
addObject(object) {
|
|
247
|
+
if (object && !this.objects.includes(object)) {
|
|
248
|
+
this.objects.push(object);
|
|
249
|
+
if (typeof object.addToScene == "function") {
|
|
250
|
+
object.addToScene(this.id);
|
|
369
251
|
}
|
|
370
252
|
}
|
|
371
253
|
return this;
|
|
372
254
|
}
|
|
373
255
|
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
256
|
+
addObjects(objects) {
|
|
257
|
+
objects.forEach(obj => this.addObject(obj));
|
|
258
|
+
return this;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
removeObject(object) {
|
|
262
|
+
this.objects = this.objects.filter(obj => obj != object);
|
|
263
|
+
if (object && typeof object.removeFromScene == "function") {
|
|
264
|
+
object.removeFromScene(this.id);
|
|
379
265
|
}
|
|
380
266
|
return this;
|
|
381
267
|
}
|
|
382
268
|
|
|
383
|
-
|
|
384
|
-
this.
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
scene.objects = scene.objects.filter(obj => obj != this);
|
|
269
|
+
clearObjects() {
|
|
270
|
+
this.objects.forEach(obj => {
|
|
271
|
+
if (obj && typeof obj.removeFromScene == "function") {
|
|
272
|
+
obj.removeFromScene(this.id);
|
|
388
273
|
}
|
|
389
274
|
});
|
|
390
|
-
this.
|
|
275
|
+
this.objects = [];
|
|
391
276
|
return this;
|
|
392
277
|
}
|
|
393
278
|
|
|
394
|
-
|
|
395
|
-
if (
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
279
|
+
getObjects(filter) {
|
|
280
|
+
if (typeof filter == "function") {
|
|
281
|
+
return this.objects.filter(filter);
|
|
282
|
+
} else if (filter == "button") {
|
|
283
|
+
return this.objects.filter(obj => obj instanceof Button);
|
|
284
|
+
} else if (filter == "gameObject") {
|
|
285
|
+
return this.objects.filter(obj => obj instanceof gameObject);
|
|
400
286
|
}
|
|
287
|
+
return this.objects;
|
|
401
288
|
}
|
|
402
289
|
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
let dy = target.y !== undefined ? target.y - this.y : target[1] - this.y;
|
|
406
|
-
return Math.sqrt(dx * dx + dy * dy);
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
collidesWith(other) {
|
|
410
|
-
return (this.x < other.x + other.width &&
|
|
411
|
-
this.x + this.width > other.x &&
|
|
412
|
-
this.y < other.y + other.height &&
|
|
413
|
-
this.y + this.height > other.y);
|
|
290
|
+
getObjectById(id) {
|
|
291
|
+
return this.objects.find(obj => obj && obj.id == id);
|
|
414
292
|
}
|
|
415
293
|
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
pa[0] < -err && pa[1] > err,
|
|
422
|
-
pa[0] < -err && pa[1] < -err,
|
|
423
|
-
pa[0] > err && pa[1] > err,
|
|
424
|
-
pa[0] > err && pa[1] < -err,
|
|
425
|
-
(pa[0] < err && pa[0] > -err),
|
|
426
|
-
(pa[1] < err && pa[1] > -err),
|
|
427
|
-
];
|
|
428
|
-
|
|
429
|
-
let da = (Math.atan(pa[1]/pa[0])*180)/Math.PI;
|
|
430
|
-
|
|
431
|
-
if((pa[1] > -err && pa[1] < err) && (pa[0] > -err && pa[0] < err)){
|
|
432
|
-
angle = NaN;
|
|
433
|
-
} else if(quads[0]){
|
|
434
|
-
angle = da+180;
|
|
435
|
-
} else if(quads[1]){
|
|
436
|
-
angle = da+180;
|
|
437
|
-
} else if(quads[2]){
|
|
438
|
-
angle = da;
|
|
439
|
-
} else if(quads[3]){
|
|
440
|
-
angle = da;
|
|
441
|
-
} else if(quads[4]){
|
|
442
|
-
if(pa[1] < -err) {
|
|
443
|
-
angle = -90;
|
|
444
|
-
} else if(pa[1] > err) {
|
|
445
|
-
angle = 90;
|
|
446
|
-
}
|
|
447
|
-
} else if(quads[5]){
|
|
448
|
-
if(pa[0] < -err) {
|
|
449
|
-
angle = 180;
|
|
450
|
-
} else if(pa[0] > err) {
|
|
451
|
-
angle = 0;
|
|
294
|
+
addUIPlane(uiPlane) {
|
|
295
|
+
if (uiPlane && !this.uiPlanes.includes(uiPlane)) {
|
|
296
|
+
this.uiPlanes.push(uiPlane);
|
|
297
|
+
if (typeof uiPlane.addToScene == "function") {
|
|
298
|
+
uiPlane.addToScene(this.id);
|
|
452
299
|
}
|
|
453
300
|
}
|
|
454
|
-
|
|
455
|
-
return angle;
|
|
456
|
-
}
|
|
457
|
-
|
|
458
|
-
pointTo(target) {
|
|
459
|
-
this.rotation = this.directionTo(target);
|
|
460
301
|
return this;
|
|
461
302
|
}
|
|
462
303
|
|
|
463
|
-
|
|
464
|
-
this.
|
|
465
|
-
|
|
304
|
+
removeUIPlane(uiPlane) {
|
|
305
|
+
this.uiPlanes = this.uiPlanes.filter(ui => ui != uiPlane);
|
|
306
|
+
if (uiPlane && typeof uiPlane.removeFromScene == "function") {
|
|
307
|
+
uiPlane.removeFromScene(this.id);
|
|
308
|
+
}
|
|
466
309
|
return this;
|
|
467
310
|
}
|
|
468
311
|
|
|
469
|
-
|
|
470
|
-
this.
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
if(isNaN(angle)){
|
|
479
|
-
angle = 0;
|
|
480
|
-
speed = 0;
|
|
481
|
-
}
|
|
482
|
-
|
|
483
|
-
this.velocity = [speed, angle];
|
|
484
|
-
return this.velocity;
|
|
312
|
+
clearUIPlanes() {
|
|
313
|
+
this.uiPlanes.forEach(ui => {
|
|
314
|
+
if (ui && typeof ui.removeFromScene == "function") {
|
|
315
|
+
ui.removeFromScene(this.id);
|
|
316
|
+
}
|
|
317
|
+
});
|
|
318
|
+
this.uiPlanes = [];
|
|
319
|
+
return this;
|
|
485
320
|
}
|
|
486
321
|
|
|
487
|
-
|
|
488
|
-
this.
|
|
489
|
-
|
|
490
|
-
if (index > -1) {
|
|
491
|
-
MALCgameObjects.splice(index, 1);
|
|
322
|
+
addScript(script) {
|
|
323
|
+
if (typeof script == "function" && !this.scripts.includes(script)) {
|
|
324
|
+
this.scripts.push(script);
|
|
492
325
|
}
|
|
326
|
+
return this;
|
|
493
327
|
}
|
|
494
328
|
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
clone.rotationMode = this.rotationMode;
|
|
499
|
-
clone.velocity = [...this.velocity];
|
|
500
|
-
clone.velocityMode = this.velocityMode;
|
|
501
|
-
clone.rvm = this.rvm;
|
|
502
|
-
clone.formatting = JSON.parse(JSON.stringify(this.formatting));
|
|
503
|
-
clone.gravity = JSON.parse(JSON.stringify(this.gravity));
|
|
504
|
-
clone.debug = this.debug;
|
|
505
|
-
clone.hitbox = JSON.parse(JSON.stringify(this.hitbox));
|
|
506
|
-
return clone;
|
|
329
|
+
removeScript(script) {
|
|
330
|
+
this.scripts = this.scripts.filter(s => s != script);
|
|
331
|
+
return this;
|
|
507
332
|
}
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
}
|
|
513
|
-
return { x: screenX, y: screenY };
|
|
333
|
+
|
|
334
|
+
clearScripts() {
|
|
335
|
+
this.scripts = [];
|
|
336
|
+
return this;
|
|
514
337
|
}
|
|
515
338
|
|
|
516
|
-
|
|
517
|
-
if (
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
let screenBottom = cameraPos[1] + camera.height;
|
|
522
|
-
|
|
523
|
-
return (this.x + this.width/2 > cameraPos[0] &&
|
|
524
|
-
this.x - this.width/2 < screenRight &&
|
|
525
|
-
this.y + this.height/2 > cameraPos[1] &&
|
|
526
|
-
this.y - this.height/2 < screenBottom);
|
|
339
|
+
onActivate(callback) {
|
|
340
|
+
if (typeof callback == "function") {
|
|
341
|
+
this.onActivateCallbacks.push(callback);
|
|
342
|
+
}
|
|
343
|
+
return this;
|
|
527
344
|
}
|
|
528
|
-
}
|
|
529
|
-
|
|
530
|
-
// ========== BUTTON CLASS ==========
|
|
531
|
-
class Button extends gameObject {
|
|
532
|
-
static buttons = [];
|
|
533
345
|
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
this
|
|
539
|
-
if (!b.active) return;
|
|
540
|
-
|
|
541
|
-
b.isHovered = b.events.hover();
|
|
542
|
-
|
|
543
|
-
if (MALCbuttons.every(b => !b.events.hover())) {
|
|
544
|
-
cursor();
|
|
545
|
-
} else if (b.isHovered) {
|
|
546
|
-
cursor(b.cursor);
|
|
547
|
-
}
|
|
548
|
-
});
|
|
346
|
+
onDeactivate(callback) {
|
|
347
|
+
if (typeof callback == "function") {
|
|
348
|
+
this.onDeactivateCallbacks.push(callback);
|
|
349
|
+
}
|
|
350
|
+
return this;
|
|
549
351
|
}
|
|
550
352
|
|
|
551
|
-
|
|
552
|
-
|
|
353
|
+
onUpdate(callback) {
|
|
354
|
+
if (typeof callback == "function") {
|
|
355
|
+
this.onUpdateCallbacks.push(callback);
|
|
356
|
+
}
|
|
357
|
+
return this;
|
|
553
358
|
}
|
|
554
359
|
|
|
555
|
-
|
|
556
|
-
|
|
360
|
+
pause() {
|
|
361
|
+
this.paused = true;
|
|
362
|
+
return this;
|
|
557
363
|
}
|
|
558
364
|
|
|
559
|
-
|
|
560
|
-
|
|
365
|
+
resume() {
|
|
366
|
+
this.paused = false;
|
|
367
|
+
return this;
|
|
561
368
|
}
|
|
562
369
|
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
text: {
|
|
570
|
-
color: 0,
|
|
571
|
-
size: 14,
|
|
572
|
-
style:"normal",
|
|
573
|
-
display: displayText,
|
|
574
|
-
},
|
|
575
|
-
colors: {
|
|
576
|
-
normal: 255,
|
|
577
|
-
hover: 220,
|
|
578
|
-
pressed: 190,
|
|
579
|
-
disabled: 150
|
|
580
|
-
}
|
|
581
|
-
};
|
|
582
|
-
|
|
583
|
-
this.cursor = "pointer";
|
|
584
|
-
this.isHovered = false;
|
|
585
|
-
this.isPressed = false;
|
|
586
|
-
this.isDisabled = false;
|
|
587
|
-
this.clickCooldown = 100;
|
|
588
|
-
this.lastClickTime = 0;
|
|
589
|
-
this.cooldownActive = false;
|
|
590
|
-
|
|
591
|
-
this.events = {
|
|
592
|
-
hover: (err = 0) => {
|
|
593
|
-
return !this.isDisabled && (
|
|
594
|
-
mouse.x < this.x + this.width / 2 + err &&
|
|
595
|
-
mouse.x > this.x - (this.width / 2 + err) &&
|
|
596
|
-
mouse.y < this.y + this.height / 2 + err &&
|
|
597
|
-
mouse.y > this.y - (this.height / 2 + err)
|
|
598
|
-
);
|
|
599
|
-
},
|
|
600
|
-
pressed: () => {
|
|
601
|
-
return this.events.hover() && mouse.down;
|
|
602
|
-
},
|
|
603
|
-
clicked: () => {
|
|
604
|
-
let wasPressed = this.wasPressed;
|
|
605
|
-
let isHovering = this.events.hover();
|
|
606
|
-
let mouseReleased = !mouse.down && wasPressed;
|
|
607
|
-
|
|
608
|
-
this.wasPressed = mouse.down && isHovering;
|
|
609
|
-
|
|
610
|
-
return mouseReleased && isHovering;
|
|
611
|
-
}
|
|
370
|
+
setTransition(type, duration = 1.0) {
|
|
371
|
+
this.transition = {
|
|
372
|
+
type: type,
|
|
373
|
+
duration: duration,
|
|
374
|
+
progress: 0,
|
|
375
|
+
active: true
|
|
612
376
|
};
|
|
613
|
-
|
|
614
|
-
this.wasPressed = false;
|
|
615
|
-
this.onClick = null;
|
|
616
|
-
|
|
617
|
-
this.buttonIndex = MALCbuttons.length;
|
|
618
|
-
MALCbuttons.push(this);
|
|
619
|
-
}
|
|
620
|
-
|
|
621
|
-
update(boolean) {
|
|
622
|
-
super.update(boolean);
|
|
623
|
-
|
|
624
|
-
if (this.cooldownActive) {
|
|
625
|
-
let currentTime = Date.now();
|
|
626
|
-
if (currentTime - this.lastClickTime >= this.clickCooldown) {
|
|
627
|
-
this.cooldownActive = false;
|
|
628
|
-
}
|
|
629
|
-
}
|
|
630
|
-
|
|
631
|
-
this.isHovered = this.events.hover();
|
|
632
|
-
this.isPressed = this.events.pressed();
|
|
633
|
-
|
|
634
|
-
if (this.events.clicked() && this.onClick && !this.isDisabled && !this.cooldownActive) {
|
|
635
|
-
this.onClick(this);
|
|
636
|
-
this.lastClickTime = Date.now();
|
|
637
|
-
this.cooldownActive = true;
|
|
638
|
-
}
|
|
639
|
-
|
|
640
|
-
MALCbuttons[this.buttonIndex] = this;
|
|
377
|
+
return this;
|
|
641
378
|
}
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
if (!this.
|
|
645
|
-
|
|
646
|
-
let btnFormat = this.formatting.button;
|
|
647
|
-
let buttonColor;
|
|
648
|
-
|
|
649
|
-
if (this.isDisabled) {
|
|
650
|
-
buttonColor = btnFormat.colors.disabled;
|
|
651
|
-
} else if (this.isPressed) {
|
|
652
|
-
buttonColor = btnFormat.colors.pressed;
|
|
653
|
-
} else if (this.isHovered) {
|
|
654
|
-
buttonColor = btnFormat.colors.hover;
|
|
655
|
-
} else {
|
|
656
|
-
buttonColor = btnFormat.colors.normal;
|
|
379
|
+
|
|
380
|
+
addTag(tag) {
|
|
381
|
+
if (!this.tags.includes(tag)) {
|
|
382
|
+
this.tags.push(tag);
|
|
657
383
|
}
|
|
658
|
-
|
|
659
|
-
let originalColor = this.formatting.color;
|
|
660
|
-
this.formatting.color = buttonColor;
|
|
661
|
-
|
|
662
|
-
super.render();
|
|
663
|
-
|
|
664
|
-
if(!this.visible) return;
|
|
665
|
-
|
|
666
|
-
push();
|
|
667
|
-
translate(this.x, this.y);
|
|
668
|
-
if (this.rotationMode == "degrees") angleMode(DEGREES);
|
|
669
|
-
rotate(this.rotation);
|
|
670
|
-
|
|
671
|
-
textStyle(btnFormat.text.style);
|
|
672
|
-
textSize(btnFormat.text.size);
|
|
673
|
-
fill(btnFormat.text.color);
|
|
674
|
-
coloredText(btnFormat.text.display, 0, 0, CENTER, CENTER);
|
|
675
|
-
pop();
|
|
676
|
-
|
|
677
|
-
this.formatting.color = originalColor;
|
|
384
|
+
return this;
|
|
678
385
|
}
|
|
679
386
|
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
setText(text) {
|
|
683
|
-
this.formatting.button.text.display = text;
|
|
387
|
+
removeTag(tag) {
|
|
388
|
+
this.tags = this.tags.filter(t => t != tag);
|
|
684
389
|
return this;
|
|
685
390
|
}
|
|
686
391
|
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
return [red(c), green(c), blue(c)];
|
|
392
|
+
hasTag(tag) {
|
|
393
|
+
return this.tags.includes(tag);
|
|
690
394
|
}
|
|
691
395
|
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
396
|
+
reset() {
|
|
397
|
+
this.clearObjects();
|
|
398
|
+
this.clearUIPlanes();
|
|
399
|
+
this.clearScripts();
|
|
400
|
+
this.onActivateCallbacks = [];
|
|
401
|
+
this.onDeactivateCallbacks = [];
|
|
402
|
+
this.onUpdateCallbacks = [];
|
|
403
|
+
this.tags = [];
|
|
404
|
+
this.paused = false;
|
|
405
|
+
this.transition = null;
|
|
406
|
+
this.timeActive = 0;
|
|
407
|
+
return this;
|
|
695
408
|
}
|
|
696
409
|
|
|
697
|
-
|
|
698
|
-
let
|
|
699
|
-
|
|
700
|
-
|
|
410
|
+
destroy() {
|
|
411
|
+
let index = MALCScene.indexOf(this);
|
|
412
|
+
if (index > -1) {
|
|
413
|
+
MALCScene.splice(index, 1);
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
this.clearObjects();
|
|
417
|
+
this.clearUIPlanes();
|
|
418
|
+
|
|
419
|
+
if (Scene.activeScene == this.id) {
|
|
420
|
+
Scene.activeScene = "blank";
|
|
421
|
+
}
|
|
701
422
|
}
|
|
702
423
|
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
let normalBrightness = this.getBrightness(originalNormal);
|
|
710
|
-
let hoverBrightness = this.getBrightness(originalHover);
|
|
711
|
-
let pressedBrightness = this.getBrightness(originalPressed);
|
|
712
|
-
|
|
713
|
-
let hoverScale = normalBrightness !== 0 ? hoverBrightness / normalBrightness : 0.86;
|
|
714
|
-
let pressedScale = normalBrightness !== 0 ? pressedBrightness / normalBrightness : 0.75;
|
|
715
|
-
|
|
716
|
-
hover = this.scaleColor(normal, hoverScale);
|
|
717
|
-
pressed = this.scaleColor(normal, pressedScale);
|
|
718
|
-
} else {
|
|
719
|
-
hover = color(hover);
|
|
720
|
-
pressed = color(pressed);
|
|
721
|
-
}
|
|
722
|
-
|
|
723
|
-
let normalColor = color(normal);
|
|
724
|
-
let disabledColor = disabled !== null ? color(disabled) : null;
|
|
725
|
-
|
|
726
|
-
this.formatting.button.colors.normal = normalColor;
|
|
727
|
-
this.formatting.button.colors.hover = hover;
|
|
728
|
-
this.formatting.button.colors.pressed = pressed;
|
|
729
|
-
if (disabledColor !== null) {
|
|
730
|
-
this.formatting.button.colors.disabled = disabledColor;
|
|
731
|
-
}
|
|
732
|
-
|
|
733
|
-
return this;
|
|
734
|
-
}
|
|
735
|
-
|
|
736
|
-
textStyle(color, size) {
|
|
737
|
-
if (color !== undefined) this.formatting.button.text.color = color;
|
|
738
|
-
if (size !== undefined) this.formatting.button.text.size = size;
|
|
739
|
-
return this;
|
|
740
|
-
}
|
|
741
|
-
|
|
742
|
-
Disable(disabled = true) {
|
|
743
|
-
this.isDisabled = disabled;
|
|
744
|
-
return this;
|
|
424
|
+
clone(newId) {
|
|
425
|
+
let clone = new Scene(newId || this.id + "_copy", this.backColor, ...this.scripts);
|
|
426
|
+
clone.objects = [...this.objects];
|
|
427
|
+
clone.uiPlanes = [...this.uiPlanes];
|
|
428
|
+
clone.tags = [...this.tags];
|
|
429
|
+
return clone;
|
|
745
430
|
}
|
|
746
431
|
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
432
|
+
getInfo() {
|
|
433
|
+
return {
|
|
434
|
+
id: this.id,
|
|
435
|
+
active: this.active,
|
|
436
|
+
timeActive: this.timeActive,
|
|
437
|
+
objectCount: this.objects.length,
|
|
438
|
+
uiPlaneCount: this.uiPlanes.length,
|
|
439
|
+
scriptCount: this.scripts.length,
|
|
440
|
+
tags: this.tags,
|
|
441
|
+
paused: this.paused
|
|
442
|
+
};
|
|
752
443
|
}
|
|
753
444
|
}
|
|
754
445
|
|
|
755
|
-
// ==========
|
|
756
|
-
class
|
|
757
|
-
static
|
|
758
|
-
static activeScene = "blank";
|
|
446
|
+
// ========== GAME OBJECT CLASS WITH GRAVITY ==========
|
|
447
|
+
class gameObject {
|
|
448
|
+
static objects = [];
|
|
759
449
|
static started = false;
|
|
760
|
-
static
|
|
761
|
-
static
|
|
762
|
-
|
|
450
|
+
static gravity = GRAVITY;
|
|
451
|
+
static terminalVelocity = TERMINAL_VELOCITY;
|
|
452
|
+
|
|
453
|
+
static render() {
|
|
454
|
+
MALCgameObjects.forEach(o => {
|
|
455
|
+
if (o.active) o.render();
|
|
456
|
+
});
|
|
457
|
+
}
|
|
458
|
+
|
|
763
459
|
static update() {
|
|
764
460
|
this.started = true;
|
|
765
|
-
this.
|
|
461
|
+
this.objects = MALCgameObjects;
|
|
766
462
|
|
|
767
|
-
|
|
463
|
+
// Update all active objects
|
|
464
|
+
MALCgameObjects.forEach(o => {
|
|
465
|
+
if (o.active) o.update();
|
|
466
|
+
});
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
static initialize() {
|
|
470
|
+
console.log("MALC gameObjects initialized");
|
|
768
471
|
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
s._active = false;
|
|
776
|
-
s.active = false;
|
|
777
|
-
|
|
778
|
-
s.objects.forEach(o => {
|
|
779
|
-
if (o && typeof o.active !== 'undefined') o.active = false;
|
|
780
|
-
});
|
|
781
|
-
}
|
|
782
|
-
});
|
|
783
|
-
|
|
784
|
-
S.active = true;
|
|
785
|
-
|
|
786
|
-
if (!S._active) {
|
|
787
|
-
S.activated = MALC.time.getTime();
|
|
788
|
-
if (typeof S.onActivate == 'function') S.onActivate();
|
|
789
|
-
}
|
|
790
|
-
|
|
791
|
-
S._active = true;
|
|
792
|
-
S.timeActive = MALC.time.getTime() - S.activated;
|
|
793
|
-
|
|
794
|
-
S.objects.forEach(o => {
|
|
795
|
-
if (o && typeof o.active !== 'undefined') o.active = true;
|
|
796
|
-
});
|
|
797
|
-
|
|
798
|
-
push();
|
|
799
|
-
if (window.camera && typeof camera.render == 'function') {
|
|
800
|
-
camera.render();
|
|
472
|
+
// Add objects to their scenes
|
|
473
|
+
MALCgameObjects.forEach(o => {
|
|
474
|
+
o.scenes.forEach(sceneId => {
|
|
475
|
+
let scene = Scene.getSceneById(sceneId);
|
|
476
|
+
if (scene && !scene.objects.includes(o)) {
|
|
477
|
+
scene.objects.push(o);
|
|
801
478
|
}
|
|
802
|
-
|
|
803
|
-
S.render();
|
|
804
|
-
|
|
805
|
-
pop();
|
|
806
|
-
}
|
|
479
|
+
});
|
|
807
480
|
});
|
|
808
|
-
|
|
809
|
-
if (!activeSceneFound && this.activeScene != "blank") {
|
|
810
|
-
console.warn(`Scene "${this.activeScene}" not found, switching to blank`);
|
|
811
|
-
this.activeScene = "blank";
|
|
812
|
-
}
|
|
813
481
|
}
|
|
814
482
|
|
|
815
|
-
static
|
|
816
|
-
return
|
|
483
|
+
static getObjectByIndex(index) {
|
|
484
|
+
return MALCgameObjects[index] || null;
|
|
817
485
|
}
|
|
818
486
|
|
|
819
|
-
static
|
|
820
|
-
return
|
|
487
|
+
static getActiveObjects() {
|
|
488
|
+
return MALCgameObjects.filter(o => o.active);
|
|
821
489
|
}
|
|
822
490
|
|
|
823
|
-
static
|
|
824
|
-
let scene =
|
|
825
|
-
|
|
826
|
-
if (addToHistory && this.activeScene) {
|
|
827
|
-
this.sceneHistory.push(this.activeScene);
|
|
828
|
-
if (this.sceneHistory.length > this.historyLimit) {
|
|
829
|
-
this.sceneHistory.shift();
|
|
830
|
-
}
|
|
831
|
-
}
|
|
832
|
-
this.activeScene = id;
|
|
833
|
-
} else {
|
|
834
|
-
console.error(`Cannot switch to scene "${id}" - not found`);
|
|
835
|
-
}
|
|
491
|
+
static getObjectsInScene(sceneId) {
|
|
492
|
+
let scene = Scene.getSceneById(sceneId);
|
|
493
|
+
return scene ? scene.objects : [];
|
|
836
494
|
}
|
|
837
495
|
|
|
838
|
-
static
|
|
839
|
-
|
|
840
|
-
let previousScene = this.sceneHistory.pop();
|
|
841
|
-
this.switchToScene(previousScene, false);
|
|
842
|
-
return true;
|
|
843
|
-
}
|
|
844
|
-
return false;
|
|
496
|
+
static setGlobalGravity(value) {
|
|
497
|
+
this.gravity = value;
|
|
845
498
|
}
|
|
846
499
|
|
|
847
|
-
static
|
|
848
|
-
return
|
|
500
|
+
static getGlobalGravity() {
|
|
501
|
+
return this.gravity;
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
constructor(x = 0, y = 0, w = 20, h = 20, ...scenes) {
|
|
505
|
+
this.id = generateId('gameObject');
|
|
506
|
+
this.x = x;
|
|
507
|
+
this.y = y;
|
|
508
|
+
this.width = w;
|
|
509
|
+
this.height = h;
|
|
510
|
+
this.rotation = 0;
|
|
511
|
+
this.rotationMode = "degrees";
|
|
512
|
+
this.velocity = [0, 0];
|
|
513
|
+
this.velocityMatrix = [0, 0];
|
|
514
|
+
this.velocityMode = "polar";
|
|
515
|
+
this.rvm = "unlinked";
|
|
516
|
+
|
|
517
|
+
// Gravity properties
|
|
518
|
+
this.gravity = {
|
|
519
|
+
enabled: false,
|
|
520
|
+
velocity: 0,
|
|
521
|
+
grounded: false,
|
|
522
|
+
groundTolerance: 1, // pixels
|
|
523
|
+
mass: 1,
|
|
524
|
+
bounce: 0, // 0 = no bounce, 1 = full bounce
|
|
525
|
+
friction: 0.1 // ground friction
|
|
526
|
+
};
|
|
527
|
+
|
|
528
|
+
this.formatting = {
|
|
529
|
+
outline: [false, 0, "black"],
|
|
530
|
+
color: "white",
|
|
531
|
+
};
|
|
532
|
+
|
|
533
|
+
this.collition = true;
|
|
534
|
+
|
|
535
|
+
this.scripts = [];
|
|
536
|
+
this.scenes = scenes.length < 1 ? ["blank"] : [...new Set(scenes)];
|
|
537
|
+
this.active = false;
|
|
538
|
+
this.visible = true;
|
|
539
|
+
this.parentScene = null;
|
|
540
|
+
|
|
541
|
+
this.debug = false;
|
|
542
|
+
this.hitbox = {
|
|
543
|
+
x: 0,
|
|
544
|
+
y: 0,
|
|
545
|
+
width: 0,
|
|
546
|
+
height: 0,
|
|
547
|
+
rotation: 0,
|
|
548
|
+
parts: null,
|
|
549
|
+
outline: 1,
|
|
550
|
+
};
|
|
551
|
+
|
|
552
|
+
this.objectInstance = MALCgameObjects.length;
|
|
553
|
+
this.lastGroundY = y;
|
|
554
|
+
|
|
555
|
+
MALCgameObjects.push(this);
|
|
849
556
|
}
|
|
850
557
|
|
|
851
|
-
|
|
852
|
-
|
|
558
|
+
// Enable gravity for this object
|
|
559
|
+
enableGravity() {
|
|
560
|
+
this.gravity.enabled = true;
|
|
561
|
+
return this;
|
|
853
562
|
}
|
|
854
563
|
|
|
855
|
-
|
|
856
|
-
|
|
564
|
+
// Disable gravity for this object
|
|
565
|
+
disableGravity() {
|
|
566
|
+
this.gravity.enabled = false;
|
|
567
|
+
this.gravity.velocity = 0;
|
|
568
|
+
return this;
|
|
857
569
|
}
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
570
|
+
|
|
571
|
+
// Set gravity parameters
|
|
572
|
+
setGravity(options = {}) {
|
|
573
|
+
if (options.enabled !== undefined) this.gravity.enabled = options.enabled;
|
|
574
|
+
if (options.mass !== undefined) this.gravity.mass = Math.max(0.1, options.mass);
|
|
575
|
+
if (options.bounce !== undefined) this.gravity.bounce = Math.min(1, Math.max(0, options.bounce));
|
|
576
|
+
if (options.friction !== undefined) this.gravity.friction = Math.min(1, Math.max(0, options.friction));
|
|
577
|
+
if (options.groundTolerance !== undefined) this.gravity.groundTolerance = options.groundTolerance;
|
|
578
|
+
return this;
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
// Apply gravity to this object
|
|
582
|
+
applyGravity() {
|
|
583
|
+
if (!this.gravity.enabled) return;
|
|
584
|
+
|
|
585
|
+
// Apply gravity acceleration (scaled by mass)
|
|
586
|
+
this.gravity.velocity += gameObject.gravity * this.gravity.mass;
|
|
587
|
+
|
|
588
|
+
// Limit to terminal velocity
|
|
589
|
+
this.gravity.velocity = Math.min(this.gravity.velocity, gameObject.terminalVelocity);
|
|
590
|
+
|
|
591
|
+
// Store last position before moving
|
|
592
|
+
let lastY = this.y;
|
|
593
|
+
|
|
594
|
+
// Apply vertical movement
|
|
595
|
+
this.y += this.gravity.velocity;
|
|
596
|
+
|
|
597
|
+
// Check for ground collision with other objects
|
|
598
|
+
this.checkGroundCollision();
|
|
599
|
+
|
|
600
|
+
// If we just landed, stop downward velocity
|
|
601
|
+
if (this.gravity.grounded) {
|
|
602
|
+
this.gravity.velocity = 0;
|
|
603
|
+
|
|
604
|
+
// Apply ground friction to horizontal movement
|
|
605
|
+
if (this.gravity.friction > 0 && this.velocityMode === "polar") {
|
|
606
|
+
this.velocity[0] *= (1 - this.gravity.friction);
|
|
607
|
+
if (Math.abs(this.velocity[0]) < 0.01) this.velocity[0] = 0;
|
|
863
608
|
}
|
|
864
|
-
}
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
// Check if this object is standing on another object
|
|
613
|
+
checkGroundCollision() {
|
|
614
|
+
if (!this.collition || !this.gravity.enabled) return;
|
|
865
615
|
|
|
866
|
-
|
|
867
|
-
this.
|
|
868
|
-
this.scripts = scripts;
|
|
616
|
+
let wasGrounded = this.gravity.grounded;
|
|
617
|
+
this.gravity.grounded = false;
|
|
869
618
|
|
|
870
|
-
|
|
871
|
-
this.
|
|
619
|
+
// Check collision with other objects in the same scene
|
|
620
|
+
if (this.parentScene && this.parentScene.objects) {
|
|
621
|
+
this.parentScene.objects.forEach(other => {
|
|
622
|
+
// Skip self and inactive objects
|
|
623
|
+
if (other.id === this.id || !other.active) return;
|
|
624
|
+
|
|
625
|
+
// Only check if gravity is enabled on this object and we're moving downward
|
|
626
|
+
if (this.gravity.velocity <= 0) return;
|
|
627
|
+
|
|
628
|
+
// Check if other object is below this one
|
|
629
|
+
let verticalDistance = (other.y - other.height/2) - (this.y + this.height/2);
|
|
630
|
+
|
|
631
|
+
// If within ground tolerance and horizontally overlapping
|
|
632
|
+
if (Math.abs(verticalDistance) <= this.gravity.groundTolerance &&
|
|
633
|
+
this.x + this.width/2 > other.x - other.width/2 &&
|
|
634
|
+
this.x - this.width/2 < other.x + other.width/2) {
|
|
635
|
+
|
|
636
|
+
this.gravity.grounded = true;
|
|
637
|
+
this.lastGroundY = other.y - other.height/2 - this.height/2;
|
|
638
|
+
|
|
639
|
+
// Apply bounce if enabled
|
|
640
|
+
if (this.gravity.bounce > 0 && wasGrounded === false) {
|
|
641
|
+
this.gravity.velocity = -this.gravity.velocity * this.gravity.bounce;
|
|
642
|
+
|
|
643
|
+
// If bounce velocity is very small, just set to zero
|
|
644
|
+
if (Math.abs(this.gravity.velocity) < 0.1) {
|
|
645
|
+
this.gravity.velocity = 0;
|
|
646
|
+
}
|
|
647
|
+
} else {
|
|
648
|
+
// Position exactly on ground
|
|
649
|
+
this.y = this.lastGroundY;
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
});
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
update() {
|
|
657
|
+
if (!this.active) return;
|
|
872
658
|
|
|
873
|
-
|
|
874
|
-
this.
|
|
875
|
-
this.activated = 0;
|
|
876
|
-
this.timeActive = -1;
|
|
659
|
+
// Apply gravity if enabled
|
|
660
|
+
this.applyGravity();
|
|
877
661
|
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
this.
|
|
882
|
-
|
|
883
|
-
|
|
662
|
+
let vel = this.velocity[0];
|
|
663
|
+
let angle = this.velocity[1];
|
|
664
|
+
|
|
665
|
+
if (this.velocityMode == "polar") {
|
|
666
|
+
let linked = false;
|
|
667
|
+
if (!/unlinked/i.test(this.rvm) && /linked/i.test(this.rvm)) {
|
|
668
|
+
this.velocity[1] = this.rotation;
|
|
669
|
+
linked = true;
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
let rot = linked ?
|
|
673
|
+
(this.rotationMode == "degrees" ? (this.rotation) : _p5.prototype.radians(this.rotation)) :
|
|
674
|
+
(this.rotationMode == "degrees" ? (this.velocity[1]) : (this.velocity[1]));
|
|
675
|
+
|
|
676
|
+
if(isNaN(rot)){
|
|
677
|
+
vel = 0;
|
|
678
|
+
rot = 0;
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
let vx = vel * _p5.prototype.cos(rot);
|
|
682
|
+
let vy = vel * _p5.prototype.sin(rot);
|
|
683
|
+
|
|
684
|
+
this.velocityMatrix = [vx, vy];
|
|
685
|
+
|
|
686
|
+
// Don't apply horizontal movement if gravity is enabled and we're grounded with friction
|
|
687
|
+
if (!(this.gravity.enabled && this.gravity.grounded && this.gravity.friction > 0)) {
|
|
688
|
+
this.x += vx;
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
// Vertical movement is handled by gravity when enabled
|
|
692
|
+
if (!this.gravity.enabled) {
|
|
693
|
+
this.y += vy;
|
|
694
|
+
}
|
|
695
|
+
} else {
|
|
696
|
+
// Cartesian velocity mode
|
|
697
|
+
if (!(this.gravity.enabled && this.gravity.grounded && this.gravity.friction > 0)) {
|
|
698
|
+
this.x += vel;
|
|
699
|
+
}
|
|
700
|
+
if (!this.gravity.enabled) {
|
|
701
|
+
this.y += angle;
|
|
702
|
+
}
|
|
703
|
+
}
|
|
884
704
|
|
|
885
|
-
|
|
886
|
-
|
|
705
|
+
// Update parent scene reference
|
|
706
|
+
this.updateParentScene();
|
|
707
|
+
|
|
708
|
+
MALCgameObjects[this.objectInstance] = this;
|
|
887
709
|
}
|
|
888
710
|
|
|
889
711
|
render() {
|
|
890
|
-
if (this.
|
|
891
|
-
|
|
892
|
-
if (this.transition) {
|
|
893
|
-
this.applyTransition();
|
|
894
|
-
}
|
|
895
|
-
|
|
896
|
-
background(this.backColor);
|
|
712
|
+
if (!this.active) return;
|
|
897
713
|
|
|
898
|
-
this.scripts.forEach(
|
|
899
|
-
if
|
|
714
|
+
this.scripts.forEach(s => {
|
|
715
|
+
if(typeof s == "function")s(this);
|
|
900
716
|
});
|
|
901
717
|
|
|
902
|
-
this.
|
|
903
|
-
|
|
904
|
-
});
|
|
718
|
+
let outline = this.formatting.outline;
|
|
719
|
+
let hb = this.hitbox;
|
|
905
720
|
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
721
|
+
// Draw debug hitbox if enabled
|
|
722
|
+
if (this.debug) {
|
|
723
|
+
_p5.prototype.push();
|
|
724
|
+
_p5.prototype.translate(this.x, this.y);
|
|
725
|
+
_p5.prototype.rectMode(_p5.prototype.CENTER);
|
|
726
|
+
if (this.rotationMode == "degrees") _p5.prototype.angleMode(_p5.prototype.DEGREES);
|
|
727
|
+
_p5.prototype.rotate(this.rotation + hb.rotation);
|
|
728
|
+
|
|
729
|
+
_p5.prototype.stroke("#00FF27");
|
|
730
|
+
_p5.prototype.strokeWeight(hb.outline);
|
|
731
|
+
_p5.prototype.noFill();
|
|
732
|
+
_p5.prototype.rect(hb.x, hb.y, this.width + hb.width, this.height + hb.height);
|
|
733
|
+
|
|
734
|
+
// Draw gravity indicator if enabled
|
|
735
|
+
if (this.gravity.enabled) {
|
|
736
|
+
_p5.prototype.stroke(0, 255, 0, 100);
|
|
737
|
+
_p5.prototype.line(0, 0, 0, this.gravity.velocity * 5);
|
|
912
738
|
}
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
if (typeof UIPlanes !== 'undefined' && UIPlanes.length > 0) {
|
|
916
|
-
UIPlanes.forEach(ui => {
|
|
917
|
-
if (ui && typeof ui.belongsToScene == "function" && ui.belongsToScene(this.id)) {
|
|
918
|
-
ui.render();
|
|
919
|
-
}
|
|
920
|
-
});
|
|
739
|
+
|
|
740
|
+
_p5.prototype.pop();
|
|
921
741
|
}
|
|
922
742
|
|
|
923
|
-
this.
|
|
924
|
-
if (ui && typeof ui.render == "function") {
|
|
925
|
-
ui.render();
|
|
926
|
-
}
|
|
927
|
-
});
|
|
928
|
-
|
|
929
|
-
MALCScene[this.sceneInstance] = this;
|
|
930
|
-
}
|
|
931
|
-
|
|
932
|
-
applyTransition() {
|
|
933
|
-
if (!this.transition || !this.transition.active) return;
|
|
743
|
+
if (!this.visible) return;
|
|
934
744
|
|
|
935
|
-
|
|
745
|
+
_p5.prototype.push();
|
|
746
|
+
_p5.prototype.translate(this.x, this.y);
|
|
747
|
+
_p5.prototype.rectMode(_p5.prototype.CENTER);
|
|
748
|
+
if (this.rotationMode == "degrees") _p5.prototype.angleMode(_p5.prototype.DEGREES);
|
|
749
|
+
_p5.prototype.rotate(this.rotation);
|
|
936
750
|
|
|
937
|
-
if (
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
751
|
+
if (outline[0]) {
|
|
752
|
+
_p5.prototype.strokeWeight(outline[1]);
|
|
753
|
+
_p5.prototype.stroke(outline[2]);
|
|
754
|
+
} else {
|
|
755
|
+
_p5.prototype.noStroke();
|
|
941
756
|
}
|
|
942
757
|
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
switch(this.transition.type) {
|
|
947
|
-
case "fade":
|
|
948
|
-
fill(0, 255 * (1 - t));
|
|
949
|
-
rect(0, 0, width, height);
|
|
950
|
-
break;
|
|
951
|
-
case "slide":
|
|
952
|
-
translate(width * (1 - t), 0);
|
|
953
|
-
break;
|
|
954
|
-
}
|
|
955
|
-
pop();
|
|
758
|
+
_p5.prototype.fill(this.formatting.color);
|
|
759
|
+
_p5.prototype.rect(0, 0, this.width, this.height);
|
|
760
|
+
_p5.prototype.pop();
|
|
956
761
|
}
|
|
762
|
+
|
|
763
|
+
// ========== HELPFUL METHODS ==========
|
|
957
764
|
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
this.objects.push(object);
|
|
961
|
-
if (typeof object.addToScene == "function") {
|
|
962
|
-
object.addToScene(this.id);
|
|
963
|
-
}
|
|
964
|
-
}
|
|
965
|
-
return this;
|
|
765
|
+
belongsToScene(sceneId) {
|
|
766
|
+
return this.scenes.includes(sceneId);
|
|
966
767
|
}
|
|
967
768
|
|
|
968
|
-
|
|
969
|
-
|
|
769
|
+
addToScene(sceneId) {
|
|
770
|
+
if (!this.scenes.includes(sceneId)) {
|
|
771
|
+
this.scenes.push(sceneId);
|
|
772
|
+
let scene = Scene.getSceneById(sceneId);
|
|
773
|
+
if (scene && !scene.objects.includes(this)) {
|
|
774
|
+
scene.objects.push(this);
|
|
775
|
+
}
|
|
776
|
+
}
|
|
970
777
|
return this;
|
|
971
778
|
}
|
|
972
779
|
|
|
973
|
-
|
|
974
|
-
this.
|
|
975
|
-
|
|
976
|
-
|
|
780
|
+
removeFromScene(sceneId) {
|
|
781
|
+
this.scenes = this.scenes.filter(id => id != sceneId);
|
|
782
|
+
let scene = Scene.getSceneById(sceneId);
|
|
783
|
+
if (scene) {
|
|
784
|
+
scene.objects = scene.objects.filter(obj => obj != this);
|
|
977
785
|
}
|
|
978
786
|
return this;
|
|
979
787
|
}
|
|
980
788
|
|
|
981
|
-
|
|
982
|
-
this.
|
|
983
|
-
|
|
984
|
-
|
|
789
|
+
removeFromAllScenes() {
|
|
790
|
+
this.scenes.forEach(sceneId => {
|
|
791
|
+
let scene = Scene.getSceneById(sceneId);
|
|
792
|
+
if (scene) {
|
|
793
|
+
scene.objects = scene.objects.filter(obj => obj != this);
|
|
985
794
|
}
|
|
986
795
|
});
|
|
987
|
-
this.
|
|
796
|
+
this.scenes = [];
|
|
988
797
|
return this;
|
|
989
798
|
}
|
|
990
799
|
|
|
991
|
-
|
|
992
|
-
if (
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
return this.objects.filter(obj => obj instanceof gameObject);
|
|
800
|
+
updateParentScene() {
|
|
801
|
+
if (Scene.activeScene) {
|
|
802
|
+
let activeScene = Scene.getSceneById(Scene.activeScene);
|
|
803
|
+
if (activeScene && this.belongsToScene(activeScene.id)) {
|
|
804
|
+
this.parentScene = activeScene;
|
|
805
|
+
}
|
|
998
806
|
}
|
|
999
|
-
return this.objects;
|
|
1000
807
|
}
|
|
1001
808
|
|
|
1002
|
-
|
|
1003
|
-
|
|
809
|
+
distanceTo(target) {
|
|
810
|
+
let dx = target.x !== undefined ? target.x - this.x : target[0] - this.x;
|
|
811
|
+
let dy = target.y !== undefined ? target.y - this.y : target[1] - this.y;
|
|
812
|
+
return Math.sqrt(dx * dx + dy * dy);
|
|
1004
813
|
}
|
|
1005
814
|
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
815
|
+
collidesWith(other) {
|
|
816
|
+
return (this.x < other.x + other.width &&
|
|
817
|
+
this.x + this.width > other.x &&
|
|
818
|
+
this.y < other.y + other.height &&
|
|
819
|
+
this.y + this.height > other.y);
|
|
820
|
+
}
|
|
821
|
+
|
|
822
|
+
directionTo(x, y, err = 0.5) {
|
|
823
|
+
let pa = [x - this.x, y - this.y];
|
|
824
|
+
|
|
825
|
+
let angle = (x && y) ? _p5.prototype.atan(pa[1]/pa[0]) : this.rotation;
|
|
826
|
+
var quads = [
|
|
827
|
+
pa[0] < -err && pa[1] > err,
|
|
828
|
+
pa[0] < -err && pa[1] < -err,
|
|
829
|
+
pa[0] > err && pa[1] > err,
|
|
830
|
+
pa[0] > err && pa[1] < -err,
|
|
831
|
+
(pa[0] < err && pa[0] > -err),
|
|
832
|
+
(pa[1] < err && pa[1] > -err),
|
|
833
|
+
];
|
|
834
|
+
|
|
835
|
+
let da = (_p5.prototype.atan(pa[1]/pa[0]) * 180)/Math.PI;
|
|
836
|
+
|
|
837
|
+
if((pa[1] > -err && pa[1] < err) && (pa[0] > -err && pa[0] < err)){
|
|
838
|
+
angle = NaN;
|
|
839
|
+
} else if(quads[0]){
|
|
840
|
+
angle = da+180;
|
|
841
|
+
} else if(quads[1]){
|
|
842
|
+
angle = da+180;
|
|
843
|
+
} else if(quads[2]){
|
|
844
|
+
angle = da;
|
|
845
|
+
} else if(quads[3]){
|
|
846
|
+
angle = da;
|
|
847
|
+
} else if(quads[4]){
|
|
848
|
+
if(pa[1] < -err) {
|
|
849
|
+
angle = -90;
|
|
850
|
+
} else if(pa[1] > err) {
|
|
851
|
+
angle = 90;
|
|
852
|
+
}
|
|
853
|
+
} else if(quads[5]){
|
|
854
|
+
if(pa[0] < -err) {
|
|
855
|
+
angle = 180;
|
|
856
|
+
} else if(pa[0] > err) {
|
|
857
|
+
angle = 0;
|
|
1011
858
|
}
|
|
1012
859
|
}
|
|
860
|
+
|
|
861
|
+
return angle;
|
|
862
|
+
}
|
|
863
|
+
|
|
864
|
+
pointTo(target) {
|
|
865
|
+
this.rotation = this.directionTo(target);
|
|
1013
866
|
return this;
|
|
1014
867
|
}
|
|
1015
868
|
|
|
1016
|
-
|
|
1017
|
-
this.
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
869
|
+
setPosition(x, y) {
|
|
870
|
+
this.x = x;
|
|
871
|
+
this.y = y;
|
|
872
|
+
return this;
|
|
873
|
+
}
|
|
874
|
+
|
|
875
|
+
move(dx, dy) {
|
|
876
|
+
this.x += dx;
|
|
877
|
+
this.y += dy;
|
|
1021
878
|
return this;
|
|
1022
879
|
}
|
|
1023
880
|
|
|
1024
|
-
|
|
1025
|
-
this.
|
|
1026
|
-
|
|
1027
|
-
|
|
881
|
+
setVelocity(speed, x, y, err = 0.5){
|
|
882
|
+
let angle = this.directionTo(x,y,err);
|
|
883
|
+
|
|
884
|
+
if(isNaN(angle)){
|
|
885
|
+
angle = 0;
|
|
886
|
+
speed = 0;
|
|
887
|
+
}
|
|
888
|
+
|
|
889
|
+
this.velocity = [speed, angle];
|
|
890
|
+
return this.velocity;
|
|
891
|
+
}
|
|
892
|
+
|
|
893
|
+
destroy() {
|
|
894
|
+
this.removeFromAllScenes();
|
|
895
|
+
let index = MALCgameObjects.indexOf(this);
|
|
896
|
+
if (index > -1) {
|
|
897
|
+
MALCgameObjects.splice(index, 1);
|
|
898
|
+
}
|
|
899
|
+
}
|
|
900
|
+
|
|
901
|
+
clone() {
|
|
902
|
+
let clone = new gameObject(this.x, this.y, this.width, this.height, ...this.scenes);
|
|
903
|
+
clone.rotation = this.rotation;
|
|
904
|
+
clone.rotationMode = this.rotationMode;
|
|
905
|
+
clone.velocity = [...this.velocity];
|
|
906
|
+
clone.velocityMode = this.velocityMode;
|
|
907
|
+
clone.rvm = this.rvm;
|
|
908
|
+
clone.formatting = JSON.parse(JSON.stringify(this.formatting));
|
|
909
|
+
clone.gravity = JSON.parse(JSON.stringify(this.gravity));
|
|
910
|
+
clone.debug = this.debug;
|
|
911
|
+
clone.hitbox = JSON.parse(JSON.stringify(this.hitbox));
|
|
912
|
+
return clone;
|
|
913
|
+
}
|
|
914
|
+
|
|
915
|
+
screenToWorld(screenX, screenY) {
|
|
916
|
+
if (window.camera && typeof camera.screenToWorld == "function") {
|
|
917
|
+
return camera.screenToWorld(screenX, screenY);
|
|
918
|
+
}
|
|
919
|
+
return { x: screenX, y: screenY };
|
|
920
|
+
}
|
|
921
|
+
|
|
922
|
+
isOnScreen() {
|
|
923
|
+
if (!window.camera) return true;
|
|
924
|
+
|
|
925
|
+
let cameraPos = camera.getOrientation();
|
|
926
|
+
let screenRight = cameraPos[0] + camera.width;
|
|
927
|
+
let screenBottom = cameraPos[1] + camera.height;
|
|
928
|
+
|
|
929
|
+
return (this.x + this.width/2 > cameraPos[0] &&
|
|
930
|
+
this.x - this.width/2 < screenRight &&
|
|
931
|
+
this.y + this.height/2 > cameraPos[1] &&
|
|
932
|
+
this.y - this.height/2 < screenBottom);
|
|
933
|
+
}
|
|
934
|
+
}
|
|
935
|
+
|
|
936
|
+
// ========== BUTTON CLASS ==========
|
|
937
|
+
class Button extends gameObject {
|
|
938
|
+
static buttons = [];
|
|
939
|
+
|
|
940
|
+
static updateButton() {
|
|
941
|
+
this.startedButtons = true;
|
|
942
|
+
this.buttons = MALCbuttons;
|
|
943
|
+
|
|
944
|
+
this.buttons.forEach(b => {
|
|
945
|
+
if (!b.active) return;
|
|
946
|
+
|
|
947
|
+
b.isHovered = b.events.hover();
|
|
948
|
+
|
|
949
|
+
if (MALCbuttons.every(b => !b.events.hover())) {
|
|
950
|
+
_p5.prototype.cursor();
|
|
951
|
+
} else if (b.isHovered) {
|
|
952
|
+
_p5.prototype.cursor(b.cursor);
|
|
1028
953
|
}
|
|
1029
954
|
});
|
|
1030
|
-
this.uiPlanes = [];
|
|
1031
|
-
return this;
|
|
1032
955
|
}
|
|
1033
956
|
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
this.scripts.push(script);
|
|
1037
|
-
}
|
|
1038
|
-
return this;
|
|
957
|
+
static getButtonByIndex(index) {
|
|
958
|
+
return MALCbuttons[index] || null;
|
|
1039
959
|
}
|
|
1040
960
|
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
return this;
|
|
961
|
+
static getHoveredButton() {
|
|
962
|
+
return MALCbuttons.find(b => b.active && b.events.hover());
|
|
1044
963
|
}
|
|
1045
964
|
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
return this;
|
|
965
|
+
static getPressedButton() {
|
|
966
|
+
return MALCbuttons.find(b => b.active && b.events.pressed());
|
|
1049
967
|
}
|
|
1050
968
|
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
969
|
+
constructor(x = 0, y = 0, w = 20, h = 20, displayText = "Button", ...scenes) {
|
|
970
|
+
super(x, y, w, h, ...scenes);
|
|
971
|
+
|
|
972
|
+
this.formatting.button = {
|
|
973
|
+
hover: 220,
|
|
974
|
+
clicked: 190,
|
|
975
|
+
text: {
|
|
976
|
+
color: 0,
|
|
977
|
+
size: 14,
|
|
978
|
+
style:"normal",
|
|
979
|
+
display: displayText,
|
|
980
|
+
},
|
|
981
|
+
colors: {
|
|
982
|
+
normal: 255,
|
|
983
|
+
hover: 220,
|
|
984
|
+
pressed: 190,
|
|
985
|
+
disabled: 150
|
|
986
|
+
}
|
|
987
|
+
};
|
|
988
|
+
|
|
989
|
+
this.cursor = "pointer";
|
|
990
|
+
this.isHovered = false;
|
|
991
|
+
this.isPressed = false;
|
|
992
|
+
this.isDisabled = false;
|
|
993
|
+
this.clickCooldown = 100;
|
|
994
|
+
this.lastClickTime = 0;
|
|
995
|
+
this.cooldownActive = false;
|
|
996
|
+
|
|
997
|
+
this.events = {
|
|
998
|
+
hover: (err = 0) => {
|
|
999
|
+
return !this.isDisabled && (
|
|
1000
|
+
window.mouse.x < this.x + this.width / 2 + err &&
|
|
1001
|
+
window.mouse.x > this.x - (this.width / 2 + err) &&
|
|
1002
|
+
window.mouse.y < this.y + this.height / 2 + err &&
|
|
1003
|
+
window.mouse.y > this.y - (this.height / 2 + err)
|
|
1004
|
+
);
|
|
1005
|
+
},
|
|
1006
|
+
pressed: () => {
|
|
1007
|
+
return this.events.hover() && window.mouse.down;
|
|
1008
|
+
},
|
|
1009
|
+
clicked: () => {
|
|
1010
|
+
let wasPressed = this.wasPressed;
|
|
1011
|
+
let isHovering = this.events.hover();
|
|
1012
|
+
let mouseReleased = !window.mouse.down && wasPressed;
|
|
1013
|
+
|
|
1014
|
+
this.wasPressed = window.mouse.down && isHovering;
|
|
1015
|
+
|
|
1016
|
+
return mouseReleased && isHovering;
|
|
1017
|
+
}
|
|
1018
|
+
};
|
|
1019
|
+
|
|
1020
|
+
this.wasPressed = false;
|
|
1021
|
+
this.onClick = null;
|
|
1022
|
+
|
|
1023
|
+
this.buttonIndex = MALCbuttons.length;
|
|
1024
|
+
MALCbuttons.push(this);
|
|
1025
|
+
}
|
|
1026
|
+
|
|
1027
|
+
update(boolean) {
|
|
1028
|
+
super.update(boolean);
|
|
1029
|
+
|
|
1030
|
+
if (this.cooldownActive) {
|
|
1031
|
+
let currentTime = Date.now();
|
|
1032
|
+
if (currentTime - this.lastClickTime >= this.clickCooldown) {
|
|
1033
|
+
this.cooldownActive = false;
|
|
1034
|
+
}
|
|
1054
1035
|
}
|
|
1055
|
-
|
|
1036
|
+
|
|
1037
|
+
this.isHovered = this.events.hover();
|
|
1038
|
+
this.isPressed = this.events.pressed();
|
|
1039
|
+
|
|
1040
|
+
if (this.events.clicked() && this.onClick && !this.isDisabled && !this.cooldownActive) {
|
|
1041
|
+
this.onClick(this);
|
|
1042
|
+
this.lastClickTime = Date.now();
|
|
1043
|
+
this.cooldownActive = true;
|
|
1044
|
+
}
|
|
1045
|
+
|
|
1046
|
+
MALCbuttons[this.buttonIndex] = this;
|
|
1056
1047
|
}
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
if (
|
|
1060
|
-
|
|
1048
|
+
|
|
1049
|
+
render() {
|
|
1050
|
+
if (!this.active) return;
|
|
1051
|
+
|
|
1052
|
+
let btnFormat = this.formatting.button;
|
|
1053
|
+
let buttonColor;
|
|
1054
|
+
|
|
1055
|
+
if (this.isDisabled) {
|
|
1056
|
+
buttonColor = btnFormat.colors.disabled;
|
|
1057
|
+
} else if (this.isPressed) {
|
|
1058
|
+
buttonColor = btnFormat.colors.pressed;
|
|
1059
|
+
} else if (this.isHovered) {
|
|
1060
|
+
buttonColor = btnFormat.colors.hover;
|
|
1061
|
+
} else {
|
|
1062
|
+
buttonColor = btnFormat.colors.normal;
|
|
1061
1063
|
}
|
|
1062
|
-
|
|
1064
|
+
|
|
1065
|
+
let originalColor = this.formatting.color;
|
|
1066
|
+
this.formatting.color = buttonColor;
|
|
1067
|
+
|
|
1068
|
+
super.render();
|
|
1069
|
+
|
|
1070
|
+
if(!this.visible) return;
|
|
1071
|
+
|
|
1072
|
+
_p5.prototype.push();
|
|
1073
|
+
_p5.prototype.translate(this.x, this.y);
|
|
1074
|
+
if (this.rotationMode == "degrees") _p5.prototype.angleMode(_p5.prototype.DEGREES);
|
|
1075
|
+
_p5.prototype.rotate(this.rotation);
|
|
1076
|
+
|
|
1077
|
+
_p5.prototype.textStyle(btnFormat.text.style);
|
|
1078
|
+
_p5.prototype.textSize(btnFormat.text.size);
|
|
1079
|
+
_p5.prototype.fill(btnFormat.text.color);
|
|
1080
|
+
_p5.prototype.coloredText(btnFormat.text.display, 0, 0, _p5.prototype.CENTER, _p5.prototype.CENTER);
|
|
1081
|
+
_p5.prototype.pop();
|
|
1082
|
+
|
|
1083
|
+
this.formatting.color = originalColor;
|
|
1063
1084
|
}
|
|
1064
1085
|
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1086
|
+
// ========== BUTTON-SPECIFIC HELPER METHODS ==========
|
|
1087
|
+
|
|
1088
|
+
setText(text) {
|
|
1089
|
+
this.formatting.button.text.display = text;
|
|
1069
1090
|
return this;
|
|
1070
1091
|
}
|
|
1071
1092
|
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
return
|
|
1093
|
+
getRGBFromColor(colorInput) {
|
|
1094
|
+
let c = _p5.prototype.color(colorInput);
|
|
1095
|
+
return [_p5.prototype.red(c), _p5.prototype.green(c), _p5.prototype.blue(c)];
|
|
1075
1096
|
}
|
|
1076
1097
|
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
return
|
|
1098
|
+
getBrightness(colorInput) {
|
|
1099
|
+
let rgb = this.getRGBFromColor(colorInput);
|
|
1100
|
+
return 0.299 * rgb[0] + 0.587 * rgb[1] + 0.114 * rgb[2];
|
|
1080
1101
|
}
|
|
1081
1102
|
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
progress: 0,
|
|
1087
|
-
active: true
|
|
1088
|
-
};
|
|
1089
|
-
return this;
|
|
1103
|
+
scaleColor(baseColor, scaleFactor) {
|
|
1104
|
+
let rgb = this.getRGBFromColor(baseColor);
|
|
1105
|
+
let scaledRGB = rgb.map(val => _p5.prototype.constrain(val * scaleFactor, 0, 255));
|
|
1106
|
+
return _p5.prototype.color(scaledRGB);
|
|
1090
1107
|
}
|
|
1091
1108
|
|
|
1092
|
-
|
|
1093
|
-
if (
|
|
1094
|
-
this.
|
|
1109
|
+
setColors(normal, hover = null, pressed = null, disabled = null) {
|
|
1110
|
+
if (hover === null && pressed === null) {
|
|
1111
|
+
let originalNormal = this.formatting.button.colors.normal;
|
|
1112
|
+
let originalHover = this.formatting.button.colors.hover;
|
|
1113
|
+
let originalPressed = this.formatting.button.colors.pressed;
|
|
1114
|
+
|
|
1115
|
+
let normalBrightness = this.getBrightness(originalNormal);
|
|
1116
|
+
let hoverBrightness = this.getBrightness(originalHover);
|
|
1117
|
+
let pressedBrightness = this.getBrightness(originalPressed);
|
|
1118
|
+
|
|
1119
|
+
let hoverScale = normalBrightness !== 0 ? hoverBrightness / normalBrightness : 0.86;
|
|
1120
|
+
let pressedScale = normalBrightness !== 0 ? pressedBrightness / normalBrightness : 0.75;
|
|
1121
|
+
|
|
1122
|
+
hover = this.scaleColor(normal, hoverScale);
|
|
1123
|
+
pressed = this.scaleColor(normal, pressedScale);
|
|
1124
|
+
} else {
|
|
1125
|
+
hover = _p5.prototype.color(hover);
|
|
1126
|
+
pressed = _p5.prototype.color(pressed);
|
|
1127
|
+
}
|
|
1128
|
+
|
|
1129
|
+
let normalColor = _p5.prototype.color(normal);
|
|
1130
|
+
let disabledColor = disabled !== null ? _p5.prototype.color(disabled) : null;
|
|
1131
|
+
|
|
1132
|
+
this.formatting.button.colors.normal = normalColor;
|
|
1133
|
+
this.formatting.button.colors.hover = hover;
|
|
1134
|
+
this.formatting.button.colors.pressed = pressed;
|
|
1135
|
+
if (disabledColor !== null) {
|
|
1136
|
+
this.formatting.button.colors.disabled = disabledColor;
|
|
1095
1137
|
}
|
|
1138
|
+
|
|
1096
1139
|
return this;
|
|
1097
1140
|
}
|
|
1098
1141
|
|
|
1099
|
-
|
|
1100
|
-
|
|
1142
|
+
textStyle(color, size) {
|
|
1143
|
+
if (color !== undefined) this.formatting.button.text.color = color;
|
|
1144
|
+
if (size !== undefined) this.formatting.button.text.size = size;
|
|
1101
1145
|
return this;
|
|
1102
1146
|
}
|
|
1103
1147
|
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
}
|
|
1107
|
-
|
|
1108
|
-
reset() {
|
|
1109
|
-
this.clearObjects();
|
|
1110
|
-
this.clearUIPlanes();
|
|
1111
|
-
this.clearScripts();
|
|
1112
|
-
this.onActivateCallbacks = [];
|
|
1113
|
-
this.onDeactivateCallbacks = [];
|
|
1114
|
-
this.onUpdateCallbacks = [];
|
|
1115
|
-
this.tags = [];
|
|
1116
|
-
this.paused = false;
|
|
1117
|
-
this.transition = null;
|
|
1118
|
-
this.timeActive = 0;
|
|
1148
|
+
Disable(disabled = true) {
|
|
1149
|
+
this.isDisabled = disabled;
|
|
1119
1150
|
return this;
|
|
1120
1151
|
}
|
|
1121
1152
|
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
MALCScene.splice(index, 1);
|
|
1126
|
-
}
|
|
1127
|
-
|
|
1128
|
-
this.clearObjects();
|
|
1129
|
-
this.clearUIPlanes();
|
|
1130
|
-
|
|
1131
|
-
if (Scene.activeScene == this.id) {
|
|
1132
|
-
Scene.activeScene = "blank";
|
|
1153
|
+
click(call) {
|
|
1154
|
+
if(typeof call == "function" && this.events.pressed()){
|
|
1155
|
+
call();
|
|
1133
1156
|
}
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
clone(newId) {
|
|
1137
|
-
let clone = new Scene(newId || this.id + "_copy", this.backColor, ...this.scripts);
|
|
1138
|
-
clone.objects = [...this.objects];
|
|
1139
|
-
clone.uiPlanes = [...this.uiPlanes];
|
|
1140
|
-
clone.tags = [...this.tags];
|
|
1141
|
-
return clone;
|
|
1142
|
-
}
|
|
1143
|
-
|
|
1144
|
-
getInfo() {
|
|
1145
|
-
return {
|
|
1146
|
-
id: this.id,
|
|
1147
|
-
active: this.active,
|
|
1148
|
-
timeActive: this.timeActive,
|
|
1149
|
-
objectCount: this.objects.length,
|
|
1150
|
-
uiPlaneCount: this.uiPlanes.length,
|
|
1151
|
-
scriptCount: this.scripts.length,
|
|
1152
|
-
tags: this.tags,
|
|
1153
|
-
paused: this.paused
|
|
1154
|
-
};
|
|
1157
|
+
return this.events.clicked();
|
|
1155
1158
|
}
|
|
1156
1159
|
}
|
|
1157
1160
|
|
|
@@ -1351,20 +1354,20 @@ class UIPlane {
|
|
|
1351
1354
|
}
|
|
1352
1355
|
|
|
1353
1356
|
render() {
|
|
1354
|
-
push();
|
|
1357
|
+
_p5.prototype.push();
|
|
1355
1358
|
|
|
1356
1359
|
this.applyOrientation();
|
|
1357
1360
|
this.applyTextFormatting();
|
|
1358
1361
|
|
|
1359
1362
|
if (this.formatting.objectScale !== 1) {
|
|
1360
|
-
scale(this.formatting.objectScale);
|
|
1363
|
+
_p5.prototype.scale(this.formatting.objectScale);
|
|
1361
1364
|
}
|
|
1362
1365
|
|
|
1363
1366
|
if (typeof this.executable == "function") {
|
|
1364
1367
|
this.executable(this);
|
|
1365
1368
|
}
|
|
1366
1369
|
|
|
1367
|
-
pop();
|
|
1370
|
+
_p5.prototype.pop();
|
|
1368
1371
|
}
|
|
1369
1372
|
|
|
1370
1373
|
applyOrientation() {
|
|
@@ -1378,21 +1381,21 @@ class UIPlane {
|
|
|
1378
1381
|
} else {
|
|
1379
1382
|
cameraPos = [window.camera.x || 0, window.camera.y || 0];
|
|
1380
1383
|
}
|
|
1381
|
-
translate(cameraPos[0] + offsetX, cameraPos[1] + offsetY);
|
|
1384
|
+
_p5.prototype.translate(cameraPos[0] + offsetX, cameraPos[1] + offsetY);
|
|
1382
1385
|
} else {
|
|
1383
|
-
translate(offsetX, offsetY);
|
|
1386
|
+
_p5.prototype.translate(offsetX, offsetY);
|
|
1384
1387
|
}
|
|
1385
1388
|
} else if (mode.toLowerCase() == "screen") {
|
|
1386
|
-
translate(offsetX, offsetY);
|
|
1389
|
+
_p5.prototype.translate(offsetX, offsetY);
|
|
1387
1390
|
} else if (mode.includes(",")) {
|
|
1388
1391
|
try {
|
|
1389
1392
|
let coords = mode.split(",").map(Number);
|
|
1390
1393
|
if (coords.length >= 2) {
|
|
1391
1394
|
if (window.camera && typeof window.camera.worldToScreen == "function") {
|
|
1392
1395
|
let screenPos = window.camera.worldToScreen(coords[0], coords[1]);
|
|
1393
|
-
translate(screenPos.x + offsetX, screenPos.y + offsetY);
|
|
1396
|
+
_p5.prototype.translate(screenPos.x + offsetX, screenPos.y + offsetY);
|
|
1394
1397
|
} else {
|
|
1395
|
-
translate(coords[0] + offsetX, coords[1] + offsetY);
|
|
1398
|
+
_p5.prototype.translate(coords[0] + offsetX, coords[1] + offsetY);
|
|
1396
1399
|
}
|
|
1397
1400
|
}
|
|
1398
1401
|
} catch (e) {
|
|
@@ -1402,46 +1405,46 @@ class UIPlane {
|
|
|
1402
1405
|
}
|
|
1403
1406
|
|
|
1404
1407
|
applyTextFormatting() {
|
|
1405
|
-
textSize(this.formatting.txt.base);
|
|
1406
|
-
fill(this.formatting.txt.color);
|
|
1407
|
-
textAlign(LEFT, TOP);
|
|
1408
|
+
_p5.prototype.textSize(this.formatting.txt.base);
|
|
1409
|
+
_p5.prototype.fill(this.formatting.txt.color);
|
|
1410
|
+
_p5.prototype.textAlign(_p5.prototype.LEFT, _p5.prototype.TOP);
|
|
1408
1411
|
}
|
|
1409
1412
|
|
|
1410
1413
|
drawText(str, x, y, hAlign = LEFT, vAlign = TOP) {
|
|
1411
|
-
push();
|
|
1414
|
+
_p5.prototype.push();
|
|
1412
1415
|
|
|
1413
1416
|
if (str.startsWith("[title]")) {
|
|
1414
|
-
textSize(this.formatting.txt.title);
|
|
1417
|
+
_p5.prototype.textSize(this.formatting.txt.title);
|
|
1415
1418
|
str = str.replace("[title]", "");
|
|
1416
1419
|
} else if (str.startsWith("[heading]")) {
|
|
1417
|
-
textSize(this.formatting.txt.heading);
|
|
1420
|
+
_p5.prototype.textSize(this.formatting.txt.heading);
|
|
1418
1421
|
str = str.replace("[heading]", "");
|
|
1419
1422
|
} else if (str.startsWith("[subtitle]")) {
|
|
1420
|
-
textSize(this.formatting.txt.subtitle);
|
|
1423
|
+
_p5.prototype.textSize(this.formatting.txt.subtitle);
|
|
1421
1424
|
str = str.replace("[subtitle]", "");
|
|
1422
1425
|
} else {
|
|
1423
|
-
textSize(this.formatting.txt.base);
|
|
1426
|
+
_p5.prototype.textSize(this.formatting.txt.base);
|
|
1424
1427
|
}
|
|
1425
1428
|
|
|
1426
|
-
fill(this.formatting.txt.color);
|
|
1427
|
-
textAlign(hAlign, vAlign);
|
|
1428
|
-
text(str, x, y);
|
|
1429
|
+
_p5.prototype.fill(this.formatting.txt.color);
|
|
1430
|
+
_p5.prototype.textAlign(hAlign, vAlign);
|
|
1431
|
+
_p5.prototype.text(str, x, y);
|
|
1429
1432
|
|
|
1430
|
-
pop();
|
|
1433
|
+
_p5.prototype.pop();
|
|
1431
1434
|
}
|
|
1432
1435
|
|
|
1433
1436
|
drawButton(button, x, y) {
|
|
1434
|
-
push();
|
|
1437
|
+
_p5.prototype.push();
|
|
1435
1438
|
|
|
1436
1439
|
if (this.formatting.objectScale !== 1) {
|
|
1437
|
-
scale(this.formatting.objectScale);
|
|
1440
|
+
_p5.prototype.scale(this.formatting.objectScale);
|
|
1438
1441
|
}
|
|
1439
1442
|
|
|
1440
1443
|
if (button && typeof button.render == "function") {
|
|
1441
1444
|
button.render();
|
|
1442
1445
|
}
|
|
1443
1446
|
|
|
1444
|
-
pop();
|
|
1447
|
+
_p5.prototype.pop();
|
|
1445
1448
|
}
|
|
1446
1449
|
|
|
1447
1450
|
belongsToScene(sceneId) {
|
|
@@ -1591,7 +1594,7 @@ class Camera {
|
|
|
1591
1594
|
}
|
|
1592
1595
|
|
|
1593
1596
|
let [translateX, translateY] = this.getOrientation();
|
|
1594
|
-
translate(-translateX, -translateY);
|
|
1597
|
+
_p5.prototype.translate(-translateX, -translateY);
|
|
1595
1598
|
}
|
|
1596
1599
|
|
|
1597
1600
|
unlink() {
|
|
@@ -2130,14 +2133,14 @@ class GameController {
|
|
|
2130
2133
|
back: null,
|
|
2131
2134
|
primary: null,
|
|
2132
2135
|
secondary: null,
|
|
2133
|
-
leftbumber: null,
|
|
2134
|
-
rightbumber: null,
|
|
2135
|
-
lefttrigger: null,
|
|
2136
|
-
righttrigger: null,
|
|
2136
|
+
leftbumber: null,
|
|
2137
|
+
rightbumber: null,
|
|
2138
|
+
lefttrigger: null,
|
|
2139
|
+
righttrigger: null,
|
|
2137
2140
|
view: null,
|
|
2138
2141
|
menu: null,
|
|
2139
|
-
leftstick: null,
|
|
2140
|
-
rightstick: null,
|
|
2142
|
+
leftstick: null,
|
|
2143
|
+
rightstick: null,
|
|
2141
2144
|
up: null,
|
|
2142
2145
|
down: null,
|
|
2143
2146
|
left: null,
|
|
@@ -2366,7 +2369,7 @@ const helpDocs = {
|
|
|
2366
2369
|
// Game Engine Overview
|
|
2367
2370
|
overview: `
|
|
2368
2371
|
MALC Game Engine - A comprehensive 2D game engine for p5.js
|
|
2369
|
-
Version: 1.0.
|
|
2372
|
+
Version: 1.0.1
|
|
2370
2373
|
|
|
2371
2374
|
Core Features:
|
|
2372
2375
|
- Scene management system
|
|
@@ -2520,8 +2523,8 @@ const helpDocs = {
|
|
|
2520
2523
|
isButtonPressed: "Check button by index",
|
|
2521
2524
|
getButtonValue: "Get analog button value"
|
|
2522
2525
|
},
|
|
2523
|
-
buttonNames: ["select", "back", "primary", "secondary", "
|
|
2524
|
-
"
|
|
2526
|
+
buttonNames: ["select", "back", "primary", "secondary", "leftbumber", "rightbumber",
|
|
2527
|
+
"lefttrigger", "righttrigger", "view", "menu", "leftstick", "rightstick",
|
|
2525
2528
|
"up", "down", "left", "right", "home"]
|
|
2526
2529
|
}
|
|
2527
2530
|
},
|
|
@@ -2542,10 +2545,10 @@ const helpDocs = {
|
|
|
2542
2545
|
}
|
|
2543
2546
|
|
|
2544
2547
|
// 2. Create a scene
|
|
2545
|
-
let gameScene = new Scene("game", 220);
|
|
2548
|
+
let gameScene = new MALC.Scene("game", 220);
|
|
2546
2549
|
|
|
2547
2550
|
// 3. Create a game object with gravity
|
|
2548
|
-
let player = new gameObject(100, 100, 50, 50, "game")
|
|
2551
|
+
let player = new MALC.gameObject(100, 100, 50, 50, "game")
|
|
2549
2552
|
.enableGravity()
|
|
2550
2553
|
.setGravity({ mass: 1, bounce: 0.3 });
|
|
2551
2554
|
|
|
@@ -2558,7 +2561,7 @@ const helpDocs = {
|
|
|
2558
2561
|
|
|
2559
2562
|
// ========== MALC MAIN OBJECT ==========
|
|
2560
2563
|
const MALC = {
|
|
2561
|
-
version: "1.0.
|
|
2564
|
+
version: "1.0.1",
|
|
2562
2565
|
|
|
2563
2566
|
// Core classes
|
|
2564
2567
|
gameObject: gameObject,
|
|
@@ -2675,7 +2678,7 @@ const MALC = {
|
|
|
2675
2678
|
|
|
2676
2679
|
// Initialize the engine
|
|
2677
2680
|
init: function(canvasX, canvasY) {
|
|
2678
|
-
createCanvas(canvasX, canvasY);
|
|
2681
|
+
_p5.prototype.createCanvas(canvasX, canvasY);
|
|
2679
2682
|
|
|
2680
2683
|
this.time = new Date();
|
|
2681
2684
|
this.startTime = this.time.getTime();
|
|
@@ -2693,7 +2696,7 @@ const MALC = {
|
|
|
2693
2696
|
// Create default scenes
|
|
2694
2697
|
new Scene("blank", 70);
|
|
2695
2698
|
new Scene("loading", 50, function(self) {
|
|
2696
|
-
textSize(24);
|
|
2699
|
+
_p5.prototype.textSize(24);
|
|
2697
2700
|
let timed = (self.timeActive / 250 % 4);
|
|
2698
2701
|
let dots = "";
|
|
2699
2702
|
|
|
@@ -2701,11 +2704,11 @@ const MALC = {
|
|
|
2701
2704
|
else if (timed < 2) dots = "..";
|
|
2702
2705
|
else if (timed < 3) dots = "...";
|
|
2703
2706
|
|
|
2704
|
-
coloredText(`\\lime|Loading Game${dots}| `, 120, 200, LEFT, CENTER);
|
|
2705
|
-
textSize(16);
|
|
2707
|
+
_p5.prototype.coloredText(`\\lime|Loading Game${dots}| `, 120, 200, _p5.prototype.LEFT, _p5.prototype.CENTER);
|
|
2708
|
+
_p5.prototype.textSize(16);
|
|
2706
2709
|
|
|
2707
2710
|
let num = (Math.floor(self.timeActive / 100) / 10);
|
|
2708
|
-
coloredText(`\\red|${ Math.round((10 - num) * 10) / 10 + ((num + "").length < 2 ? ".0" : "")}|`, 200, 225, CENTER, CENTER);
|
|
2711
|
+
_p5.prototype.coloredText(`\\red|${ Math.round((10 - num) * 10) / 10 + ((num + "").length < 2 ? ".0" : "")}|`, 200, 225, _p5.prototype.CENTER, _p5.prototype.CENTER);
|
|
2709
2712
|
});
|
|
2710
2713
|
|
|
2711
2714
|
Scene.activeScene = "loading";
|
|
@@ -2720,11 +2723,11 @@ const MALC = {
|
|
|
2720
2723
|
this.timer = this.time - this.startTime;
|
|
2721
2724
|
|
|
2722
2725
|
if (this.mouse) {
|
|
2723
|
-
this.mouse.rawX = mouseX;
|
|
2724
|
-
this.mouse.rawY = mouseY;
|
|
2725
|
-
this.mouse.x = this.mouse.rawX + camera.getOrientation()[0];
|
|
2726
|
-
this.mouse.y = this.mouse.rawY + camera.getOrientation()[1];
|
|
2727
|
-
this.mouse.down = mouseIsPressed;
|
|
2726
|
+
this.mouse.rawX = _p5.prototype.mouseX;
|
|
2727
|
+
this.mouse.rawY = _p5.prototype.mouseY;
|
|
2728
|
+
this.mouse.x = this.mouse.rawX + window.camera.getOrientation()[0];
|
|
2729
|
+
this.mouse.y = this.mouse.rawY + window.camera.getOrientation()[1];
|
|
2730
|
+
this.mouse.down = _p5.prototype.mouseIsPressed;
|
|
2728
2731
|
}
|
|
2729
2732
|
|
|
2730
2733
|
controller.update();
|
|
@@ -2734,8 +2737,8 @@ const MALC = {
|
|
|
2734
2737
|
|
|
2735
2738
|
this.fps = fps;
|
|
2736
2739
|
|
|
2737
|
-
if (typeof camera.render == "function") {
|
|
2738
|
-
camera.render();
|
|
2740
|
+
if (typeof window.camera.render == "function") {
|
|
2741
|
+
window.camera.render();
|
|
2739
2742
|
}
|
|
2740
2743
|
Scene.update();
|
|
2741
2744
|
}
|