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.
Files changed (3) hide show
  1. package/malc.js +140 -118
  2. package/malc.min.js +21 -16
  3. 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.2
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
- _p5.prototype.coloredText(btnFormat.text.display, 0, 0, _p5.prototype.CENTER, _p5.prototype.CENTER);
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.1
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.1",
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
- _p5.prototype.textSize(24);
2700
- let timed = (self.timeActive / 250 % 4);
2701
- let dots = "";
2702
-
2703
- if (timed < 1) dots = ".";
2704
- else if (timed < 2) dots = "..";
2705
- else if (timed < 3) dots = "...";
2706
-
2707
- _p5.prototype.coloredText(`\\lime|Loading Game${dots}| `, 120, 200, _p5.prototype.LEFT, _p5.prototype.CENTER);
2708
- _p5.prototype.textSize(16);
2709
-
2710
- let num = (Math.floor(self.timeActive / 100) / 10);
2711
- _p5.prototype.coloredText(`\\red|${ Math.round((10 - num) * 10) / 10 + ((num + "").length < 2 ? ".0" : "")}|`, 200, 225, _p5.prototype.CENTER, _p5.prototype.CENTER);
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);_p5.prototype.pop();this.formatting.color=originalColor}
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
- p5.prototype._parseColoredText=function(str){const lines=str.split('\n');const result=[];for(let i=0;i<lines.length;i++){const line=lines[i];const parts=this._parseColoredLine(line);result.push(...parts);if(i<lines.length-1){result.push({text:'\n',color:null,isNewline:!0})}}
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.1
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.1",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}
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;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="...";_p5.prototype.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);_p5.prototype.coloredText(`\\red|${ Math.round((10 - num) * 10) / 10 + ((num + "").length < 2 ? ".0" : "")}|`,200,225,_p5.prototype.CENTER,_p5.prototype.CENTER)});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}
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}))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "malc-game-engine",
3
- "version": "1.0.2",
3
+ "version": "1.0.3",
4
4
  "description": "A comprehensive 2D game engine for p5.js",
5
5
  "main": "malc.js",
6
6
  "unpkg": "malc.min.js",