MMF2Random Grid Movement Example7C:\Sebastian\MMF2\examples\random_grid_movement_ex2.mfa4(@0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;**************************************************;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;**********;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;********************;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;********************;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;**********;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;********************;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;**************************************************ATNFJArialAPMSASUMAGMI """)))UUUMMMBBB999|PP3f333f3333f3ffffff3f̙3ff333f333333333f33333333f33f3ff3f3f3f3333f33̙33333f333333f3333f3ffffff3f33ff3f3f3f3fff3ffffffffff3ffff̙fff3fffff3fff333f3f3ff3ff33f̙̙3̙ff̙̙̙3f̙3f333f3333f3ffffff3f̙3f3f3f333f3333f3ffffff3f̙3f3ffffffffff!___wwwB00 h hpppph`@qxaxaxExpp`xÀI,0Qqqiph0$À$(mq4U444Uep`$IŽqUUuq$pHiÀ0YYYY888 xXDZmu8YY8U444UuuYyyyya`eÀm88Uqq4u8Y4ahÀDZ840Q4uY4aP,UMMIzizzzz {,{M{U<}}<yx8ax0uUQ ,m``E)}}Y $#W 51uO ~% ,;@= /&{m?S 5#P +*S}D 1U4_ Mk"8X )Th{> ){~L3jخvQ) 8WeO1  $&''&"  xAxAxAx㐂pppX$Ү0QqMAxhHÀiUUuUax`〆4YY8u$hu8U488puUQӎ0Ӽ<<$`axMUm)s͞c  `[  q= P2pO-AhppqmEumx4QӮq8AGMI{׻kϻ[ǻwwwcccSSSCCC333oSKC;{3k+Ww#G_7K'3 kWCw;k3_+S#C7g+K 3ssccSSGG;;33s++_##K7#ۧϏ{gWG7{+osccW WGK;;//ssKK##kS;#ۻÓoG#gc[WO;/s_K ;CϳÛscSwGg7W+K#ߧϏwwggSWCG3;w'/g#[K ; +ӃkgSK73# o_SC7'{cK7'o _##'#'#'#'##skkSS??ۧןϓLJsgߏ[ӃSsKgCW;K3?+{3#o+_OC3 '{k_OC3' w223wW+0{;wW+0{;wW+0{;wW+0{;wW+0{;wW+0{;wW+0{;wW+0{;wW+0{;wW+0{;wW+0{;wW+0{;wW+0{;wW+0{;wW+0{;wW+0{;wW+0{;wW+0{;wW+0{;wW+0{;wW+0{;wW+0{;wW+0{;wW+0{;wW+0{;wW+0{;wW+0{;wW+0{;wW+0{;wW+0{;wW+0{;wW+0{;wW+0{;wW+0{;wW+0{;wW+0{;wW+0{;wW+0{;wW+0{;wW+0{;wW+0{;wW+0{;wW+0{;wW+0{;wW+0{;wW+0{;wW+0{;wW+0{;3wW+pMK    Xc m   /e22D("  """" # $ $ $ $ #""""  ")E22N ????kk????kk????kk????kk????kk????kk????kk????kk????kk#'kk#'kk#'kk#'kk#'kk#'kk#'kk#'????kk#'kk#'kk#'kk#'kk#'kk#'kk#'kk#'kk????kk#'kk#'kk#'kk#'kk#'kk#'kk#'kk#'kk#'kk#'kk????kk#'kk#'kk#'kk#'kk#'kk#'kk#'kk#'kk#'kk#'kk????kk#'kk#'kk#'kk#'kk#'kk#'kk#'kk#'kk????kk#'kk#'kk#'kk#'kk#'kk#'kk#'kk#'kk????kk????kk????kk????kk????kk#'kk#'kk#'kk#'kk#'kk????kk#'kk#'kk#'kk#'kk#'kk#'kk#'kk#'kk????kk#'kk#'kk#'kk#'kk#'kk#'kk????kk#'kk#'kk#'kk#'kk#'kk#'kk????kk#'kk#'kk#'kk#'kk#'kk#'kk#'kk#'kk????kk#'kk#'kk#'kk#'kk#'kk????kk????kk????kk????kk????kk????kk?? ??NRandom Grid Movement ExampleSebastian Janisz20062&(%' &(%' &(%' &(%' &H&File&New F2Pass&word&Pause Ctrl+PPla&yers Ctrl+Y&Quit Alt+F4&OptionsPlay &samples Ctrl+SPlay &musics Ctrl+M&Hide the menu F8&Full Screen Alt+Enter&Help&Contents F1&About...  P Y S Mpqsw ~X,eHFrame 1{׻kϻ[ǻwwwcccSSSCCC333oSKC;{3k+Ww#G_7K'3 kWCw;k3_+S#C7g+K 3ssccSSGG;;33s++_##K7#ۧϏ{gWG7{+osccW WGK;;//ssKK##kS;#ۻÓoG#gc[WO;/s_K ;CϳÛscSwGg7W+K#ߧϏwwggSWCG3;w'/g#[K ; +ӃkgSK73# o_SC7'{cK7'o _##'#'#'#'##skkSS??ۧןϓLJsgߏ[ӃSsKgCW;K3?+{3#o+_OC3 '{k_OC3' w?? Backdrop Active 4 gridDirection addDirection Movement #122Where enemy isWhere enemy should beString Movement #1?4The enemy starts out where it should be (of course).String 2 Movement #1?LWe add 50 pixels to its X, so that we can check for a backdrop on the right.String 3 Movement #1?LIn order to check for backdrops on top, we subtract 50 from its X and its Y. String 4 Movement #1?[In order to check for backdrops on the left, we subtract 50 from its X and add 50 to its Y. String 5 Movement #1?VIn order to check for backdrops on the bottom, we add 50 to its X and add 50 to its Y. String 6 Movement #1?AFinally, to move it back where it was, we subtract 50 from its Y. String 7 Movement #1$@This is a diagram to explain the "enemyDetectSurroundings" loop. String 8 Movement #13HRandom grid movement example By Sebastian Janisz (UltimateWalrus) 2006String 9 Movement #17ERandom direction every frame--- Press space to go to the next frame. pppppppp p p p p p;222d2222,2^d^^^ ^ ,^ ^^ ^ ^^,d222^22,222d2d, !d"d#(*x+x,-./0^1h235^678 M9 4 M: g; $%,&^'(Evtsh`|l%"Arialh@|l%"Arial>$  8 2  X 2@   h`|l%"ArialJ$  J(-enemyDetectSurroundings :-findDir h|l%"Arialn$  .  2 2$  2n$  .  2 2$  2n $  .  2 2$  2n $  .  2 2$  2h |l%"Arial $  "# f ~n&findDirh 0 |l%"Arial J (-findDir$  .  2 .  2 J (-findDir$  .  2 .  2 J (-findDir$  .  2 .  2 J (-findDir$  .  2 .  2 h |l%"Arial p (-findDir.  2 ,  2 p (-findDir.  2 ,! 2  f ~n&enemyDetectSurroundingsh |l%"Arial 2 8(-enemyDetectSurroundings"$ "$ "$ "$  8(-enemyDetectSurroundings2$  2 8(-enemyDetectSurroundings "# V 8(-enemyDetectSurroundings2$  22$  2 8(-enemyDetectSurroundings "# V 8(-enemyDetectSurroundings2$  22$  2 8(-enemyDetectSurroundings "# V  8(-enemyDetectSurroundings2$  22$  2 ! 8(-enemyDetectSurroundings "#  "!8(-enemyDetectSurroundings2$  2 #"h$#|l%"Arial %$  "$ &%  Rems When Flag 4 is off, that means our enemy is ready to move. The first thing we have to do is pick a gridDirection at random. We also randomize addDirection to either -1 or 1. If the enemy can't move in gridDirection, we will add addDirection to it to find a new direction.^Before we decide if the move is OK, we run the loop "enemyDetectSurroundings", which will set Flags 0-3 according to backdrops immediately next to the enemy. Then, we run the loop "findDir" four times. This loop detects if it is OK to move in gridDirection, and if it isn't, tries to find a good direction by adding addDirection to gridDirection.0Once the enemy is done moving, we set Flag 4 on. If any of the next four events are true, that means that gridDirection is not a good direction to move (i.e., there is a backdrop there). So we add addDirection to it to try to find a good direction. aThese next two events make the direction "loop around," just like if we were using MMF directions mThis loop is best described visually. Look at the off-screen diagram in the frame editor for an explanation. Move every 00"-50gridDirection: Indicates what direction the enemy should move in. 0=right, 1=up, 2=left, 3=down addDirection: Indicates which direction the enemy should turn to find an empty space to move into. Should be randomized to either -1 or 1. Flags 0-3: Indicate if there is a backdrop at each of the four directions. They are set on if there is a backdrop there. Flag 4: Is set off when the enemy is ready to move.+These next four events just move the enemy.EvOb ActiveSpriteStringTextString 2TextString 3TextString 4Text String 5Text String 6Text String 7Text String 8Text String 9TextEvEd EvTs EvLsEvCs,!DNE!Frame 2x{׻kϻ[ǻwwwcccSSSCCC333oSKC;{3k+Ww#G_7K'3 kWCw;k3_+S#C7g+K 3ssccSSGG;;33s++_##K7#ۧϏ{gWG7{+osccW WGK;;//ssKK##kS;#ۻÓoG#gc[WO;/s_K ;CϳÛscSwGg7W+K#ߧϏwwggSWCG3;w'/g#[K ; +ӃkgSK73# o_SC7'{cK7'o _##'#'#'#'##skkSS??ۧןϓLJsgߏ[ӃSsKgCW;K3?+{3#o+_OC3 '{k_OC3' w ??Backdrop Active 4 gridDirection addDirectionrandomizeDirectionTimer Movement #122String 9 Movement #1(MRandom direction at random intervals--- Press space to go to the next frame.ppp)222d2222,2^d^^^ ^ ,^ ^^ ^ ^^,d222^22,222d2d, !d"d#%,&),$<Evtsh0|l%"Arial$  ,! 2 h |l%"Arial $  .  2 H 20  8 2  v$  X 2@   J$  J(-enemyDetectSurroundings :-findDir n$  .  2 2$  2n$  .  2 2$  2n $  .  2 2$  2n $  .  2 2$  2 $  "# f ~n&findDirJ  (-findDir$  .  2 .  2 J  (-findDir$  .  2 .  2 J (-findDir$  .  2 .  2 J (-findDir$  .  2 .  2 h |l%"Arial p (-findDir.  2 ,  2 p (-findDir.  2 ,! 2  f ~n&enemyDetectSurroundings2 8(-enemyDetectSurroundings"$ "$ "$ "$  8(-enemyDetectSurroundings2$  2 8(-enemyDetectSurroundings "# V 8(-enemyDetectSurroundings2$  22$  2 8(-enemyDetectSurroundings "# V 8(-enemyDetectSurroundings2$  22$  2 8(-enemyDetectSurroundings "# V 8(-enemyDetectSurroundings2$  22$  2 8(-enemyDetectSurroundings "#  8(-enemyDetectSurroundings2$  2  !   "$ "!  Rems aThese next two events make the direction "loop around," just like if we were using MMF directionsThe only difference is these next two events. Instead of randomizing every single time, we only do it in random intervals. The randomizeDirectionTimer value of the enemy object is used to count down to the next time that the direction should be randomized.When randomizeDirectionTimer gets to 0, we set it to random(5)+1, which will make it so the direction will be randomized again in anywhere between 1 and 5 moves. Every time the timer reaches 0 we randomize the direction.EvObActiveSpriteString 9TextEvEd EvTsEvLsEvCs,!DNE!Frame 3{׻kϻ[ǻwwwcccSSSCCC333oSKC;{3k+Ww#G_7K'3 kWCw;k3_+S#C7g+K 3ssccSSGG;;33s++_##K7#ۧϏ{gWG7{+osccW WGK;;//ssKK##kS;#ۻÓoG#gc[WO;/s_K ;CϳÛscSwGg7W+K#ߧϏwwggSWCG3;w'/g#[K ; +ӃkgSK73# o_SC7'{cK7'o _##'#'#'#'##skkSS??ۧןϓLJsgߏ[ӃSsKgCW;K3?+{3#o+_OC3 '{k_OC3' w ??Backdrop Active 4 gridDirection addDirectionrandomizeDirectionTimertrueXtrueYxOffsetyOffset Movement #122String 9 Movement #1<8Smooth movement--- Press space to go to the next frame.ppp)222d2222,2^d^^^ ^ ,^ ^^ ^ ^^,d222^22,222d2d, !d"d#%,&),$<Evtsh |l%"Arialh|l%"ArialT$  "# , 2 , 2 $  ,! 2  $  .  2 H 20  8 2  v$  X 2@   J$  J(-enemyDetectSurroundings :-findDir h |l%"ArialH $  .  2 ,  2 2, 2 H $  .  2 ,! 2 2, 2 2H $  .  2 ,! 2 2, 2 2H $  .  2 ,  2 2, 2  $  "# h |l%"Arialv 6(  6(  h|l%"Arial.  2 ,! 2 .  2 ,  2 .  2 ,! 2 .  2 ,  2 f ~n&findDirJ (-findDir$  .  2 .  2 J (-findDir$  .  2 .  2 J (-findDir$  .  2 .  2 J (-findDir$  .  2 .  2 h |l%"Arial p (-findDir.  2 ,  2 p (-findDir.  2 ,! 2  f ~n&enemyDetectSurroundings2 8(-enemyDetectSurroundings"$ "$ "$ "$   8(-enemyDetectSurroundings2$  2 ! 8(-enemyDetectSurroundings "# V "!8(-enemyDetectSurroundings2$  22$  2 #"8(-enemyDetectSurroundings "# V $#8(-enemyDetectSurroundings2$  22$  2 %$8(-enemyDetectSurroundings "# V &%8(-enemyDetectSurroundings2$  22$  2 '&8(-enemyDetectSurroundings "#  ('8(-enemyDetectSurroundings2$  2 )(h*)|l%"Arialt+*.  2 .  2 "$ ,+  Rems aThese next two events make the direction "loop around," just like if we were using MMF directionsThis frame is done a little differently. trueX and trueY specify the enemy's actual position on the grid, while xOffset and yOffset specify how far off the enemy is from that point, in order to allow for smooth movement.@Flag 5 is used to initialize the enemy's trueX and trueY values.Every time we change the object's trueX and trueY values, we change xOffset and yOffset to how much the enemy will be "offset" from the location it is moving to. We want to continuously subtract from these offset values until they are 0.NWe set its position so that it is offset from its trueX and trueY coordinates.CIf any of the offsets aren't 0, we want to subtract until they are.IWe only want to start moving again when the object has finished its move.EvObActiveSpriteString 9TextEvEd EvTsEvLsEvCs,!DNE!Frame 3R{׻kϻ[ǻwwwcccSSSCCC333oSKC;{3k+Ww#G_7K'3 kWCw;k3_+S#C7g+K 3ssccSSGG;;33s++_##K7#ۧϏ{gWG7{+osccW WGK;;//ssKK##kS;#ۻÓoG#gc[WO;/s_K ;CϳÛscSwGg7W+K#ߧϏwwggSWCG3;w'/g#[K ; +ӃkgSK73# o_SC7'{cK7'o _##'#'#'#'##skkSS??ۧןϓLJsgߏ[ӃSsKgCW;K3?+{3#o+_OC3 '{k_OC3' w??Backdrop Enemy 4 gridDirection addDirectionrandomizeDirectionTimertrueXtrueYxOffsetyOffsetID doNothing Movement #122String 9 Movement #148Enemy collisions--- Press space to end the application.Enemy Collision 4 Movement #122pppp+222d2222,2^d^^^ ^ ,^ ^^ ^ ^^,d222^22,222d2d, !d"d#%,&,d)$<'(EvtsD1h0|l%"Arialh |l%"ArialB! 2$ (h|l%"ArialT$  "# , 2 , 2 $  ,! 2  $  .  2 H 20  8 2  v$  X 2@   h |l%"Arialh |l%"ArialB!  $  6" 2 h |l%"ArialB!8 $  J(-enemyDetectSurroundings L*- enemyDetectSurroundings2 h |l%"ArialB!$  "# h|l%"Arialv 6(  6(  h|l%"Arial.  2 ,! 2 .  2 ,  2 .  2 ,! 2 .  2 ,  2 f ~n&findDirh |l%"ArialB!!J (-findDir$  .  2 .  2 J (-findDir$  .  2 .  2 J (-findDir$  .  2 .  2 J (-findDir$  .  2 .  2 h |l%"Arial p (-findDir.  2 ,  2 p (-findDir.  2 ,! 2   f ! ~n&enemyDetectSurroundings (2)qh @"!|l%"Arial@h #"|l%"ArialB!   $#:*- enemyDetectSurroundings2"$ "$ "$ "$ h %$|l%"ArialB!6 &%:*- enemyDetectSurroundings2P  26. enemyDetectSurroundings22$  2* '&:*- enemyDetectSurroundings2P  26. enemyDetectSurroundings2  "#  (':*- enemyDetectSurroundings2P  26. enemyDetectSurroundings22$  22$  2* )(:*- enemyDetectSurroundings2P  26. enemyDetectSurroundings2  "#  *):*- enemyDetectSurroundings2P  26. enemyDetectSurroundings22$  22$  2* +*:*- enemyDetectSurroundings2P  26. enemyDetectSurroundings2  "#  ,+:*- enemyDetectSurroundings2P  26. enemyDetectSurroundings22$  22$  2* -,:*- enemyDetectSurroundings2P  26. enemyDetectSurroundings2  "# 6 .-:*- enemyDetectSurroundings2P  26. enemyDetectSurroundings22$  2h /.|l%"ArialB!f 0/:*- enemyDetectSurroundings2P  26. enemyDetectSurroundings2$  $  $  $  $  "# , 2 2~ 10:*- enemyDetectSurroundings2:-findDir h 021|l%"Arial"h 32|l%"ArialB! 43:*- enemyDetectSurroundings2P  26. enemyDetectSurroundings2$  .  2 ,  2 2, 2 2$ 2( 54:*- enemyDetectSurroundings2P  26. enemyDetectSurroundings2$  .  2 ,! 2 2, 2 22$ ( 65:*- enemyDetectSurroundings2P  26. enemyDetectSurroundings2$  .  2 ,! 2 2, 2 22$ ( 76:*- enemyDetectSurroundings2P  26. enemyDetectSurroundings2$  .  2 ,  2 2, 2 2$ 2( 87f 98~n&enemyDetectSurroundings2 :98(-enemyDetectSurroundings"$ "$ "$ "$  ;:8(-enemyDetectSurroundings2$  2 <;8(-enemyDetectSurroundings "# V =<8(-enemyDetectSurroundings2$  22$  2 >=8(-enemyDetectSurroundings "# V ?>8(-enemyDetectSurroundings2$  22$  2 @?8(-enemyDetectSurroundings "# V A@8(-enemyDetectSurroundings2$  22$  2 BA8(-enemyDetectSurroundings "#  CB8(-enemyDetectSurroundings2$  2 DChED|l%"Arialh FE|l%"ArialB!GF.  2 ,! 2 FHG.  2 .  2 .  2 "$ IH  hJI|l%"ArialB! KJ P +hLK|l%"ArialB!ML Rems aThese next two events make the direction "loop around," just like if we were using MMF directionsNWe set its position so that it is offset from its trueX and trueY coordinates.CIf any of the offsets aren't 0, we want to subtract until they are.IWe only want to start moving again when the object has finished its move.This frame is done a little differently. trueX and trueY specify the enemy's actual position on the grid, while xOffset and yOffset specify how far off the enemy is from that point, in order to allow for smooth movement.@Flag 5 is used to initialize the enemy's trueX and trueY values.FI added one extra loop to check if the enemy is overlapping each otherThen they seem to cancel each other.. not to hard to understand why. One loop already set off the flags. It should be If enemy overlapping a backdrop OR another enemy, then do.. or should we use another method? iWe want to keep the info we got from the first enemyDetectSurroundings loop, so we don't want this event. What I do is "spread a value" in the ID value of the enemy objects. This gives each enemy a uniqe ID, starting with 0, that I can use to iterate through them in a loop.EI run the loop "enemyDetectSurroundings2" once for each Enemy object.In this loop, I "select" a single enemy object by comparing its ID to the LoopIndex. This is the only object that the event will effect.OSince the objects are always created, we destroy them at the end of each cycle.8If the enemy is blocked on all sides, it shouldn't move.wdoNothing is an extra value I added to make it so the object will freeze for 50 cycles when it is blocked on all sides.We have to do the rest of the stuff inside the loop. This is because each enemy needs to "reserve" a spot in which it is to move. We don't want two enemies moving onto the same spot.!3findDir now only finds a direction for the current "Every time we change the object's trueX and trueY values, we change xOffset and yOffset to how much the enemy will be "offset" from the location it is moving to. We want to continuously subtract from these offset values until they are 0.hIn order to "reserve" the enemy's spot, we must create another object for other enemies to collide with. aUncomment (get rid of the never) this event to see where the collision objects are being created.Since MMF sometimes has difficulties detecting collisions between duplicates of the same object, I create another object for the enemies to detect.EvObEnemySpriteString 9Text Group.EnemiesSpriteEnemy CollisionSprite(EvEd EvTsEvLsEvCs,!DNE!08 ACHK 8