R0J0hound's Forum Posts

  • I’m becoming more and more convinced that construct isn’t as simple to use as it appears.

    There are many solutions to that, each with their own set of things to be familiar with.

    The first approach I’d use is how would you do that in real life? What would the steps be?

    Probably: roll 4 dice, then look for two or more dice that are the same, and reroll the duplicates and check again. So roll, and reroll if there are duplicates.

    However picking seems to be hard to most, so is picking two separate instances at the same time.

    So you could put all the possibilities values in an array, shuffle that, and use that to set frames.

    Start of layout

    — array: set size to (sprite.frame count,1,1)

    Start of layout

    Repeat array.width times

    — array: set at loopindex to loopindex

    Start of layout

    — array: shuffle

    Start of layout

    For each sprite

    — sprite: set frame to array.at(loopindex)

  • One of the issues you’re encountering is the object’s blend mode and the “drawing blend mode” are two different things. You’d want to set the drawing blend mode to destination-out before filling the ellipse, but you should leave the object’s blend mode as normal.

    So roughly this would create a canvas over the sprite, draw the sprite to the canvas, and erase a circle out of it. What you do with the sprite after is up to you, but I destroyed it here.

    On clicked sprite
    — create canvas at sprite position
    — set canvas size to sprite size
    — canvas: paste sprite
    — sprite: destroy
    — canvas: set drawing blend mode to destination-out
    — canvas: fill ellipse at mouse

    The other way could be to use circle sprites with the destination-out blend on layers with “force own texture”.

    You said each sprite is on its own layer, so just make sure each of those layers has “force own texture” enabled. Then erasing holes would be as simple as:

    On sprite clicked
    — create: circleSprite on layer: sprite.layer at mouse.x, mouse.y
    — circleSprite: set blend mode to destination-out
  • Try Construct 3

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

    Try Now Construct 3 users don't see these ads
  • TestOverlapSolid just returns true or false. It doesn’t provide any info about what instance it was overlapping.

    To know the instance you’d need to use testOverlap(a,b) instead. But for that you’d need a list of instances with the solid behavior to loop over.

    One way to get that list is to access an object type that has the solid behavior, and get a list of all instances with solid like so:

    let inst = runtime.objects.Sprite. getFirstInstance();

    let list = inst.behaviors.Solid.behavior. getAllInstances();

    That’s basically how you access behaviors according to the manual. It’s not too generic if you have to tell it a type that has the solid behavior. Also it needs an instance to exist to be able to access the list too.

    A generic way could be to have a function that loops over the types in runtime.objects, gets the first instance and if it has the solid behavior save that somewhere. A bit brute force but ideally it would only need to run once, so if it found the solid behavior it would save it. Worst case is you’d have no instances with the solid behavior so it would keep searching and failing to find it.

    Anyways with that you’d be able to get a list of the instances with the solid behavior, loop over them and use testOverlap() to see if they overlap. And if they do you could then compare inst.instVars or something. Or you could even access the solid behavior tags but that may be automatic.

    You could also try and utilize constructs collision cells. To do that you’d use runtime.collisions.getCollisionCandidates() but for that it needs an object type. To get those you could loop over the list of instances with the solid behavior and make a second list without duplicates of the object types.

    Anyways I’d argue that js is fairly easy to learn. However, the hard part is finding ways to access things from the engine. Some things are easy to access, some things have to be accessed in round about ways, and for some there’s no access at all.

  • I’d say anything really. You don’t need a top of the line machine to do development. In fact if you develop something with an underpowered machine you’ll notice performance issues with your projects faster.

  • You can utilize the formula: speed*time=distance

    And solve it for time: Time=distance/speed

    You can the set distance to whatever the spacing you want is. Maybe every 8 pixels?

    Then you’d have “every 8/speed seconds”

    I can see a few issues with that approach though. At low speeds, say 0.1 pixels per second, it will be “every 80 seconds”, or worse still at a speed of zero it will be “every infinity seconds”. You can mitigate it by limiting how big the number can be: min(0.1, 8/speed)

    A second issue is the “every x seconds” is any value less than dt will be the same as dt. So at high speeds the tracks would be spaced out more again.

    Another idea is to keep track of the previous position of the tank and and use a loop to create tracks between the previous position and the next.

    Var prevx=0

    Var prevY=0

    Var ang=0

    Start of layout

    — set prevx to sprite.x

    — set prevy to sprite.y

    Every tick

    — set ang angle(prevx,prevy,sprite.x,sprite.y)

    Repeat distance(prevx,prevy,sprite.x,sprite.y)/8-1 times

    — create track at prevx,prevy

    — track: set angle to ang

    — add 8*cos(ang) to prevx

    — add 8*sin(ang) to prevy

  • Initially all the tiledbg instances share the same texture from the type. They could very well have made loading another texture replace the texture of the type instead of just the instance.

    With sprites the type has the animations attached to it so basically all the instances share the same list of animations. So when loading an image it is simplest to just replace the image in the animation which affects all instances. Only replacing an image in the animation for just one instance would be much harder to do. Probably would require duplication of the animations per instance but not the textures.

  • I think we may be talking about different things at this point. I was talking about something along the lines of:

    Mykey = str(sprite.uid)

    Dictionary: add key mykey with value dictionary.get(mykey)+1

    But I may have misunderstood what was being asked.

  • I don’t understand what you mean by str() doesn’t work with a dictionary. Sure it requires that the key be a string but you can convert a number into a string with the str() expression and it’s happy. And I’m not just saying that, I’ve done it a lot.

    I’ll defer the json questions to dop as he uses them pretty heavily. I’ve only used them sporadically and have to re figure out how to use them every time.

    If changing the layouts clears values then the object isn’t global. When something isn’t global it gets destroyed when leaving the layout and recreated when returning to it. You can make an object global in the objects settings. So maybe that’s what you’re encountering?

  • Interesting stuff. The precision of the numbers on the gpu varies depending on the hardware but the renderer does guarantee at least some minimum precisions.

    Webgl1 gives at least 24,16 and 10bit for highp,mediump and lowp float numbers.

    Webgl2 gives at least 32,16 and 10bit for highp,mediump and lowp float numbers.

    But my phone happens to give 32bit for all three.

    Presumably your phone implements the minimum spec or close to it. With less bits floating point numbers have bigger gaps between values when farther from zero. That’s why limiting the offset to be within the size of the image helps since it’s keeping values closer to zero.

    A significant example of that would be the so called “farlands” in Minecraft when exploring extremely far away.

    Anyways, I thought it was interesting. Also the fact that lowp,mediump and highp all are 32bit on my phone means if I was to make a shader I wouldn’t encounter issues that other users would see when I use mediump or lowp.

  • Just make the number a string with str().

    I don’t understand the statement about json. It’s a plugin you can use.

  • That sounds fine to have a value per type in the family. If you wanted a value per instance you could use cards.uid as the key.

    If you wanted multiple values per type or instance you could just use another dictionary or append something like “:value1” to the key or something. For example cards.uid&“:value1”

  • I had a quick look but can’t test since I’m not on a pc.

    Bear in mind that using a ray cast only approximates the collision normal between two overlapping polygons. Thats probably at least partially why it doesn’t work well between two solids. A more elaborate algorithm such as SAT (separating axis theorem) would give a more precise normal between polygons, or you may be able to to do multiple raycasts and maybe average the normals to get a better approximation.

    Another reason you may want to do multiple ray casts is one ray will only hit one of the solids and it won’t necessarily be the one the player is overlapping. Even so, it still seems a bit hit and miss doing it with raycasts vs SAT.

    After the ray cast and comparing the normal you push out of the solids with a loop. First you say you try to push out left then right. The push out right is not doing what you think it’s doing. You’re just moving at the opposite angle which is back into the solids.

    I also see you’re using the reflection angle when doing the pushing. You possibly could try using the normal instead.

  • There are actions to change the zorder of objects. So even though you can’t sort by y with one action like you can with sprites, there are other ways.

    One way could be two use an array to store the y and uid of all the objects you want to sort. Then you’d sort the array and loop over it and pick the objects by uid and move them to front.

    Another way could be to zsort all the sprites, then loop over the tiledbg objects by y and pick the sprite with the lowest y greater than the tiledbg y. Then you’d set the zorder to be behind the sprite.

    There may be other schemes you could try too.

  • Glad it was somewhat useful. SDF stands for signed distance field, which basically lets you have a formula that gives the closest distance from a point to a shape. In the example the shape is a rotated box. It’s not exactly made for collision detection, but can be used for it. Specifically it’s simple enough to use to find a collision between a circle and a shape. Also it’s fairly simple to use to get the contact point and collision normal.

  • Here's my tests with the ideas I mentioned.

    With this you simulate the path and simply reuse that same path when you want to move along it. You can make the simulation step anything, but when moving along the path it moves in a framerate independent way.

    dropbox.com/scl/fi/ksuj6rfhow2q5gf19jdcq/path_perdict.capx

    Here's an iteration on the idea. The previous capx simulates by moving, and once a collision is detected it uses the normal to push the object out and bounce. This one finds the time of collision by assuming motion is linear between steps and interpolating when the collision occurs and moving to that point before bouncing. This could be done even better, but it seems fine.

    dropbox.com/scl/fi/70e4s84lsjz1wyxo65lwi/path_perdict_percise_contact.capx

    Anyways, just some examples to demonstrate the ideas I mentioned.