I'm going to be a bit detailed and specific with my request, so I can easily relate to everyone and my request for help.
Allow any objects in my game to "Burn", "Catch fire" and "get destroyed from the fire", not just one object.
What I have done:
I have sucessfully programmed one object to be able to catch Fire, namely an "AppleTree", and it works great! It burns, and after a while, it will change it's animation to show that it is burnt after it's "Health" value reaches 0. I have also successfully created the concept of spreading fires to other AppleTree objects if the burning fire in question is touching another AppleTree.
What I was working on before I got lost:
Since the AppleTree object is the only thing that can burn in my game at the moment, I wanted to expand the possibilities here, so anything can catch on fire. The trouble is; every object has different variables and the event system recognises each object differently for different things. For example, I have not given the object "Shop" the same variables or events as the AppleTree to catch on fire, etc. So I thought what if I changed the AppleTree into "FireCloak". So it would be an invisible object, and the idea of this would be to use the FireCloak object to cover all objects that can catch fire in the game, so then, using the existing events, it can spread or catch Fire to any object. The reason why I changed AppleTree into FireCloak is because the object for AppleTree has all the programming I need for it to catch on fire (of course).
What I am stuck with:
The only thing I need to make sure of here (and correct me here if I'm wrong) is to recognise the visible object that is burning to change it's animation to the appropriate "burnt" animation. Now, I could do something like this, which, apart from the sub-event, I had, except I created the sub-event to consider different types of objects.
Is FireCloak overlapping Fire
Is Health = 0
Is FireCloak overlapping AppleTree
Event Actions (for sub event):
AppleTree Set Animation to "Burnt"
However, in my game, objects, and particularly objects like Trees can overlap each other for a graphical effect. If I used the same code here to change the animation of an AppleTree to burnt when it is overlapping another AppleTree that is not ready to change it's animation, it will pre-maturely happen, and it will likely cause other bugs I do not want. So, I am trying to figure out a way I can match each FireCloak with their respective objects.
Possible solutions I am looking at:
1) I thought about Containers, but this only works effectively if you're talking about the same object and it's instances, I have multiple objects with different variables, I would have to spend a lot of energy and time in changing a lot and this could also cause bugs with other objects, so I am not keen on this.
2) I was seriously thinking I could create a variable under the FireCloak object which will be "Object_UID" and I would then somehow assign the UID of the appropriate object to the FireCloak, then when it comes to changing animations to Burnt, I can just compare the object's UID with the FireCloak's Object_UID variable, and if it matches to change the animation. The only thing I am stuck with here is how do I do this without having to copy FireCloak and then specifically change the object_UID variable to each appropriate object. I suppose this does not matter so much, Flammable objects on a level will not be changing shape, size, or position.
Please tell me what you think, is my solution 2 the best and most effective solution?
Thanks so much in advance!
I have made similar systems in the past.
The way I did it, was anything that I wanted to be able to burn had it's own set of instance variables, basically to control things like "IsOnFire:0/1" or "BurnRate:X" etc.
I then had a single event for each burnable item that checked if fire existed, and if it did to check what it's overlapping, and if it's overlapping anything that has the variable "IsOnFire" and that value was "0" then it would change to 1.
Once this variable was set to 1 (or whatever you want to make it be) then I had one more event that would create fire sprites, etc.
I used "Fade" behaviour on the fire to give it an automatic lifespan (if it was overlapping nothing burnable, or something that had already burnt). Essentially what you want to try and create is a blanket system that works on anything by building a "fire system" that you can add objects to by either including them in a family (called BURNABLES or something) or by creating one event per burnable item. I went with using separate events myself because my burnables had very different effects on them depedning on the thing that was burning... but if you want a nice generic burn effect that looks pretty much the same on all or most items, using a family would be a good way to do it.
Remember that you can easily add all objects to multiple families... so you can make a BURNABLE family, and add objects to it that might be part of some other family already, and that should work just fine.
Hope this helps a bit!
I forgot to mention, what I created to solve my issue was basically what's referred to commonly as a "state machine" - wherein you have a sequence of steps that will happen when fire is encountered. IE: Step 1 check for fire, Step 2 initiate burn if applicable, Step 3 generate fire effects and particles/etc, Step 4 change to "Burnt" state and set animations, Step 5 destroy or invalidate. I actually use a string based instance variable that I call "STATE" and set it to whatever text word I feel is appropriate - like "fresh" and "burning" and "burnt" - then use these "state words" to jump from the initial state to the next and next, and so on.
Thanks for the prompt response. It was very quick.
I have not done much family stuff in my project. I have studied families, and perhaps in some cases I should use them, and I might, but in this case, I think the best thing for me to do is to continue along the idea of the blanket system that you mentioned and that I have been trying to create, because I have pretty much everything ready. Like you said, it is better if it is done this way, particularly if they have different ways of burning, and I do, so I will copy my FireCloak over each of the objects I want to burn and then simply create an animation for that object suitable for burnt, and I will also create different points For the FireCloak and set the position of the fire accordingly depending on what is burning. I think this is appropriate, considering that I know what all the flammable objects are and where they are and how many I have. It would be a different story if I didn't know that stuff. Thanks dude, you've definitely, given me a better understanding of what I'm doing!
Of course, if anyone else has a better idea, please reply.
Edit: By the way, those steps you mentioned in your Edit, are principles that I intend to follow. Thanks for sharing!
No problem at all.
I fumble through this stuff just as much as the next guy... my ideas are probably not the most efficient way to deal with things, but it certainly helps get the job done via my way of thinking and seems pretty solid.
You can easily make the fire "spread" via a simple event "fire is overlapping X object/family" - then create events to control EXACTLY what happens when said object is on fire.
I would probably still suggest adding all flammable objects into a family (called flammable, or burnable, etc) then use that family to do the fire "spread". From there, reference each object individually once it's "on fire, IsBurning=1, etc" and create the effects or frame/animation changes as required.
I think I am definitely on the right track with this in accordance with your advice, SoldjahBoy. The only problem though is getting my head around families and how I can incorporate that in my project currently. I've read guides and watched videos, but I lack confidence in using them with what I'm doing. It might be because I feel like I have to do an overhaul. =[
Develop games in your browser. Powerful, performant & highly capable.
Nah it should be super easy to add a family for burnable items.
Just do to your project and in the right side pane, find families and right click -> add new family -> add all burnable objects to family -> name family "flammable" or something like that. Give the family some instance variables for things like "IsOnFire" or whatever is needed. These variables will reference the object only through it's family relationship and work separately to the objects actual instance variables, but the variable data can easily be transferred to the object itself.
Now make an event:
Fire overlapping "Flammable" (family)
-> "Flammable" (family) "isOnFire" = false ==> Set object on Fire (set "IsOnFire"=true)
Families are super easy to work with, and not as difficult as you perceive. The idea is to be able to affect many objects and instances of objects using one event. For another example if you had a bunch of enemies that are all different objects to each other, you can make a family called "enemy" and combine them into a single reference for say, when you shoot a bullet. Bullet collides with "enemy" then subtract health variable from whatever "enemy" the bullet hit. It saves you from haveing to make events like "bullet hits enemy 1 -> do this" then "bullet hits enemy 356 -> do this".
Hmm, I'll give this a go, but there is just one thing I am not sure about, and I think I can do it with families because I am sure I can set individual instance variables:
I have to be able to identify which Fire is what, because in my game, I have to be able to recognise that Fire1 and Fire2 are different. The reason being is because the player will get points for extinguishing Fires, but the player has to extinguish the entire Fire, so the entire Fire of Fire1 or the entire fire of Fire2 to get points. The game can create multiple Fires, so for each Fire that is created in the game, I have set a unique instance value called Fire_ID which is given to the Fire when it is created and when it spreads to other objects, I also assign the burning objects the same Fire_ID as the Fire that is burning it. This is to stop it conflicting with other fires. So the question is, even though all my flammable objects would be in a family, can they be set different Fire_IDs without changing the Fire_ID to all of the objects in the family?
Ah yes well if you need that additional control over individual fires, then doing them as separate objects could prove a more flexible method
So in this case, doing families is not a good idea?
Sorry, I'm just a bit confused. xD
Oh, not saying it's a bad idea at all... it all really depends on your requirements and how you want the game to work.
If you want fire spread to be simple, then using a family will help a lot for that type of thing. The difficulties will start to arise when you're defining whatever constitutes a "new fire" from the old fire. I guess only you really know exactly what you're wanting to achieve, so the methods used can often be specific to the problem
I understand. Thanks so much for your patience and help!
I'm actually having a lot of trouble trying to get this to work properly with what I suggested in Solution 2. For every Apple Tree, I have an instance variable called Object_UID and every tick I set it to self.UID, so it's UID is in an instance variable. For the FireCloak I also have an Object_UID that I manually set for each instance to match the AppleTree's UID.
Basically, here is my event:
FireCloak is overlapping Fire
FireCloak is Burning
FireCloak Health = 0
AppleTree Object_UID = FireCloak.Object_UID
AppleTree Set animation to Burnt (play from beginning)
It works on the first AppleTree that is set on fire, but it doesn't work on the second one.
And then it's Eradic, sometimes it works and sometimes it doesn't, but there is generally always one of the AppleTrees that does not change it's animation to "burnt" when it should. I haven't changed the code around.
I have tried to Pick by Comparison the apple tree's UID and the FireCloak's Object_UID instance variable. Same thing happens. It does not always work.
I assume I am doing something wrong here, but I'm out of options.
Edit: By the way, I have checked to make sure that the Object_UID instance variable on every FireCloak instance matches the correct AppleTree's UID.
Yeah, picking instance ID's can be tricky.
I always create my own numbering system for every object on creation. I have things like "entCount" or "DudeCount" which I start from 0 and just add 1 each time a new thing is spawned that I need to track. This way, I have sequential numbers that are more easily (for me) tracked.
Comparing the UID or custom ID is crucial, but you should have that all nested in a loop "for each appletree" or "for each fire", depending which way your comparison is set up. This will make sure it compares every tree independently. You can even check them in order of UID if you want, if "age" of a tree is important.
Using instances can be tricky, especially when you have multiple instances of multiple objects all trying to interact with each other. You'll get the hang of it after experimenting around.
Hey Sol, I did try a For Each loop for the Apple tree, as a Sub-event so like I did try this:
For each AppleTree
It still seems to do the same thing, so I removed the For Each loop because it didn't seem to make a difference.
What I am seeing in my in-game bug mode details is that the numbers are all there in the instance variables to match the "Object_UID" instance variable on both the AppleTree and the FireCloak objects, but for some reason, it is not always working.
All I essentially need now is for construct 2 to recognise these two objects properly so it works each time. I'm not 100% sure if I'm doing this right. At the moment, I have 4 AppleTrees, and I just tested it again, and it worked for the first two AppleTrees correctly, the third one didn't work, but when the fourth one lost all Health, it changed both the third and the fourth AppleTree to Burnt. I do not understand. Another test shows that the fire started backwards (since fires can start at random flammable objects), this time, the second and third AppleTree would not change. But changed again after it was late for a couple more minutes. It's eradic.
The frustrating thing is I often compare instance variables with quite a few different objects in the game for different things, and a lot of those things are objects I do not know are going to happen, so the game creates them and then assigns them the appropriate numbers to be recognised. I never have a problem doing it that way, and i don't normally have an issue with doing stuff like this. For some reason, I'm just having problems with this. I could try smaller numbers and see what happens, but I definitely think I am missing something here and it's bigger than that.
It's times like this, I feel like I need to re-study the way construct 2 picks objects and instance variables. I actually feel like I may have to specifically program every single flammable object individually, but surely there is a better way to do it, hence why I thought my FireCloak object idea was the best way.