• Content count

  • Joined

  • Last visited

Everything posted by Parasyte

  1. Hybrid GFX test - scaling tilemap

    @Growler I think you might want to try it the other way; Set the video mode into the highest resolution supported, and scale up the tile background layer. I don't have any code on hand for this, and I'm not 100% sure it will work with collision shapes and stuff, but you definitely want to go with this approach. Going through some old github issues, it looks like the new Renderable transformation matrices will make this significantly easier to work with: The problem you are facing in the screenshots is that the canvas size is very small, and you're stretching the whole thing, making big chunky pixels. Scaling down a GUI element onto that canvas is the same thing as scaling the image down in photoshop, and then scaling it back up with nearest neighbor (this is the "stretching" that I just described).
  2. How do I tween the rotation

    I used it in Neverwell Moor for the intro scrolling:
  3. How do I tween the rotation

    The me.Tween class provides a callback that is called with a delta on each frame. The delta can be passed directly to the rotate method; no need to manage state on the class at all.
  4. Do you build your UI's in MelonJS or DOM?

    For a quest log, yes. For other bits of status GUI, no, probably not. You want to avoid moving DOM elements as much as possible, since that will cause the UA to reflow the DOM. Status bars are easy to render in melonJS, using either the canvas context drawing methods (like fillRect()) or by clipping a texture. Using the melonJS font classes are also pretty decent performance-wise (except when you want to update the text on every frame, that doesn't work well with the WebGL compositor).
  5. Do you build your UI's in MelonJS or DOM?

    Simple elements like buttons can be implemented with the melonJS GUI_Button class. The advantages with this are immediate feedback (DOM click events have a delay on mobile devices), and they use the WebGL compositor (great for all-in-one ├╝ber textures) For more complex UIs, use the DOM. DOM should definitely be in your toolbelt for rich GUIs. The advantages are obvious, and there are very few disadvantages (more like just caveats). It's great for any form input fields, scrollable areas, etc. DOM also has the advantage that the text rendering is really fantastic, especially with web fonts, and certain character sets (CJK, RTL, etc) One of the caveats you might run into is that by default all DOM elements consume pointer events. There are some useful CSS properties that can help you workaround it if needed: and
  6. Fix position after scale

    If you are using the collision shapes for pointer events, you can create a plugin to patch me.input.globalToLocal() to apply the same scaling transformation. This won't make the debugPanel render the collision shapes scaled, but your plugin could also patch the debugPanel's draw method to apply the scaling transformation, if you needed to. If, however, you aren't using pointer events, why would you want to scale the collision shapes at all?
  7. Run without rendering (for online game)

    I think you will find it significantly more difficult than it appears at first. I'm not trying to discourage you, that's just the reality. But if you can manage to make it successful, then that is awesome.
  8. Run without rendering (for online game)

    Out of curiosity, how do you expect running melonJS on the server to prevent cheating? This is a topic which I have studied fairly extensively. Unless you implement a mechanism to actively address cheating, you're going to get a very sad surprise one day when your players start complaining about cheaters. For starters, here's a short list of relevant resources on the subject: Deterministic Lockstep Lag Hacking Pick your favorite anti-cheat tools; EAC, Punkbuster, ... To followup with an idea provided in that Stack Overflow answer, running the game only server-side is effective against cheaters if you can guarantee low latency while streaming an audio/video feed (or the procedural equivalent). But that's way beyond the scope of what melonJS intends to provide. By the way, are you familiar with the concepts of prediction, dead reckoning, and jitter buffering for networked multiplayer? If you miss these, you're going to have an unpleasant experience because the network is unreliable. Once your game goes multiplayer, you've entered the realm of distributed computing. And as with the CAP theorem, you can't sacrifice partition tolerance. This is a fun can of worms that many platform engineers will spend their entire careers learning and dealing with. Isn't it amazing how extending a simple game to play on even two computers suddenly raises the complexity exponentially?
  9. melonjs zooming and panning

    @Growler I actually wrote a crazy bit of logic that can animate tile layers for that... Each frame is on its own layer, and the animation just cycles the layer visibility. The code for that is here: There are better ways to do this now that melonJS and Tiled both support tile animations. But back then, this was a really impressive feat. BTW the original windmill assets are available here:
  10. Glad it all worked out! 10,000 is also quite a lot; each of those entities needs to update in a tight loop on every frame, and again in a second tight loop to draw. It's a very similar problem that the particle emitter experiences; but we have the luxury that the particles are much lighter-weight than entities. A more efficient implementation would be moving the BasicPlant logic into the PlantManager. The manager is already recording the state of each plant in a 2D array, so it's not a huge leap to have the PlantManager draw each plant to an off-screen canvas when a new plant is spawned. That will reduce the update and draw calls from O(n) to O(1) runtime, which is huge! (Where n is the maximum number of plants.) And updating the plant state from the manager will be much lighter weight than the Entity class, too. So that's also a win. It sounds like a really cool concept, though. I've always wanted to make a game with some evolution simulation elements.
  11. First thing I noticed is that you are using a bunch of global variables in the PlantManager class, probably unintentionally. plantMap should probably be a class property: this.plantMap. The others (plantLocation, clean, random, x, y, growthLocation, plant) should be declared with var (or let if you're using ES6 syntax). Fixing the variable scoping may not solve the issue, though. The second thing I noticed is that on the edges of the tilemap, the plantManger.getGrowthLocation() method will raise an exception, because you're filtering the undefined values after attempting to access the plant property on undefined. You can easily solve this by filtering the array before mapping the values. Ah, here is the problem, on this line: if(growthLocation && !plantMap[x][y].plant){ The boolean is pointing at the parent location, which is initially false. You want to check the value of growthLocation.plant here, and assign true to this property inside the condition body. Also, as a side note, you should set plantMap[50][50].plant = true in the seed method, otherwise it will grow a second plant in that location. Also, one question and an observation: Are all of these plants supposed to be 1x1 pixel each? Seems like you're going to end up creating a ton of plant objects if that's true! A modern retina display has over 5 million pixels, as an example. So a full screen plant-reproduction-simulator on such a device will create a maximum of 5,184,000 plant objects. The game will become unplayably slow before it fills the entire screen with green pixels, though.
  12. NPC Healthbar with DOM element

    I just noticed you're using the "flex-width" scaling method, which means the canvas aspect ratio is flexible along the horizontal axis. The vertical aspect ratio can be used to scale both dimensions equally. In your example code: let divY = canvasH / ratioH; This is the ratio you want to scale both axes by. So if you change the newCoordsX to scale by divY instead, it will all work: let newCoordsX = coords.x * divY; let newCoordsY = coords.y * divY; BTW, all of this scaling logic will have to change if you decide to switch to a different video scaling mode.
  13. melonjs zooming and panning

    I have some really old code that does non-linear interpolations (tweening) between camera positions. Some of it should still be usable. You can see it in action on the Neverwell Moor title screen, and the code is available here: Maybe it will help you out.
  14. NPC Healthbar with DOM element

    Ok, the test was successful. It means the scaling is what's causing the issue. You can fix it by applying the same transformation to the DOM element position. You can get the transformation by reading the canvas width and height, and dividing by the width and height that is passed to This will give you two values; one for width and one for height. When you go to move the DOM elements, multiply the x and y coordinates with the two scaling values you got from the last step.
  15. NPC Healthbar with DOM element

    I think you might be having problems with the DOM element position because the canvas is scaled. If you disable the video scaling mode, you should see the element position align with the entity. You can try this to validate the hypothesis that video scaling is the issue. If this identifies the cause, then you can fix it by scaling the position by the same factor as the video scaling. You might have to compute the scaling factor from the initial resolution and actual canvas dimensions...
  16. HTML 5 canvas with Melon causing high fan speeds

    There have been a few improvements to the WebGL renderer since 2.1.1, lots of bug fixes with Audio and TMX maps, performance improvements all over the place (especially the particle emitters), plus some new features like the GamePad API. It is probably going to be a lot of work upgrade; I was just curious. But we do maintain an upgrade guide to help with the transition.
  17. Error during chrome version change

    Are you inspecting those variables in the same stack frame that crashed? What about the variables at the rest of the stack frames?
  18. Error during chrome version change

    @Hashasm Were you able to get the variable state during that stack trace as well? I'm interested in the values of all the variables on lines 20135 and 20136. It seems like NaN is getting introduced in some way. But this is only a guess, based on the error message.
  19. HTML 5 canvas with Melon causing high fan speeds

    This is off-topic, but I thought I would quickly followup here to explain the 20ms requestAnimationFrame that I was seeing; My VR desktop has a GeForce GTX 1080, and my monitor supports 100 Hz with G-sync enabled. On the other hand, RAF only supports 60 fps (60 Hz) max (which is 16.667ms minimum between each callback). So Chrome lowers its frame rate to exactly half of my monitor refresh rate, which is 50 Hz. There is currently an open issue at w3c for supporting variable refresh rates, it appears to be targeted for HTML 5.2: A timer-based workaround is quite easy if you don't mind hard-coding the refresh rate (or providing a UI to set the refresh rate manually). For example, adding this code prior to loading melonJS will monkeypatch requestAnimationFrame to 144 Hz (which is 6.944ms minimum between each callback): (function () { var lastTime = 0; var frameDuration = 1000 / 144; // or 60, 75, 90, 100, 120, etc. requestAnimationFrame = function (callback) { var currTime =; var timeToCall = Math.max(0, frameDuration - (currTime - lastTime)); var id = window.setTimeout(function () { callback(currTime + timeToCall); }, timeToCall); lastTime = currTime + timeToCall; return id; }; cancelAnimationFrame = function (id) { window.clearTimeout(id); }; window.requestAnimationFrame = requestAnimationFrame; window.cancelAnimationFrame = cancelAnimationFrame; })();
  20. Nice! This is something we should definitely include in the tutorial. I have added an issue to track this: If you would like to contribute to the tutorial, we would be glad to accept.
  21. Error during chrome version change

    Hi! Click on the left-most arrow to get a stack trace. You can also enable "pause on uncaught errors" in the debugger, which will allow you to inspect the actual values of x and y, and (may be more important) walk the stack to find where those values originate. Debugging in this manner is best done with the non-minified melonJS build. Give it a try and let us know if you manage to track it down. If you need additional support, please don't hesitate to respond here with further information. Best of luck!
  22. HTML 5 canvas with Melon causing high fan speeds

    Also, 2.1.1 is 2 years old. Is there are reason you are not using a recent build?
  23. HTML 5 canvas with Melon causing high fan speeds

    The high fan speeds can happen with large canvases and high refresh rate. It's because your CPU is doing all of the work to render and draw the scene. WebGL helps a lot in this area because the GPU starts doing most of the drawing work. The CPU is still heavily involved, but not quite as taxed. DOM modification is also pretty heavyweight, which is why frameworks like React implement a virtual DOM... Even though you're not doing that work in the game, you're still asking the browser to do a lot of work when changing colors and layout. One tip I can provide is capturing a profile in the Performance tab of Chrome Dev Tools. You already shared a screenshot of the summary wheel chart from such a capture. Importantly, you'll get a flame graph representing function call times, which you can zoom into and inspect. For 60fps, you should expect each frame takes 16.667ms. When you inspect the flame graphs at the frame-level (mouse wheel to zoom in) you can gather a sense of what is taking the most time, and optimize around it. I grabbed a profile of about 10 seconds on my relatively powerful VR desktop. Here's the summary: This shows that over the 10 second run, the CPU was idle for 9.5 seconds. (91.7% idle) This was captured from the game in the website background, which uses WebGL. The more idle, the lower your fan speed. This screenshot is zoomed in on a single frame, and shows how much time each function call took. The entire frame was completed in 0.87ms. And the drawing alone took just 0.32ms. In other words, it performs incredibly well. One thing I find curious here is that Chrome is showing the animation frame timing is about 20ms instead of 16.667ms. That means I'm not getting a full 60fps. I'm actually getting 50fps. Must be a bug in Chrome or my GPU drivers ... During each frame, my CPU and GPU are both completely idle for 19ms, and active for less than 1ms. Here's what it looks like zoomed out a bit. Look at all that idle time, and still 20ms between each frame! In any case, this tool can help you diagnose performance issues. IMHO, WebGL will help a bit, but you have an unusually high amount of time spent doing "other" things in Chrome. Which is an obnoxiously named category, but it could include extensions, even the Chrome Dev Tools, or other tabs doing things in the background.
  24. Adding gradient background

    Are you using the ImageLayer API directly, or is it created from a tile map? Are you setting the repeat property correctly? Are you setting or changing the layer size? If you're using the repeat property, you should not change the size, since they are mutually exclusive configurations... Logically, anyway. There's nothing wrong with using them together if you wanted that black bar! When using repeat, the image is sized to match the viewport (not the level). So this leads me to believe you're using the API in an unexpected way.
  25. Adding gradient background

    WebGL has a soft requirement that textures width and height are a power of two, e.g. 128, 256, 512, 1024, ... And any combination is allowed; 128x1024, 512x256, etc. You should be able to accomplish your goal with a single background texture (just draw your gradients in Photoshop or whatever) that is wider than tall. You can also set the scrolling ratio to <1 so that it scrolls slower than the other tile layers in your map. For example, a ratio of 0.5 will cause the background to scroll at half the speed of the viewport.