• Content Count

  • Joined

  • Last visited

About Parasyte

  • Rank
    Advanced Member

Contact Methods

  • Twitter

Recent Profile Visitors

2692 profile views
  1. There's also VIEWPORT_ONRESIZE. Depending on which event you really care about. But the event handler is definitely the right way to handle this.
  2. FWIW, you can use the pointer-events CSS property to allow events to "fall through" the invisible DOM container to the canvas below. You'll have to set the same property on the GUI element children to allow them to recapture pointer events that the parent ignores.
  3. The rectangle defines the draw destination. Usually it's the viewport: If you already have a GUI object or something else that represents the minimap size and position, you might just be able to use its rect. Otherwise you can create a me.Rect with the parameters you need, and use that.
  4. Do any of these examples work for you? The drag-and-drop and particles examples no longer work for me, but the other examples do. They all use registerPointerEvent
  5. @Growler No problems with that! It's conceptually similar to using shape entities for things like doors or kill planes. I guess in this case it's most similar to me.ParticleEmitter
  6. What kind of events would trigger the entities to "actually load"? Would it be something that just happens nondeterministically, or when loading the map with certain state? If the latter, I would probably lean toward using a copy of the map with the various different states. I know this won't work for every situation, but it's definitely the easiest to implement. For a longer-term solution, you might consider using the object layers supported by Tiled. IIRC, you can change the visibility (on/off, but melonJS just uses it to set the entity opacity to 0) and melonJS won't render invisible layers. But the entity would still be active and needs to be "disabled" or else it will continue to be updated and will be included in collision detection tests, etc. One idea that just came to me is that each object layer can be implemented as a me.Container, if you pass options.flatten=false to me.levelDirector.loadLevel. In short, the most naïve approach is to grab the container reference by the layer's name in the options.onLoaded callback, then remove it from the scene and store it somewhere for later until you need it again. It might look something like this: me.levelDirector.loadLevel('my_map', { flatten: false, onLoaded: () => { // Save an array of every layer named 'quest' to a global object game.quest_layers ='quest'); // Remove all of the quest layers from the scene game.quest_layers.forEach((layer) => {, true); // The second arg preserves the layer }); }, }); setTimeout(() => { // ... Some time passes and we can trigger the quest entities to appear // We'll just use a random layer index for illustration ... let x = Math.floor(Math.random() * game.quest_layers.length); // Remove the layer from the global array, and add it to the scene let layer = game.quest_layers.splice(x, 1);; }, 5000); This is super simplified. A more complex implementation might take layers by multiple names, and store them in a hash map, or even iterate the entire world container looking for invisible containers... There's a lot that can be done to customize it, but the takeaway is that it's desirable to remove children from the scene graph, and add them back in later. And this can be done with the optional keepalive argument when removing children. That might be a good place to start, anyway. Hope it helps.
  7. I am familiar with immediate mode GUI! Never really considered it in the web stack, though. The DOM is already the opposite of immediate mode, and trying to reimplement the entire collection of GUI elements in webGL would be insane. 😅 I also can't see the immediate mode working well with a batching GL compositor that melonJS uses, since the compositor relies on the fact that GL is a stateful API; It tries to optimize rendering by uploading everything early and reusing state often. It is possible to stream vertices to the GPU, though. And that's exactly how dear imgui works.
  8. Forgive me if this sounds skeptical, but most of the existing abstractions are already lightweight, and you'll just end up reinventing the wheel in many areas. The one major exception is probably the observable vector classes. On the other hand, there's really no requirement to use them, nor any of the physics classes, or particle emitters, or tile maps, etc. if you don't plan to use any of that functionality. The existing game loop is about as bare-bones as it gets: The update and draw loops are likewise very light: ... handling various things like pausable timers and accurate frame skipping/interpolation logic. is a container which hosts an array of children to update and draw. The complexity that you envision comes from the nested hierarchy of containers, that can build a complete-but-flexible scene graph. The added flexibility comes at the cost of added complexity. Containers are also fairly lightweight: Everything else in this module is a collection of utility methods to help support nesting. It is conceivable to replace the root container ( with a non-nestable container, if that's what you're going for... Which is exactly what the ParticleContainer is. It's unclear just how much benefit you can extract from doing such a thing, but it is certainly an option. So to answer your question, you just need to determine at which level you want to replace the game loop, and patch out that part. You can either monkeypatch it through the references, or using the builtin patching APIs. And then you need to determine which pieces you need to reimplement for a solid foundation beyond just drawing textures.
  9. The code in the OP shows that you return true from the collision handler unconditionally. (Remember, this is the only information I have to go on! I can't see all of your code, and I definitely don't see any conditions checking the shape index.) Which means it would apply the collision response (repel the entities by adjusting the velocity). The code I linked above shows how it calls respondToCollision on the body when the collision handler returns true. And this method adjusts the velocity accordingly. Thus, my observation.
  10. I think what you're seeing has something to do with the misunderstanding of collision shapes on a body. Collision detection does not happen on a "per-shape basis", but on a "per-body basis". In short, bodies collide with other bodies, not with shapes. The shapes are only there to add a physical structure to the body. Under this axiom, it doesn't make sense to have a large rectangle with a smaller inner rectangle, because only the larger rectangle "matters" when performing collision detection. Secondly, you are using two competing collision processes and expecting them to operate independently (I guess). In reality, they are just two sides of the same feature; the me.collision.check() call is the caller, and the onCollision handler is the callee. Obviously, the check ignores itself, but it will call onCollision on the same object in addition to other objects that implement the handler. What you're seeing in the console log is this exact behavior: one of the entities somewhere in the scene is not colliding with anything, and somewhere else, two or more entities are colliding. Thirdly, the scenario that you are testing is artificial, since it should not be possible (under normal circumstances) to end up with two solid entities in the configuration shown in the screenshot. What I mean by artificial is that you have set explicit coordinates to "force" the smaller entity inside the larger one. If they were moved using only the physics properties such as velocity, they would instead repel one another by responding to the collision; adjusting the velocities to counteract any motion that would result in overlapping like that. I believe that describes the situation, at least in short. To fix it, you want to use the collision detection system only as a way to respond to collisions (e.g. pushing solid entities apart, taken damage from projectiles, etc.) and use something else like distanceTo() for the interaction range. You can use me.collision.quadTree.retrieve() to gather a list of potential candidates for performing distance checks. edit: I had mistakenly asserted that onCollision will not be called on the same object that calls me.collision.check(). The handler is definitely called on both entities when they collide. You can see the implementation here:
  11. @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).
  12. I used it in Neverwell Moor for the intro scrolling:
  13. 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.
  14. 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).
  15. 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