Duplicate spawning/creation problems

This forum is currently in read-only mode.
From the Asset Store
Build your own spaceship with the various components in the pack
  • So I'm posting this here since I'm not sure if this is intended behavior or not, though I bet it is not.

    See example cap here:

    Basically the problem is that spawning the same object doesn't seem to be working right. I have three behaviors for the bullet object, Bullet, Fade and Timer. I want the Bullet to spawn copies of itself, but it seems that when I perform Spawn "Sprite" on "Sprite", not only a new object gets created, but the original spawner object seems to reset/respawn itself too. The fade timer starts counting from zero, the timer gets disabled, etc. There are other tries at solving the problem in other layouts, all of which fail. I've tried working around the problem by using a value for a timer instead of the timer behavior, removing the fade behavior, using ball behavior instead of bullet behavior, using create object (with both relative to another object and just spawning at Sprite.X & Sprite.Y)... everything seems to fail.

    I don't really want to have multiple sprites for similar objects because it'd make the code a whole lot complicated for no good reason, and spawning copies of itself and setting new properties for them is quite a vital thing, especially for the bullet hell game I'm working on. It just isn't a bullet hell unless there's bullets shooting bullets shooting bullets.

    So is spawning/creating duplicates simply broken or am I just missing something?

  • Normally when you spawn an object, that object is automatically "picked" so that any actions you perform on that object in the same event after spawning will apply to the new object.

    However, you already have a specific instance of that object picked in the condition, so it appears the selected object list is getting confused as to which instance you mean to perform actions on. What is happening is that the newly spawned bullet shoots off at 0 degrees and fades out quickly, while the original bullet turns 90 degrees, and because you set it's type to 2 it no longer spawns any more bullets when the timer clicks on.

    Try this:

    <img src="http://i48.tinypic.com/2d8kigz.png">

    By using the System object to create new instances at the bullet's location you're interrupting the normal picking. The original bullet continues to sail onward, and spawns four bullets before fading out. Is that the result you were going for?

    You may also want to check out a trick known as "Family picking." By assigning two families to the same object you have much greater control over picking and actions. If your bullet belongs both to the Red and Blue families, then you can pick by Red, and spawn Blue, and perform all of the actions you want on the newly spawned objects by using Blue in the actions. That might be just the exact thing you need for this situation. If you need any help with it, feel free to ask.

  • If your bullet belongs both to the Red and Blue families, then you can pick by Red, and spawn Blue

    You can spawn a family? that's weird, what if there's more than one object in there? which should be spawned?

    hmm.. testing....

    okay so that's funny. Sometimes spawns one, sometimes the other, sometimes both, sometimes THREE OF A KIND. I'd guess that's a bug

    Also, try spawning from a family. That's also funny.

    Doublechecking.....

    spawning a family spawns a random object in the family, the numbers were because the spawner was in that family, thus the newly spawned would spawn some other objects also.

    But if you spawn from a family, Construct crashes.

    I'm filing this.

  • Try Construct 3

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

    Try Now Construct 3 users don't see these ads
  • okay so that's funny. Sometimes spawns one, sometimes the other, sometimes both, sometimes THREE OF A KIND. I'd guess that's a bug

    Hmm, I was under the impression that it was supposed to just spawn one random instance of a member of that family, but since Daiz has only one member in the family then that shouldn't be a problem *(see below, it's not a problem).

    Spawning multiples is a bug though, yes.

    But if you spawn from a family, Construct crashes.

    I just assumed that should work, I didn't test it out. I don't see why it wouldn't work. (Unless of course it's a bug, which it sounds like it is )

    Fake edit:

    Before hitting submit on this post I decided to test this out on Daiz's example. The family spawning trick I described works just fine. I guess it's not a problem after all if there is just one object in the family:

    http://dl.dropbox.com/u/529356/multifamilybullet.cap

  • yeah I was spawning the spawner object along with some other one, so that the spawner would spawn some more things. This was a mistake on my part.

    However, the runtime does crash when spawning from a family.

  • However, the runtime does crash when spawning from a family.

    In my example above it doesn't.

    I looked at the .cap you posted to the tracker, and you have the Blue family spawning it's own member (the Blue family contains the "lol" sprite, and you're telling Blue to spawn "lol"). If you change it to Blue spawning the other "spawn" sprite it works just fine.

    It could be crashing just because you're spawning things at an exponential rate? I don't know for sure. But spawning from a family does appear to work as long as you're not spawning that same family.

    Still, a crash is a bug and all so yeah something is wrong there.

  • Try this:

    [snip]

    By using the System object to create new instances at the bullet's location you're interrupting the normal picking. The original bullet continues to sail onward, and spawns four bullets before fading out. Is that the result you were going for?

    The problem with the approach in your image is that if I do that there's no way to set things relative to the original bullet without using something like globals. Let's say I want the bullet to spawn at [original spawner angle]-90. With the spawn function, the new object would start with the angle of the original spawner, so I could just use .angle-90 for the new bullet, but if I were to use the create object (and not use "relative to another object") I would first have to store the original angle in a global before creating the new bullet, and then set the angle as global('spawnangle')-90.

    This isn't exactly what I'd want, because it'd complicate the bullet spawning code a lot, especially if I want to set other things besides just the angle relative to the original spawner object. And since I'm going for a bullet hell game, I'm going to have to do lots and lots of different kind of bullet spawns, and even some seemingly minor increase in the code required to create a spawn, the workload could increase very notably.

    I thought about using families as well, but they'd also introduce another layer of "things to worry about" when coding bullet patterns and it could slow things down quite a bit.

    In either case, you said it yourself:

    [quote:j8dkt3jk]However, you already have a specific instance of that object picked in the condition, so it appears the selected object list is getting confused as to which instance you mean to perform actions on.

    I would say that this is a bug, since in my opinion after spawning an object all actions in the same event should be performed on the new object afterwards.

  • Well, good luck then . I guess I don't see what the problem is with the method I showed you. It does work after all, and it's not like it's a complicated fix. Just avoid the bug shown in Madster's example and you'll be fine.

    [quote:c1gvm2mc]However, you already have a specific instance of that object picked in the condition, so it appears the selected object list is getting confused as to which instance you mean to perform actions on.

    I would say that this is a bug, since in my opinion after spawning an object all actions in the same event should be performed on the new object afterwards.

    Maybe, maybe not. The only way to know for sure is to get one of the devs in here to clarify how it should work in that situation. It seems to me though that instances that are picked by condition get preference over newly spawned instances, and if you think about it it does make sense. Logically it could go either way, though.

  • It could be crashing just because you're spawning things at an exponential rate?

    I made sure that wasn't the case. It's just spawning one each 500ms. While one could probably avoid spawning from a family, it's still a crash and therefore, a bug.

  • Crash=bug, so make sure that's reported.

    As for the spawning problem, this is an extremely interesting .cap. I have investigated it and at first there seems to be a problem with the timer behavior. If you replace the timer behavior with a simple "Every 500 ms" condition, the interesting stuff starts happening.

    It looks like the initial object moving to the right incorrectly keeps resetting its fade behavior, while the objects it's spawning also don't get a fade in. But it is actually working correctly!

    Let's go back to what Spawn Object does in terms of picking. Say you have an object called A, and in an event which picks A1, it spawns A2. Should you get A1 and A2 picked, or just A2? The code is supposed to pick A2 only since it's the only new created object (the system create object action works this way). This way you can control A1 by actions before the spawn action, and control A2 with actions after the spawn action.

    In this particular case though, you end up with just A1 picked - spawning an object does not pick it and the actions affect the original object! This means the 'Set angle to .angle+90' and 'set type to 2' apply to the object moving horizontally. So it ends up redirecting itself downwards, and spawning another object to continue its current path. It's kind of backwards and crazy, but it's actually necessary. If you spawn an object of the same type as the object spawning, the new object cannot be picked because of limitations in the engine. The reason is very complicated, but the code behind running a general action is:

    For each currently picked instance 'Obj':

    -> Run action for instance 'Obj'

    So for example 'Set X to 0' runs the 'set X' action for every picked instance. However, in the 'spawn object' action, it would modify the list of currently picked instances, which it is currently processing in a for-each. This can cause a crash, so the fix was to prevent spawning an object of the same type from picking the spawned object. This results in the counterintuitive behavior in your example .cap.

    The fix? I don't know what the best thing to do is; this picking behavior probably can't be changed in the 0.x engine because it's so integral to the running of actions. I think the best thing to do is to always spawn a different object type (even if it looks the same). So you could have RedBulletA spawning RedBulletB which in turn spawns RedBulletA again. You can then use families to save repeating events. Hopefully that will do you for now.

  • so.... system->create object picks the newly created object, but spawn doesn't?

  • Yes, when you're spawning an object of the same type. If you spawn an object of a different type, it can be picked.

  • Well, create and families seem to work quite fine for my intended purposes... though for some reason I can't get timers to work with it. The cap straight out refuses to compile. In any case, take a look at this:

    When you run it, you can see that the first bullet creates bullets to both left and right, but then only the left side creates further two bullets. The right side should also create two more bullets and destroy afterwards, but right now it only destroys.

    Any ideas on how to solve this?

  • Can't catch a break on this picking thing, huh?

    What's happening is that in the second wave you have not one but two objects that are spawning things, and you're not picking them by anything more than "timer > 500, type = 2." Since both objects meet the criteria for the condition Construct doesn't know which one you mean so it selects the first created instance, which is the one that was created first in wave 1. This is the one that spawned to the left (Angle+90).

    You need to tell Construct that you intend for every instance that meets the criteria to follow these instructions, so you need to add a For Each loop to wave 2.

    http://dl.dropbox.com/u/529356/spawnforeach.cap

    By the way, you should probably use absolute angles when spawning the second wave, because using relative angles makes each side shoot in different directions.

    Oh, and if you intend for there to ever be more than one first wave bullet on the screen you should probably add a For Each to that sequence as well.

    Also, I saved that in 0.99.62 so you might need to upgrade.

Jump to:
Active Users
There are 1 visitors browsing this topic (0 users and 1 guests)