R0J0hound's Recent Forum Activity

  • Maybe you could set an instance variable in the timeline that’s normally a different value. Or if you specify the instance at runtime with the “set instance” action you could try to keep track of it then too.

    If you don’t mind a multiple build step approach you could make a tool to parses the timeline information out of the c3p file and sets a json file in the project you can access. Or maybe you could access the exported data file directly and parse out the timeline info from that.

    Scripting wise it may be easier to just request a method to be able to access it from the api.

  • Short of access to the actual project and someone taking time to look through it it won’t be possible to debug.

    That said areas you could focus your attention on is the “or” blocks and “trigger once” conditions. Or blocks tend to bite me often so I carefully ensure they are doing what I intend when I use them.

    Maybe putting a for each in the custom actions may help too. In general many find it simpler to use “for each” in any place that there may be multiple picked instances to make the logic more clear to them.

  • Try Construct 3

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

    Try Now Construct 3 users don't see these ads
  • Let us know if you want to be confined to any other shape.

    A rotated rectangle can be done by first rotating position offset by the -angle, then clamping by the size, and rotating the angle back again.

    A circle shape can be done by measuring the angle and distance, clamping the distance, the calculating a new position from that.

    If you want to limit it to an object’s collision polygon, and the polygon is a convex polygon, you can take the position offset and clip it by each edge with a bit of math. Namely with (x-x0)*cos(a)+(y-y0)*sin(a) you can measure a distance along a certain direction. If you use that with an angle 90 degrees from an edge you can find if a point is on either side of an edge and clip it if on one side.

    Finally if you want to limit the motion to a concave shape you probably could do that by storing the players previous position and calculating the line intersections between the edges and the segment connecting the new and old position, and finally just stop at the first intersection. I don’t think that would provide any wall sliding but one idea for that involves decomposing the concave shape into convex ones, but it may be a bit more involved. Basically you’d check for overlaps with edges, the limit to the convex sub polygon that edge is part of.

    Also depending on the shape you could possibly utilize sdfs to implement the limit. That would let you have shapes with rounded corners.

    Taking the sdf idea further, you could make an approximate sdf on a 2d grid of any shape and raymarch through that. The main complexity there would be generating it.

    There are some low tech approaches too. You could store the old and new positions and use a loop with an overlap test to move but stop short of leaving the other object.

    Dop’s suggestion to place invisible solid objects around the shape is probably the easiest no code option. Another is to make the collision polygon a crescent shape that you wrap around the object image so there’s a thick wall around it.

    With collision based approaches beware of tunneling. Aka with high speeds and thin walls the collisions can be missed and objects will move right through.

    There are probably other approaches with varying pros and cons.

  • That’s a tricky one to give an exact answer since most don’t have such specific requirements.

    That said, it looks like there are expressions to get the current playback time and the time of nodes on the timeline. That combined with the duration of a landing animation you could have an event to check the time to decide when to change the animation.

    Having the requirement of only changing animations on a particular frame can be handled with events too. However combined with that other constraint you may need to adjust the speeds of things.

    For example, say you have a looping running animation you want to jump at a node on the timeline, but you only want it to change on a particular frame you’d want to either pause the timeline at that node and wait till it’s at the right frame or look at the time anticipating the node and speed up/ or slow down the animation speed so that the frame is where you want it to be at that node.

    There’s probably a system you could make to do that in a general way. Like you’d have the list of animations you know you need to move through and a list of the nodes on the timeline where you what the transitions to be. Then it would adjust either the speed on the path or the speed of the animations so that the transitions are at the exact time and frame you want.

  • I mean I know why it happens. It’s an artifact of how those behaviors resolve collisions.

    The collisions are resolved roughly by moving in steps till there is no overlap. Since it moves in steps it’s only approximate but is generally good enough. With zoomed in pixel art the error is magnified though.

    Anyways, I don’t think there’s any setting to eliminate it, but shrinking the collision poly could shift to look like it’s slightly overlapping instead of having a gap.

    You could also do your own collision handling. Aka don’t use the solid or jump through behaviors and do your own collision detection/resolution. You might get away with doing that with the 8direction behavior but with the platform behavior it would likely be better to just do the whole behavior from events.

    Focusing on how we could do a better collision resolution, we could do a progressive stepping solution that moves in big steps first then increasingly smaller steps to get a very close near perfect touch between the objects. Alternately, you could focus on calculating where the objects should be to be just touching. Either way we’d need to be able to calculate the collision normal to be able to update the velocity.

  • How many cases are you trying to handle? All of them?

    If it’s only some then you just need to know the number of wall to compare the pickedCount with and pick each wall in turn separated by pick all.

    You could make a helper function that returns 0 or 1 if a wall is at a location. But then you’d have to use 8 compares to check for each case.

    Or you could do that idea in my second reply that sets a neighbor variable to whether a wall is at each direction or not. For example “00000001” would be a wall to the NE.

    Not super readable but maybe you could modify it to be “NE” instead or maybe “7”.

  • My bad, it should be comparing the picked count with two in the second example since we are checking two tiles. I edited that post.

    You may just need to work though the logic yourself a bit more. The best solution is one you understand.

  • So it appears you can’t stay logged in on the same account with multiple devices anymore. I check the forum from my phone and laptop and if I login on one it logs me out on the other. I can see the reasoning to avoid multiple users using the same subscription, but I’m kind of the outlier since I don’t have a subscription, I’m just a forum user.

    No worries though. I’ll get used to it.

    More annoying is the incessant huge delay to verify I’m a human almost every visit to the forum from my phone. Often repeatedly if I use “back”. It seems to even be taking longer as of late. I suppose those kind of things are the new reality of the internet.

    It’s just a lot of friction to the point where I think maybe I should spend my time doing something else. Which isn’t a bad thing.

  • The pick all needs to be in the same event block. You’re using multiple.

    All the conditions in the last example I posted can be in one event block and it’ll work. Most of the conditions can have their own block but this at least has to be grouped in the same block.

    Wall: x=tile.x-100
    Wall: y=tile.y
    Pick all wall
    Wall: x=tile.x+100
    Wall: y=tile.y

    All it does if it’s able to pick the first wall it then tries to pick the second. The pick all makes so it can even pick another wall.

  • The trigger once while true condition doesn’t do anything in a loop.

    Looks like you’d need to check for walls in all 8 directions. Where if a wall is there is just as important as if there isn’t one.

    So you’d basically do this 8 times for each direction… you’d have to accumulate the result in a var somehow.

    Wall: x=tile.x+100
    Wall: y=tile.y-100
    — there is a wall there
    Else
    — there isn’t a wall there

    Maybe this?

    For each tile
    — tile: set neighbors to “”
    — repeat 8 times
    — — wall: x=tile.x+100*round(cos(45*loopindex))
    — — wall: y=tile.y+100*round(sin(45*loopindex))
    — — — tile: add 1 to neighbors
    — — else
    — — — tile: add 0 to neighbors
    
    Tile: neighbors=“00000001”
    — do something

    But that’s ugly. Another approach could be to add all the walls to a 2d array to simplify checking a grid for a tile or not.

    Start of layout:
    — array: set size to (100,100,1)
    —array: clear to 0
    — for each wall
    — — array: set at (int(wall.x/100), int(wall.y/100)) to 1
    
    Var gx=0
    Var gy=0
    
    For each tile
    — set gx to int(wall.x/100)
    — set gy to int(wall.y/100)
    — compare: array.at(gx-1,gy-1)=0
    — compare: array.at(gx,gy-1)=0
    — compare: array.at(gx+1,gy-1)=0
    — compare: array.at(gx-1,gy)=0
    — compare: array.at(gx+1,gy)=0
    — compare: array.at(gx-1,gy+1)=0
    — compare: array.at(gx,gy+1)=0
    — compare: array.at(gx+1,gy+1)=0
    — — do something

    Still pretty verbose. And you’d want the array to be big enough to cover all grid positions, and you’d have to update it if you moved or add/remove walls.

    But we could do better. With an overlap check we could pick all the neighboring walls at once. And the case you’re looking for only has one wall next to the tile and we know what position we’d want that tile to be at.

    For each tile
    Tile: overlaps wall
    Compare: wall.pickedCount=1
    Wall: x=tile.x+100
    Wall: y=tile.y-100
    — do something 

    It extends nicely to other possible cases too. Say you want to check if there are only two walls to the left or right.

    For each tile
    Tile: overlaps wall
    Compare: wall.pickedCount=2
    Wall: x=tile.x-100
    Wall: y=tile.y
    Pick all wall
    Wall: x=tile.x+100
    Wall: y=tile.y
    — do something 
  • What if you set the up vector to (0,0,1) instead?

  • So trying it out, the reason it doesn't work is you are picking the tile to the SW of the wall, then trying to pick the tile above that wall. They will never be the same tile, so it doesn't work. Sure the tile could have a wall below it and to the NE, but your logic doesn't check for that.

    Anyways, here is one possible solution with 32x32 tiles. Loop over the tiles instead and check for walls around it. The pick all is so we only need to pick one wall at a time.