Game Development Community

Timed Enemy Pattern

by rennie moffat · in Torque Game Builder · 07/22/2009 (7:32 am) · 69 replies

Hi guys, today I will be working on a pattern timer for a scene object which will act like an enemy to my hero. It will simply turn on and off, when on, my hero can not cross it, move over it. When it is off he can. So I must develop some type of shield. which must be turned on and off. I of course want to take that and make it so that I could have several on screen at once which can then have there own timers on so that an object. our hero, must maneuver safely between. Think Mario Bros, when he has to time his run underneath the giant monoliths.


As I say I will be working on this today, research, piecing together code, but if anyone has any clue, tips prior, please don't hesitate to chirp in.




About the author

My thanks to Garage Games and the Garage Games Community combined with owned determination I got one game up, Temple Racer and I am looking to build more interesting, fun games for the mass market of the iOS app store.

#21
07/23/2009 (12:41 pm)
these are my bare working functions just to show the logic.
this will help me I think, I just have to now work on this, tho if you see any red lights in my logic, please stop me before I waste a day.

Thanks so much,
Ren





function FrameSwitcherBehavior::onBehaviorAdd(%this, %time, %frame)
{
%this.schedule(6,)
if time < 3 frame 0 is used

else frame 1 is used
}

function ShieldBehavior::onBehaviorAdd(%this, %amount, %victim)
{
if %this.schdule <3 seconds %amount = 3

else %amount = 0
}



#22
07/23/2009 (12:56 pm)
Quick note: you can use the {code}foobar{/code} tags to make code look pretty - just replace the { with [

Anyway, I'm getting annoyed at apartment hunting, so here's a rough draft of what I think you're trying to do (I might be wrong about your goal, though).

%template.addBehaviorField(FrameSwitcher, "the mechanism controlling frame and time of exposure", float, 3);
%template.addBehaviorField(Sheild, "turns shields (damage) on and off", int, 3);

Not sure what you're trying to do here - is the FrameSwitcher some thing that gets pressed to activate the square or something? Makes me think I'm confused about your goal, so I'll just through down some code and you tell me what's wrong :) I'll make it simpler than you probably want in the end, but hopefully it'll be a start.
Edit: I think you want one behavior for this, not two...maybe that's what you were alluding to.

The behavior description and header stuff looks fine, but it's been a while.
%template.addBehaviorField(stableTime, "seconds between safe/pain switches", int, 3);
//I guess that's it, though you could have separate lengths of time for each state, specify a particle effect or image to use instead of frames, etc

//I don't remember when onBehaviorAdd is triggered, but whatever, try onAddToScene(%this, %scenegraph) otherwise :)
function BigSquareBehavior::onBehaviorAdd(%this)
{
   //initialize safe to be something, use switch to start the schedule
   %this.safe = true;
   %this.switch();
}

function BigSquareBehavior::switch(%this) {
   //switch the safe state, set the frame accordingly
   %this.safe = !%this.safe;
   if(%this.safe)
      %this.owner.setFrame(1);
   else {
      %this.owner.setFrame(0);
      %this.checkForPlayer();
   }

   //If there's already a switch schedule running, cancel it and use the new one (so that you can switch when you want, too
   if(isEventPending(%this.switchSchedule))
      cancel(%this.switchSchedule);

   //Start the switch schedule (convert to milliseconds)
   %this.switchSchedule = %this.schedule(%this.stableTime * 1000, "switch");
}

function BigSquareBehavior::checkForPlayer(%this){
   //Just turn on collisions, cast for a collision and do damage to the player or whatever here
}

So, I think that should 'work' and flip between two frames of an image without a problem.

Let me know if it doesn't ;)
#23
07/23/2009 (1:04 pm)
ok word on the code brackets, will implore.....
so sorry.







anyhow, the idea is to have a large square which will switch from angry (dangerous, will cause damage) to normal (the player can walk over it, it is safe. This, in theory, will be done, by toggling between, frame 0 and 1, whcih are set to a timer, schedule (little confused here).

thats pretty much it. I am going to read your code now. I vill holler.
#24
07/23/2009 (1:07 pm)
ok, I am little confused about your "switch". what is this, is this set to a timer. in essence, is a switch base coding language or an abstract object a player would trigger?




#25
07/23/2009 (1:13 pm)
ps. schedule can run on an infinite loop, does not need a trigger in my case.
#26
07/23/2009 (1:13 pm)
I'm confused by your question :) I'll see if describing the code's behavior helps: if you put the behavior I wrote on an image with two frames, it would switch frames every 3 seconds.

Does that make sense? I'll throw it in TGB in a bit if it doesn't and see if it actually works. It's not an abstract object that the player would trigger at all - just an image with no collision that switches frames occasionally. Right now it only checks for the player when it switches from safe to not safe, but that could be a scheduled check too (or could get the collision callback and apply damage that way)
#27
07/23/2009 (1:22 pm)
no thats perfect, sorry I m kinda of getting tossed around here between different thoughts, approaches... etc.



that sounds good, I will try too. If you say it works, it might be worth a go, I was just toying trying to use elements of various sources. I am a bit of a coding rook as in rookie so please forgive me.




#28
07/23/2009 (1:25 pm)
just to keep pace, this is what I am looking at now for my own logic.

I am confused many places, but still going.


major parts I am having difficulty with are whether I use onLevelLoaded, onAddToScene. I will be going over this.




if (!isObject(BigSquareBehavior))
{
%template = new BehaviorTemplate(BigSquareBehavior);

%template.friendlyName = "BigSquare";
%template.behaviorType = "AI";
%template.description = "Square changes modes from on to off, killing on on.";
}


%template.addBehaviorField(FrameSwitcher, "the mechanism controlling frame and time of exposure", float, 3);
%template.addBehaviorField(Sheild, "turns shields (damage) on and off", int, 3);



function BigSquareBehavior::onLevelLoaded(%scenegraph)
{
current frame
current time
}


function BigSquareBehaviour::onBehaviorAdd(%this, %time, %frame)
{
%this.schedule(6,)
if time < 3 frame 0 is used

else frame 1 is used
}

function BigSquareBehaviour::onBehaviorAdd(%this, %amount, %victim)
{
if %this.schdule <3 seconds %amount = 3

else %amount = 0
}


#29
07/23/2009 (1:35 pm)
Just for some clarification, onLevelLoaded and onAddToScene are pretty much the same thing, except that they're triggered on different occasions. onAddToScene gets triggered whenever the object is added to the level, which could be when the level is loaded if it's in the level file (I think, might have changed) and onLevelLoaded is only called if it's in the level file and not if it's added later.

Also worth noting is that schedules produce events, so it's not really good practice (as far as I know) to check the time remaining on a schedule. You want to just set it and wait until it's triggered to do something. So, instead of setting a schedule to 6 and then checking the time, you would have one count to 3, change the frame, reschedule for 3, change the frame, etc (that's what my code did).

Hope that helps a bit :)
#30
07/23/2009 (1:39 pm)
yes it does!

So, for a schedule, would i simply allow for the time to elapse, 3 seconds, (and in a nutshell that is the entire schedule?



of course It will need to relate to the frame but is that the jist?
#31
07/23/2009 (1:42 pm)
Yeah, I think you've got it. If you see my code, the schedule is started again every time the function switch is called (probably shouldn't have called it switch, but whatever). So, each time the schedule counts down it's 3 seconds, calls switch, which changes the frame, and is rescheduled for 3 more seconds. The function just keeps waking up every 3 seconds forever.
#32
07/23/2009 (1:44 pm)
so there is no <,> required?
#33
07/23/2009 (1:48 pm)
I have a question?


function BigSquareBehavior::switch(%this) {
//switch the safe state, set the frame accordingly
%this.safe = !%this.safe;


in this, specifically...
%this.safe = !%this.safe;

you are comparing safe and not safe... so in this line, what are you suggesting actually?
#34
07/23/2009 (1:49 pm)
Yep, exactly. Instead of thinking about it as a timer that ticks down, think of an infinite schedule as an alarm clock that goes off every x milliseconds. So, you don't have to check what time it is, you just have the 'safe' variable in my example that changes to remember what state you're in. That way, you know that the last three seconds were in one state and can change the state for the next three seconds accordingly.
#35
07/23/2009 (1:51 pm)
That's not a comparison (that would be ==), it's an assignment. It makes it so %this.safe changes changes to it's opposite.

%this.safe = true;
//safe is true, obviously
%this.safe = !%this.safe;
//safe is now false!
%this.safe = !%this.safe;
//safe is now true again!
if( %this.safe == %this.safe )
//always true

Hope that clarifies that ;)
#36
07/23/2009 (1:54 pm)
%this.safe = !%this.safe;

I dont get this,
how can safe be true again!? underline again, is it because it switches back?
#37
07/23/2009 (2:00 pm)
%this.safe = true;  //Creates a local boolean variable (can be true or false)

//So, both these are true statements (would activate an if statement)
%this.safe  == true     //True because %this.safe is true
!%this.safe == false    //True because %this.safe is true

//The exclamation point, '!' negates a boolean,
// so true becomes false and vice versa

//So, this changes safe to false
%this.safe = !%this.safe;

Does that help?
#38
07/23/2009 (2:07 pm)
um yes.
#39
07/24/2009 (5:11 am)
function BigSquareBehavior::switch(%this) {  
   //switch the safe state, set the frame accordingly  
   %this.safe = !%this.safe;  
   if(%this.safe)  
      %this.owner.setFrame(1);  
   else {  
      %this.owner.setFrame(0);  
      %this.checkForPlayer();  
   }

why did you add in that last line...
%this.checkForPlayer();
#40
07/24/2009 (5:18 am)
ok, so I just noticed its inclusion later in the code...

function BigSquareBehavior::checkForPlayer(%this){  
   //Just turn on collisions, cast for a collision and do damage to the player or whatever here  
}


my question is, does this function require any methods?