![]() |
||||||||||||||
|
||||||||||||||
blade2k
» articles & tutorialsDynamic Stealth Tutorial
by: HeavyBlade DON'T PANIC! (Thanks Douglas Adams!) When reading this - or scrolling down and wetting yourself at it's size, please remember that I uh... talk a lot. Keep with this, and you will be well rewarded :D Things of important note: I am using this system in my game and I spent a great deal of time creating it. And, in an effort to add to the community, I am posting this before the release of my game - hence, inevitably, stealing some of its thunder. I don't mind doing this, but I would appreciate some form of note or credit - ie. adding a special thanks to... or something somewhere, would be fine. The term "dynamic" is a programming term used to describe one or more variables that (if there's more then one) work together by sharing ever-changing data. The opposite is "static" which refers to one or more variables that do not change unless specifically told too. This is an example of a static variable: Variable = 1. But enough. Let's get onto the scripting! Step 1 - the overview. The Dynamic Stealth System works like this: 1) a series of variables are initiated detailing the number, range of vision, and other necessities of what we shall call, "the guards". 2) the main loop takes this information and uses it to set up and activate itself. 3) the main loop calls the current guard which relays to it it's location, facing direction and ros (range of sight). 4) the sub-common-event detailing the guard's los (line of sight) then takes the current information from the loop and uses it to perform los calculations. 5) the main loop goes onto the next iteration (in this case - the next guard). 6) should the section be completed, or the player caught, this loop will terminate ("break") and react appropriately. When this is all finished, you'll have a fairly realistic, lagless (give a couple of the guards a wait 0.1 seconds at the end of their list of commands), and easily re-usable stealth system! This is technically version 3 of the stealth system and by far the best, as it will allow you to determine the number of guards you desire, the range of sight for each guard, the location of the starting point (done by variables so it doesn't need a separate long series of switch cases!) and pretty much anything you desire. ...settle pride. Let's actually get this tutorial going :P lol. Step 2 - the setup. First of all, create the new switches you'll be needing: STH_Sys_Found STH_Sys_Complete STH_Sys_Called ...and the new variables: Guard_X (for the guard's X co-ordinate) Guard_Y (for the guard's Y co-ordinate) Guard_Facing (for the direction the guard is facing) Guard_ID (for the loop to track the current/next guard event). First_Guard_Num (for the loop to know which event to start at.) Last_Guard_Num (for the loop to know which event to start-over/end at.) Guard_ROS (for the common events to know the range of the guard's sight.) Hero_X (for the hero's X co-ordinate) Hero_Y (for the hero's Y co-ordinate) STH_Cur_Map_Num (number of the map where the player starts and will restart if captured). STH_Start_Hero_X (X co-ordinate where the player starts and will restart if captured). STH_Start_Hero_Y (Y co-ordinate where the player starts and will restart if captured). Stealth_One (A useless variable containing the number - "1.") Stealth_Tries (A useful variable that tracks the number of attempts it takes the player to successfully complete the stealth section - perhaps for a prize? :) ) Stealth_Sys_Useless (Shockingly, this value is useless! :O ). Now that you've done all that I must issue to you a few warnings: 1. When implementing this system ensure that you have finished placing any other events beforehand... or at-least, please do not place a non-guard event with an ID larger then the First_Guard_Num and smaller then the Last_Guard_Num (between the two) or you will get an error. Errors are bad. This is due to the natural setup of the loop and cannot be helped. Step 3 - actually doing something. Let's dive right in now and get all the unpleasantness - the common-event scripting out of the way. It's a lot of code and you may find it hard to follow at first, but stick with me and you'll be well-rewarded. Common Event: Name: LOS_Stealth_Sys_Main Trigger: Call ----- Memorize Location: STH_Cur_Map_Num, STH_Start_Hero_X, STH_Start_Hero_Y Variable Oper: Guard_ID Set equal to: First_Guard_Num. Variable Oper: Stealth_One Set equal to: 1. [This completes the initialization placed in the common event.] Loop >Memorize Location: STH_Cur_Map_Num, STH_Start_Hero_X, STH_Start_Hero_Y >Branch if (Switch[STH_Sys_Found] is ON) >>[The player has been caught.] >>Break Loop. >:End >Branch if (Switch[STH_Sys_Complete] is ON) >>Break Loop >>End Event Processing >>[Yea! The Player made it through! I'm not sure if the end event] >>[processing part is required but meh.] >:End >Branch if (Guard_ID is Last_Guard_Num or more) >>Variable Oper: Guard_ID set equal to: Guard_First_Num >>[This is to loop over once the last guard has been reached.] >:Else Handler >>Variable Oper: Guard_ID +1. >:End >Call Event: Guard_ID, Stealth_One. >[Get the needed information from the current guard.] >Call Event: Stealth_Sys_GSearch > >:End Loop [end of common event] That wasn't so bad, was it? ...I hope :grin: I've added comments in some of the less obvious places to inform you that there is a reason for that command to be there and that I do not, in fact, smoke anything. lol. It will probably scare you to know that that wasn't the largest of the 3 events. The next is the largest, so get ready, grab a beer (unless you're under 18) and get ready to click... a lot... :D Step 4 - a-LOS-a, jhonny a-LOS-a... hehe... This is the most confusing part of the coding, so let me explain to you exactly how the LOS calculations work. 1) take the guard and the hero’s x-location. 2) if they are the same, then there is a possibility the guard can see the hero (vertically). 3) subtract the larger of the two y-co-ordinates from the other. 4) provided the result is less then the guard's range of vision, the hero has been seen. If this confuses you, think of it like this: H_______G H_[_____]G The Guard can see the tiles in the brackets (the number of which is determined by the ROS). In this case the tiles affected by the ROS do not contain the hero - the hero and the guard are too far apart. But in this case... H____G [_H___]G After the calculation is preformed, we can tell that the hero is occupying a tile in the guard's line of sight. I hope that made sense... 'cause if not, this could get really confusing for ya! :) [Comment: First check to see if the guard is on a valid x coordinate to see the hero on the y coordinate.] Branch if(Guard_X is equal to Hero_X) >Branch if(Guard_Y is greater then or equal to Hero_Y) >>Variable Oper: Guard_Y - Hero_Y >>Branch if(Guard_Facing is 4 (down) Not.) >>>Branch if(Guard_Y is less then or equal to Guard_ROS) >>>>[The hero has been seen! (vertical up). >>>>Switch Operation: STH_Sys_Found turn ON. >>>:End >>:End >>[Restore the Guard_Y to it's correct value.] >>Variable Oper: Guard_Y + Hero_Y. >:Else Handler >>Variable Oper: Hero_Y - Guard_Y. >>Branch if(Guard_Facing is 1 (Up) Not) >>>Branch if(Hero_Y is less then or equal to Guard_ROS) >>>>[The hero has been seen! (vertical down) >>>>Switch Operation: STH_Sys_Found turn ON. >>>:End >>:End >Variable Oper: Hero_Y + Guard_Y. >:End :End [Vertical check is complete - now check horizontally.] Branch if(Guard_Y is Hero_Y equal) >Branch if(Guard_X is Hero_X or more) >>Variable Oper: Guard_X - Hero_X. >>Branch if(Guard_Facing is 3 (Right) Not) >>>Branch if(Guard_X is less then or equal to Guard_ROS) >>>>[The hero has been seen! horizontal left.] >>>>Switch Operation: STH_Sys_Found turn ON. >>>:End >>:End >>Variable Oper: Guard_X + Hero_X. >:Else Handler >>Variable Oper: Hero_X - Guard_X >>Branch if(Guard_Facing is 2 (left) Not) >>>Branch if(Hero_X is less then or equal to Guard_ROS) >>>>Switch Operation: STH_Sys_Found turn ON. >>>:End >>:End >>Variable Oper: Hero_X + Guard_X. >:End :End. [end of common event]. Step 5 - "Game over, man! Game over!"- Aliens XD Well guys, we're nearly there! All that's left is our final common event, our init_event, and of course the guards (they're all identical, so I'm just giving you a blueprint.) Common Event: Name: Stealth_Sys_Found Trigger: Auto-Start Trigger Switch: STH_Sys_Found ----- [put some dialog here if you want]. [start a battle here if you want]. Variable Oper: Stealth_Tries + 1 Tint Screen: R000,B000,G000,S000, 0.0 Sec (Wait) Recall to Location: STH_Cur_Map_Num, STH_Start_Hero_X, STH_Start_Hero_Y Tint Screen: R100,B100,G100,S100, 2.0 Sec (Wait) Switch Operation: STH_Sys_Found turn OFF Switch Operation: STH_Sys_Called turn OFF [End of common event!] nice and simple there. You're probably cheering over the finished common events right about... NOW. :) 6) Initiating all the freakin' code. It's been a long haul - but you're nearly there. The end is in sight! Event: Stealth_Op_Start Trigger Condition: Parallel Process Event Layer: Below Hero Do not Forbid Event Overlap Transparent --------- Variable Oper: STH_Cur_Map_Num set equal to [Map ID of map this event is placed on.] Variable Oper: STH_Start_Hero_X set equal to [Set your starting X coord here.] Variable Oper: STH_Start_Hero_Y set equal to [Set you starting y coord here.] Switch Operation: STH_Sys_Called turn OFF Switch Operation: STH_Sys_Complete turn OFF Variable Oper: First_Guard_Num set equal to [your first guard event's ID]. Variable Oper: Last_Guard_Num set equal to [your last guard event's ID]. Call Event: LOS_Stealth_Sys_Main Switch Operation: STH_Sys_Called turn ON -------- Make a second page requiring STH_Sys_Called to be on, change the start condition to action key, and leave the rest blank. (dummy page...) 7) And for a fine deed to your country... Congratulations to all of you who made it here. I know it hasn't been easy. You've endured hardship, snow, rapid aging... and wtf am I talking about? XD anyway... The last piece of code I'll need to retype for this tutorial >:) This is the blueprint for the guards: Name: Guard. Trigger Condition: Collision with Hero (he can't bump into them and expect to go home free now can he?) Event Layer: Same Layer as Hero -------- (You can make patrol routes for a guard by giving them a custom pattern under movement type. This will not prevent their LOS from working properly .) Variable Oper: Guard_X Set equal to This Event X Coord. Variable Oper: Guard_Y Set equal to This Event Y Coord. Variable Oper: Guard_Facing Set equal to This Event Facing Variable Oper: Guard_ROS Set 6 (or whatever value you want). ...That really is it! Simply copy-paste your new guard as much as you please - but play test it to ensure you can still succeed! :D Oh yes, and to remove any lag - simply give one (stationary works best) guard a 0.1 second wait. There are a few bugs - ie. Guards can currently see you through obstacles (if it's smaller then their ROS), but it should be easy for you to fix this - provide a change in ROS when they go past the obstacle?. Please provide feedback to me about this via my email. Thanks, and enjoy :D |
|
|||||||||||||
|
©2002-2008 blade2k.net - parsed in 0.002 seconds - view active users
[16401 members][newest member: magicalkittie]
Active Users (2)[ Xamusel_Uzumaki ] [ demonfire666 ]
|
||||||||||||||