fisholith's Forum Posts

  • Interesting, and a very good point.

    With respect to "properties", do you mean C2 property panel properties, or JavaScript object properties? In my earlier post I meant JavaScript object properties, but at the time it hadn't occurred to me that it was ambiguous. Sorry about that.

    And, yes, now that I've been looking through more plugins, "onCreate" seems to be the way to go. I haven't tested to see if "pluginProto.Instance" is called on a per-instance-created basis, but I think you're right about "onCreate" being the better option for objects that are intended to allow multiple instances. In any case, "onCreate" will definitely get called each time.

    Thanks again for the information and advice. You're always super helpful rex.

  • One method that can be really handy for diagnosing these kinds of problems is to create a Text object, and then create an event inside the loop to print debuging info into that Text object.

    e.g.

    Insert the following event as a sub-event of the

    "Segments.ImagePointCount = 2", and

    "Segments.ImagePointCount = 3".

    Event:

    * Compare ( loopindex >= 0 )

    * Compare ( loopindex <= 3 )

    // This event will run 4 times, for the loop indexes 0, 1, 2, and 3.

    Actions:

    * Append text ( " Loopindex:" & loopindex )

    * Append text ( " SegUID:" & Segments.UID )

    * Append text ( " platUID:" & PlatformCollision.UID )

    * Append text ( " plat2UID:" & PlatformCollision2.UID ) // Only needed for count = 3

    * Append text ( " Seg.ImgPtX1" & Segments.ImagePointX(1) )

    * Append text ( " Seg.ImgPtY1" & Segments.ImagePointY(1) )

    * Append text ( " Seg.ImgPtX2" & Segments.ImagePointX(2) ) // Only needed for count = 3

    * Append text ( " Seg.ImgPtY2" & Segments.ImagePointY(2) ) // Only needed for count = 3

    * Append text ( " Seg.Col:" & Segments.Collision)

    * Append text ( newline )

    The "newline" at the end will make each loop iteration print out on it's own line.

    Be sure to use "Append text" and NOT "Set text".

    Note that some of the actions in the above event only apply to the case where "Segments.ImagePointCount = 3", and not when it "= 2". For the "= 2" case, you can remove all the actions that are commented "// Only needed for count = 3".

    You'll probably have to stretch out the text object so that it has room to display multiple lines.

    You may also want to set it's font size to something, small like 8 point, and set it's initial text to be blank.

  • Hey kaleu50,

    To my knowledge C2 uses a polygon collision system, rather than calculating per-pixel collisions, meaning you would need a polygon collision object, or several, that match the contents of the canvas.

    It's theoretically possible to create invisible collision objects via events that overlay the drawn-on parts of the canvas, but it's not likely to be very practical outside of some special cases.

    One possible approach might be to use the tile map object, set the tiles to 1x1 pixels, and create a "solid" tile with a square collision polygon. if you can paint 1x1 collision tiles over the same area your canvas brush is painting color, then it might work.

    Granted I've never used the tile map for anything like that so I don't know if there would be performance issues. I expect there would be. Though I think the tile map would still be much better than a ton of 1x1 sprites, which might not even run at all.

    Update:

    Okay I just tried the tile map setup I described, and to my astonishment, it actually runs in realtime without issue. Granted that was with 1 px wide lines. When I blocked in 50% of the 832, 480 screen with a solid mass of 1x1 collision tiles (over 200,000 collidable tiles) the game still ran smoothly. It started to slow down a bit when I got to 75% coverage (over 300,000 tiles). Practically speaking, if you could cull out the center tiles, and only make the edges of objects collidable, then you could probably make a pretty decent per pixel collision system.

    I tried both 8-Direction and Platform behavior with it and it seems to work as you'd expect.

    Also, the 1x1 pixel tiles are only important if you're doing something like simulating a per-pixel collidable terrain for a platformer. If super precise collision detection isn't essential, such as testing for loose overlaps with the mouse pointer, you could make the tiles 4x4 pixels and the whole setup would have 16 times fewer tiles in filled areas.

    (By "16 times fewer" I mean "1/16th the amount of tiles", but both ways of phrasing it sound weird, now that I'm looking at them.)

    In any case, I hope that helps somewhat.

  • No problem, glad I could help

  • No problem.

  • Interesting.

    Thanks for pointing out that they can be declared in onCreate

    I was going to ask about that specifically, as I wasn't sure if there was anything special needed to use it reliably. It sounds like it just works.

    Between Instance and onCreate, is there a particular reason one might be preferable to the other, or is it more just a matter of style or convention?

    I was trying to remember why I did one versus the other, and looking back through the original SDK templates (I mainly work from custom templates) I found the following comment inside the pluginProto.Instance body:

    this.type = type;

    this.runtime = type.runtime;

    // any other properties you need, e.g...

    // this.myValue = 0;

    I think this may be why I've been putting properties there. I'm not sure if it makes a difference.

    That said, the official Dictionary plugin declares properties in onCreate, and the official AJAX plugin declares properties in pluginProto.Instance. So I'm not sure if there's anything important about one vs the other, or if it's just down to preference.

  • When adding properties to my object in the SDK runtime, should I create instance properties in:

    (Edit: By "properties" I mean JavaScript Object properties, not C2 property-panel properties.)

    pluginProto.Instance = function(type) { ... }

    or

    instanceProto.onCreate = function() { ... }

    Currently I'm creating them inside "pluginProto.Instance" as that's what I've seen in other plugins.

    Is there any situation where one is better than the other?

  • Hey cmbbar,

    I think the two main things you're probably looking for are global variables, and the "Persist" behavior.

    (Those links go to the corresponding C2 manual pages.)

    Global variables keep their values between layouts.

    The Persist behavior, saves and preserves the state of objects between layouts, such that when you go back to a layout, the persistent objects will be wherever you left them last, instead of resetting to their starting positions.

  • Hey p0tayters,

    Below are a few things that came to mind.

    David Silverman - Match 3 in Construct 2 (from scratch)

    RexRainbow - Match 3 demo

    RexRainbow - Plugins Website

    RexRainbow has built a ton of plugins for C2, and several are tailored to board & tile game mechanics.

    My best wishes for your gaming grandmother.

    You sound like an awesome grandkid.

  • Hey DiVeR, <img src="{SMILIES_PATH}/icon_e_smile.gif" alt=":)" title="Smile">

    I believe a family can only have one kind of object (plugin) in it.

    e.g. Only Sprite objects, or only Text objects, or only Tilemap objects.

    The icon of the family is borrowed from the object (plugin) type it currently contains.

    Manual > Families: https://www.scirra.com/manual/142/families

    • "All the object types in a family must be from the same plugin ..."

    The problem you're having might be that you're trying to add a Tilemap object into a family already dedicated to Sprite objects.

  • Hey ChefSeth,

    I'm not sure I quite understand what aspects of the code are currently not working.

    The first thing I notice that might be an issue is that in your last two events, there is no icon for either the PlatformCollision object, or the PlatformCollision2 object. I don't know if that's indicative of a problem, but it might shed some light on what's going on.

    In particular, in the "Set animation" actions, it looks like there's no way to visually tell which object is being acted on. I assume they should be PlatformCollision and then PlatformCollision2, but if they're not, that might be causing a problem.

    It looks like every object in the Segments family has a private var named "collision", just out of curiosity, what does it do, and what would cause it to be greater than 900?

  • Try Construct 3

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

    Try Now Construct 3 users don't see these ads
  • Hey JasonS,

    One possible approach might be to separate the problem of path finding from the problem of overlap prevention.

    Instead of having the Soldier be the object doing the path finding, make your current path finding object invisible, and make a new soldier object to follow the path finding object. Then give that Follower object the physics behavior, with a constant force pulling it towards its personal Pathfinder. By default, Physics objects won't overlap each other, and will instead slide past each other, or bunch up like gumballs in a jar.

    But what if there's a physics traffic jam, and one of the physics Followers can't keep up with its Pathfinder object? After all, if a Pathfinder goes around a corner while the Follower is stuck, even if the Follower later gets un-stuck the Follower may not be able to reach the Pathfinder by moving straight at it, via a physics force. We need to make sure a Follower never gets left behind.

    Basically each Pathfinder should be a mini Dr. Alan Grant. :)

    To prevent Followers from getting left behind, you can pause the Pathfinder if it gets too far from the Follower. "Too far" in this case might mean 1 or 2 soldier widths. Ideally the soldier (Follower) will nearly always be just behind, and almost touching its Pathfinder.

  • No problem, glad to help. :D

  • Hey imothep85,

    ... imothep ... imothep ... imothep ...

    One possible method:

    Assuming the sprite objects are already set up to move forwards, (e.g. they have "Bullet" behavior or something), you can set their angle each tick to make them approach a target on a spiral path.

    Every tick:

    • Set the sprite angle to face the target position.
    • Rotate the sprite 20 degrees clockwise.

    Note: Rotating 0 degrees would make the sprite move straight at the target, 90 degrees is circling the target, and anything between 0 and 90 will spiral towards the target.

    The above method results in spirals that get curlier as you get closer to the target. If you want more uniform curvature as the sprites approach, you can set that rotation offset to be dependent on the distance between the sprite and the target. So, when the sprite is far from the target, the rotation offset is large (e.g. 45 degrees), and as the sprite gets close to the target the rotation offset gets smaller (e.g. 10 degrees).

    Proportional - (with upper limit)

    Rotate the sprite min( 80 , 80 * ( distance( Sprite.X , Sprite.Y , Target.X , Target.Y ) / 400 ) )

    Here we scale the rotation offset by the distance to the target, with 400 pixels being the distance where the scaling value equals 1.0 (or 100%). We are scaling the number 80 to act as the rotation offset, and we are capping the maximum rotation offset at 80 as well. We cap the offset so that it doesn't reach or exceed 90 degrees which would cause the sprite to start spiraling away from the target.

    Making the cap number smaller will make the maximum turning radius softer. (It should be between 0 and up to but not including 90.)

    Making the base rotation offset smaller will make the approach turning radius softer. (It should be between 0 and up to but not including 90.)

    Making the distance scale larger will make the curves softer.

    ArcTangent

    Rotate the sprite atan( distance( Sprite.X , Sprite.Y , Target.X , Target.Y ) / 400 )

    This is a slightly simpler expression to write and it doesn't require an artificial cap value, because no matter how big the distance gets, the arc-tangent will never return 90 degrees or more. The 400 in this case is the distance at which the arc-tangent will return 45 degrees.

    Making the distance scale larger will make the curves softer.

  • I may be misunderstanding what you mean, but I believe all instances of objects in a layout have a unique integer ID assigned on creation by Construct. That automatically assigned integer ID is what I was referring to when I mentioned the "UID".

    The object type (e.g. "helmet") is different from the UID.

    Each helmet should have it's own totally unique ID number.

    UID explained in the manual: https://www.scirra.com/manual/130/common-features

    Example

    If you spawn three helmet objects in your game, their UIDs might be automatically assigned as 61, 62, and 63, respectively.

    If the player collides with one of the helmets, you can ask Construct which UID that specific helmet has.

    ...Event: Player collides with helmet. Action: set variable itemTouchedLast to helmet's UID.

    Let's assume the player touched the helmet with the UID of "62".

    You can now refer to that specific helmet in other events by using the UID to pick it.

    Suppose we want to place a selection box image on the last item the player touched.

    ...Event: Every Tick. Pick helmet by UID ( itemTouchedLast ). Action: Move selectionBoxSprite to position of helmet.

    This event will pick the helmet with the UID of "62", and it will then run the action only on helmet 62.