R0J0hound's Forum Posts

  • It calculates the position on the screen from an xyz position. Actually I forgot to take the camera rotation into account.

    Take the xyz subtract the camera position, then multiply that by the orientation matrix.

    Xyz = (Xyz-camera.xyz)*camera.orientationMatrix

    z = z*tan(fov/2)

    ScreenX = x/z +scrollx

    ScreenY = y/z +scrolly

    Wikipedia or something would be a good source for how to multiply a vector by a matrix. Honestly you probably could use a dummy object to do all the calculations.

    Maybe:

    Set position to xyz

    Move by offset -“camera”

    Rotate by camera

    Set z to z*tan(fov/2)

    Set xy to x/z+scrollx, x/z+scrolly

    But I honestly don’t recall how the plug-in works exactly.

  • All you need is the camera position (cx,cy,cz), the fov, and the scroll position (scrollx, scrolly) apparently. Math below is adapted from the Wikipedia about 3d projection.

    screenx = (x-cx)/(z-cz)/tan(fov/2)+scrollx
    screeny = (y-cy)/(z-cz)/tan(fov/2)+scrolly

    There is no expression to get the fov so you’ll just have to remember it from when you set it.

    Not tested.

  • Try Construct 3

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

    Try Now Construct 3 users don't see these ads
  • I opted to just have it work without flipping or mirroring. Hence the abs. One solution could be to record the sign of the width and height of the sprite into variable and apply that again when setting the sign. There may be a more compact way to do it though.

  • Sure.

    When dragging a handle it limits the motion to be along a line.

    Line equation:

    Y=slope*(x-x0)+y0

    Slope calculation uses the ratio of height to width.

    Slope = changeInY/changeInX = originalHeight/originalWidth

    The slope of the line should be negative for two of the points so I did

    (int(mid(“2002”,self.iid,1))-1)

    But either of these would be the same

    ((Self.iid=0 | self.iid=3)?1:-1)

    (int((Self.iid+1)/2)%2*2-1)

    Basically converting the index 0-3 to a negative or positive in a specified way.

    0123 -> 0110 -> 1,-1,-1,1

    The handles are laid out like this:

    0-1
     /
    2-3

    We also need to access the opposite handle to calculate the new size and position, as well as using it for x0,y0 in the line equation. In construct you can do sprite(i).x to access any instance by iid. And if we use 3-i you’ll get the opposite one:

    0123 -> 3210

    Then the new size would be the absolute value of the difference between the current handle and the opposite handle. The new position would be the midpoint.

    Finally the last event positions all the handles around the box that aren’t being dragged.

    I was trying to make it compact as possible so those iid tricks are a bit hard to read. The less terse way could look like this:

    //make a family with the handles
    
    var slope=0
    
    handle: on drag start
    pick family instance 3-handle.iid
    -- set slope to (sprite.y-family.y)/(sprite.x-family.x)
    
    handle is dragging
    pick family instance 3-handle.iid
    -- handle: set y to slope*(self.x-family.x)+family.y
    -- sprite: set size to abs(handle.x-family.x), abs(handle.y-family.y)
    -- sprite: set position to (handle.x+family.x)/2, (handle.y+family.y)/2
    
    pick handle instance 0
    handle is not dragging
    -- set pos to sprite.bboxLeft, sprite.bboxTop
    
    pick handle instance 1
    handle is not dragging
    -- set pos to sprite.bboxRight, sprite.bboxTop
    
    pick handle instance 2
    handle is not dragging
    -- set pos to sprite.bboxLeft, sprite.bboxBottom
    
    pick handle instance 3
    handle is not dragging
    -- set pos to sprite.bboxRight, sprite.bboxBottom

    It uses a family to pick the opposite handle and is more verbose about how the other handles are positioned. The slope just uses the starting size more or less. However it has a failure case if the size starts at 0,0 then the slope would be NaN. That would have to be handled.

  • I don't see any 3d. I just see a bunch of images stacked. They change color and scale to give the illusion of moving down a tunnel. There is also some parallax proportionate to the scale.

    For example with some crudely drawn edges:

    dropbox.com/scl/fi/8mn0fzzhhzrmslnkl6inf/pit_fall_effect.capx

    The most novel problem is the collision detection which would require pixel collisions. It's not completely straightforward with Constructs features to do that, but it is possible to take the images, paste them into canvas, read the pixels, and store a collision mask into an array. Then you just would sample use the arrays when you run the game to see if the player hit a wall or if they had a near miss, etc...

  • Can't open your file since I don't install addons but here are a few ideas:

    Most basic is to just randomly select a direction and speed to launch the striker.

    A bit better would be to pick a direction toward one of the men. You could randomize the angle a bit to add variance.

    More advanced would be to look at a straight line from each man to the pockets, and keep a list of then that have a clear path there. You could also check for bank shot paths. Next you'd can figure out a formula to figure out the required angle and speed for the striker to hit the men to make them move in that direction. The main requirement would be for there to be a clear path from the striker to where you want to hit the man. This would be rather math intensive and you'd have to deal with some quirks of the physics behavior, but if done right you'd get ai that could sink shots that most players try to go for. You can always add some randomness to make it not so good.

    To check for a clear path you can use a loop to move the circles in small steps in a line and check for overlaps.

    Now for a deeper ai that can handle complex bank shots or bouncing off other pieces you may need to re-design your game's internals. The idea is to simulate many frames of the simulation in one tick. That would allow you to test multiple different shots and then pick the one that had the best outcome. You could start with random shots, but you could then take the shots with the best outcome and run more tests as variations of that to make better shots. The limiting factor would be how much time you'd want to let the ai try to find a good shot.

    Other ideas could be to come up with a way to rate the shot by how many points you scored and how much closer your pieces were to the pockets vs how favorable the board layout is for the other player to score points.

  • I can't seem to open the link so I have no idea if this is similar or not, but here is one way to do it.

    dropbox.com/scl/fi/igcw9hcfb9uy3esjxsga7/aspect_resize_handles.capx

  • megatronx

    I have no input on that other than yes you can access values in an array immediately after you set them.

    Maybe your logic just isn’t correct for what you’re doing. It could be helpful to output what’s going on at each step to debug things. Or maybe simplify the data you’re using to be able to analyze what’s it’s doing better.

    As is I can’t make sense of it. Arrays are useful but i find code using them often unreadable

  • I guess this topic kind of turned into a catch all for questions.

    megamente br

    To use paster you just move it wherever you want, then pasting other objects onto it will draw then in place onto the paster object. That’s basically it.

    megatronx

    I appreciate it, but it’s merely in the idea phase since I don’t code a whole lot. Unfortunately when/if I make it it would be smaller scoped than that.

  • For steps of 10 you can do this when setting the angle:

    set angle to round(Self.currentAngle/10)*10

    But really with your image this is the correct rounding:

    round(Self.currentAngle/(45/9))*45/9

  • I was able to test mine as working so I now see what you had amiss.

    You had:

    (Vx / 10)* (Vy + sqrt(((Vy * Vy) + (2 * 10 * Y0Height)))) - X0

    But it needs to be this. 500 instead of 10, and you don't subtract x0.

    (Vx / 500)* (Vy + sqrt(((Vy * Vy) + (2 * 500 * Y0Height))))

    That will the calculated be approximately the actual. It will be off since the floor is hit a bit early.

  • You could delay it a frame with something like this pseudocode. Beyond that I guess you'd have to implement the platform behavior from scratch so you can actually know when a collision occurs.

    bool overlap = false;
    bool futureOverlap = false
    
    onTick(){
     if futureOverlap==true && overlap==false
     then doStuff()
     
     overlap = futureOverlap
     futureOverlap = obj.isOverlappingSolidAtOffset(obj.vx*dt, obj.vy*dt)
    }
  • One way to do an undo is to make a save of the game state before you move. It's the same kind of problem as saving your game, you probably can utilize construct's save features for that. Another way is to just save the changes of each move. Could be a bit trickier though.

    Hints would be done in the same way as a real player finds a move. Basically come up with a way to check all possible moves.

  • Messed with your example briefly but no luck. Do note, that the gravity value you should use in the equations needs to be 50x the gravity value that the physics behavior uses.

    Anyways you could try it with the bullet behavior instead in case the physics behavior is throwing it off.

    I mean your logic seems sound. There’s probably something I didn’t notice that’s throwing it off. If it helps this is what I come up with when working out the math. I haven’t tested it though.

    Var g=500
    Var x0=0
    Var rangeCalc=0
    Var rangeActual=0
    
    Start of layout 
    — ball: set position to (0, 400)
    — ball: set velocity to (100,-100)
    — set x0 to ball.x
    — set rangeCalc to (-vy + sqrt(vy*vy + 2*g*(480-ball.y)))*vx/g
    
    On ball collides with ground
    — set rangeActual to ball.x-x0
  • I guess the use of the trig functions look obscure. If it helps this is the formula I’m using that uses trig. All it does is rotate an xy point around 0,0 by some angle.

    NewX =x*cos(a)-y*sin(a)

    NewY =x*sin(a)+y*cos(a)

    The cool thing about it is you can rotate other ways too such as xz, just replace the y with z in the formulas.

    This is all I’m using that equation for:

    // make a circle

    Vector(radius1, 0, 0)

    RotateXY(b)

    //Then rotate the circle in an arc to make the rings.

    Move(-radius1, 0, 0)

    RotateXZ(a)

    The equation I used is just all that combined and simplified. All the equations I ever use in my examples are like that, a combination of simple steps combined and simplified.