malc-game-engine 1.0.2 → 1.0.4
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 +165 -155
- package/malc.min.js +18 -16
- 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.3
|
|
4
4
|
* Description: A comprehensive 2D game engine for p5.js
|
|
5
5
|
*/
|
|
6
6
|
|
|
@@ -40,6 +40,93 @@ function generateId(prefix) {
|
|
|
40
40
|
return `${prefix}_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
+
// ========== COLORED TEXT FUNCTION (STANDALONE) ==========
|
|
44
|
+
function coloredText(str, x, y, horizontal, vertical, maxWidth) {
|
|
45
|
+
const p = _p5.prototype; // Use the current p5 instance
|
|
46
|
+
const parts = parseColoredText(str);
|
|
47
|
+
let currentX = x;
|
|
48
|
+
let currentY = y;
|
|
49
|
+
|
|
50
|
+
p.push();
|
|
51
|
+
p.textAlign(horizontal || LEFT, vertical || BASELINE);
|
|
52
|
+
|
|
53
|
+
for (const part of parts) {
|
|
54
|
+
if (part.isNewline) {
|
|
55
|
+
currentX = x;
|
|
56
|
+
currentY += p.textLeading() || p.textSize() * 1.2;
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (part.color) {
|
|
61
|
+
try {
|
|
62
|
+
p.fill(part.color);
|
|
63
|
+
} catch (e) {
|
|
64
|
+
p.fill(255);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
p.text(part.text, currentX, currentY, maxWidth);
|
|
69
|
+
currentX += p.textWidth(part.text);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
p.pop();
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Keep these helper functions (they don't need to change)
|
|
76
|
+
function parseColoredLine(str) {
|
|
77
|
+
const regex = /\\([^|\\\n]+)\|([^|]+)\|/g;
|
|
78
|
+
const parts = [];
|
|
79
|
+
let lastIndex = 0;
|
|
80
|
+
let match;
|
|
81
|
+
|
|
82
|
+
while ((match = regex.exec(str)) !== null) {
|
|
83
|
+
if (match.index > lastIndex) {
|
|
84
|
+
parts.push({
|
|
85
|
+
text: str.substring(lastIndex, match.index),
|
|
86
|
+
color: null
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
parts.push({
|
|
91
|
+
text: match[2],
|
|
92
|
+
color: match[1]
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
lastIndex = match.index + match[0].length;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
if (lastIndex < str.length) {
|
|
99
|
+
parts.push({
|
|
100
|
+
text: str.substring(lastIndex),
|
|
101
|
+
color: null
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
return parts.length ? parts : [{ text: str, color: null }];
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function parseColoredText(str) {
|
|
109
|
+
const lines = str.split('\n');
|
|
110
|
+
const result = [];
|
|
111
|
+
|
|
112
|
+
for (let i = 0; i < lines.length; i++) {
|
|
113
|
+
const line = lines[i];
|
|
114
|
+
const parts = parseColoredLine(line);
|
|
115
|
+
|
|
116
|
+
result.push(...parts);
|
|
117
|
+
|
|
118
|
+
if (i < lines.length - 1) {
|
|
119
|
+
result.push({
|
|
120
|
+
text: '\n',
|
|
121
|
+
color: null,
|
|
122
|
+
isNewline: true
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return result;
|
|
128
|
+
}
|
|
129
|
+
|
|
43
130
|
// ========== SCENE CLASS (DEFINED FIRST) ==========
|
|
44
131
|
class Scene {
|
|
45
132
|
static scenes = [];
|
|
@@ -84,8 +171,8 @@ class Scene {
|
|
|
84
171
|
});
|
|
85
172
|
|
|
86
173
|
_p5.prototype.push();
|
|
87
|
-
if (window.camera && typeof camera.render == 'function') {
|
|
88
|
-
camera.render();
|
|
174
|
+
if (window.camera && typeof window.camera.render == 'function') {
|
|
175
|
+
window.camera.render();
|
|
89
176
|
}
|
|
90
177
|
|
|
91
178
|
S.render();
|
|
@@ -913,8 +1000,8 @@ class gameObject {
|
|
|
913
1000
|
}
|
|
914
1001
|
|
|
915
1002
|
screenToWorld(screenX, screenY) {
|
|
916
|
-
if (window.camera && typeof camera.screenToWorld == "function") {
|
|
917
|
-
return camera.screenToWorld(screenX, screenY);
|
|
1003
|
+
if (window.camera && typeof window.camera.screenToWorld == "function") {
|
|
1004
|
+
return window.camera.screenToWorld(screenX, screenY);
|
|
918
1005
|
}
|
|
919
1006
|
return { x: screenX, y: screenY };
|
|
920
1007
|
}
|
|
@@ -922,9 +1009,9 @@ class gameObject {
|
|
|
922
1009
|
isOnScreen() {
|
|
923
1010
|
if (!window.camera) return true;
|
|
924
1011
|
|
|
925
|
-
let cameraPos = camera.getOrientation();
|
|
926
|
-
let screenRight = cameraPos[0] + camera.width;
|
|
927
|
-
let screenBottom = cameraPos[1] + camera.height;
|
|
1012
|
+
let cameraPos = window.camera.getOrientation();
|
|
1013
|
+
let screenRight = cameraPos[0] + window.camera.width;
|
|
1014
|
+
let screenBottom = cameraPos[1] + window.camera.height;
|
|
928
1015
|
|
|
929
1016
|
return (this.x + this.width/2 > cameraPos[0] &&
|
|
930
1017
|
this.x - this.width/2 < screenRight &&
|
|
@@ -1047,42 +1134,45 @@ class Button extends gameObject {
|
|
|
1047
1134
|
}
|
|
1048
1135
|
|
|
1049
1136
|
render() {
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
}
|
|
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;
|
|
1137
|
+
if (!this.active) return;
|
|
1138
|
+
|
|
1139
|
+
let btnFormat = this.formatting.button;
|
|
1140
|
+
let buttonColor;
|
|
1141
|
+
|
|
1142
|
+
if (this.isDisabled) {
|
|
1143
|
+
buttonColor = btnFormat.colors.disabled;
|
|
1144
|
+
} else if (this.isPressed) {
|
|
1145
|
+
buttonColor = btnFormat.colors.pressed;
|
|
1146
|
+
} else if (this.isHovered) {
|
|
1147
|
+
buttonColor = btnFormat.colors.hover;
|
|
1148
|
+
} else {
|
|
1149
|
+
buttonColor = btnFormat.colors.normal;
|
|
1084
1150
|
}
|
|
1085
1151
|
|
|
1152
|
+
let originalColor = this.formatting.color;
|
|
1153
|
+
this.formatting.color = buttonColor;
|
|
1154
|
+
|
|
1155
|
+
super.render();
|
|
1156
|
+
|
|
1157
|
+
if(!this.visible) return;
|
|
1158
|
+
|
|
1159
|
+
_p5.prototype.push();
|
|
1160
|
+
_p5.prototype.translate(this.x, this.y);
|
|
1161
|
+
if (this.rotationMode == "degrees") _p5.prototype.angleMode(_p5.prototype.DEGREES);
|
|
1162
|
+
_p5.prototype.rotate(this.rotation);
|
|
1163
|
+
|
|
1164
|
+
_p5.prototype.textStyle(btnFormat.text.style);
|
|
1165
|
+
_p5.prototype.textSize(btnFormat.text.size);
|
|
1166
|
+
_p5.prototype.fill(btnFormat.text.color);
|
|
1167
|
+
|
|
1168
|
+
// Use the standalone coloredText function
|
|
1169
|
+
coloredText(btnFormat.text.display, 0, 0, _p5.prototype.CENTER, _p5.prototype.CENTER);
|
|
1170
|
+
|
|
1171
|
+
_p5.prototype.pop();
|
|
1172
|
+
|
|
1173
|
+
this.formatting.color = originalColor;
|
|
1174
|
+
}
|
|
1175
|
+
|
|
1086
1176
|
// ========== BUTTON-SPECIFIC HELPER METHODS ==========
|
|
1087
1177
|
|
|
1088
1178
|
setText(text) {
|
|
@@ -2265,100 +2355,6 @@ function refreshLoop() {
|
|
|
2265
2355
|
});
|
|
2266
2356
|
}
|
|
2267
2357
|
|
|
2268
|
-
// ========== COLORED TEXT FUNCTION ==========
|
|
2269
|
-
p5.prototype._parseColoredText = function(str) {
|
|
2270
|
-
const lines = str.split('\n');
|
|
2271
|
-
const result = [];
|
|
2272
|
-
|
|
2273
|
-
for (let i = 0; i < lines.length; i++) {
|
|
2274
|
-
const line = lines[i];
|
|
2275
|
-
const parts = this._parseColoredLine(line);
|
|
2276
|
-
|
|
2277
|
-
result.push(...parts);
|
|
2278
|
-
|
|
2279
|
-
if (i < lines.length - 1) {
|
|
2280
|
-
result.push({
|
|
2281
|
-
text: '\n',
|
|
2282
|
-
color: null,
|
|
2283
|
-
isNewline: true
|
|
2284
|
-
});
|
|
2285
|
-
}
|
|
2286
|
-
}
|
|
2287
|
-
|
|
2288
|
-
return result;
|
|
2289
|
-
};
|
|
2290
|
-
|
|
2291
|
-
p5.prototype._parseColoredLine = function(str) {
|
|
2292
|
-
const regex = /\\([^|\\\n]+)\|([^|]+)\|/g;
|
|
2293
|
-
const parts = [];
|
|
2294
|
-
let lastIndex = 0;
|
|
2295
|
-
let match;
|
|
2296
|
-
|
|
2297
|
-
while ((match = regex.exec(str)) !== null) {
|
|
2298
|
-
if (match.index > lastIndex) {
|
|
2299
|
-
parts.push({
|
|
2300
|
-
text: str.substring(lastIndex, match.index),
|
|
2301
|
-
color: null
|
|
2302
|
-
});
|
|
2303
|
-
}
|
|
2304
|
-
|
|
2305
|
-
parts.push({
|
|
2306
|
-
text: match[2],
|
|
2307
|
-
color: match[1]
|
|
2308
|
-
});
|
|
2309
|
-
|
|
2310
|
-
lastIndex = match.index + match[0].length;
|
|
2311
|
-
}
|
|
2312
|
-
|
|
2313
|
-
if (lastIndex < str.length) {
|
|
2314
|
-
parts.push({
|
|
2315
|
-
text: str.substring(lastIndex),
|
|
2316
|
-
color: null
|
|
2317
|
-
});
|
|
2318
|
-
}
|
|
2319
|
-
|
|
2320
|
-
return parts.length ? parts : [{ text: str, color: null }];
|
|
2321
|
-
};
|
|
2322
|
-
|
|
2323
|
-
p5.prototype.coloredText = function(str, x, y, horizontal = LEFT, vertical = BASELINE, maxWidth) {
|
|
2324
|
-
const parts = this._parseColoredText(str);
|
|
2325
|
-
let currentX = x;
|
|
2326
|
-
let currentY = y;
|
|
2327
|
-
|
|
2328
|
-
const originalFill = this.drawingContext.fillStyle;
|
|
2329
|
-
const originalAlign = this.drawingContext.textAlign;
|
|
2330
|
-
const originalBaseline = this.drawingContext.textBaseline;
|
|
2331
|
-
|
|
2332
|
-
this.textAlign(horizontal, vertical);
|
|
2333
|
-
|
|
2334
|
-
for (const part of parts) {
|
|
2335
|
-
if (part.isNewline) {
|
|
2336
|
-
currentX = x;
|
|
2337
|
-
currentY += this.textLeading() || this.textSize() * 1.2;
|
|
2338
|
-
continue;
|
|
2339
|
-
}
|
|
2340
|
-
|
|
2341
|
-
if (part.color) {
|
|
2342
|
-
try {
|
|
2343
|
-
this.fill(part.color);
|
|
2344
|
-
} catch (e) {
|
|
2345
|
-
this.fill(originalFill);
|
|
2346
|
-
}
|
|
2347
|
-
}
|
|
2348
|
-
|
|
2349
|
-
this.text(part.text, currentX, currentY, maxWidth);
|
|
2350
|
-
currentX += this.textWidth(part.text);
|
|
2351
|
-
}
|
|
2352
|
-
|
|
2353
|
-
this.fill(originalFill);
|
|
2354
|
-
if (originalAlign && originalBaseline) {
|
|
2355
|
-
this.drawingContext.textAlign = originalAlign;
|
|
2356
|
-
this.drawingContext.textBaseline = originalBaseline;
|
|
2357
|
-
}
|
|
2358
|
-
|
|
2359
|
-
return this;
|
|
2360
|
-
};
|
|
2361
|
-
|
|
2362
2358
|
// ========== FPS ACCESSOR ==========
|
|
2363
2359
|
function getFPS() {
|
|
2364
2360
|
return fps;
|
|
@@ -2369,7 +2365,7 @@ const helpDocs = {
|
|
|
2369
2365
|
// Game Engine Overview
|
|
2370
2366
|
overview: `
|
|
2371
2367
|
MALC Game Engine - A comprehensive 2D game engine for p5.js
|
|
2372
|
-
Version: 1.0.
|
|
2368
|
+
Version: 1.0.3
|
|
2373
2369
|
|
|
2374
2370
|
Core Features:
|
|
2375
2371
|
- Scene management system
|
|
@@ -2561,7 +2557,7 @@ const helpDocs = {
|
|
|
2561
2557
|
|
|
2562
2558
|
// ========== MALC MAIN OBJECT ==========
|
|
2563
2559
|
const MALC = {
|
|
2564
|
-
version: "1.0.
|
|
2560
|
+
version: "1.0.4", // Increment version
|
|
2565
2561
|
|
|
2566
2562
|
// Core classes
|
|
2567
2563
|
gameObject: gameObject,
|
|
@@ -2587,6 +2583,7 @@ const MALC = {
|
|
|
2587
2583
|
// Utility functions
|
|
2588
2584
|
generateId: generateId,
|
|
2589
2585
|
getTimestamp: getTimestamp,
|
|
2586
|
+
coloredText: coloredText, // Add this line
|
|
2590
2587
|
|
|
2591
2588
|
// Gravity constants
|
|
2592
2589
|
GRAVITY: GRAVITY,
|
|
@@ -2690,26 +2687,39 @@ const MALC = {
|
|
|
2690
2687
|
this.mouse = new MouseHandler();
|
|
2691
2688
|
window.mouse = this.mouse;
|
|
2692
2689
|
|
|
2690
|
+
|
|
2691
|
+
|
|
2693
2692
|
// Start FPS tracking
|
|
2694
2693
|
refreshLoop();
|
|
2695
2694
|
|
|
2696
2695
|
// Create default scenes
|
|
2697
|
-
|
|
2698
|
-
|
|
2699
|
-
|
|
2700
|
-
|
|
2701
|
-
|
|
2702
|
-
|
|
2703
|
-
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
|
|
2710
|
-
|
|
2711
|
-
|
|
2712
|
-
|
|
2696
|
+
// Create default scenes
|
|
2697
|
+
new Scene("blank", 70);
|
|
2698
|
+
new Scene("loading", 50, function(self) {
|
|
2699
|
+
try {
|
|
2700
|
+
_p5.prototype.textSize(24);
|
|
2701
|
+
let timed = (self.timeActive / 250 % 4);
|
|
2702
|
+
let dots = "";
|
|
2703
|
+
|
|
2704
|
+
if (timed < 1) dots = ".";
|
|
2705
|
+
else if (timed < 2) dots = "..";
|
|
2706
|
+
else if (timed < 3) dots = "...";
|
|
2707
|
+
|
|
2708
|
+
// Use standalone coloredText function
|
|
2709
|
+
coloredText(`\\lime|Loading Game${dots}| `, 120, 200, _p5.prototype.LEFT, _p5.prototype.CENTER);
|
|
2710
|
+
|
|
2711
|
+
_p5.prototype.textSize(16);
|
|
2712
|
+
|
|
2713
|
+
let num = (Math.floor(self.timeActive / 100) / 10);
|
|
2714
|
+
let percentText = `${ Math.round((10 - num) * 10) / 10 + ((num + "").length < 2 ? ".0" : "")}`;
|
|
2715
|
+
|
|
2716
|
+
// Use standalone coloredText function
|
|
2717
|
+
coloredText(`\\red|${percentText}|`, 200, 225, _p5.prototype.CENTER, _p5.prototype.CENTER);
|
|
2718
|
+
} catch (e) {
|
|
2719
|
+
// Fallback if coloredText fails
|
|
2720
|
+
_p5.prototype.text(`Loading Game...`, 120, 200);
|
|
2721
|
+
}
|
|
2722
|
+
});
|
|
2713
2723
|
|
|
2714
2724
|
Scene.activeScene = "loading";
|
|
2715
2725
|
|
|
@@ -2749,4 +2759,4 @@ MALC.mouse = new MouseHandler();
|
|
|
2749
2759
|
|
|
2750
2760
|
return MALC;
|
|
2751
2761
|
|
|
2752
|
-
}));
|
|
2762
|
+
}));
|
package/malc.min.js
CHANGED
|
@@ -1,7 +1,17 @@
|
|
|
1
1
|
(function(root,factory){if(typeof define==='function'&&define.amd){define(['p5'],factory)}else if(typeof module==='object'&&module.exports){module.exports=factory(require('p5'))}else{root.MALC=factory(root.p5)}}(typeof self!=='undefined'?self:this,function(p5){const _p5=p5;const MALCgameObjects=[];const MALCbuttons=[];const MALCScene=[];var UIPlanes=[];var buttonsToggled=!0;const GRAVITY=0.5;const TERMINAL_VELOCITY=20;function getTimestamp(){return new Date().getTime()}
|
|
2
2
|
function generateId(prefix){return `${prefix}_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`}
|
|
3
|
+
function coloredText(str,x,y,horizontal,vertical,maxWidth){const p=_p5.prototype;const parts=parseColoredText(str);let currentX=x;let currentY=y;p.push();p.textAlign(horizontal||LEFT,vertical||BASELINE);for(const part of parts){if(part.isNewline){currentX=x;currentY+=p.textLeading()||p.textSize()*1.2;continue}
|
|
4
|
+
if(part.color){try{p.fill(part.color)}catch(e){p.fill(255)}}
|
|
5
|
+
p.text(part.text,currentX,currentY,maxWidth);currentX+=p.textWidth(part.text)}
|
|
6
|
+
p.pop()}
|
|
7
|
+
function parseColoredLine(str){const regex=/\\([^|\\\n]+)\|([^|]+)\|/g;const parts=[];let lastIndex=0;let match;while((match=regex.exec(str))!==null){if(match.index>lastIndex){parts.push({text:str.substring(lastIndex,match.index),color:null})}
|
|
8
|
+
parts.push({text:match[2],color:match[1]});lastIndex=match.index+match[0].length}
|
|
9
|
+
if(lastIndex<str.length){parts.push({text:str.substring(lastIndex),color:null})}
|
|
10
|
+
return parts.length?parts:[{text:str,color:null}]}
|
|
11
|
+
function parseColoredText(str){const lines=str.split('\n');const result=[];for(let i=0;i<lines.length;i++){const line=lines[i];const parts=parseColoredLine(line);result.push(...parts);if(i<lines.length-1){result.push({text:'\n',color:null,isNewline:!0})}}
|
|
12
|
+
return result}
|
|
3
13
|
class Scene{static scenes=[];static activeScene="blank";static started=!1;static sceneHistory=[];static historyLimit=10;static update(){this.started=!0;this.scenes=MALCScene;let activeSceneFound=!1;this.scenes.forEach(S=>{if(S.id==this.activeScene){activeSceneFound=!0;this.scenes.forEach(s=>{if(s!=S){s._active=!1;s.active=!1;s.objects.forEach(o=>{if(o&&typeof o.active!=='undefined')o.active=!1})}});S.active=!0;if(!S._active){S.activated=MALC.time.getTime();if(typeof S.onActivate=='function')S.onActivate();}
|
|
4
|
-
S._active=!0;S.timeActive=MALC.time.getTime()-S.activated;S.objects.forEach(o=>{if(o&&typeof o.active!=='undefined')o.active=!0});_p5.prototype.push();if(window.camera&&typeof camera.render=='function'){camera.render()}
|
|
14
|
+
S._active=!0;S.timeActive=MALC.time.getTime()-S.activated;S.objects.forEach(o=>{if(o&&typeof o.active!=='undefined')o.active=!0});_p5.prototype.push();if(window.camera&&typeof window.camera.render=='function'){window.camera.render()}
|
|
5
15
|
S.render();_p5.prototype.pop()}});if(!activeSceneFound&&this.activeScene!="blank"){console.warn(`Scene "${this.activeScene}" not found, switching to blank`);this.activeScene="blank"}}
|
|
6
16
|
static getSceneById(id){return MALCScene.find(scene=>scene.id==id)||null}
|
|
7
17
|
static getActiveScene(){return this.getSceneById(this.activeScene)}
|
|
@@ -98,9 +108,9 @@ setVelocity(speed,x,y,err=0.5){let angle=this.directionTo(x,y,err);if(isNaN(angl
|
|
|
98
108
|
this.velocity=[speed,angle];return this.velocity}
|
|
99
109
|
destroy(){this.removeFromAllScenes();let index=MALCgameObjects.indexOf(this);if(index>-1){MALCgameObjects.splice(index,1)}}
|
|
100
110
|
clone(){let clone=new gameObject(this.x,this.y,this.width,this.height,...this.scenes);clone.rotation=this.rotation;clone.rotationMode=this.rotationMode;clone.velocity=[...this.velocity];clone.velocityMode=this.velocityMode;clone.rvm=this.rvm;clone.formatting=JSON.parse(JSON.stringify(this.formatting));clone.gravity=JSON.parse(JSON.stringify(this.gravity));clone.debug=this.debug;clone.hitbox=JSON.parse(JSON.stringify(this.hitbox));return clone}
|
|
101
|
-
screenToWorld(screenX,screenY){if(window.camera&&typeof camera.screenToWorld=="function"){return camera.screenToWorld(screenX,screenY)}
|
|
111
|
+
screenToWorld(screenX,screenY){if(window.camera&&typeof window.camera.screenToWorld=="function"){return window.camera.screenToWorld(screenX,screenY)}
|
|
102
112
|
return{x:screenX,y:screenY}}
|
|
103
|
-
isOnScreen(){if(!window.camera)return!0;let cameraPos=camera.getOrientation();let screenRight=cameraPos[0]+camera.width;let screenBottom=cameraPos[1]+camera.height;return(this.x+this.width/2>cameraPos[0]&&this.x-this.width/2<screenRight&&this.y+this.height/2>cameraPos[1]&&this.y-this.height/2<screenBottom)}}
|
|
113
|
+
isOnScreen(){if(!window.camera)return!0;let cameraPos=window.camera.getOrientation();let screenRight=cameraPos[0]+window.camera.width;let screenBottom=cameraPos[1]+window.camera.height;return(this.x+this.width/2>cameraPos[0]&&this.x-this.width/2<screenRight&&this.y+this.height/2>cameraPos[1]&&this.y-this.height/2<screenBottom)}}
|
|
104
114
|
class Button extends gameObject{static buttons=[];static updateButton(){this.startedButtons=!0;this.buttons=MALCbuttons;this.buttons.forEach(b=>{if(!b.active)return;b.isHovered=b.events.hover();if(MALCbuttons.every(b=>!b.events.hover())){_p5.prototype.cursor()}else if(b.isHovered){_p5.prototype.cursor(b.cursor)}})}
|
|
105
115
|
static getButtonByIndex(index){return MALCbuttons[index]||null}
|
|
106
116
|
static getHoveredButton(){return MALCbuttons.find(b=>b.active&&b.events.hover())}
|
|
@@ -110,7 +120,7 @@ update(boolean){super.update(boolean);if(this.cooldownActive){let currentTime=Da
|
|
|
110
120
|
this.isHovered=this.events.hover();this.isPressed=this.events.pressed();if(this.events.clicked()&&this.onClick&&!this.isDisabled&&!this.cooldownActive){this.onClick(this);this.lastClickTime=Date.now();this.cooldownActive=!0}
|
|
111
121
|
MALCbuttons[this.buttonIndex]=this}
|
|
112
122
|
render(){if(!this.active)return;let btnFormat=this.formatting.button;let buttonColor;if(this.isDisabled){buttonColor=btnFormat.colors.disabled}else if(this.isPressed){buttonColor=btnFormat.colors.pressed}else if(this.isHovered){buttonColor=btnFormat.colors.hover}else{buttonColor=btnFormat.colors.normal}
|
|
113
|
-
let originalColor=this.formatting.color;this.formatting.color=buttonColor;super.render();if(!this.visible)return;_p5.prototype.push();_p5.prototype.translate(this.x,this.y);if(this.rotationMode=="degrees")_p5.prototype.angleMode(_p5.prototype.DEGREES);_p5.prototype.rotate(this.rotation);_p5.prototype.textStyle(btnFormat.text.style);_p5.prototype.textSize(btnFormat.text.size);_p5.prototype.fill(btnFormat.text.color);
|
|
123
|
+
let originalColor=this.formatting.color;this.formatting.color=buttonColor;super.render();if(!this.visible)return;_p5.prototype.push();_p5.prototype.translate(this.x,this.y);if(this.rotationMode=="degrees")_p5.prototype.angleMode(_p5.prototype.DEGREES);_p5.prototype.rotate(this.rotation);_p5.prototype.textStyle(btnFormat.text.style);_p5.prototype.textSize(btnFormat.text.size);_p5.prototype.fill(btnFormat.text.color);coloredText(btnFormat.text.display,0,0,_p5.prototype.CENTER,_p5.prototype.CENTER);_p5.prototype.pop();this.formatting.color=originalColor}
|
|
114
124
|
setText(text){this.formatting.button.text.display=text;return this}
|
|
115
125
|
getRGBFromColor(colorInput){let c=_p5.prototype.color(colorInput);return[_p5.prototype.red(c),_p5.prototype.green(c),_p5.prototype.blue(c)]}
|
|
116
126
|
getBrightness(colorInput){let rgb=this.getRGBFromColor(colorInput);return 0.299*rgb[0]+0.587*rgb[1]+0.114*rgb[2]}
|
|
@@ -239,18 +249,10 @@ getButton(name){name=name.toLowerCase();const buttonMap={'select':0,'back':1,'pr
|
|
|
239
249
|
return this.buttons[btn]?.pressed||!1}}
|
|
240
250
|
const controller=new GameController();const fpsTimes=[];let fps;function refreshLoop(){window.requestAnimationFrame(()=>{const now=performance.now();while(fpsTimes.length>0&&fpsTimes[0]<=now-1000){fpsTimes.shift()}
|
|
241
251
|
fpsTimes.push(now);fps=fpsTimes.length;refreshLoop()})}
|
|
242
|
-
|
|
243
|
-
return result};p5.prototype._parseColoredLine=function(str){const regex=/\\([^|\\\n]+)\|([^|]+)\|/g;const parts=[];let lastIndex=0;let match;while((match=regex.exec(str))!==null){if(match.index>lastIndex){parts.push({text:str.substring(lastIndex,match.index),color:null})}
|
|
244
|
-
parts.push({text:match[2],color:match[1]});lastIndex=match.index+match[0].length}
|
|
245
|
-
if(lastIndex<str.length){parts.push({text:str.substring(lastIndex),color:null})}
|
|
246
|
-
return parts.length?parts:[{text:str,color:null}]};p5.prototype.coloredText=function(str,x,y,horizontal=LEFT,vertical=BASELINE,maxWidth){const parts=this._parseColoredText(str);let currentX=x;let currentY=y;const originalFill=this.drawingContext.fillStyle;const originalAlign=this.drawingContext.textAlign;const originalBaseline=this.drawingContext.textBaseline;this.textAlign(horizontal,vertical);for(const part of parts){if(part.isNewline){currentX=x;currentY+=this.textLeading()||this.textSize()*1.2;continue}
|
|
247
|
-
if(part.color){try{this.fill(part.color)}catch(e){this.fill(originalFill)}}
|
|
248
|
-
this.text(part.text,currentX,currentY,maxWidth);currentX+=this.textWidth(part.text)}
|
|
249
|
-
this.fill(originalFill);if(originalAlign&&originalBaseline){this.drawingContext.textAlign=originalAlign;this.drawingContext.textBaseline=originalBaseline}
|
|
250
|
-
return this};function getFPS(){return fps}
|
|
252
|
+
function getFPS(){return fps}
|
|
251
253
|
const helpDocs={overview:`
|
|
252
254
|
MALC Game Engine - A comprehensive 2D game engine for p5.js
|
|
253
|
-
Version: 1.0.
|
|
255
|
+
Version: 1.0.3
|
|
254
256
|
|
|
255
257
|
Core Features:
|
|
256
258
|
- Scene management system
|
|
@@ -280,7 +282,7 @@ const helpDocs={overview:`
|
|
|
280
282
|
function draw() {
|
|
281
283
|
MALC.update(); // Updates all MALC systems
|
|
282
284
|
}
|
|
283
|
-
`};const MALC={version:"1.0.
|
|
285
|
+
`};const MALC={version:"1.0.4",gameObject:gameObject,Button:Button,Scene:Scene,UIPlane:UIPlane,Camera:Camera,mouse:null,keyboard:keyboard,controller:controller,fps:fps,getFPS:getFPS,time:new Date(),startTime:new Date().getTime(),timer:0,generateId:generateId,getTimestamp:getTimestamp,coloredText:coloredText,GRAVITY:GRAVITY,TERMINAL_VELOCITY:TERMINAL_VELOCITY,help:function(topic="overview"){if(topic==="overview"){console.log(helpDocs.overview);return helpDocs.overview}
|
|
284
286
|
if(helpDocs.classes[topic]){console.log(`=== ${topic.toUpperCase()} ===`);console.log(helpDocs.classes[topic].description);console.log("\nConstructor:",helpDocs.classes[topic].constructor);if(helpDocs.classes[topic].properties){console.log("\nProperties:");Object.entries(helpDocs.classes[topic].properties).forEach(([prop,desc])=>{console.log(` ${prop}: ${desc}`)})}
|
|
285
287
|
if(helpDocs.classes[topic].methods){console.log("\nMethods:");Object.entries(helpDocs.classes[topic].methods).forEach(([method,desc])=>{console.log(` ${method}: ${desc}`)})}
|
|
286
288
|
if(helpDocs.classes[topic].staticMethods){console.log("\nStatic Methods:");Object.entries(helpDocs.classes[topic].staticMethods).forEach(([method,desc])=>{console.log(` static ${method}: ${desc}`)})}
|
|
@@ -289,6 +291,6 @@ if(helpDocs.input[topic]){console.log(`=== ${topic.toUpperCase()} ===`);console.
|
|
|
289
291
|
return helpDocs.input[topic]}
|
|
290
292
|
if(helpDocs.utilities[topic]){console.log(`=== ${topic.toUpperCase()} ===`);console.log(helpDocs.utilities[topic]);return helpDocs.utilities[topic]}
|
|
291
293
|
if(topic==="quickStart"||topic==="start"){console.log(helpDocs.quickStart);return helpDocs.quickStart}
|
|
292
|
-
console.log(`Help topic "${topic}" not found. Try: overview, classes (gameObject, Button, Scene, UIPlane, Camera), input (mouse, keyboard, controller), utilities (coloredText, getFPS), quickStart`);return null},helpTopics:function(){const topics=["overview","classes: "+Object.keys(helpDocs.classes).join(", "),"input: "+Object.keys(helpDocs.input).join(", "),"utilities: "+Object.keys(helpDocs.utilities).join(", "),"quickStart"];console.log("Available help topics:\n"+topics.join("\n"));return topics},init:function(canvasX,canvasY){_p5.prototype.createCanvas(canvasX,canvasY);this.time=new Date();this.startTime=this.time.getTime();window.camera=new Camera(canvasX,canvasY);this.mouse=new MouseHandler();window.mouse=this.mouse;refreshLoop();new Scene("blank",70);new Scene("loading",50,function(self){_p5.prototype.textSize(24);let timed=(self.timeActive/250%4);let dots="";if(timed<1)dots=".";else if(timed<2)dots="..";else if(timed<3)dots="...";
|
|
294
|
+
console.log(`Help topic "${topic}" not found. Try: overview, classes (gameObject, Button, Scene, UIPlane, Camera), input (mouse, keyboard, controller), utilities (coloredText, getFPS), quickStart`);return null},helpTopics:function(){const topics=["overview","classes: "+Object.keys(helpDocs.classes).join(", "),"input: "+Object.keys(helpDocs.input).join(", "),"utilities: "+Object.keys(helpDocs.utilities).join(", "),"quickStart"];console.log("Available help topics:\n"+topics.join("\n"));return topics},init:function(canvasX,canvasY){_p5.prototype.createCanvas(canvasX,canvasY);this.time=new Date();this.startTime=this.time.getTime();window.camera=new Camera(canvasX,canvasY);this.mouse=new MouseHandler();window.mouse=this.mouse;refreshLoop();new Scene("blank",70);new Scene("loading",50,function(self){try{_p5.prototype.textSize(24);let timed=(self.timeActive/250%4);let dots="";if(timed<1)dots=".";else if(timed<2)dots="..";else if(timed<3)dots="...";coloredText(`\\lime|Loading Game${dots}| `,120,200,_p5.prototype.LEFT,_p5.prototype.CENTER);_p5.prototype.textSize(16);let num=(Math.floor(self.timeActive/100)/10);let percentText=`${ Math.round((10 - num) * 10) / 10 + ((num + "").length < 2 ? ".0" : "")}`;coloredText(`\\red|${percentText}|`,200,225,_p5.prototype.CENTER,_p5.prototype.CENTER)}catch(e){_p5.prototype.text(`Loading Game...`,120,200)}});Scene.activeScene="loading";console.log("MALC Game Engine initialized v"+this.version);console.log("Type MALC.help() for documentation")},update:function(){this.time=new Date();this.timer=this.time-this.startTime;if(this.mouse){this.mouse.rawX=_p5.prototype.mouseX;this.mouse.rawY=_p5.prototype.mouseY;this.mouse.x=this.mouse.rawX+window.camera.getOrientation()[0];this.mouse.y=this.mouse.rawY+window.camera.getOrientation()[1];this.mouse.down=_p5.prototype.mouseIsPressed}
|
|
293
295
|
controller.update();gameObject.update();Button.updateButton();this.fps=fps;if(typeof window.camera.render=="function"){window.camera.render()}
|
|
294
296
|
Scene.update()}};MALC.mouse=new MouseHandler();return MALC}))
|