CannedEssence's Recent Forum Activity

  • Yeah, mine is set up the same way as yours.

    Here's my .capx, minus the Pause and Function objects: dl.dropboxusercontent.com/u/811222/temp/CiS2NoPause.capx

    I get a 404 error, not file not found.

  • Capx or screenshot of events?

  • There appears to be common confusion here.

    Events pick objects, narrowing down a selected object list (SOL), and then the actions will be performed only on those objects.

    However, the System Create Object action will apparently also pick objects, specifically the object it just created. So, if you properly placed a create object bullet action right before your set angle bullet action, then it should only apply to that created object.

  • Consider a beat-em-up like Double Dragon, Streets of Rage, or River City Ransom.

    Imagine an enemy type, say "Whip Girl", who also spawns with a whip (that other enemies use too). Of course, I'd be tempted to make a whip object, and add it to a container for whip girl, because that enemy always spawns with the whip.

    But let's say that if you defeat a whip girl, she drops the whip, and the player can start using that whip.

    The problem is that it appears that an object can only be part of one parent container.

    Is there a better way than to either make a whip sprite, a whipgirlwhip sprite, a playerwhip sprite, and assign them to their respective parent objects,

    or to have one whip sprite and try and keep track of all the instances on screen with their proper z indexes?

    I'm assuming I can't just have one whip sprite that can belong to both whipgirl and player?

  • I'm pretty new to this program, but I'm assuming that you'd make sure that both the new object and the player sprite are on the same layer.

    Then when you create this new object in the event sheet, set Z-order "move to bottom" action to that object.

    If you are making these instances in the layout view, then Construct 2 is a bit lacking. You'll have to set the Z-order "move to bottom" to all instances of those object in the on start of layout event.

    Someone can correct me if I'm wrong.

  • That answers my questions, thank you all!

    newt

    No, I agree that referencing the instance you just created is more common than referencing all instances of the just-created instance. I prefer that functionality (it makes my second example constructor work =P). I just found it fishy that it worked, because as far as I knew, no action (just events) picked instances. I was just afraid that it was incidentally picking the most recent instance because it happened to be at the "top" of the SOL or something.

    Good to know the create object action also picks the instance.

    zenox98

    I agree with the essence of what you are saying: Construct 2 is designed to be accessible to non-programmers, shirking away lots of the scary syntax, boilerplate, etc, of code. However, there are reasons for why object-oriented languages were designed the way they were, it wasn't just job security.

    Being able to clean up the on layout start event by logically grouping events into functions is smart. Notice how the Ghost Shooter example start layout event is a bit unruly? Having a constructor function to handle instantiating an object and its properties is good organization, not "programmer-minded."

    That's the kind of stuff you see in the popular thread about best event practices in Construct 2: scirra.com/forum/programming-best-and-worst-practices_topic63136.html

  • Object-oriented programming utilizes "constructors" which at its basic level allow the programmer to instantiate a bunch of member (instance) variables upon creating the object.

    Correct me if I'm wrong, but it appears Construct 2 doesn't have that built in.

    For this simple example where we just set the position and scale of Ball on creation, are these the current alternatives:

    Make the constructor simply just an On created trigger:

    <img src="http://cannedessence.com/construct2screens/constructor1.png" border="0" />

    Problem: you can't elegantly send values to the constructor. This would be desired if the place where you create the object has contextual information from some other picked object, etc.

    OR

    Make a function as a constructor replacement, and this is where it gets confusing to me:

    <img src="http://cannedessence.com/construct2screens/constructor2.png" border="0" />

    Why does this work? Notice the second action in the Create_Ball function. Shouldn't this pick all instances of Ball, since the event doesn't pick any instances of Ball? Somehow it picks the most recently created Ball, which works here. However, it doesn't seem right, so I don't want to rely on it.

    I can't put an On Created trigger inside the function definition because they are both triggers.

    Is there something I'm missing about this?

    Thanks!

  • Thanks, good to know!

  • Try Construct 3

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

    Try Now Construct 3 users don't see these ads
  • Like many others have in the past, I'm considering creating a random background with a single sprite object repeated randomly across a layout (think: starry sky).

    Is there any way to make a sprite object static, where the only thing it holds is essentially just an array of coordinates, and the only thing it updates is drawing those coordinates to the screen?

    It's my impression that all sprite objects have a whole bunch of extra stuff that gets updated, with a bunch of unnecessary checks for something that never moves or needs to be checked for collision.

    What kind of overhead would this produce? What's the solution with maximum efficiency?

    Thanks!

  • Can you share the event/actions in question?

    It's probably that you aren't providing the object as the context of the action, and rather you are just referencing the position in the action's instruction (on the right side of the action).

    I'm guessing your action looks something like this:

    System -> YourObject.X [do something]

    This will reference just the first object in the list of instances of YourObject.

    You'll either have to do something like this:

    YourObject -> self.X [do something]

    or

    Event: System -> foreach YourObject

    Action: System -> YourObject.X [do something]

    Good luck!

  • Thank you for all your responses =), especially ramones-- you look like you put a lot of effort into that answer. I'm glad to join such a helpful community.

    I think I see the pattern now. I'd be grateful if anyone can confirm the truth about the following assumptions concerning the behavior of Construct 2 Events.

    Quick definitions: "context of action" refers to left side of action statement; "instruction" refers to right side of action statement.

    • The context of the action (e.g. "Ball") will reference all the instances filtered (or "picked") from the condition(s) of the event (generating a "selected object list"), or simply all existing instances of the object type if not referenced in the condition(s).
    • An arrayMap of the instruction will be applied to the context.
    • If the instruction references the context object (or more accurately the SOL for the context object type), then the properties (instance variables) for the instance of the object in the instruction will line up with each object in the SOL when the instruction is performed on each instance in the SOL.
    • If the instruction references an object type that doesn't match up with the context, then the properties of that object will reference only the first object in the all-existing-objects list for that type, or SOL if that object type was referenced in the condition(s) of the event.
    • For static classes like "Function" or "System" as the context, there is only one instance, so the instruction will only perform once no matter what, unless you use a foreach condition.
    • If more than one object type is referenced in the conditions for the event, then a separate SOL will be generated for each object type.
    • Using a foreach condition will override the default arrayMap behavior of the context object. See image below:

    <img src="http://cannedessence.com/public_images/impliedForEach2.png" border="0" />

    Note that the ball action would ordinarily arrayMap the instruction (or create a for each in this code translation), but here if we add a foreach condition, it overrides that and instead the context becomes just the current instance of the context object in the outer foreach loop.

    Is this all correct?

    If it is, then I hope that other people in the future see this thread, because I had trouble finding these clarifications elsewhere. The foreach and SOL part of the manual is a bit scant, but I guess I understand, since it's probably a bit advanced for the target user of the tools.

    Thanks again!

  • It does pick all, but like you said it passes only single value to function as it is just single variable. Put for each sprite loop at the condition where you call the function. This will call the function for each picked sprite.

    Thank you, I feared it would have to resort to something like that.

    When an event picks more than one instance of an object, don't the actions work like a foreach loop themselves?

    For instance, say there's a game where there are balls, and some of them are spiky, and you want to move all of the spiky balls one pixel to the right.

    Construct 2 logic:

    Event: Ball -> Is isSpikey

    Action: Ball -> Set X to self.X + 1

    loose programming translation:

    foreach (Ball ball in listOfBalls)

    if (ball.isSpiky)

    ball.X += 1;

    ----------

    Doing this with functions:

    Construct 2 logic:

    Event: Ball -> Is isSpikey

    Action: Function -> Call "MoveOnePixelRight" (Ball.UID)

    Event: Function -> On "MoveOnePixelRight"

    Sub-Event: Ball -> Pick instance UID Function.Param(0)

    Action: Ball -> Set X to self.X + 1

    loose programming translation:

    foreach (Ball ball in listOfBalls)

    if (ball.isSpiky)

    MoveOnePixelRight(ball);

    void MoveOnePixelRight(Ball ball)

    { ball.X += 1; }

    ---------

    Do you see how this makes sense?

    I don't see why I have to add a foreach to Construct 2 when it appears that that's what the event logic is doing by default.

    Why is this:

    Event: Ball -> Is isSpiky

    Any different than

    Event: Ball -> Is isSpiky

    Sub-Event: System -> For each Ball

    ?

    Thanks for the help =)

CannedEssence's avatar

CannedEssence

Member since 17 May, 2013

None one is following CannedEssence yet!

Trophy Case

  • 11-Year Club
  • Email Verified

Progress

12/44
How to earn trophies