R0J0hound's Forum Posts

  • 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.

  • Try Construct 3

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

    Try Now Construct 3 users don't see these ads
  • 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.

  • Well, the 8-direction behavior works by doing the horizontal and vertical axis of motion separately. When a key is pressed it accelerates toward that direction, and if the velocity is opposite that direction, then it adds the deceleration to the acceleration to allow sharper turning and make the motion less floaty. And finally, it applies deceleration if no keys are pressed on a given axis.

    Changing it to work with any angle is similar but different enough to not be a simple tweak.

    Here is one attempt. Acceleration can be applied to any angle. Deceleration is added to the acceleration when the velocity is in the opposite direction to allow faster turning. It also applies deceleration to velocity perpendicular to the acceleration. And finally, it applies deceleration when no acceleration is applied.

    dropbox.com/scl/fi/igrj1axj136hhuycmpp5w/360direction_movement.capx

    I don't have a joystick, so I used a touch screen one. Collision detection and response (wall sliding) is done with an SDF. Player is a circle, and obstacles are any number of rotated boxes.

    Seems to work alright.

    Now you could do a hybrid approach to reuse as much of the 8-direction behavior as possible. Read the velocity and apply an acceleration at an angle. One key idea to make it less floaty and turn faster is to add the deceleration to the acceleration. You can find the velocity along an angle with vx*cos(a)+vy*sin(a) where vx,vy is the velocity and "a" is the angle. It will be negative if "a" is in the opposite direction from the angle of motion. You may also need to decelerate the perpendicular velocity, but after that just set the velocity of the behavior and it will handle slowing down if there are no keys pressed, and it will handle the collision detection and response.

  • Computing the exact path an object will move is a tricky problem. Between collisions we can calculate the path exactly but when the collisions occur will vary. The reason for this is motion if done in steps so once a collision is detected it’s usually overlapping a bit already. Typically the exact point where the objects just started colliding would be somewhere between the steps.

    Two solutions come to mind.

    The first is to calculate the exact time of collision. Fairly complex but basically when an object isn’t colliding one step then overlaps the next you’d find the position in between where the objects touch. Then you’d have it bounce and do the calculation again for the remainder of the step. You’d need to do this both for the predicted motion and normal motion. You’d probably want full continuous collision detection with swept volumes to not miss glancing collisions with corners. Anyways you could get a pretty accurate path that way. But there is always some precision loss with the calculations so the actual path will diverge from the predicted path a bit the further down the predicted path you go.

    Another idea is use a fixed timestep to calculate the path of the object. That would give a consistent path. Then to move the object just move it over that calculated path. Basically you’d calculate a list of xy positions with the time at those points. Then you can interpolate the moving objects position over that in a frame independent way. So you could for example simulate the path at a fixed 30hz and no matter the screen refresh rate it would follow the exact path.

    The main annoyance of that is you wouldn’t really be able to use behaviors for the motion anymore, but I guess the same can be said about the other idea.

    I’ll see if I can drum up an example of the second idea later.

  • dop2000

    Actually it does more than match them by pairs

    For example

    Enemy: set width to box.width

    Becomes:

    for(let n=0; n<enemy.pickedCount; n+=1)
    — enemy[n].width = box[n%box.pickedCount].width

    So yeah if the count of both is the same they are paired. But if there are more enemies than boxes then it will loop over the boxes again.

    Anyways related to the original question. For each is needed whenever you want to do things to each object individually when more than one object is picked. That’s the easiest rule of thumb to me. Although you can get away without a for each in some cases.