R0J0hound's Forum Posts

  • That’s caused by the drawing order of images with transparency. Ideally polygons are drawn back to front, and construct generally tries to do that. The issue is just sorting the polygons won’t always work. I guess intersecting polygons is a common case that can’t be solved by sorting.

    One possible solution is to use a discard shader on problem sprites. What it does is not draw the transparent parts so stuff behind it is shown even if the order isn’t ideal. The only con is it would be a hard jump from transparent to not which may or may not look good in your project. Someone made one, but I don’t recall where. I think someone also made a dithered semi transparency effect too. Makes me wonder if you could render at double resolution and smooth resize it down to half resolution to get rid of dithering and hard edges.

    Another idea is to somehow control the sorting yourself to see if you can improve things. Fiddle with zorder and zelevation perhaps? In previous tests it wasn’t straightforward to override it. For example getting the walls to be drawn before the transparent stuff would help with the first artifact. For the second drawing the sword after the character would kind of help but I imagine the sword would get the clipping then.

    With the exception of intersecting polygons and cases where there’s a cyclic loop (ex: A in front of B, B in front of C, C in front of A) then doing a topological sort instead of a distance sort can help. But it’s probably not worth the effort here.

    Another idea is to split the objects into smaller ones. Or maybe dynamically split the intersecting polygons. An algorithm like BSP does that and likely would solve it. But again probably not worth the effort here and it would be rather heavy.

    Leveraging the gpu to solve it per pixel is another idea. Intuitively each pixel would be a list of colors and zdepths which would then be sorted. One algorithm called depth peeling supposedly does that semi efficiently. But that sort of thing is lower level than what’s really possible with construct’s renderer.

  • Well, what does construct provide to be able to do this? Maybe:

    System: pick 3dshape overlapping point (mouse.x, mouse.y)

    If the bottom of the 3dshape is on the z=0 plane then that will let you click on the bottom face. The other faces though? you're out of luck with Construct features. You'll have to do something from scratch...

    First you'll need the mouse ray. You can get that from the camera distance to the screen. One way to calculate that is from a non scrolling 2d layer: xyz: (mouse("2d").x-320, 240-mouse("2d").y, 240/tan(fov/2)). 320,240 is half the viewport size. Next you'll have to normalize that vector and rotate it by the inverse of the 3d camera orientation. That will give you a ray direction from the camera position.

    The second part is to do some kind of raycasting to see if and where the ray hits a 3d shape. Using an sdf with raymarching is a relatively simple solution for a single unrotated cube.

    dropbox.com/scl/fi/on24os5ezt8bqkugnea58/raycast_mouse_cube.c3p

    Overall for this kind of problem you figure out how to solve it from scratch and then adapt it to what features construct provides.

  • Roughly you’d calculate the angle difference between the two edges, and if the angle difference exceeds the angle limits you specified then you’d rotate the end edge till the angle is within range.

    We can calculate the angle of the edges with the angle() expression. To get the angle difference we could use anglediff() but we need the signed angle diff where its negative when CCW. That can be calculated with angle(0,0,cos(a-b),sin(a-b)). Then you’d check if the angle diff is greater or less that an angle limit. And if it is rotate the endpoint so it’s back in range. The formula to do that is:

    Pos: ((x-cx)*cos(a)-(y-cy)*sin(a)+cx, (x-cx)*sin(a)+(y-cy)*cos(a)+cy)

    As an example (barring any typos) this will move multiple instances of a sprite in a chain. The first instance will be moved to the mouse position, then all the following instances will be moved to be 32 pixels from each other. Then from the third instance on it limits the angle to the range (-10,10)

    Var p0=0
    Var p1=0
    Var p2=0
    Var da=0
    
    For each sprite
    — set p2 to p1
    — set p1 to p0
    — set p0 to sprite.iid
    — compare: loopindex=0
    — — sprite: set position to (mouse.x,mouse.y)
    — compare: loopindex >0
    — — sprite: move distance(self.x,self.y,sprite(p1).x,sprite(p1).y)-32 pixels at angle angle(self.x,self.y,sprite(p1).x,sprite(p1).y)
    — compare: loopindex>1
    — — set da to angle(sprite(p1).x,sprite(p1).y,sprite(p0).x,sprite(p0).y)-angle(sprite(p2).x,sprite(p2).y,sprite(p1).x,sprite(p1).y)
    — — set da to angle(0,0,cos(da),sin(da))
    — — set da to da>10?(10-da):(da<-10?(-da-10):0)
    — sprite: set position to (self.x-sprite(p1).x)*cos(da)-(self.y-sprite(p1).y)*sin(da)+sprite(p1).x, self.x-sprite(p1).x)*sin(da)+(self.y-sprite(p1).y)*cos(da)+sprite(p1).y)
  • Well the imagUrl is just a string which you can download with the browser object’s action: invoke download.

    With nwjs you can save it to a file too.

  • In events “sprite.something” only gives numbers and text.

    The drawing canvas is probably what you need to use to access image stuff. You’d paste the sprite to the canvas then you can access and set individual pixels or get an imageurl to save or download a png/jpg file.

  • Found if you set sampling to nearest then the thin slivers go away with meshes. It's probably not a viable solution since you'd want smoother sampling for everything else but still could be useful.

  • Likely int() uses parseInt() under the hood so it would still return 0. The string would need to start with a number for int() to work.

    If your layout makes have the pattern of a letter then a number then you could do int(mid(layoutname,1,10)) or something.

  • Mesh is almost an option if we can avoid the thin transparent gaps. I want to investigate fiddling with the math to see if I can remove or reduce the rounding errors. In theory I could scale tue triangles up slightly to eliminate it too. If that works out then I’ll make it combine triangles to reduce object count. Anyways, I’ll let you know. As is it’s mostly trivial to change between drawing with canvas or a mesh.

  • Here's the wip of the triangulation. It works with the the polygon defined by sprite instances in a CW order.

    Using a mesh to display the triangles didn't quite pan out because it gives thin transparent slivers due to math rounding. So it also lets you draw the triangles with the canvas as well since it doesn't have the slivers. It doesn't look worthwhile to extend it to generate convex polygons or triangle strips at this point. It will need reworking if you want to define the polygon in another way other than sprite instances. Doesn't work with self intersecting or CCW polygons, but the CCW case can be solved by detecting the order and reversing the list.

    dropbox.com/scl/fi/png6jg6a1qresctjq5ra6/triangulate_ear_clip_mesh_wip.c3p

    Alternately, if you want to use js for this you could look into this one:

    github.com/mapbox/earcut

    Or you could take the triangulation function out the old c2 chipmunk plugin. That one generates convex polygons.

    Edit:

    Just noticed that points ordered in CCW order could be used for a convex hull.

  • If the orbit is controlled by physics then to make it be able to orbit slower you need to reduce the gravity force. Or maybe just don’t give physics to the moon and move it with the orbit behavior instead.

  • The 14.2 mb is the compressed png size. That should remain the same which means faster downloads. When the game runs, the images need to be decompressed to use.

    45*650*540*4 =~ 63.2 mb

    Depending on the hardware texture sizes are only power of two so 650x540 may have to take up 1024x1024 which would give:

    ~188.7 mb

    Also keep in mind there will be other memory usage needed for the renderer in general. I think Ashley made a blog about it.

  • Self.x+dist*cos(ang)

    Self.y+dist*sin(ang)

  • A few ideas:

    Since you’re hitting the limit of the algo that the canvas object uses to convert a concave polygon to multiple convex ones, you could feed your polygon to another js library to do that and just draw the list of convex polygons it generates.

    Also as a tangent you could use a mesh distort to render convex polygons.

    For example for a 100 point polygon you’d do it roughly by:

    Set mesh size to (50x2)
    Repeat 50 times
    — set mesh at (loopindex,0) to point(loopindex).xy
    — set mesh at (50-loopindex-1,1) to point(50+loopindex).xy

    And actually you aren’t limited to just convex polygons. In general you can do any triangle strip in this way which includes some concave polygons. Also if you adjust the uvs you can get a textured polygon without using blend modes, but I guess that’s unrelated to what you’re doing.

    Anyways, the idea to explore is convert any polygon to multiple triangle strips and use mesh distorts to display them. To do that you’d slightly modify a triangulation algorithm like “Ear clipping”, which basically adds triangles at convex points if no other points are inside that triangle. To make it generate triangle strips instead of just triangles you’d zig zag moving cw then ccw on the plolygon when adding triangles.

    Alternatively you could triangulate, then merge triangles sharing edges if the result is still convex.

    I’ll be attempting to make an example of the idea when I get time.

  • Almost there. You need to click on one of the sub forums first.

  • Try Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Try Now Construct 3 users don't see these ads
  • That’s all I have at the moment.

    The array is a history of the positions of the head which basically can be thought of as a polyline. You can move along the polyline by a specific distance. A simple starting point would be to move a distance along a single line segments. Anyways, many path following examples do that.

    Another idea is to just move each section toward the section ahead of it till they overlap.

    Just some ideas. I won’t be making any examples any time soon.