12 02


Delphi Graphics and Game Programming Exposed! with DirectX For versions 5.0-7.0:Artificial Intelligence Techniques                       Search Tips   Advanced Search        Title Author Publisher ISBN    Please Select ----------- Artificial Intel Business & Mgmt Components Content Mgmt Certification Databases Enterprise Mgmt Fun/Games Groupware Hardware IBM Redbooks Intranet Dev Middleware Multimedia Networks OS Productivity Apps Programming Langs Security Soft Engineering UI Web Services Webmaster Y2K ----------- New Arrivals









Delphi Graphics and Game Programming Exposed with DirectX 7.0

by John Ayres

Wordware Publishing, Inc.

ISBN: 1556226373   Pub Date: 12/01/99














Search this book:
 



Previous Table of Contents Next Modeling aggression is simple enough. The application simply examines the horizontal and vertical position of the enemy unit and the player unit, and adjusts the enemy unit’s horizontal and vertical positions to bring it close to the player. For example, if the player unit’s horizontal position is less than the enemy’s, subtracting 1 from the enemy’s horizontal position brings it closer to the player. If the player’s horizontal position is greater than the enemy’s, adding 1 to the enemy’s horizontal position brings it closer to the player. The same holds true for the vertical position. This is illustrated below. Figure 12–1:  Chasing the player Modeling evasion is just as simple. Indeed, if we simply reverse the signs of the values being added to the horizontal and vertical position of the enemy, it will run from the player instead of chasing after it. This is illustrated below. Figure 12–2:  Evading the player Of course, most games would need to take into account obstacles and line of sight, but the basic principle holds true. The following example illustrates how to implement chase and evasion algorithms. The player’s dot is controlled by the cursor keys, and the enemy dot will either chase or flee from the user based on its current status, which is toggled by the Enter key. Listing 12–2: Aggression and evasion in action type . . . TSprite = class XPos, YPos: Integer; procedure MoveSprite(XOffset, YOffset: Integer); end; var . . . Enemy, Player: TSprite; Chase: Boolean; implementation . . . procedure TfrmDXAppMain.FormActivate(Sender: TObject); begin . . . {create the two sprites} Enemy := TSprite.Create; Player := TSprite.Create; {initialize the enemy and player sprite positions} Enemy.XPos := 320; Enemy.YPos := 0; Player.XPos := 320; Player.YPos := 477; {start out in aggression/chase mode} Chase := TRUE; . . . end; . . . procedure TfrmDXAppMain.DrawSurfaces; var SrfcDc: HDC; TempCanvas: TCanvas; EnemyOffset: Integer; begin {erase the last frame of animation} ColorFill(FBackBuffer, clBlack, nil); {if the Enter key was pressed, toggle aggression/evasion} if (GetAsyncKeyState(VK_RETURN) and $8000) = $8000 then Chase := not Chase; {move the player sprite based on the cursor keys} if (GetAsyncKeyState(VK_LEFT) and $8000) = $8000 then Player.MoveSprite(–2, 0); if (GetAsyncKeyState(VK_RIGHT) and $8000) = $8000 then Player.MoveSprite(2, 0); if (GetAsyncKeyState(VK_UP) and $8000) = $8000 then Player.MoveSprite(0, – 2); if (GetAsyncKeyState(VK_DOWN) and $8000) = $8000 then Player.MoveSprite(0, 2); {determine the appropriate movement for chasing or evading} if Chase then EnemyOffset := 1 else EnemyOffset := –1; {move the enemy accordingly} if Player.XPos > Enemy.XPos then Enemy.MoveSprite(EnemyOffset, 0); if Player.XPos < Enemy.XPos then Enemy.MoveSprite(–EnemyOffset, 0); if Player.YPos > Enemy.YPos then Enemy.MoveSprite(0, EnemyOffset); if Player.YPos < Enemy.YPos then Enemy.MoveSprite(0, –EnemyOffset); {retrieve a device context and create a canvas} FBackBuffer.GetDC(SrfcDc); TempCanvas := TCanvas.Create; try {set up the canvas} TempCanvas.Handle := SrfcDc; TempCanvas.Font.Color := clWhite; {draw the two sprites as small dots} TempCanvas.Pen.Style := psClear; TempCanvas.Brush.Style := bsSolid; TempCanvas.Brush.Color := clBlue; TempCanvas.Ellipse(Player.XPos, Player.YPos, Player.XPos+3, Player.YPos+3); TempCanvas.Brush.Color := clRed; TempCanvas.Ellipse(Enemy.XPos, Enemy.YPos, Enemy.XPos+3, Enemy.YPos+3); {indicate which state the enemy sprite is in} TempCanvas.Brush.Style := bsClear; if Chase then TempCanvas.TextOut(0, 0, ‘Chasing’) else TempCanvas.TextOut(0, 0, ‘Evading’); TempCanvas.TextOut(0, 440, ‘Press Enter to toggle state’); finally {clean up} TempCanvas.Handle := 0; FBackBuffer.ReleaseDC(SrfcDc); TempCanvas.Free; end; end; procedure TSprite.MoveSprite(XOffset, YOffset: Integer); begin {update the sprite’s position} XPos := XPos + XOffset; YPos := YPos + YOffset; {clip to the screen boundaries} if XPos < 0 then XPos := 0; if XPos > DXWIDTH – 1 then XPos := DXWIDTH – 1; if YPos < 0 then YPos := 0; if YPos > DXHEIGHT – 1 then YPos := DXHEIGHT – 1; end; We could have just as easily made the chase/evade decision based upon whether or not the player was actively moving. If the player’s sprite positioned has changed, we could have switched to evade mode; if the player hadn’t moved, we could go right to chase mode. This would certainly keep players on their toes, and in the event our enemy units could kill a player, this would certainly discourage anyone from waiting around somewhere for very long! Patterned Movement Chasing the player, running from the player, and moving around randomly can get pretty boring after a while. Typically, enemy units need to exhibit more complex movement, and one way to simulate this is through movement patterns. For example, take the old arcade game Galaxian. When the enemies appeared in each round, they flew onto the screen in a complex flight path. Although their movements were a bit predictable, it made their appearance more menacing and deliberate. We can use patterned movement in our games to model similar complex, deliberate movements and make our enemies appear to move about more intentionally. Indeed, we could create several patterns and choose one randomly (or in a more context–sensitive manner), as illustrated in Figure 12–3. Figure 12–3:  Movement patterns There are several methods by which patterned movement can be implemented based on the type of game and the sprite engine. If we had a simple, 2–D shooter, our patterns could simply be based off of a series of horizontal and vertical offsets that move the unit in the desired manner. These offsets would be relative to the current position of the sprite, so the patterns could be used anywhere within the game world. Tip: It is relatively easy to flip the movement pattern horizontally or vertically, thus increasing the flexibility of this technique. To implement this method of patterned movement, we could make an array of TPoints, filling each entry with the horizontal or vertical offset for that position within the pattern. As we move the sprite, we keep track of an index into this array of offsets, incrementing the offset at a preset time to advance to the next movement within the pattern. Once the pattern is complete, we can choose another array (or another row within a multidimensional array) and reset the index to 0, thus starting a new pattern. This technique is illustrated below. Listing 12–3: Implementing patterned movement TSprite = record XPos, YPos: Integer; CurPattern, CurPatternIdx: Integer; PatternIdxChange, CurTimer: Longint; end; TPatterns = array[0..5, 0..31] of TPoint; const {in this example, the patterns are stored as direct X and Y offsets, but any method of specifying a direction and/or offset will do} Patterns: TPatterns = ( ((x: 1; y: 0), (x: 1; y: 0), (x: 1; y: 0), (x: 0; y: 1), (x: 0; y: 1), ... ((x: –1; y: –1), (x: –1; y: –1), (x: –1; y: –1), (x: –1; y: –1), ... ((x: 1; y: 0), (x: 1; y: 0), (x: 1; y: 1), (x: 1; y: 1), (x: 0; y: 1), ... ((x: 1; y: 0), (x: 1; y: 0), (x: 1; y: 0), (x: 1; y: 0), (x: 0; y: –1), ... ((x: 1; y: 0), (x: 1; y: 0), (x: 1; y: 0), (x: 1; y: –1), (x: 0; y: –1), ... ((x: 0; y: –1), (x: 0; y: –1), (x: 0; y: –1), (x: 0; y: –1), ... var . . . Enemy: TSprite; implementation . . . procedure TfrmDXAppMain.FormActivate(Sender: TObject); begin . . . {initialize the enemy sprite} Randomize; Enemy.XPos := 320; Enemy.YPos := 240; Enemy.CurPattern := Random(6); // start at a random pattern Enemy.CurPatternIdx := 0; Enemy.PatternIdxChange := 100; // change the pattern index often Enemy.CurTimer := timeGetTime; . . . end; . . . procedure TfrmDXAppMain.DrawSurfaces; var SrfcDc: HDC; TempCanvas: TCanvas; begin {erase the last frame of animation} ColorFill(FBackBuffer, clBlack, nil); {if it is time to change the pattern index...} if timeGetTime – Enemy.CurTimer > Enemy.PatternIdxChange then begin {...move to the next step in the pattern} Enemy.CurPatternIdx := Enemy.CurPatternIdx + 1; {if we have moved the entire pattern...} if Enemy.CurPatternIdx > 31 then begin {...choose a new pattern} Enemy.CurPattern := Random(6); Enemy.CurPatternIdx := 0; end; {track for the next pattern index change} Enemy.CurTimer := timeGetTime; end; {update the enemy sprite’s position based on the current step with the pattern} Enemy.XPos := Enemy.XPos + Patterns[Enemy.CurPattern, Enemy.CurPatternIdx].X; Enemy.YPos := Enemy.YPos + Patterns[Enemy.CurPattern, Enemy.CurPatternIdx].Y; {clip the enemy to the screen boundaries} if Enemy.XPos < 0 then Enemy.XPos := 0; if Enemy.XPos > DXWIDTH – 1 then Enemy.XPos := DXWIDTH – 1; if Enemy.YPos < 0 then Enemy.YPos := 0; if Enemy.YPos > DXHEIGHT – 1 then Enemy.YPos := DXHEIGHT – 1; {retrieve a device context and create a canvas} FBackBuffer.GetDC(SrfcDc); TempCanvas := TCanvas.Create; try {set up the canvas} TempCanvas.Handle := SrfcDc; TempCanvas.Font.Color := clWhite; {draw the enemy sprite} TempCanvas.Pen.Style := psClear; TempCanvas.Brush.Style := bsSolid; TempCanvas.Brush.Color := clRed; TempCanvas.Ellipse(Enemy.XPos, Enemy.YPos, Enemy.XPos + 3, Enemy.YPos + 3); {indicate the pattern number} TempCanvas.Brush.Style := bsClear; TempCanvas.TextOut(0, 0, ‘Pattern: ’+IntToStr(Enemy.CurPattern)); finally {clean up} TempCanvas.Handle := 0; FBackBuffer.ReleaseDC(SrfcDc); TempCanvas.Free; end; end; Previous Table of Contents Next Products |  Contact Us |  About Us |  Privacy  |  Ad Info  |  Home Use of this site is subject to certain Terms & Conditions, Copyright © 1996-2000 EarthWeb Inc. All rights reserved. Reproduction whole or in part in any form or medium without express written permission of EarthWeb is prohibited. Read EarthWeb's privacy statement.

Wyszukiwarka

Podobne podstrony:
Kopia pliku Medycyna ratunkowa 12 02 14 r Arkusz1
BEKO chassis 12 7 02
11 12 02 wyklad algebra
Wyniki egzaminu z Chemii (12 02 06)
12 02
2012 12 02
12 02
Ruszyła kampania wyborcza (12 02 2010)
TI 99 12 02 T B M pl(2)

więcej podobnych podstron