R0J0hound's Forum Posts

  • Had a go at attempting to replicate the effect, since it's not super clear how it works. I used C2 and the paster plugin for drawing and compositing. C3 may be able to do the drawing in some other way.

    My first attempt just used a shadowcaster blended with a radial gradient to do the shadows. Made lowres with a lower res paster object. The next step would be to do some kind of bloom to feather the lit area to light the surrounding walls. Maybe could be done with a shader, maybe. Anyways, I stopped there.

    dropbox.com/s/g068azvan5t3m7y/shadowtest.capx

    The next test did a kind of weighted flood fill to expand light gradually outward from a mouse click. When a wall is hit it wouldn't stop the light but make it reduce quicker. Used sprites as a test and only runs on a click.

    dropbox.com/s/0m9gm2fuqz5tdrn/shadowtest2.capx

    The third test used a weighted flood fill as well but in a different way. It referenced a tilemap for walls and used some arrays to keep track of stuff while flood filling. Paster was merely used here to draw the shadow area. The lit area is carved out with a destnation-out blend.

    dropbox.com/s/eo7iafxuoh3fsmz/shadowtest3.capx

    A hybrid between the first and third could look alright. Colored lights could be done with more blending modes with paster instances to do the multiple steps one by one. In C3 you may just need apply the ideas in a similar but different way since paster doesn't run there.

    Anyways just some ideas.

  • It’s still not 100% clear but I’ll give it a shot.

    So I’m guessing you have an object moving along the top line left to right, and you want a second object to be on the line below, so that both objects will hit the right yellow line at the same time while moving in parallel?

    If that’s the case set the second object’s speed and angle of motion to be the same as the first. Then you can either do

    Object2: set position to object1

    Object2: move 32 pixels at angle self.bullet.angleOfMotion+90

    Or you can do:

    Object2: set position to (object1.x+cos(self.bullet.angleOfMotion+90)*32, object1.y+sin(self.bullet.angleOfMotion+90)*32)

    Where the 32 is the pixel offset.

  • Guess I’m confused by what you’re describing as well. A diagram could probably make it clearer.

    Instead of an angle from one object to another, you’d like the angle from one object to the other if the other moved forward a bit?

    Or maybe you mean the two objects are both moving at the same angle. They’d be moving along parallel lines then. I’m not sure what you want to calculate though. A diagram should make it clearer though.

  • If the array is square you can set another array of the same size to be a rotated version. Here's a simplified version.

    for CW 90 degrees

    array1: for each xy
    -- array2: set at (array1.width-1-array1.curY, array1.curX) to array1.curValue

    for CCW 90 degrees

    array1: for each xy
    -- array2: set at (array1.curY, array1.width-1-array1.curX) to array1.curValue

    Long version on how that's derived

    2d rotation is defined by these formulas:

    newX = (x-centerX)*cos(angle)-(y-centerY)*sin(angle) +centerX
    newY = (x-centerX)*sin(angle)+(y-centerY)*cos(angle) +centerY

    Then we can simplify things when using say 90 degrees for the angle since cos(90)=0 and sin(90)=1.

    newX = -(y-centerY)+centerX
    newY = (x-centerX)+centerY

    Then we can simplify further since the array is square so centerX=centerY, and centerX = (array.width-1)/2. Plug that into the formulas and we get:

    newX = -y+array.width-1
    newY = x

    Using similar logic you could do rotation of non square arrays, you'd just have to flip the x and y sizes of the second array.

    I suppose you could do something clever to rotate an array in place, but I think it's much simpler to just save the rotation on something else and then copy it back to the original if needed.

  • Here's one way to do it. It basically just pushes balls out of each other by using the distance between them. Pushing the balls out of the wall is done by comparing the distances from the corners and edges of the wall's collision polygon and using the smallest distance. It defines the polygon with imagepoints as you can't access the actual collision polygon used by construct.

    Anyways, the value of doing it this way is we can then push the balls out of other balls and walls perfectly, plus we get the collision normal to then do a perfect bounce.

    dropbox.com/s/8t7mugpm6d8u5e9/ballvsConvex.capx

    A few usage notes:

    In the capx I just move the balls with two instance variables for the velocity (vx, xy) and one event to do the motion. It is equivalent to bullet motion.

    The bounce calculation is based on vx and vy, but if you wanted to do the movement with another behavior, you would disable the motion event and set vx and vy before the two events and set the behavior velocities afterwards. Here are some formulas to convert velocities:

    vx = speed*cos(angleOfmotion)
    vy = speed*sin(angleOfmotion)
    
    speed = distance(0,0,vx,vy)
    angleOfMotion = angle(0,0,vx,vy)

    Other thoughts

    It's a similar result to using the physics behavior (you can tell a physics behavior object to use a circle instead of the collision polygon). The bouncing angle has been more consistent from what I've tested. That is probably due to other things the physics behavior does to resolve collisions in a softer way in some cases.

    As with the physics behavior this solves the bounce after the objects are overlapping. Basically on overlap, push out, calculate bounce. Good enough almost always. A more perfect albeit slower solution would be to calculate the exact time of the collisions between each frame and using those points to solve for the bounces.

  • theseanmullins

    To move along the arc it is just moving along a circle. And you can do that with a bit of trig with:

    X = radius*cos(angle) +centerX

    Y = radius*sin(angle) +centerY

    So basically the code calculates the radius and center from the start and end positions.

    Angle is the angle from the center to the start point, which is then gradually changed to the angle to the end point. Basically a lerp, but I do it here with t. we make t go from 0 to 1 and stop at 1.

    Angle = startAngle +180*t

  • construct.net/en/forum/construct-2/how-do-i-18/8-direction-behavior-slide-95148

    I think that was the topic. Later posts have a more refined solution.

  • Try Construct 3

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

    Try Now Construct 3 users don't see these ads
  • Good to know, I still use c2 though.

    I apologize I didn’t look at the section to see the question was for c3.

    Does the textheight expression take into account new lines and wrapping? If so you could divide it by the height for a single word to get the number of lines.

    If it acts like that js function then I guess you could use the same algorithm above, just set the text before using the textWidth expression.

    And actually for c2 you could do something similar. Create a bunch of dummy text objects with the same font, set each to a word from the text, wait till the next frame, and use the measurements with the algorithm. Then you wouldn’t need to use js at all.

  • I didn’t test it, but yeah seems it doesn’t take parameters in construct. It’s just measuring whatever you set the text to.

    The js function is what’s needed though. I’ll maybe put to and to together another day.

  • The wrapping is done in constructs runtime, but I guess you can run through the wrapping logic yourself. The only tool we need is to be able get the width of any text with a given font. The text object has textWidth but last I checked it takes a tick to update in construct which isn’t ideal.

    Here’s a algorithm to find the number of lines with word wrap. I’ll be a bit lazy and just use a single line of text like in your op.

    Global number x=0
    Global number y=0
    Global number w=0
    Global text line=“four score...”
    
    Start of layout
    Repeat tokencount(line, “ “) times
    — set w to text.textWidth(tokenat(line, loopindex, “ “))
    — compare x+w+1 < text.width
    — — add w+1 to x
    — else
    — — add 1 to y
    — — set x to w

    Basically at least. At the end of it y will be the number of lines. It requires resetting x and y if it’s used again.

    Anyways since the textWidth expression is delayed a tick and you’re after how to do it with js here’s an idea.

    This is the function you’re after:

    developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/measureText

    Basically you’d create a canvas object, get a 2d context, set the font of the context and use that above function with the same algorithm as above.

    Admittedly I was a bit sloppy since it’s Adding 1 for a space in front of some lines. But it should give a general idea to refine later to match what construct is doing.

  • One way would be to loop between the previous and current positions and check for overlaps there.

    If you’d like an algorithm, this should work, or at least some variation of this would be acceptable.

    Global number x0=0
    Global number y0=0
    Global number x1=0
    Global number y1=0
    Global number steps=0
    
    Sprite: is dragging
    Or
    Sprite: on drop
    — Set x1 to sprite.x
    — set y1 to sprite.y
    — set steps to max(abs(x1-x0),abs(y1-y0))
    — repeat steps+1 times
    — — sprite: set x to lerp(x0,x1,loopindex/steps)
    — — sprite: set y to lerp(y0,y1,loopindex/steps)
    — — sprite: overlaps sprite2
    — — — stop loop
    — — — sprite: set x to lerp(x0,x1,(loopindex-1)/steps)
    — — — sprite: set y to lerp(y0,y1,(loopindex-1)/steps)
    
    Sprite: on drag start
    Or
    Sprite: is dragging
    — set x0 to sprite.x
    — set y0 to sprite.y
  • The tilemap plugin combines tiles together into larger collision rectangles. That probably explains why the collision checks go up when the ground gets more irregular. The tilemap can’t combine as many tiles

  • If it's in a group or a sub-event it will say local instead of global. Making it static will make it behave like a global.

  • I do it all the time in C2. It should work fine unless something changed in C3. I can’t find any info of such a change.

    I don’t agree with the lack of safety though. Things are run in order and the global will only change when you tell it to.

  • Picking is pretty consistent but the issue you are having has to do with when newly created objects are pickable.

    Elsewhere on the forum it’s discussed as newly created objects are pickable as normal on the next “top level event.”

    So you probably have an event setup similar to this:

    start of layout
    — repeat 3 times
    — — create sprite
    — for each sprite
    — — rotate sprite 45 degrees

    Function calls can be thought of as their events being run in place without anything picked. Here I just used a rotate action to illustrate.

    Anyways the effect of the above is only the already existing sprites get rotated, not the newly created ones.

    One fix could be to do this:

    start of layout
    — repeat 3 times
    — — create sprite
    
    Start of layout
    — for each sprite
    — — rotate sprite 45 degrees

    Which will rotate all the sprites.

    The short version of what’s going on is newly created objects are not pickable till another top level event (an event that isn’t a sub-event). That is other than the new object being picked in that event.

    Long version:

    construct.net/en/forum/construct-2/closed-bugs-22/picking-objects-not-work-129083

    Hope some of that helps.