malc-game-engine 1.0.2 → 1.0.3
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 +140 -118
- package/malc.min.js +21 -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,91 @@ function generateId(prefix) {
|
|
|
40
40
|
return `${prefix}_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
+
// ========== COLORED TEXT FUNCTIONS (SAFE VERSION) ==========
|
|
44
|
+
function parseColoredLine(str) {
|
|
45
|
+
const regex = /\\([^|\\\n]+)\|([^|]+)\|/g;
|
|
46
|
+
const parts = [];
|
|
47
|
+
let lastIndex = 0;
|
|
48
|
+
let match;
|
|
49
|
+
|
|
50
|
+
while ((match = regex.exec(str)) !== null) {
|
|
51
|
+
if (match.index > lastIndex) {
|
|
52
|
+
parts.push({
|
|
53
|
+
text: str.substring(lastIndex, match.index),
|
|
54
|
+
color: null
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
parts.push({
|
|
59
|
+
text: match[2],
|
|
60
|
+
color: match[1]
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
lastIndex = match.index + match[0].length;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (lastIndex < str.length) {
|
|
67
|
+
parts.push({
|
|
68
|
+
text: str.substring(lastIndex),
|
|
69
|
+
color: null
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return parts.length ? parts : [{ text: str, color: null }];
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function parseColoredText(str) {
|
|
77
|
+
const lines = str.split('\n');
|
|
78
|
+
const result = [];
|
|
79
|
+
|
|
80
|
+
for (let i = 0; i < lines.length; i++) {
|
|
81
|
+
const line = lines[i];
|
|
82
|
+
const parts = parseColoredLine(line);
|
|
83
|
+
|
|
84
|
+
result.push(...parts);
|
|
85
|
+
|
|
86
|
+
if (i < lines.length - 1) {
|
|
87
|
+
result.push({
|
|
88
|
+
text: '\n',
|
|
89
|
+
color: null,
|
|
90
|
+
isNewline: true
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return result;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function renderColoredText(p, str, x, y, horizontal, vertical, maxWidth) {
|
|
99
|
+
const parts = parseColoredText(str);
|
|
100
|
+
let currentX = x;
|
|
101
|
+
let currentY = y;
|
|
102
|
+
|
|
103
|
+
p.push();
|
|
104
|
+
p.textAlign(horizontal, vertical);
|
|
105
|
+
|
|
106
|
+
for (const part of parts) {
|
|
107
|
+
if (part.isNewline) {
|
|
108
|
+
currentX = x;
|
|
109
|
+
currentY += p.textLeading() || p.textSize() * 1.2;
|
|
110
|
+
continue;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (part.color) {
|
|
114
|
+
try {
|
|
115
|
+
p.fill(part.color);
|
|
116
|
+
} catch (e) {
|
|
117
|
+
p.fill(255);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
p.text(part.text, currentX, currentY, maxWidth);
|
|
122
|
+
currentX += p.textWidth(part.text);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
p.pop();
|
|
126
|
+
}
|
|
127
|
+
|
|
43
128
|
// ========== SCENE CLASS (DEFINED FIRST) ==========
|
|
44
129
|
class Scene {
|
|
45
130
|
static scenes = [];
|
|
@@ -84,8 +169,8 @@ class Scene {
|
|
|
84
169
|
});
|
|
85
170
|
|
|
86
171
|
_p5.prototype.push();
|
|
87
|
-
if (window.camera && typeof camera.render == 'function') {
|
|
88
|
-
camera.render();
|
|
172
|
+
if (window.camera && typeof window.camera.render == 'function') {
|
|
173
|
+
window.camera.render();
|
|
89
174
|
}
|
|
90
175
|
|
|
91
176
|
S.render();
|
|
@@ -913,8 +998,8 @@ class gameObject {
|
|
|
913
998
|
}
|
|
914
999
|
|
|
915
1000
|
screenToWorld(screenX, screenY) {
|
|
916
|
-
if (window.camera && typeof camera.screenToWorld == "function") {
|
|
917
|
-
return camera.screenToWorld(screenX, screenY);
|
|
1001
|
+
if (window.camera && typeof window.camera.screenToWorld == "function") {
|
|
1002
|
+
return window.camera.screenToWorld(screenX, screenY);
|
|
918
1003
|
}
|
|
919
1004
|
return { x: screenX, y: screenY };
|
|
920
1005
|
}
|
|
@@ -922,9 +1007,9 @@ class gameObject {
|
|
|
922
1007
|
isOnScreen() {
|
|
923
1008
|
if (!window.camera) return true;
|
|
924
1009
|
|
|
925
|
-
let cameraPos = camera.getOrientation();
|
|
926
|
-
let screenRight = cameraPos[0] + camera.width;
|
|
927
|
-
let screenBottom = cameraPos[1] + camera.height;
|
|
1010
|
+
let cameraPos = window.camera.getOrientation();
|
|
1011
|
+
let screenRight = cameraPos[0] + window.camera.width;
|
|
1012
|
+
let screenBottom = cameraPos[1] + window.camera.height;
|
|
928
1013
|
|
|
929
1014
|
return (this.x + this.width/2 > cameraPos[0] &&
|
|
930
1015
|
this.x - this.width/2 < screenRight &&
|
|
@@ -1077,7 +1162,14 @@ class Button extends gameObject {
|
|
|
1077
1162
|
_p5.prototype.textStyle(btnFormat.text.style);
|
|
1078
1163
|
_p5.prototype.textSize(btnFormat.text.size);
|
|
1079
1164
|
_p5.prototype.fill(btnFormat.text.color);
|
|
1080
|
-
|
|
1165
|
+
|
|
1166
|
+
// Use colored text if available, otherwise use normal text
|
|
1167
|
+
if (_p5.prototype.coloredText) {
|
|
1168
|
+
_p5.prototype.coloredText(btnFormat.text.display, 0, 0, _p5.prototype.CENTER, _p5.prototype.CENTER);
|
|
1169
|
+
} else {
|
|
1170
|
+
_p5.prototype.text(btnFormat.text.display, 0, 0);
|
|
1171
|
+
}
|
|
1172
|
+
|
|
1081
1173
|
_p5.prototype.pop();
|
|
1082
1174
|
|
|
1083
1175
|
this.formatting.color = originalColor;
|
|
@@ -2265,100 +2357,6 @@ function refreshLoop() {
|
|
|
2265
2357
|
});
|
|
2266
2358
|
}
|
|
2267
2359
|
|
|
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
2360
|
// ========== FPS ACCESSOR ==========
|
|
2363
2361
|
function getFPS() {
|
|
2364
2362
|
return fps;
|
|
@@ -2369,7 +2367,7 @@ const helpDocs = {
|
|
|
2369
2367
|
// Game Engine Overview
|
|
2370
2368
|
overview: `
|
|
2371
2369
|
MALC Game Engine - A comprehensive 2D game engine for p5.js
|
|
2372
|
-
Version: 1.0.
|
|
2370
|
+
Version: 1.0.3
|
|
2373
2371
|
|
|
2374
2372
|
Core Features:
|
|
2375
2373
|
- Scene management system
|
|
@@ -2561,7 +2559,7 @@ const helpDocs = {
|
|
|
2561
2559
|
|
|
2562
2560
|
// ========== MALC MAIN OBJECT ==========
|
|
2563
2561
|
const MALC = {
|
|
2564
|
-
version: "1.0.
|
|
2562
|
+
version: "1.0.3",
|
|
2565
2563
|
|
|
2566
2564
|
// Core classes
|
|
2567
2565
|
gameObject: gameObject,
|
|
@@ -2690,25 +2688,49 @@ const MALC = {
|
|
|
2690
2688
|
this.mouse = new MouseHandler();
|
|
2691
2689
|
window.mouse = this.mouse;
|
|
2692
2690
|
|
|
2691
|
+
// Add coloredText method to p5 instance safely
|
|
2692
|
+
if (!_p5.prototype.coloredText) {
|
|
2693
|
+
_p5.prototype.coloredText = function(str, x, y, horizontal, vertical, maxWidth) {
|
|
2694
|
+
renderColoredText(this, str, x, y, horizontal || LEFT, vertical || BASELINE, maxWidth);
|
|
2695
|
+
return this;
|
|
2696
|
+
};
|
|
2697
|
+
}
|
|
2698
|
+
|
|
2693
2699
|
// Start FPS tracking
|
|
2694
2700
|
refreshLoop();
|
|
2695
2701
|
|
|
2696
2702
|
// Create default scenes
|
|
2697
2703
|
new Scene("blank", 70);
|
|
2698
2704
|
new Scene("loading", 50, function(self) {
|
|
2699
|
-
|
|
2700
|
-
|
|
2701
|
-
|
|
2702
|
-
|
|
2703
|
-
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
|
|
2710
|
-
|
|
2711
|
-
|
|
2705
|
+
try {
|
|
2706
|
+
_p5.prototype.textSize(24);
|
|
2707
|
+
let timed = (self.timeActive / 250 % 4);
|
|
2708
|
+
let dots = "";
|
|
2709
|
+
|
|
2710
|
+
if (timed < 1) dots = ".";
|
|
2711
|
+
else if (timed < 2) dots = "..";
|
|
2712
|
+
else if (timed < 3) dots = "...";
|
|
2713
|
+
|
|
2714
|
+
if (_p5.prototype.coloredText) {
|
|
2715
|
+
_p5.prototype.coloredText(`\\lime|Loading Game${dots}| `, 120, 200, _p5.prototype.LEFT, _p5.prototype.CENTER);
|
|
2716
|
+
} else {
|
|
2717
|
+
_p5.prototype.text(`Loading Game${dots}`, 120, 200);
|
|
2718
|
+
}
|
|
2719
|
+
|
|
2720
|
+
_p5.prototype.textSize(16);
|
|
2721
|
+
|
|
2722
|
+
let num = (Math.floor(self.timeActive / 100) / 10);
|
|
2723
|
+
let percentText = `${ Math.round((10 - num) * 10) / 10 + ((num + "").length < 2 ? ".0" : "")}`;
|
|
2724
|
+
|
|
2725
|
+
if (_p5.prototype.coloredText) {
|
|
2726
|
+
_p5.prototype.coloredText(`\\red|${percentText}|`, 200, 225, _p5.prototype.CENTER, _p5.prototype.CENTER);
|
|
2727
|
+
} else {
|
|
2728
|
+
_p5.prototype.text(percentText, 200, 225);
|
|
2729
|
+
}
|
|
2730
|
+
} catch (e) {
|
|
2731
|
+
// Fallback if coloredText fails
|
|
2732
|
+
_p5.prototype.text(`Loading Game...`, 120, 200);
|
|
2733
|
+
}
|
|
2712
2734
|
});
|
|
2713
2735
|
|
|
2714
2736
|
Scene.activeScene = "loading";
|
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 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})}
|
|
4
|
+
parts.push({text:match[2],color:match[1]});lastIndex=match.index+match[0].length}
|
|
5
|
+
if(lastIndex<str.length){parts.push({text:str.substring(lastIndex),color:null})}
|
|
6
|
+
return parts.length?parts:[{text:str,color:null}]}
|
|
7
|
+
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})}}
|
|
8
|
+
return result}
|
|
9
|
+
function renderColoredText(p,str,x,y,horizontal,vertical,maxWidth){const parts=parseColoredText(str);let currentX=x;let currentY=y;p.push();p.textAlign(horizontal,vertical);for(const part of parts){if(part.isNewline){currentX=x;currentY+=p.textLeading()||p.textSize()*1.2;continue}
|
|
10
|
+
if(part.color){try{p.fill(part.color)}catch(e){p.fill(255)}}
|
|
11
|
+
p.text(part.text,currentX,currentY,maxWidth);currentX+=p.textWidth(part.text)}
|
|
12
|
+
p.pop()}
|
|
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,8 @@ 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);_p5.prototype.coloredText(btnFormat.text.display,0,0,_p5.prototype.CENTER,_p5.prototype.CENTER)
|
|
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);if(_p5.prototype.coloredText){_p5.prototype.coloredText(btnFormat.text.display,0,0,_p5.prototype.CENTER,_p5.prototype.CENTER)}else{_p5.prototype.text(btnFormat.text.display,0,0)}
|
|
124
|
+
_p5.prototype.pop();this.formatting.color=originalColor}
|
|
114
125
|
setText(text){this.formatting.button.text.display=text;return this}
|
|
115
126
|
getRGBFromColor(colorInput){let c=_p5.prototype.color(colorInput);return[_p5.prototype.red(c),_p5.prototype.green(c),_p5.prototype.blue(c)]}
|
|
116
127
|
getBrightness(colorInput){let rgb=this.getRGBFromColor(colorInput);return 0.299*rgb[0]+0.587*rgb[1]+0.114*rgb[2]}
|
|
@@ -239,18 +250,10 @@ getButton(name){name=name.toLowerCase();const buttonMap={'select':0,'back':1,'pr
|
|
|
239
250
|
return this.buttons[btn]?.pressed||!1}}
|
|
240
251
|
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
252
|
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}
|
|
253
|
+
function getFPS(){return fps}
|
|
251
254
|
const helpDocs={overview:`
|
|
252
255
|
MALC Game Engine - A comprehensive 2D game engine for p5.js
|
|
253
|
-
Version: 1.0.
|
|
256
|
+
Version: 1.0.3
|
|
254
257
|
|
|
255
258
|
Core Features:
|
|
256
259
|
- Scene management system
|
|
@@ -280,7 +283,7 @@ const helpDocs={overview:`
|
|
|
280
283
|
function draw() {
|
|
281
284
|
MALC.update(); // Updates all MALC systems
|
|
282
285
|
}
|
|
283
|
-
`};const MALC={version:"1.0.
|
|
286
|
+
`};const MALC={version:"1.0.3",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,GRAVITY:GRAVITY,TERMINAL_VELOCITY:TERMINAL_VELOCITY,help:function(topic="overview"){if(topic==="overview"){console.log(helpDocs.overview);return helpDocs.overview}
|
|
284
287
|
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
288
|
if(helpDocs.classes[topic].methods){console.log("\nMethods:");Object.entries(helpDocs.classes[topic].methods).forEach(([method,desc])=>{console.log(` ${method}: ${desc}`)})}
|
|
286
289
|
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 +292,8 @@ if(helpDocs.input[topic]){console.log(`=== ${topic.toUpperCase()} ===`);console.
|
|
|
289
292
|
return helpDocs.input[topic]}
|
|
290
293
|
if(helpDocs.utilities[topic]){console.log(`=== ${topic.toUpperCase()} ===`);console.log(helpDocs.utilities[topic]);return helpDocs.utilities[topic]}
|
|
291
294
|
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;
|
|
295
|
+
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;if(!_p5.prototype.coloredText){_p5.prototype.coloredText=function(str,x,y,horizontal,vertical,maxWidth){renderColoredText(this,str,x,y,horizontal||LEFT,vertical||BASELINE,maxWidth);return this}}
|
|
296
|
+
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="...";if(_p5.prototype.coloredText){_p5.prototype.coloredText(`\\lime|Loading Game${dots}| `,120,200,_p5.prototype.LEFT,_p5.prototype.CENTER)}else{_p5.prototype.text(`Loading Game${dots}`,120,200)}
|
|
297
|
+
_p5.prototype.textSize(16);let num=(Math.floor(self.timeActive/100)/10);let percentText=`${ Math.round((10 - num) * 10) / 10 + ((num + "").length < 2 ? ".0" : "")}`;if(_p5.prototype.coloredText){_p5.prototype.coloredText(`\\red|${percentText}|`,200,225,_p5.prototype.CENTER,_p5.prototype.CENTER)}else{_p5.prototype.text(percentText,200,225)}}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
298
|
controller.update();gameObject.update();Button.updateButton();this.fps=fps;if(typeof window.camera.render=="function"){window.camera.render()}
|
|
294
299
|
Scene.update()}};MALC.mouse=new MouseHandler();return MALC}))
|