Handling Multiple Actors (using clones)

Learn how to make certain types of games and use gameEditor.

Handling Multiple Actors (using clones)

Postby DST » Thu Feb 05, 2009 5:18 pm

Sometimes handling many actors can be a bother, but you must learn to deal with CLONES in order to make successful games.

You will find, over time, that you can reduce the number of actors each time you make a game, and that doing so will reduce the complexity and difficulty in programming your game.

Here are two basic examples of cloning vs. new actor creation.

#1. Powerups.

Ok, so you got a health powerup, a weapons powerup, an ammo powerup, an extra life powerup....these should be 1 cloned actor.

Simply add an animation, 'healthp', for instance. to the powerup actor. Add another animation...'weaponp'.

Powerup>CreateActor>
Code: Select all
type=rand(2);

switch(type){

case 0:
ChangeAnimation("Event Actor", "healthp", FORWARD);
break;

case 1:
ChangeAnimation("Event Actor", "weaponp", FORWARD);
break;

}


Now player>collision>any side>powerup
Code: Select all
switch(collide.animindex){

case 0:
health+=3;
break;

case 1:
weapon+=1;
break;

}
DestroyActor("Collide Actor");


Animindex refers to the # of the animation in the animation list; the first animation you add is 0, etc. etc.
Now you have one actor for unlimited powerup types, and only 1 create actor, and only 1 collision to deal with.

Much much much easier than having multiple powerup actors!!!!!!!


#2. Text Meters.

You might have a text actor displaying a variables, such as score.
textactor>DrawActor>
Code: Select all
textNumber=score;


You can reuse that actor too! Try cloning it and:
textactor>DrawActor>
Code: Select all
switch(cloneindex){

case 0:
textNumber=score;
break;

case 1:
textNumber=lives;
break;

case 2:
textNumber=time;
break;

}

Also, when you create text, DO NOT USE COLORS. Make text WHITE, then on textactor>createactor, set the rgb values. In this way you can make an unlimited number of colors with only 1 font! The more fonts you use, the more likely you are to experience errors.
Using these methods will greaty increase the running speed of your game, the ease of programming/changing script, and as well the handling of other variables(like ZDEPTH).

If the coding involved in the case switch seems like a pain when you're a beginner, you'll soon find that the amount of time it saves and the amount of power and flexibility it offers is more than worth it. Take time to familiarize yourself with the case switch, it is vital to making complex games.

If you've never used a case switch, here is the syntax:

Code: Select all
switch (variablenametobechecked){
case 0:
action here
break;
case 1:
action here
break;
}


all 'case x' must be followed by a colon :
all 'break' must be followed by a semicolon ;

Also, you can omit cases you won't be needing. If you don't want to take any action when the variable is 0, you can simply omit case 0 from the switch, and start with case 1 instead.
It's easier to be clever than it is to be kind.
http://www.lostsynapse.com
http://www.dstgames.com
User avatar
DST
 
Posts: 1117
Joined: Sun Apr 15, 2007 5:36 pm
Location: 20 minutes into the future
Score: 151 Give a positive score

Re: Handling Multiple Actors (using clones)

Postby Fuzzy » Thu Feb 05, 2009 7:20 pm

Beautiful post. I'm giving you a point. I hope everyone that reads this does too.
Mortal Enemy of IF....THEN(and Inspector Gadget)

Still ThreeFingerPete to tekdino
User avatar
Fuzzy
 
Posts: 1068
Joined: Thu Mar 03, 2005 9:32 am
Location: Plymostic Programmer
Score: 95 Give a positive score

Re: Handling Multiple Actors (using clones)

Postby Kalladdolf » Mon Feb 09, 2009 2:28 pm

I encourage newbies to read this very carefully (as well as pros who missed this chapter somehow). Awesome post, DST.
User avatar
Kalladdolf
 
Posts: 2427
Joined: Sat Sep 08, 2007 8:22 am
Location: Germany
Score: 120 Give a positive score

Re: Handling Multiple Actors (using clones)

Postby Fuzzy » Tue Feb 10, 2009 4:42 am

Also note that you dont have to have the break for each case. in that case it will assess the next case in line.
Mortal Enemy of IF....THEN(and Inspector Gadget)

Still ThreeFingerPete to tekdino
User avatar
Fuzzy
 
Posts: 1068
Joined: Thu Mar 03, 2005 9:32 am
Location: Plymostic Programmer
Score: 95 Give a positive score

Re: Handling Multiple Actors (using clones)

Postby DST » Tue Feb 10, 2009 5:22 am

What fuzzy is saying is if you have a var of 1 and there's no break after 1, it will continue and perform case 2.

This could be useful as a cumulative event;

The following two codes will perform exactly the same.

Code: Select all
switch(hp){
case 0:
DestroyActor(etc.etc);
break;
case 1:
b-=100;          //<----- no break here
case 2:
g-=100;
break;
}


Code: Select all
switch(hp){
case 0:
DestroyActor(etc.etc);
break;
case 1:
b-=100;
g-=100;
break;
case 2:
g-=100;
break;
}


Either way, case 1 will reduce both b and g;
while case 2 will reduce only g;
It's easier to be clever than it is to be kind.
http://www.lostsynapse.com
http://www.dstgames.com
User avatar
DST
 
Posts: 1117
Joined: Sun Apr 15, 2007 5:36 pm
Location: 20 minutes into the future
Score: 151 Give a positive score

Re: Handling Multiple Actors (using clones)

Postby Fuzzy » Tue Feb 10, 2009 5:29 am

Yes that is what I mean, thanks. also, since you can put a variable in the case to compare to the switch, you can do some neat stuff.
Code: Select all
switch(c) {
case y:
 b = 127;
case q:
 g = 255;
 break;
}


Which is an interesting way to do comparisons. You can do a strange sort of hybrid if/loop. note that it never goes back to the first case though.

You could also change the value of c, making a loop.
Mortal Enemy of IF....THEN(and Inspector Gadget)

Still ThreeFingerPete to tekdino
User avatar
Fuzzy
 
Posts: 1068
Joined: Thu Mar 03, 2005 9:32 am
Location: Plymostic Programmer
Score: 95 Give a positive score

Re: Handling Multiple Actors (using clones)

Postby sillydraco » Mon May 31, 2010 2:29 am

Aha nevermind! i figured it out x3

i tried using the code, but it didnt seem to work :( im trying to have a block (like in mario) you hit it and it destroys it self, and it also has Destroy Actor>Create Actor (Powerup). the Powerup has CreateActor>Script Editor:

Code: Select all
type=rand(7);

switch(type)
   
{

    case 0:
    ChangeAnimation("Event Actor", "berry", FORWARD);
    break;

    case 1:
    ChangeAnimation("Event Actor", "bolt", FORWARD);
    break;

    case 2:
    ChangeAnimation("Event Actor", "coin", FORWARD);
    break;

    case 3:
    ChangeAnimation("Event Actor", "feather", FORWARD);
    break;

    case 4:
    ChangeAnimation("Event Actor", "Full", FORWARD);
    break;

    case 5:
    ChangeAnimation("Event Actor", "Health", FORWARD);
    break;

    case 6:
    ChangeAnimation("Event Actor", "Mana", FORWARD);
    break;
}



Powerup has 7 animations, just little icons. but whenever i try to finalize the script it gives me errors (see attatchment)

:<
Attachments
Untitled.png
Time for sleepy, dream of new things...new life, new reality, new wings.
Image
User avatar
sillydraco
 
Posts: 71
Joined: Fri Apr 03, 2009 7:54 am
Score: 3 Give a positive score

Re: Handling Multiple Actors (using clones)

Postby DST » Mon May 31, 2010 4:13 am

You have to declare variables before you use them. To use type as a single (one use only) variable, start the script with:

int type=rand(7);

This declares it as an integer, and reserves the memory for it. Creating it in this way will make it disappear after the CreateActor script finishes.

To use it as a lasting variable, use the 'variables' tab at the bottom of the script window, and create a new variable with these settings:

Integer
Actor Variable

Now that variable will stay with the actor until it is destroyed, and there will be one type variable reserved for each actor that wants to use it.

If you use global instead of actor variable, then there will be only one type variable in the game, shared by all.

Examples of Actor Variables:
health
type
damage

Examples of global variables:
lives
score
level
It's easier to be clever than it is to be kind.
http://www.lostsynapse.com
http://www.dstgames.com
User avatar
DST
 
Posts: 1117
Joined: Sun Apr 15, 2007 5:36 pm
Location: 20 minutes into the future
Score: 151 Give a positive score

Re: Handling Multiple Actors (using clones)

Postby sillydraco » Mon May 31, 2010 7:43 pm

yes, i noticed my mistake shortly after i posted here x3 heh heh, silly me ^^
Time for sleepy, dream of new things...new life, new reality, new wings.
Image
User avatar
sillydraco
 
Posts: 71
Joined: Fri Apr 03, 2009 7:54 am
Score: 3 Give a positive score

Re: Handling Multiple Actors (using clones)

Postby Zivouhr » Sat May 31, 2014 6:22 pm

Thanks for the info on using the same clone actors for multiple tasks. I just started applying this idea prior to reading this thread, and it does save time.
City of Rott Game created on Game Editor http://cityofrott.wordpress.com/
User avatar
Zivouhr
 
Posts: 549
Joined: Sat May 17, 2014 2:12 pm
Score: 59 Give a positive score

Re: Handling Multiple Actors (using clones)

Postby Zivouhr » Sun Jun 01, 2014 9:03 pm

Bump Thread:

I gave this a try and got the first result, but then the other items didn't do what I wanted them to. I could use some help if possible.

Items: 3 treasure clones, all look the same using the same animation, just clones of the first in different locations.
Goal: When player collision meets treasure.0, treasure.1 becomes visible, then when you find that treasure.1, treasure.2 becomes visible somewhere else.

The first part worked, so when the player contacts treasure.0, treasure.1 then became visible. But after contacting treasure.1, treasure.2 stays invisible/transparent. Testing it, I want the treasures to be contacted in the exact order, so one leads to the appearance of the next one, each at a time.

After setting up the first part:
treasure.0 / draw actor / script editor: (also tried it separately at a time using create actor, but same result)
Code: Select all
type=rand(4);    //had to declare "type" as variable to get code to accept.
switch(type){

case 0:
"treasure.0";   //Wondering if I can just say which clone I'm using instead of an animation?
break;
case 1:
"treasure.1";    //Is this code correct?
break;
case 2:
"treasure.2";
break;
}




I used in the treasure.0 > collision with player: (all but treasure.0 have been originally set to full transparency/invisible).

Code: Select all
switch(collide.cloneindex){
case 0:  //just wondering where I went wrong with this code here?
ChangeTransparency("treasure.1"), 0.000); //this makes invisible treasure.1 visible after contacting treasure.0.
break;

case 1:
ChangeTransparency("treasure.2"), 0.000); //this makes invisible treasure.2 visible after contacting treasure.1.

case 2:
ChangeTransparency("treasure.3"), 0.000); //this makes invisible treasure.3 visible after contacting treasure.2.
}


And for the variable, I added the word "type" (without quotes) into the Integer Global code, and then tried it with Integer Actor code too, but can't get this to work right beyond the player contacting the first treasure and making treasure.1 visible. Treasure.2 never appears when contacting treasure.1 for some reason. But when I test it and make treasure.2 slightly visible just to see what happens if contacted by player, after going in order from treasure.0, treasure.2 makes treasure.1 reappear, looping back to that one (again as a test to see what happened).

Thanks for any help you can offer.
City of Rott Game created on Game Editor http://cityofrott.wordpress.com/
User avatar
Zivouhr
 
Posts: 549
Joined: Sat May 17, 2014 2:12 pm
Score: 59 Give a positive score

Re: Handling Multiple Actors (using clones)

Postby lcl » Mon Jun 02, 2014 12:42 pm

Hi again, Zivouhr! Image

I'm now going to try to explain what is wrong with your code, how you should fix it, and what you should do to make your game perform the desired actions more efficiently. I urge you to read the full post before beginning to modify your code based on my corrections of your code, since I first tell what is wrong with the code and how you could fix it, but after that I tell you about an alternative way of achieving what you want to do, and I strongly recommend using that one instead. Image

This code doesn't do anything:
Code: Select all
type=rand(4);

switch(type)
{
    case 0:
        "treasure.0";
    break;

    case 1:
        "treasure.1";
    break;

    case 2:
        "treasure.2";
    break;
}

Or, well, it does set a random value varying from 0 to 3 to type and then the compiler goes through the switch case and it type is equal to 0, 1 or 2, it interprets the texts but doesn't do anything with them. What is this part supposed to do? I don't see any meaning with this since you don't actually need to do anything in any actor's draw actor code to achieve what you want to do. Also, you should know that you can't add any code just for a single clone. You said that this code is in treasure.0's draw actor code, but it's actually in every treasure actor's draw actor code. The way to make some code happen only in certain clones is by using an if check to see what clone is interpreting the code, or to use a switch case for the same result as using an if statement.

Also, here you are using collide.cloneindex, when you'd want to only use cloneindex:
Code: Select all
switch(collide.cloneindex) //You shouldn't use collide.cloneindex here
{
case 0:  //just wondering where I went wrong with this code here?
ChangeTransparency("treasure.1"), 0.000); //this makes invisible treasure.1 visible after contacting treasure.0.
break;

case 1:
ChangeTransparency("treasure.2"), 0.000); //this makes invisible treasure.2 visible after contacting treasure.1.

case 2:
ChangeTransparency("treasure.3"), 0.000); //this makes invisible treasure.3 visible after contacting treasure.2.
}

I see that you're confusing this collision event with the thing I talked to you about earlier. The thing with "collide" is that it's meant for reading the variables of the actor the current actor is colliding with. So, for example, in your previous problem with the saving of the food actors, you had the code in the player's collision event with the food actors. And you wanted to know the cloneindex of the food actor the player collided with, so you had to use collide.cloneindex.

But now, in this case, the situation is reversed, you don't now have the code in the event when the player actor collides with the treasure actor, but instead where the treasure actor collides with the player actor. Of course, this is the same thing when you look at it in the game, but it differs in the way the code gets interpreted, and in this case, "collide" refers to player actor, not the treasure actor.

So now, because you're always using player's cloneindex, the code will always make treasure.1 reappear, since there's only 1 player actor and thus it's cloneindex is 0. Just remove the "collide." part from before of the "cloneindex" in the switch statement, and you should be good to go. :)






BUT. There is a lot simpler way to achieve what you want to do. Yes, this setup you have would do what you want, but think of it, you'll have to write 3 more lines of code for every new treasure you add to your game! Think if you end up to a point where you have 100 treasure actors in there, way too much code for something as simple as this. There is a very nice trick to achieving what you want to do, but first I'll point out another issue with this concept.

You currently have the code in the treasure actor's collision event with player. What this means in practice, is that every single frame of the game, each of the treasure actors runs a collision detection event to see if they collide with player. And that can cause slowdown on your game, and it's generally a bad habit to add any events to clones when you can have some single actor handle it all for the clones. So, instead of using treasure -> collision with player, use player -> collision with treasure. Only one actor having to check for collisions now. :)
(This would of course mean, that you now then again have to use collide.cloneindex in the collision event, to get the cloneindex of the treasure the player collides with, instead of using only cloneindex, because that would give you the 0 cloneindex of the player actor's)

Now, about that neat trick for avoiding the need to write three new lines of code for every new treasure you add to your game.
This is very simple because you want to have the treasures activate each other in the simple order based on their cloneindex. So what you want to do is this:

Player -> Collision with treasure -> script editor:
Code: Select all
char temp[256];
//The above line of code creates a temporary variable to be only used in this event. This variable is an array of characters, also called a string. This string is 256 characters long. The name temp is an abbreviation for temporary, you can call it whatever you want.

sprintf(temp, "treasure.%i", collide.cloneindex + 1);
//The above line of code prints the clonename (=actor name.cloneindex) of the next clone to the temporary string called temp. For example, if the treasure that collides with player in this event has the cloneindex of 2, the string printed to temp will be this: "treasure.3". That's because we use the "%i" to tell sprintf to add an integer value to that place in the string, and then we tell sprintf that this integer value will be equal to the collide actor's (the treasure the player collides with) cloneindex plus 1, which then is 2 + 1 = 3.

VisibilityState(temp, ENABLE);
//The above line of code sets the visibility state of the actor who's clonename is stored in the temp, to ENABLE, and that meas that the actor will become visible.

And that there, is all. This code will do what you want no matter how many clones of the treasure actor there is. :)

But now you might think what this VisibilityState command is? Well, I explained that in my latest answer to your previous question, and basically, it's just a better way of making actors invisible / visible. For more information on the command, see this page and search (F3 or CTRL + F) for the word VisibilityState.

Of course, for using VisibilityState instead of changing the transparency of the actors, you'll need to make them invisible via the use of VisibilityState in the first place. For doing this, just add a code like this to the Create Actor event of the treasure actor:
Code: Select all
if (cloneindex != 0) //This means "if cloneindex is not equal to 0". That's because we want the treasure number 0 to be visible upon startup, right? =)
{
    VisibilityState("Event Actor", DISABLE); //This makes the current clone have it's visibility state set to DISABLE, and because this code gets interpreted for every clone, it sets all clones (except clone 0) to be invisible
}


I hope this wasn't too messy of an explanation, I tried my best to cover all things as well as I could. If there's still some trouble, don't hesitate to ask more. :)




Oh, one more thing..
Zivouhr wrote:And for the variable, I added the word "type" (without quotes) into the Integer Global code, and then tried it with Integer Actor code too

Just so that you know, the variables created via the Variables window, are either:

- Global variables = This means that there's just that one variable with that name and it's accessible by every actor at any point in the game.
- Actor variables = This means that every actor in the game has it's own unique case of this variable, every actor has it's own copy of this variable, just like every actor has it's own value for it's x and y coordinates, for example. These are also accessible by any actor in the game, but you'll have to define which actor's variable you want to access, except if the code you're using for accessing the variable is in an event of the actor who's variable you want to access.

An example of actor variables:

Let's say we've created an actor variable called "myVar", and it's an integer variable.
Now, let's say we have an actor called "myActor" and we want to set it's "myVar" to 5.
What we can do, is to, for example, add this to "myActor"'s Create Actor event:
Code: Select all
myVar = 5;

Note that we can simply write myVar, because we are accessing the variable from an event of the actor itself, and Game Editor will then use the current actor's variable.

But if we wanted to set "myActor"'s "myVar" to 5 when, for example we click another actor with the left mouse button, we would add this code to that actor's mouse button down -> left -> script editor:
Code: Select all
myActor.myVar = 5;


I think that's all I wanted to say :D
Last edited by lcl on Tue Jun 03, 2014 9:25 am, edited 1 time in total.
User avatar
lcl
 
Posts: 2339
Joined: Thu Mar 25, 2010 5:55 pm
Location: Finland
Score: 276 Give a positive score

Re: Handling Multiple Actors (using clones)

Postby Zivouhr » Tue Jun 03, 2014 2:25 am

Hi LCL. 8)
I read through your post regarding handling multiple actors and clones, and it looks like a very detailed, well thought out explanation that I will apply carefully and see what I can do with it this week. Thanks also for the suggestion to make the process easier, and for describing how the player should be the one doing all of the collision with events rather than the items or enemies in the game waiting to collide with the player. That is something I wasn't aware of till now regarding slow down, but thankfully that is how I was able to do most of my collisions aside from a number of the newer ones, thanks to some demos including Bee-Ant's Mario demo, where I saw how many collision events Mario was handling, and assumed that is the way to go.

Once again, awesome effort on your part explaining all of this in such great detail to help myself and others learning C and Game Editor! :D Keep up the awesome work. And thanks also to everyone on this forum who contributes their knowledge as well. All valuable information is appreciated! 8)
City of Rott Game created on Game Editor http://cityofrott.wordpress.com/
User avatar
Zivouhr
 
Posts: 549
Joined: Sat May 17, 2014 2:12 pm
Score: 59 Give a positive score

Re: Handling Multiple Actors (using clones)

Postby Zivouhr » Wed Jun 04, 2014 1:08 am

Hi LCL,

I gave the simpler scripts a try; very easy to code in since they're so short, and all scripts accepted for immediate action in the script editors for the appropriate actors (player, treasure).
The only thing is, when my player walked up to the first treasure, with the other treasures hidden as hoped, after colliding with the treasure, the treasure remained in place, and didn't disappear or allow other treasures to appear.

Should I add a visibility code after the player's collision code that you wrote? Just wondering, but it's still early so I will tinker with the code a little more if I can to get it working in the intended way.

In the meantime, I ran activation events that got the desired effect, but your coding would be much faster and more efficient if I can get it working as hoped. Thanks again!
City of Rott Game created on Game Editor http://cityofrott.wordpress.com/
User avatar
Zivouhr
 
Posts: 549
Joined: Sat May 17, 2014 2:12 pm
Score: 59 Give a positive score

Re: Handling Multiple Actors (using clones)

Postby lcl » Wed Jun 04, 2014 1:30 am

Hi.

Zivouhr wrote:The only thing is, when my player walked up to the first treasure, with the other treasures hidden as hoped, after colliding with the treasure, the treasure remained in place, and didn't disappear or allow other treasures to appear.

Well, yes, I forgot to mention, that you should also disable the current treasure actor's VisibilityState. But the current code does allow the other treasures to appear for me, are you sure you checked that, or did you just assume that because the current treasure doesn't vanish, it doesn't make the other ones appear either? :)

Zivouhr wrote:Should I add a visibility code after the player's collision code that you wrote?

If you meant disabling the treasure actor's VisibilityState, as I mentioned above, yes you should.
User avatar
lcl
 
Posts: 2339
Joined: Thu Mar 25, 2010 5:55 pm
Location: Finland
Score: 276 Give a positive score

Next

Return to Tutorials

Who is online

Users browsing this forum: No registered users and 1 guest