R0J0hound's Forum Posts

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

  • Try Construct 3

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

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

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

  • You can post your events like that, or even screenshot them for a small amount of events, but generally you’ll want to upload the entire c3p for anyone to be able to give any suggestions.

    Since the issue is with color you only need to look at the events that set the color and in turn the rgb variables. If you disable the event to cycle the colors does the rest of the colors work?

    Just a hunch, but the rgb expressions may not take the values you expect in the set color action. Some of them take values in the range of 0-100 (rgbex), and some 0-255 (rgb).

  • Setting the speed before the angle of motion like dop suggested probably will fix it.

    Why that fixes it is because when the speed is 0 trying to set the angle of motion will do nothing. That’s because the bullet behavior stores its velocity as horizontal and vertical components instead of an angle and direction. As such when speed is zero the angle of motion will always be 0. In the simple case without gravity this is all the behavior is doing if you want to try the math and get an intuition of why.

    Function setAngleOfMotion(ang)
    — set speed to distance0,0,vx,vy)
    — set vx to speed*cos(ang)
    — set vy to speed*sin(ang)
    
    Function setSpeed(speed)
    — set ang to angle(0,0,vx,vy)
    — set vx to speed*cos(ang)
    — set vy to speed*sin(ang)
    
    Every tick
    — set x to x+vx*dt
    — set y to y+vy*dt

    Anyways, all you need to know is set speed first then angle and you’ll be golden.

  • It’s always hard to debug formulas so I make them incrementally. One thing that throws setting mesh points off is if the object has an angle since points are relative to the object’s orientation. What happens if you disable the action to set the angle?

    You could simplify things by just creating the dashes at the center and just setting the points to be in a circle without setting the angle. Unless you wanted the center of the dashes to be their actual centers, then that’s fine creating them in a circle.

    Generally to set mesh points to be a location on the layout you’d subtract the object’s position from the location and divide by the object’s size to get it in mesh coordinates. If the object has an angle you’d need to rotate the point by -self.angle, so I tend to avoid that if I don’t need it.

    Var cx=320
    Var cy=240
    Var r0=200
    Var r1=215
    Var cnt=10
    Var a0=0
    Var a1=0
    
    Start of layout
    — dash: destroy
    — repeat cnt times
    — — set a0 to 360/cnt*loopindex
    — — create dash at (cx, cy)
    — — dash: set mesh size (10,2)
    — — repeat 10 times
    — — — Set a1 to a0+360/cnt*loopindex/10
    Dash: set mesh at (loopindex,0) to (cx+r0*cos(a1)-self.x)/self.width, (cy+r0*sin(a1)-self.y)/self.height
    — — — Dash: set mesh at (loopindex,1) to (cx+r1*cos(a1)-self.x)/self.width, (cy+r1*sin(a1)-self.y)/self.height

    Interestingly the gap between the dashes ends up being 360/cnt/10 or 3.6 degrees in the above example. You probably want a way to control that. If you changed the expression used to change a1 to:

    Set a1 to a0+360/cnt*loopindex/9*percent

    Then you can control the gap spacing based on the percent value.

    0.9 would be what it was before

    1 would be no gap

    0.5 would make the gap width match the dash width.

  • To open in c3 you’ll have to install versions of those plugins that were ported to c3.

    To install a plugin you either have to drag the c3addon file onto the c3 window, or go to menu->view->addon manager to install them from there.

    You’ll have to hunt to see if the plugins you need were ported from c2 to c3. Not all were, but from what I’ve seen a fair amount have been on the forum. There is even a webpage someone made that has a running list of ported plugins.

    You could also open the project in c2 and remove those plugins so you can load the project in c3 before re-adding the functionality in a c3 way. But that depends on how much you want to mess with it.

  • Construct 3 is a different license than c2. You’d have to buy a subscription to get full c3 access.

  • A looser idea could be to have the fly always moving and just gradually rotate towards a target. Since it a fly we don’t mind it overshooting the target.

    Every 0.25 seconds:
    — fly: set targetx to bag.x+random(-100,100)
    — fly: set targety to bag.y+random(-100,100)
    
    Every tick
    — fly: rotate 50*dt degrees towards (self.targetx, self.targety)
    — fly: move forward 50*dt pixels

    Another idea could be to just have the fly move forward and randomly turn left or right. To make it turn smoother you could randomly affect the amount the turning rate changes per frame instead of changing the rate directly. All that’s left is to check to see if it leaves the area and steer it back.

    Also in the same vein as the orbit behavior you could apply multiple sine behaviors to the fly to make a believable random looking motion.

  • Very cool. You’re on a roll with the updates!

    This is the kind of thing that brings life to the forums. I like seeing people creating stuff and having fun doing it.

    Any thoughts on doing some more rendering in the editor than just the box? I know the plugin is geared toward generating shapes at runtime, but even approximate shapes would help with layouting. If not users would have come up with some kind of strategy to do it I suppose. I know there are many hard limits with the plugin sdk.

    On the events side, I was able to access the points of the outer main polygon, but I may have missed how to access the points of other polygons (like holes and such). I probably just need to mess with it more as I may just have missed it.

    Anyways, keep up the good work.