R0J0hound's Forum Posts

  • You do not have permission to view this post

  • You do not have permission to view this post

  • There was a box3d physics plugin released about a week ago, you could try that. There was also a 3d physics plugin released my mikal too that you could try. I'm sure others have patched in a js library too. So take your pick I guess.

  • I focused on the bounce portion while moving only on the grid here.

    dropbox.com/scl/fi/t7bbsf3u9989nyxuzw2fs/tilemap_bounce_grid.c3p

    This one moves smoothly between grid positions with an emphasis on smooth and robust collisions. AKA. Collisions are never missed.

    dropbox.com/scl/fi/p3w0tzuxk7phzpdl5s9je/tilemap_bounce_grid_smooth.c3p

    Might provide some ideas.

    For what you want you could count how many tiles it moved before reversing the angle of motion.

    You could use any other movement behavior to move and bounce the objects too, but there is a inaccuracy that will come up.

  • Sounds pretty straightforward. You can know when to bounce depending on the direction you want to move and the tiles in that direction.

    Like if moving to the right, check one tile to the right first. If it’s a wall then just set the direction to left.

    Same can be done for all directions. Although it should be possible to simplify it down.

  • 3d collisions aren't a thing as of yet. Unless you use a third party 3d physics plugin or roll your own collision detection logic.

  • The logic mostly directly transfers to events. Doesn't matter if it's C2 or C3, and nothing has been suggested yet that isn't possible in either version.

    If examples help i could post some, but they tend to be dense. Ideally we'd like to help you be able to do the events in a way you understand. If you're stumped you either just start trying stuff out, or try to break the problem down into simpler doable steps.

    So far you have a grid of blocks that you can drag around. You want to drag blocks onto adjacent blocks and have them swap positions.

    You can know when a block is being dragged with the "is dragging" condition. You could know the direction you are dragging by using the angle() expression between the block's starting position and it's current position. You can also find the distance it's been dragged with the distance() expression.

    That could look something like this:

    var startX=0
    var startY=0
    
    block: on drag start
    -- set startX to block.x
    -- set startY to block.y
    
    var ang=0
    var dist=0
    
    block: is dragging
    -- set ang to angle(startX, startY, block.x, block.y)
    -- set dist to distance(startX, startY, block.x, block.y)

    So presumably you'd only want to swap the object's position if you drag far enough, and even then you'd only want to swap with blocks in the cardinal directions (up,down,left,right). Maybe half the block width would be a good distance to drag to trigger a swap. So with 32x32 tiles you could see if the distance is more than 16. To get a cardinal direction we could round the angle to the nearest 90 degree. round(ang/90)*90 is one such formula to round it.

    So your events could look like this now:

    var startX=0
    var startY=0
    
    block: on drag start
    -- set startX to block.x
    -- set startY to block.y
    
    var ang=0
    var dist=0
    
    block: is dragging
    -- set ang to angle(startX, startY, block.x, block.y)
    -- set ang to round(ang/90)*90
    -- set dist to distance(startX, startY, block.x, block.y)
    -- compare: dist > 16
    -- -- ... swap with block in direction ang...

    That "swap" bit is what we'd want to figure out next. We need to be able to access both the block we are dragging and the block we are dragging onto. Families are one way to pick two different instances at once yet individually, but usually the way to go about it is to pick one at a time.

    The dragged block is already picked, so to pick another block we need to first use "pick all block", then some other conditions to pick it.

    We could use the ang to get the position of a tile in that direction. x=startX+32*cos(ang), y=startY+32*sin(ang), and then use that with the "pick closest" condition. However there are many other ways to do it.

    var startX=0
    var startY=0
    
    block: on drag start
    -- set startX to block.x
    -- set startY to block.y
    
    var ang=0
    var dist=0
    
    block: is dragging
    -- set ang to angle(startX, startY, block.x, block.y)
    -- set ang to round(ang/90)*90
    -- set dist to distance(startX, startY, block.x, block.y)
    -- compare: dist > 16
    -- -- system: pick all block
    -- -- block: pick closest to (startX+32*cos(ang), startY+32*sin(ang))
    -- -- -- ... 2nd object is picked ... just need to swap ...

    Ok, cool, now we just need to swap the two objects. set the second object's position to startx/y and add 32*cos(ang),32*sin(ang) to startx/y. A little bookeeping too. when drag ends we need to set the block position to startx/y to end the move. We want clean values so throw a round() over the sin/cos as well. Finally we need to make the is dragging event an "or" event and add "on drag end" to that too.

    var startX=0
    var startY=0
    
    block: on drag start
    -- set startX to block.x
    -- set startY to block.y
    
    var ang=0
    var dist=0
    var dx=0
    var dy=0
    
    block: is dragging
     - or -
    block: on drag end
    -- set ang to angle(startX, startY, block.x, block.y)
    -- set ang to round(ang/90)*90
    -- set dist to distance(startX, startY, block.x, block.y)
    -- compare: dist > 16
    -- -- set dx to round(32*cos(ang))
    -- -- set dy to round(32*sin(ang))
    -- -- system: pick all block
    -- -- block: pick closest to (startX+dx, startY+dy)
    -- -- -- block: set position to (startx, starty)
    -- -- -- add dx to startx
    -- -- -- add dy to startY
    
    block: on drag end
    -- block: set position to (startX, startY)

    Anyways, that is one way to do it, with some ideas behind it. The one I gave in the previous one works too.

    Here is the solution from my previous post. Doesn't get much more compact than that. It has an addition to limit it to only swap between adjacent blocks.

    dropbox.com/scl/fi/aavs1gwox2b6ontf2j8tf/swap_drag.capx

    Another solution that uses drag and drop, and eases:

    dropbox.com/scl/fi/egxhufb92axrisdpfyzuy/swap_drag4.capx

  • Well to swap the position of two instances of the same object you’d pick one and save the xy to variables. Then you’d pick the second one and save its xy to other variables. Then you’d pick each one again and set the position to the saved variables. However, you could simplify that a bit to use less variables.

    Basic swap logic would be

    Temp=a

    A=b

    B=temp

    But the main busywork would be picking.

    Picking each instance one at a time can be tedious and require a lot of events. However, if you add two instances of a helper sprite on the layout and call it temp, you could do this to swap instances with minimal events. You also need to add a swap instance variable to the blocks.

    Mouse: left is down
    Mouse: is over block
    Block: pick instance 0
    — block: set swap to true
    
    On mouse: left released
    — block: set swap to false
    
    Block: swap is true
    Compare: block.pickedCount = 2
    — temp: set position to block
    — block: set x to temp(1-temp.iid).x
    — block: set y to temp(1-temp.iid).y
    — block: set swap to false
  • You probably just need to set the linear and angular velocity to zero after enabling physics and moving the object.

    By default moving a physics object will give it velocity with the physics behavior. So that may be it.

  • Here's a demonstration of the idea. It takes any tile xy and in turn picks a tilemap chunk containing that tile. If there is no chunk there it creates one. Events have some particular picking rules in relation to newly created objects so I added a uid cache that's cleared every tick to fix that.

    dropbox.com/scl/fi/798zsobcdg72pt5cx8dcg/infiniteTileMap.c3p

    If you want to change the chunk size or tile size you'll need to change the 64 and 16 in the expressions. Also, you should clear the tiles in the editor if you want it to by default be empty.

    Anyways, that's the idea. There are many different ways you could tweak it. Or maybe someone else may have a different idea.

  • Probably one way to do it would be to create those 64x64tile tilemaps as needed, and make some functions to read/modify tiles. The functions would serve as a way to select the correct tilemap from an xy. They could also be a good place to create a new tilemap when accessing a tile from somewhere that there isn’t one.

    All that’s left is to create the missing tilemaps when scrolling around. But you probably could do that with some tile accessing.

    At least that’s a rough initial idea.

  • I guess if the y velocity of an object is positive then it’s falling. Since it’s a stack and you don’t want to consider the one you’re placing on top you could pick all the falling apples and if there are more than one, you could consider the stack falling.

    A first iteration of the idea could be something like this:

    Pick by comparison: apple: apple.physics.velocityY>0
    Conpare: apple.pickedCount>1
    — set falling to true

    If comparing by 0 gives too many false positives you could use a higher number.

    There may be ways to make it more rigorous. Maybe if you looked at the total speed of each apple and if more than one were increasing in speed then you may be able to detect the stack tipping before it actually starts falling.

    Another idea is to just count the number of apples on the ground. However, that would only detect that the stack already fell.

  • Try Construct 3

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

    Try Now Construct 3 users don't see these ads
  • In a simple test outside of construct there is no delay between positioning a dom button over a canvas with a 2d context. I’d have to test webgl later to see if there is any difference. But possibly that is lost when things are done in a more asynchronous way. Not sure.

  • You probably have to do the movement manually with events until behaviors get updated to support 3d.

    One way could be to give the node sprites a next variable that you set to the uid of the next node you want to move to.

    In the same way you can give the sprite you want to follow the path a variable called target which is the uid of the node it's currently moving toward.

    Then to move the sprite, and update the target node when a node is reached you could do:

    | Global number d‎ = 0
    | Global number speed‎ = 200
    + System: For each Sprite
    + node: Pick instance with UID sprite.target
    -> System: Set d to distance3d(Sprite.X,Sprite.Y,Sprite.Z, node.X, node.Y, node.Z)
    -> Sprite: Set position to (Self.X+(node.X-Self.X)÷d×speed×dt, Self.Y+(node.Y-Self.Y)÷d×speed×dt, Self.Z+(node.Z-Self.Z)÷d×speed×dt)
    ----+ System: d < 16
    -----> Sprite: Set target to node.next
  • So testing with the button object...

    With workers on setting the position every tick will be 2 frames behind.

    Turning workers off improves it to be only 1 frame behind.

    So if you can predict where an object will be a frame in advance then you can compensate.

    For example

    every tick:
    -- sprite: set x to 320+200*sin(200*time)
    -- button: set x to 320+200*sin(200*(time+dt))

    However I don't have a general way to predict future positions.

    That said, looks to be a update order thing in the engine similar to how the pin behavior lagged a frame behind.