Basic Movement AI Chasing, Evading, Intercepting, Pattern Movements Movement AI • Movement – Ubiquitous behavior found in many games • Chasing and Evading – the most basic movement AI that can be implemented on NPCs Chasing & Evading • 2 parts ▫ Decision to initiate a chase or evade ▫ Effecting the chase or evade • Sometimes, a 3rd part, to avoid obstacles while chasing and evading is required, but that can be considered separately • 1st part – decision making • Focus on 2nd part – concerns the action itself, to chase and evade Basic method • Simplest method: Update NPC coordinates through each game loop to ▫ Decrease the distance between NPC and player (chase) ▫ Increase the distance between NPC and player (evade) • Pays no attention to NPC or player headings (direction of travel) or speeds More complex methods • Positions and velocities (direction of travel) of both NPC and player are considered so that NPC can be moved to intercept the player instead of relentless chasing • In short: Predicting where the player will likely to be at in the future, and moving towards that as target Basic Chasing • Pseudocode for Chasing if (npcX > playerX) npcX--; else if (npcX < playerX) npcX++; if (npcY > playerY) npcY--; else if (npcY < playerY) npcY++; Basic Evading • Moving farther, instead of moving closer • Pseudocode for Evading if (npcX > playerX) npcX++; else if (npcX < playerX) npcX--; if (npcY > playerY) npcY++; else if (npcY < playerY) npcY--; Tile-based environment – How? • 8-way movement Tile-based Chase movement • Updating difference ▫ Continuous environment: x, y coordinates in Cartesian coordinate system (float) ▫ Tile-based environment: x, y in tile coordinate system (int.) are columns and rows if (npcCol > playerCol) npcCol--; else if (npcCol < playerCol) npcCol++; if (npcRow > playerRow) npcRow--; else if (npcRow < playerRow) npcRow++; Tile-based Chase – Any problem? Line-of-sight Chasing • Make NPC take a direct straight-line path towards player • Stationary player – straight path • Moving player – path is not necessarily straight Note may not look too bad if game loop constantly updates position, path should appear curved and natural • Movements in TBE will appear less smoother than CE due to coarse movement units L-o-S Chasing in TBE • Aesthetic disadvantage of using simple basic chase – although no. of steps are the same • Limitation of 8-way movement, no other possible angles • Will look really BAD if many NPCs are chasing this way L-o-S Chasing in TBE • Solution: To calculate an intermediate path (closest to a straight line) for the NPC to chase • Use a standard line-drawing algorithm – Bresenham’s algorithm ▫ Nice thing: Does not draw two adjacent pixels along a line’s shortest axis • Path calculation function ▫ Calculate and store a series of tiles to be moved to ▫ Needs to be called every time player changes position L-o-S Path in TBE “Looking At” Rotation • Without “Looking At” Rotation (x1, y1) • With “Looking At” Rotation (x1, y1) θ (x2, y2) • Only x and/or y are updated at each time (8-direction) (x2, y2) • Additional rotation steers NPC to look at target and chase in that direction Thrust and Steering forces • Thrust force: pushes object to the front (velocity) • Steering force: pushes the nose of object to the right or left to rotate (angular velocity) L-o-S Chasing in CE • No need to determine path like in TBE, movement updates are in floating-point (rounding to nearest pixel integer gives good approximation) • Similarly, rotation angle (“looking at” direction) should be re-calculated every time player changes position L-o-S Chasing in CE • Curved path taken by predator when chasing prey • What happens if the speed of the predator is set too fast? Preventing overshooting • Implement speed control logic to allow predator to slow down as it gets closer to prey ▫ Calculate distance between both, if distance < some predefined distance, reduce thrust velocity to slow down L-o-S Evading • Since we now understand L-o-S Chasing, L-o-S Evading is just doing everything the reverse • TBE ▫ Update movement in opposite direction (good enough!) • CE ▫ “Looking at” rotation should steer to opposite face ▫ Update movement in opposite direction Further improvements? • Acceleration (and deceleration) for thrust force and steering force? • Any way to improve “intelligence” of chasing movement? Intercepting • Line-of-Sight Chase: NPC will always head directly towards player • In the case of a moving target, what happens? Player Line-of-sight Chase NPC Intercepting • Movement can be more “intelligent”, if it knows how to intercept the player somewhere along the player’s “trajectory”. • How do we work this out? What information do we need? Player Line-of-sight Chase NPC Intercepting – In Principle • Predict some “future” position of the player and move towards that position, so that it reaches the same time as player… Player Line-of-sight Chase A “future” position of player NPC Intercepting Chase Intercepting – A “Future” Position • “Future” can be safely predicted linearly • How to compute this position? Player Line-of-sight Chase A “future” position of player NPC Intercepting Chase Intercepting • Important to consider relative velocities (direction and magnitude) and distance instead of just their current positions • Let’s work out the math to determine what is the predicted future position… Intercepting - Code • Recall: You would have implemented the Enemy class already, and have it to chase the player. Target Player position • For Intercept, Target Player’s predicted future position ▫ Easy to modify and adapt code from Chase to Intercept • Function to be called through the game loop to constantly update interception point Intercepting Intercepting • There are scenarios where intercepting may not be possible or unrealistic ▫ NPC moving at much slower velocity ▫ NPC ends up chasing from behind a player moving in straight line ▫ NPC gets ahead of player and moving at a faster speed Pattern Movement • Simple way of giving the illusion of intelligent behavior • “Choreographed” movements of enemy NPCs making organized maneuvers, loops • Can be used effectively for ▫ Enemy NPCs (patrol, attack) ▫ Friendly NPCs (to exhibit or act intelligently to cooperate with player) ▫ Secondary NPCs (doing all kinds of random patterned actions) Standard Pattern Movement • Uses lists or arrays of encoded instructions to tell NPC how and where to move each step ▫ Easy to loop through again • Sample control data ControlData { double turnRight; double turnLeft; double stepForward; double stepBackward; }; Standard Pattern Movement • Can include other kinds of actions: ▫ Fire weapon, release chaff, drop bomb, do nothing, speed up, slow down, etc. • Pattern initialization ▫ Hardcoded in game ▫ Loaded from a data file (text, XML) • Process pattern ▫ Maintain and increment an index to the pattern array through the game loop Standard Pattern Movement void GameLoop(void) { . . . Object.orientation += Pattern[CurrentIndex].turnRight; Object.orientation -= Pattern[CurrentIndex].turnLeft; Object.x += Pattern[CurrentIndex].stepForward; Object.x -= Pattern[CurrentIndex].stepBackward; CurrentIndex++; . . . } Pattern Movement in TBE • Bresenham’s line drawing algorithm used again to pre-calculate path steps • More complex paths can be created by joining up line segments ▫ Each new segment will begin once a previous one ends ▫ Line-of-sight function End of segment now assigned as the target Pattern Movement in TBE • Instead of resetting L-o-S path array, new line segment is appended to previous path (Why do we do this?) Pattern Movement in TBE • High-level code for pattern initialization entityList[1].InitializePathArrays(); entityList[1].BuildPathSegment(10, 3, 18, 3); entityList[1].BuildPathSegment(18, 3, 18, 12); entityList[1].BuildPathSegment(18, 12, 10, 12); entityList[1].BuildPathSegment(10, 12, 10, 3); entityList[1].NormalizePattern(); entityList[1].patternRowOffset = 5; entityList[1].patternColOffset = 2; Patrolling: Cyclical & Ping Pong A A B C ABCBABCBA D B C ABCDABCD Pattern Movement in TBE • Ping Pong Patrolling entityList[1].InitializePathArrays(); entityList[1].BuildPathSegment(10, 3, 18, 3); entityList[1].BuildPathSegment(18, 3, 10, 3); entityList[1].NormalizePattern(); entityList[1].patternRowOffset = 5; entityList[1].patternColOffset = 2; Pattern Movement in TBE • To prevent repetition and predictability Add a random factor for choosing alternative patrolling path How to implement? Pattern Movement in PSE • PSE – Physically Simulated Environments (or Continuous Environments with Physics) ▫ You may specify positions for NPC to traverse, but that defeats the purpose of using CE. Bad realism! • Control structure needs to be designed to accommodate forces (thrust, steering) Pattern Movement in PSE struct ControlData { bool PThrusterActive; bool SThrusterActive; double dHeadingLimit; double dPositionLimit; bool LimitHeadingChange; bool LimitPositionChange; }; • Changes in heading and position are relative in patrolling • Based on this control data, how do you initialize a square pattern patrol? Pattern Movement in PSE • More implementation details can be found in textbook Other Useful Movements • Velocity Matching (for friendly NPCs, flocking) • Wander (roaming NPCs) (can be found in Millington’s book)