cacotigon's Forum Posts

  • Animmaniac

    Couple things.

    1. An overlap combined with trigger once is basically the same thing as an On collision.

    2. You would have to duplicate that collision event for every monster type in MonsterFamily if you wanted something similar to happen for each one. Granted, you can simplify the action component through a common function but still.

    3. To further elaborate on 2, ideally you want to consolidate collision checking into as few check events as possible to avoid unnecessary duplicate collision checking and keep things as performant as possible. Doing a Family check against Family allows us to reduce collision checking to a single event.

  • Hey guys,

    I've decided that this question is fairly important and hits a lot important concepts that are crucial to understanding how Construct 2 works, so I've written a tutorial to help explain:

    Understanding Picking with Respect to Families

    The tutorial not only covers how to distinguish between identical objects within single events, but why it's important from a modular design standpoint.

    Ashley, I'd love to get your feedback about it, particularly if I've made any mistakes in my explanations. <img src="smileys/smiley36.gif" border="0" align="middle">

    I hope this helps everybody.

  • ChrisAlgoo, I've noticed that this type of question seems to come up every once in a while on the forums, so I've written a tutorial to hopefully clarify the confusion.

    Understanding Picking with Respect to Families

    The tutorial not only covers how to distinguish between identical objects within single events, but why it's important from a modular design standpoint.

  • jayderyu

    That won't work. As Ashley has stated in the past, Indexing by IID is not limited to the SOL (list of selected objects).

    See my earlier response to this thread for workarounds.

  • TELLES0808

    I think that's a bit of a harsh assessment for GM.

    A lot of people who use GM "know how to code" as you've stated, but GM gives you a foundational framework so that you can focus on the unique aspects of coding your game. Frameworks like GM/Unity make it so we don't have to re-invent the wheel. We don't have to develop our own physics engine / scene graph / asset management system / map editor / etc.

    In the end, both are great tools, the choice of which one to use boils down to a couple factors for most people:

    1. What kind of coding environment are you more comfortable with

    (Scripting vs GUI Event system)

    2. What's your budget

    -- Construct 2 - $120.00

    -- Game Maker - If you want to develop for android/ios/ubuntu/windows 8/pc/etc for Game Maker, the Master Collection is what you want and costs $500. That being said, you can do a lot with the $50 dollar one as well.

    3. What kind of platforms do you want to develop for

    Great games can be made on both engines. For an interesting read on Game Maker (among other engines including Unity), see this:

    PC Gamer Indies Guide to Game Making

    Spelunky is a text-book example of an amazing game that was made using Game Maker. I used Game Maker extensively before migrating to Construct and can say that for the majority of users (especially the Construct 2 demograph), it has a much steeper learning curve. There's a lot less built-in behaviors/plugins and you have to do more actual "coding".

  • Ashley,

    EDIT: I just re-read your post in which you kind of address this potential solution. :p Sounds like as you've said, it might actually hurt performance.

    Thanks for your reply.

    What if you invalidated all cached Collision results for a given entity after any command which results in a change of position/angle/scale using some kind of HasChanged boolean?

    So maybe you have a central collision Cache which is an internal dictionary, it is only added to when two elements collide. The key represents the unique instance of the object, and the value is a enumerable list of elements that it has collided with on this loop cycle.

    CollisionMap[Obj1] = { Obj2 }; // set of objects Obj1 has collided with

    CollisionMap[Obj2] = { Obj1 }; // set of objects Obj2 has collided with

    So in the game loop:

    <font size="2">

    <font face="Verdana, Arial, Helvetica, sans-serif">

    Clear Collision Dictionary at beginning

    Set all objects HasChanged = false

    On Obj1 Collision Obj2 routine: (doesn't actually do any bound checking yet)

    Foreach(Obj1 in Layout)

    -- Foreach(Obj2 in Layout)

    -- -- If Obj1.HasModified = false && CollisionMap[Obj1].Value.Contains(Obj2) { TriggerCollision(); }

    -- -- Else { Run Normal collision bounding checks -- save results into CollisionMap }

    </font>

    </font>

    Would this help to optimize collision performance at all?

  • Unfortunately, there really isn't an elegant solution to being able to easily do subconditions / actions across each distinct instance between collidee and collider in an On Collision based on a single Family at this time.

    You can get around this by duplicating the Family. So you have OriginalFamily and DuplicateFamily with the same set of collidable objects.

    Then you can do:

    OriginalFamily On Collision DuplicateFamily : Actions

    While this solves the problem of being able to access both objects distinctly in the same descending subevent tree, you lose access to behaviors and instance variables that belong to OriginalFamily when referring to the DuplicateFamily collision instance.

    I've gotten around this somewhat through the use of "System Pick nth instance". In this approach, you pick each one in a separate subevent and save off the information you need to local variables. For example, let's say you had a list of monsters (Ogre, Troll, Imp, Al Sharpton, etc), all of which belong to family called Monsters. You needed X/Y and a custom Family variable called Life. Your code would look similar to this:

    <img src="https://dl.dropboxusercontent.com/u/12667027/Construct%202/IdenticalObjectCollision/MonstersExample.png" border="0" />

    Make sense?

  • Ashley, I can understand that. I created a PinFamily whose objects have attributes:

    IsPinned (bool)

    Owner (UID)

    ImagePtName (string)

    Then I just have a single statement that repositions any objects on layout in PinnedFamily with IsPinned = Enabled.

    That way whenever I spawn an object I want pinned, I can just set those attributes on the object, and the game will handle pinning them.

    Thanks!

  • Ashley,

    Could you please explain to me how the "On Collision Event" works internally?

    For example, hypothetically, let's say that I have Event Sheet 1:

    Obj1 On Collision Obj2 : Do some actions

    Event Sheet 2:

    Obj2 On Collision Obj1 : Do some actions

    If I assume that the events in both sheets are run as a single concatenated logic loop, would it be correct to assume that the collision detection stores a dictionary of prior checked collisions for objects? In this manner, Event Sheet 2's collision check cost would be minimal.

    The reason that I ask is because I have two ways of handling collision detection at this point.

    My original way was more modular, all objects belong to EntityFamily which has a local var called CollidedFn, which is a link to a function. All collision detection was centralized in a single CollisionEventSheet which would do something along the lines of:

    On EntityFamily Collided with EntityFamily : Call EntityFamily.CollidedFn which would hand off the collision to the object's collision routine.

    However, each object (which is represented in my project by a single event sheet) could also have an:

    On Object CollidedWith EntityFamily : Do something (note that this is Object-specific)

    However, if we're not tracking existing checked collisions in a single "loop cycle", having this On Collision statement repeatedly could get very computationally expensive.

    I'm just trying to look for best practices here.

    Thanks,

    -- Cacotigon

    P.S. I might be thinking about this the wrong way, are "On Events" different from regular events in the game loop? Are they maybe like delegate triggers?

  • Bingo! That's it! Was not aware of this change. I'll just make it a rule to always have a "StorageLayout" where at least one instance of every object is already initialized.

    Thanks Pixel perfick.

  • As was demonstrated in the capx example, the start of Layout was already the first event in the event sheet. *Even* if it wasn't the first event linearly in the sheet itself, think about it. On Start of Layout is defined as the condition that occurs when the layout begins, I would think the layout would get initialized before objects were created on said layout.

    The whole point of doing Destroy ChildObj in the "On Start of layout" is to get rid of the troublesome fact that we are required to include one instance of every object on a layout, something which I recall the makers of Construct having stated in the past that they would eventually like to rectify.

  • The only way to get pin to work again after mirroring its parent is to manually unpin the object, update its position to the image point again, and repin it. So the image points themselves appear to be mirroring correctly, but the pinned objects are not following suit. Pinned objects *will* follow any other type of motion / rotation / etc.

    In the unlikely even that a change of this type could potentially break legacy projects which depend on mirror not updating the pinned object's position, could we at least have a Pin Option when an object is pinned along the lines of "Respect Parent Mirroring"?

    I'm using the workaround currently, but the problem with this is that I have some objects which have N number of image points and the objects that are pinned are also fairly dynamic (mostly belonging to families but occasionally different), having to reset this stuff all the time can get kind of frustrating.

    Link to .capx file (required!):

    Pin Mirror Capx

    Steps to reproduce:

    1. Create parent object

    2. Spawn child object and pin to parent

    3. Mirror parent

    Observed result:

    Child does not mirror with parent, it remains in the same position.

    Expected result:

    Child should mirror with parent.

    Operating system & service pack:

    Windows 7 64-bit

    Construct 2 version:

    Release 126

  • Since Construct 2 still requires the layout to have (as I workaround I can create an extra Loading Layout to handle this but anyway...) at least one instance of every object, when working on small single layout projects I usually start with:

    On start of layout: ChildObj.Destroy()

    I also have an On Create Master Obj : Spawn Child Obj

    From what I can tell though, the On Create is firing *before* On Layout Start, causing an object to be spawned then summarily deleted. Is this order of events intentional?

    Link to .capx file (required!):

    Order of Events Capx

    Steps to reproduce:

    0. Create Layout -> Add ChildObj and ParentObj to Layout

    1. Create ChildObj

    2. Create ParentObj

    3. Add On Create ParentObj : Spawn ChildObj

    4. Add On Start Layout : Destroy ChildObj

    Observed result:

    Both instances of ChildObj are destroyed.

    Expected result:

    Only the existing ChildObj should have been destroyed, then "On Create" should have been run.

    Browsers affected:

    Chrome: yes

    Firefox: yes

    Internet Explorer: yes

    Operating system & service pack:

    Windows 7

    Construct 2 version:

    Release 126

  • Try Construct 3

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

    Try Now Construct 3 users don't see these ads
  • I have a pusher object which is a solid box sprite with bullet and solid behaviors. The player is just a single box sprite with platform behavior applied to it.

    The problem is that when the pusher object runs into the player, it causes the player to jump randomly in addition to being pushed which breaks the players ability to jump since they aren't on the floor half the time.

    Here is a very simple example capx to demonstrate what I mean:

    Random Jump Capx

    I tried removing solid behavior and manually handling the push through checking for collisions/overlapping but this breaks the ability for the player to jump on top of the bullet. I could go through the trouble of trying to create multiple invisible collision boxes for the sides of the object, but given that I have a lot of differently shaped bullets, this is really more heavyweight than I would like.

    Anyone have a simple solution for this?

    Thanks,

    -- cacotigon

  • yeah, for all intents and purposes scope doesn't change. It's more of a "hey I'm OCD and I want to organize these global vars in a global event sheet" kind of thing.