You are on page 1of 64

Simple TS Gme Dsign & Cding

Simple TS Gme Dsign

& Cding
e

OpenEdition Copyright 23 by CzBab All rights reserved June 6th, 2003

CrazyBabe 2003. K-Outertainment Trang 1

Simple TS Gme Dsign & Cding

Chapter I: Introduction

Why did I write this book ?


Trong thi im hin ti, c rt nhiu bn tr hng s quan tm ca mnh vo thit k v lp trnh game, phi cng nhn mt iu rng chi game l mt s hp dn, nhng chi game mnh lm ra cn hp dn hn nhiu, cho d l mt tr chi d c. Trn nhng din n tin hc trn Internet y ry nhng topic kiu nh l Lp trnh game vi.. hay l Ai ch gip em lp trnh game nh th no, tt c u l s quan tm n mc ch Lm th no vit nn mt game ?. Nhng kin xoay quanh vn ny rt a dng, ni kh cng c m nid cng c. Vi kinh nghim v trnh hin ti, ti cng nhn mt iu l kh, nhng khng phi l qu kh nu bn bit t mc tiu va tm v tm cch tip cn n. Nu ai cng hi vng mnh vit ra game tng ng vi Quake hay l Warcraft l sn phm ca c mt tp th chuyn nghip c xy dng trong mt thi gian di - ngay lp tc th qu l vin vng, nhng nu bn h thp mc tiu xung mt cht nh l lm nhng game n gin kiu nh bn tng hay Mario, IQ hoc l nhng game cho tr em trc th khng qu kh nu bn bit lp trnh. C nhn ti dng nh nhn thc c iu ny v c c mt s thnh cng nh trong vic thit k v lp trnh game. Trong thi im ny ti ang c ngh n thi v ti quyt nh dnh mt thi gian ngn vit cun sch ny, trong cun sch ny ti trnh by mt cch y qu trnh ti thit k v vit m cho mt game RTS n gin (c lc b kh nhiu tnh nng v d nh chi mng) nhm gip cc bn hiu c phn no qu trnh zit game ti gia. Hi vng cun sch c th gip cc bn trong qu trnh thit k v vit game ca chnh mnh. Chc tt c cc bn thnh cng trong d n vit game ca mnh.

What is RTS game ?


RTS Realtime Strategy - Th loi game chin thut thi gian thc m khi u vi dng game Dune, Command & Conquer ca Westwood Studio v nhanh chng tr thnh dng CrazyBabe 2003. K-Outertainment Trang 2

Simple TS Gme Dsign & Cding game n khch trn ton th gii v c ti Vit Nam. Thi im hin ti s pht trin ca dng tr chi ny dng nh chng li, do khng c nhiu tin b vt bc nh thi im Starcraft (Blizzard Entertainment) ra i m ch xut hin nhng game lai tp vi cc th loi khc (Warcraft III l th loi Roleplay Strategy) nn dng nh dng game ny ang dn nhng bc cho cc dng game n khch khc. Nhng c nhn ti vn m c vng c th xy dng mt game RTS n vo bi cnh lch s Vit Nam v em li cho ngi chi nhiu ci tin quan trng trong cch chi (He he, ci tin quan trng nha, nhng khng ni u, lc no lm xong sni, h h).

How this book will help you


Cun sch ny ti vit li qu trnh thit k, vit m d nhin l ch thch tng i c th cho mt game RTS c thit k n gin ti a. Bn cnh ti cng a ra mt s kinh nghim c nhn c c trong qu trnh lm vic nhm gip cc bn c th hiu c phn no cng vic thit k v lp trnh game (Khng chuyn nghip). Cn cun sch ny gip g c bn th cn tu thuc vo bn, nu m bn thuc hng cao th bt ht ri hoc l bn dumb qu c chng hiu g th d nhin l n chng gip g c bn u. Ti s c gng gii thch cn k nht nhm gip cc bn c th hiu c chng trnh lm vic nh th no. Tt c nhng g cn li u ph thuc vo bn.

Readers requirements
Trong cun sch ny, ti s dng ngn ng Delphi vit chng trnh. Nhng thc t hon ton lp trnh khng h s dng n cc component v cng khng h s dng n Window API m thng qua th vin xy dng ring nn gn nh cc bn ch cn bit Object Pascal l c th hiu c m ca chng trnh lm vic nh th no, ti c gng vit m mt cch chn phng nht c th khng h ti u, ti c t thi gian w - nhm mc ch mi ngi u c th cm thy d hiu v c th chuyn sang ngn ng khc, theo tnh ton ca ti th chng trnh ny c th chuyn sang mi ngn ng lp trnh bc cao thng dng nh l VB, C, C++, C# hoc Java. V mt ho ti khng s dng nhng h thng 3D phc tp m ch thit k vi h thng 2D v sprite animation n gin, chc chn a s cc bn c th hiu c k thut th s ny. M ngun v d liu ca game c cung cp km theo y , cc bn ch cn bin dch li l c th chy c ngay lp tc.

System & Software requirements


H thng PIII 500Mhz, 64MB RAM, card mn hnh 8MB, mn hnh h tr ch phn gii 800x600x16bit mu, c card sound (Thc t ti cha chy th trn my c cu hnh yu hn nn khng r c chy c hay khng). Windows 95, 98, 98SE, NT, 2000 hoc XP. DirectX 8.1 tr ln. Bin dch bng Borland Delphi 6 hoc Borland Delphi 7. Nu cc bn cn chnh sa d liu ca game th cn thm mt trnh son tho nh (Photoshop, ACD FotoCanvas).

Misc
Ti vit cun sch ny ch yu hng n cc bn gn nh cha bit g v lp trnh game v ch c dng chia s cht kin thc t i ca bn thn, nu trong qu trnh bin tp c cht s st mong cc bn lng th, nu nh cun sch ny lm bn cm thy hng th hoc mun trao i thm vi ti cc bn c th lin lc qua a ch e-mail kimngan2508@yahoo.com (y l a ch mirror thi, ng bomb tui nha, he he) hoc qua YIM: kimngan2508.

CrazyBabe 2003. K-Outertainment Trang 3

Simple TS Gme Dsign & Cding Cun sch ny ti vit hon ton khng nhm mc ch thng mi, ton b m ngun chng trnh v cun sch ny c phn phi min ph, ti khng chp nhn mi hnh vi kinh doanh da trn tp sch v chng trnh ny. i vi chng trnh, cc bn c th tu nghi s dng, nng cp, ch cn mt record ghi ch l nng cp t chng trnh ca CrazyBabe l c. Nhng ti ngh cc bn nn vit li hon ton th hn (nu mun lm game thc s) v chng trnh ny khng c tt. Trong chng trnh, v ngi thit k hnh nh v m thanh nn ti mn tm hnh nh v m thanh trong lot game Starcraft ca nh sn xut Blizzard Entertainment (H h, chc l ch ai bt nn s khng b..kin).

CrazyBabe 2003. K-Outertainment Trang 4

Simple TS Gme Dsign & Cding

Chapter II: Game Design

Design a very simple RTS game


Nh ni trc y, ti vit cun sch ny trong mt khong thi gian ngn (Ch bn ngy c vit m v vit ti liu) nn i tng game ti s dng phi tng i n gin (Do l do hn ch thi gian v c trnh na, h h). y ti thit k mt game th loi RTS 2D nhng tnh nng rt hn ch. Ti xy dng game ny hin ti hon ton khng h tr ch multiplayer, nhng hi vng trong thi gian n ti s c thi gian nng cp game ln h tr ch ny. V ti cng loi b mt s yu t m ti cho l n gin nh l ch menu, chn bn , loi qun m nhy vo l chng trnh load mt bn mc nh v chy lun bn ny cho n khi trn chin kt thc hoc l bn.. chn w thot ra ngoi he he - tc l ti ch quan tm duy nht n ch battle ca tr chi m thi, b qua tt c cc yu t khc. Mt game RTS c bn th xoay quanh mt s yu t nh sau: c ch khai thc ti nguyn, c ch sinh sn cc n v qun, tnh nng ca cc n v qun v cch chng tn cng, kiu a hnh cng l mt yu t quan trng. Game ny ti thit k s b nh sau: Th loi chin tranh trong khng gian - Starwars lun, chin cha ? :) Khng c a hnh, loi b bt yu t phc tp cho a hnh. Ci ny cng nhm d lp trnh na. Game gm hai loi n v chnh l tu m v tu con. Tu m l trung tm m nhn vic xy dng tu con, lu gi ti nguyn Tu con th m nhn nhiu nhim v khc nhau nh l tun tiu, tn cng, khai thc Cc n v tu c cc tnh nng nh l di chuyn, tn cng, tun tiu, khai thc, xy tu con. H thng phm tt c nh (Ti b qua vic xy dng h thng menu iu khin). H thng xy dng game l 2D.

CrazyBabe 2003. K-Outertainment Trang 5

Simple TS Gme Dsign & Cding S b l nh vy, cc tnh nng khc ti ngh rng cc bn c th thm vo n gin nu nh hiu c chng trnh. Nu mun nng cp game thnh 3D ti ngh cng c th lm c. Di y l mt screen shot t game ny:

Game programming environment


Cc bn khi trao i vi nhau v lp trnh game thng trao i vi nhau v nhng vn c t nh l v bng DirectX hay OpenGL, lm th no ly mt sprite hay l v sprite y bng hiu ng nh th nothit ngh nhng th qu lt vt d nhin l khng ni n chuyn thit k cc engine 3D ln ri Trong khi lp trnh game ny, ti s dng b th vin AvenusHelper c ti thit k nhm gim ti a cc cng vic cc bn cn thc thi chi tit vi h thng nh l khi to ho, c nh v v nh bng nhng hiu ng n gin nh l add, sub, mul y cc bn ch cn ch n vic lm th no game chy c, cc unit c x l nh th no, my tnh chi ra sao, nhng s kin c x l th nom thi. Nu cn quan tm n nhng chi tit nhng l lm th no thc hin hiu ng alpha blend chng hn chng ta s bn sau - mt tp sch khc.

CrazyBabe 2003. K-Outertainment Trang 6

Simple TS Gme Dsign & Cding

Chapter III: Game Coding

Chng ny ch n gin l ti ch thch m ngun ca chng trnh. Di y l m ngun ca n v Game, l thnh phn chnh ca chng trnh. { Ti t nh ngha ny nhm ch chng trnh chy trong ch ton mn hnh hay ch ca s } {$Define FullScreen} { nh ngha ny nhm xc nh chng trnh c h tr m thanh hay khng } {$Define SoundPlaying} UNIT Game; INTERFACE { y ti khai bo cc n v m chng trnh s dng } USES Windows, MMSystem, SysUtils, Math, FireStormDLL, AvenusHelperDLL; CONST { ScrWidth x ScrHeight l hng nh ngha kch thc ca s hoc phn gii ch ton mn hnh. Ch l khi chng trnh ch ca s tc l bin dch khng c ch th FullScreen th kch thc l tu , nhng nu chng trnh chy ch ton mn hnh th kch thc phn gii ny phi c mn hnh h tr v thng l cc phn gii thng dng nh l: 640x480, 800x600, 1024x768, 1152x864, 1280x1024 CrazyBabe 2003. K-Outertainment Trang 7

Simple TS Gme Dsign & Cding } ScrWidth ScrHeight { } Caption { MaxUnit l hng s nh ngha s lng unit ln nht m chng trnh h tr x l, con s ny l tui t i nh zy ch nu m x l thc t nh th (chng trnh hon ton khng ti u) th ch cn khong 4000 chc l con P4 ca tui cng die hard lun ch khng cn phi th trn my cu hnh yu u :> } MaxUnit = 8000; { DataPath l ng dn n th mc cha d liu ca chng trnh } DataPath = 'Data\'; { ShipsSettingDir l ng dn n th mc con cha cc file d liu v cc loi tu trong game. } ShipsSettingDir = 'ShipsSetting\'; { ScrollSpeed l tc di chuyn minimap trong game, ti t n l bin s nhm mc ch c th thay i tc nhng phn ny tui cha vit, cc bn t thm vo nha. } ScrollSpeed : Word = 15; { MoveFarLeng, TooNearLeng, AroundLeng l cc hng s ch ln gii hn v d nh l gii hn ca cc tu qu gn nhau } MoveFarLeng = 10; TooNearLeng = 3; AroundLeng = 100; { ScreenUpDate l khong thi gian (phn nghn giy) m chng trnh thc thi cp nht li mn hnh. Vi gi tr 33 chng trnh cp nht khong 28-30 ln mt giy. UnitUpDate l khong thi gian m chng trnh thc hin x l cho cc n v, vi gi tr 10 th chng trnh x l cc n v trung bnh khong 70 ln mt giy. InputUpDate, MiniMapUpDate ln lt l khong thi gian chng trnh thc hin cp nht bn phm, chut v cp nht li minimap (Bn con). MoneyTime l khong thi gian chng trnh thm xin cho cc phe. } ScreenUpdate : LongWord = 33; UnitUpdate : LongWord = 10; InputUpdate : LongWord = 10; MiniMapUpdate : LongWord = 10; MoneyTime : LongWord = 120000; { DefaultMoney l s xin game cho mi phe mi ln cp pht. } DefaultMoney = 10000; { PanelSizeX, PanelSizeY l kch thc Panel th hin thng tin v n v ang c chn. MiniMapSizeX, MiniMapSizeY l kch thc bn nh hin th trn mn hnh. CrazyBabe 2003. K-Outertainment Trang 8 = 'Simple RTS Game Demo [C]CrazyBabe.2003'; = 1024; = 768;

Caption l hng xu nh ngha tn ca s ca chng trnh to ra

Simple TS Gme Dsign & Cding } PanelSizeX PanelSizeY MiniMapSizeX MiniMapSizeY { C sau khong FrameRateForFindTarget frame th chng trnh thc hin tm kim mc tiu cho cc n v ang khng c lnh. } FrameRateForFindTarget = 40; TYPE { nh ngha kiu nh s cc n v trong game. } TUnitCount = 1..MaxUnit; { nh ngha kiu to nguyn v to thc. } TRPoint = Record X,Y : Single; End; TPoint = Record X,Y : Integer; End; { nh ngha s hng n v c th xoay l 32 hng. S hng ny cng nhiu th n v xoay cng mn, nu xy dng vi 3D th khng cn n nh ngha s hng ny m ch cn lu li gc nhn ca n v. Hic, chng mt w } THeading = ( H01,H02,H03,H04, H05,H06,H07,H08, H09,H10,H11,H12, H13,H14,H15,H16, H17,H18,H19,H20, H21,H22,H23,H24, H25,H26,H27,H28, H29,H30,H31,H32); { nh ngha s kiu tu c trong game, hik, bn ba tn g cng ok } TSpaceShip = ( NoneShip, FirePlanet, SupperBattleShip, BattleCruiseAmon, BattleCruiseBaton, CooNok, Scout, Interceptor, Carrier, MiniMissile, EvelMissile, MileMissile, Burn ); { = = = = 700; 80; 200; 200;

CrazyBabe 2003. K-Outertainment Trang 9

Simple TS Gme Dsign & Cding nh ngha s lnh m unit c th thc hin trong game, do game ti thit k rt n gin nn unit mi ch c th nhn cc lnh nh l di chuyn, i tun, tn cng, chuyn dch (i n ch c th nhng tn cng ch gp trn ng) } TCommand = ( NoCmd, // //Mouse command // MouseSelection, // //Unit command // CmdMove, CmdAttack, CmdAttackP, CmdAttackT, CmdAttackM, CmdPatrol, CmdFire, CmdBurn, CmdEnd//Temporary command ); { nh ngha s phe trong game, bn phe Player1-4 dng nh du cc phe chi, cn NonePlayer dng nh du nhng unit misc nh l khi, tn la PlayerNature nh du cc vt th nh l cc hnh tinh, thin thch } TPlayer = ( NonePlayer, PlayerNature, Player1, Player2, Player3, Player4 ); { nh ngha cc kiu sng m unit s dng } TGun = ( GunMiniMissile, GunEvelMissile, GunMileMissile ); { nh ngha cc tn kiu, tn hng ly gi tr t file config. } //Defined a name of types for configuration getting types CONST HeadingName : Array[THeading] of String[5] = ( '[H01]','[H02]','[H03]','[H04]', '[H05]','[H06]','[H07]','[H08]', '[H09]','[H10]','[H11]','[H12]', '[H13]','[H14]','[H15]','[H16]', '[H17]','[H18]','[H19]','[H20]', '[H21]','[H22]','[H23]','[H24]', '[H25]','[H26]','[H27]','[H28]', '[H29]','[H30]','[H31]','[H32]'); PlayerName : Array[TPlayer] of String[8] = ( '',//NonePlayer 'NATURE', CrazyBabe 2003. K-Outertainment Trang 10

Simple TS Gme Dsign & Cding

'PLAYER01', 'PLAYER02', 'PLAYER03', 'PLAYER04' ); ShipName : Array[TSpaceShip] of String[20] = ( '',//NoneShip 'FIREPLANET', 'SUPPERBATTLESHIP', 'BATTLECRUISEAMON', 'BATTLECRUISEBATON', 'COONOK', 'SCOUT', 'INTERCEPTOR', 'CARRIER', 'MINIMISSILE', 'EVELMISSILE', 'MILEMISSILE', 'BURN' ); GunName : Array[TGun] of String[20] = ( 'MINIMISSILE', 'EVELMISSILE', 'MILEMISSILE' ); { nh ngha mt s tn ch th ly thng tin t file config. } //Constant name of script directive CONST SettingStr = 'SETTING'; ImageFilesStr = 'IMAGEFILES'; ShipFrameStr = 'SHIPFRAME'; ExplosionSkinStr = 'EXPLOSIONSKIN'; ShipGunStr = 'SHIPGUN'; ShipDamageStr = 'SHIPDAMAGE'; ShipAttackRangeStr = 'ATTACKRANGE'; ShipNameStr = 'SHIPNAME'; ShipSizeStr = 'SHIPSIZE'; ShipSpeedStr = 'SHIPSPEED'; ShipWaitStr = 'SHIPWAIT'; ShipTurnWaitStr = 'SHIPTURNWAIT'; ShipHitPointStr = 'SHIPHITPOINT'; ShipCanCreate = 'SHIPCANCREATE'; ShipCreateTime = 'SHIPCREATETIME'; ShipCost = 'SHIPCOST'; TYPE { nh ngha kiu frame animation: Mi hng c mt bn ghi ring Bn ghi ghi li s frame animation v mt mng lu chi tit thng tin v frame animation : s hiu ca frame, kiu v frame. } TFrame = Array[THeading] of Record NumFrames : Integer; Ani : Array of Record FramePos : Integer; FrameStyle : Integer; End; End; { CrazyBabe 2003. K-Outertainment Trang 11

Simple TS Gme Dsign & Cding nh ngha kiu d liu animator ca mt bin tu. y c hai trng l Move v Attack nhng tui mi dng c trng Move thui, h h } TShipAni = Record Move,Attack : TFrame; End; TYPE { nh ngha kiu d liu lu tr nhng thng tin c bn v mt kiu unit: _HitPoint: S mu mc nh ca n v. _Damage: S damage (tm dch: ch s st thng) ca n v. _AttackRange: Gii hn tn cng ca n v. _Speed: Tc ca n v. _Wait, _TurnWait: Thi gian ch di chuyn v xoay u ca n v. _Size, _Size2: Kch thc ca n v/kch thc chia hai ca n v, bin ny lu v nhiu khi dng bin ny lm, phi tnh li. _Gun: Kiu sng ca n v. _Explosion: Kiu n ca n v (Hin ti cha lm g c, gi cc bn khai bo thm vi unit kiu n ri thm n vo khi unit tiu tng ging nh l thm khi Burn khi tn la bn i vy). _NumOfImages: S lng nh ca n v. _Images: Mng lu s hiu cc nh ca n v (Do AvenusHelper qun l cc nh theo s hiu nn phi lu tr theo cch ny truy cp li) _ShipCanCreate: Tu con m unit ny c th sinh, nu l NoneShip th unit khng c kh nng sinh tu mi. _DrawLevel: cng thp th c v trc, ci ny nhm chnh li cc hnh tinh khng c v sau cc tu chng hn. _BuildTime: l thi gian sinh ra loi n v ny. _Cost: l chi ph sinh loi n v ny. } TUnitProperty = Record _HitPoint : Integer; _Damage : Integer; _AttackRange : Integer; _Speed : Integer; _Wait,_TurnWait : Integer; _Size,_Size2 : Integer; _Gun : TGun; _Explosion : TSpaceShip; _NumOfImages : Integer; _Images : Array of Integer; _ShipCanCreate : TSpaceShip; _ShipAni : TShipAni; _DrawLevel : Byte; _BuildTime : Integer; _Cost : Integer; End; { nh ngha kiu d liu lu tr thng tin v mt n v: Owner: Unit thuc phe no ? HitPoint: Mu hin ti ca n v. Pos: V tr ca n v trn bn . Vi n v l FirePlanet: Mc m, tc m v vin ca unit ny. Vi cc n v tu: Dest: ch n ca unit. CrazyBabe 2003. K-Outertainment Trang 12

Simple TS Gme Dsign & Cding PatrolStart, PatrolDest: im xut pht v kt thc ca lnh i tun (Patrol) CurrentHead, Head: Hng hin ti, hng cn xoay n. CurrentFrame: Frame nh hin ti. WaitTimeForMove: S game frame cn di chuyn. UnitCmd, UnitNextCmd: Command ca unit hin ti v command k tip. UnitTarget, UnitNextTarget: Unit ch hin ti v unit ch tip theo. UnitGroup: S hiu nhm ca unit. CreationCounting: S bc thc hin to tu mi (Khi unit thc hin lnh to

qun). } TUnit = Record Owner : TPlayer; HitPoint : Integer; Pos : TRPoint; Case Typer : TSpaceShip of FirePlanet : ( TransparentLevel : Integer; TransparentSpeed : Integer; ); SupperBattleShip, BattleCruiseAmon, BattleCruiseBaton, CooNok, Scout, Interceptor : ( Dest,PatrolStart,PatrolDest : TRPoint; CurrentHead,Head : THeading; CurrentFrame, WaitTimeForMove : Integer; UnitCmd,UnitNextCmd : TCommand; UnitTarget,UnitNextTarget : TUnitCount; UnitGroup : Byte; CreationCounting : Integer; ); End; { nh ngha kiu d liu lu thng tin cho tng player trong game: Name: D nhin l lutn roi. Money: Bi ch em ang c bao nhiu xin h ? CountUnit: Tng s unit player ny hin ang c. Enemy: nh du xem ch no l ch ? } TYPE TPlayersData = Record Name : String[20]; Money : Integer; CountUnit : Integer; Enemy : Array[TPlayer] of Boolean; End; { nh ngha kiu d liu lu thng tin v bn : Scale: Kch c zoom ca bn ny. ViewPos: V tr nhn hin ti. Size: Kch c ca bn , Size = Scale * DefaultMiniMapSize StarBackGround: nh nn, map ny c dng n gin vi ton cc nh nn ny xp xp bn cnh nhau. NumTile: S lng nh nhn thy c trn mn hnh. } TYPE CrazyBabe 2003. K-Outertainment Trang 13

Simple TS Gme Dsign & Cding

TWorld = Record Scale,ViewPos,Size : TPoint; StarBackGround : Integer; NumTile : TPoint; End; { i tng chnh: GamePlay. } TYPE TGame = Class { nh du game kt thc. } EndGame : Boolean; { nh du game ang trong ch tm dng. } PauseGame : Boolean; { D liu v nhng ngi chi trong game. } GamePlayers : Array[TPlayer] of TPlayersData; { D liu v tnh nng chun ca cc unit trong game. } UnitsProperty : Array[TSpaceShip] of TUnitProperty; { D liu v cc unit trong game. } GameUnits : Array[TUnitCount] of TUnit; { D liu v bn trong game. } GameWorld : TWorld; { D liu v lnh ang ch t thc hin (Bng chut - Ging nh khi bn ra lnh Patrol trong game Warcraft th chng trnh cn ch bn chn v tr bng chut mi thc hin lnh iu khin ny). } MouseCommand : TCommand; { V tr u v v tr cui cng ngi chi ko chut (Khi chn cc n v). } SelectStart,SelectEnd : TPoint; { Phe m ngi chi iu khin. } HumanControl : TPlayer; { To unit dch chuyn trong tng bc i. S lng hng cng nhu th unit xoay cng mn v ti s dng to ca unit kiu s thc do nu dng s nguyn th bc di chuyn ca unit s c di khng u nhau v khi chuyn ln to nguyn ca mn hnh unit s di chuyn trng git git k lm } Moving : Array[THeading,1..2] of Single; { CrazyBabe 2003. K-Outertainment Trang 14

Simple TS Gme Dsign & Cding nh lu bn nh, khi v li bn nh ti ch v li nh ny, cn vic cp nht nh dng bng mt hm khc. Hm ny ch cp nht bn sau mt khong thi gian c nh bi nu cp nht lin tc th tc c chng trnh gim thm hi v kt qu s l mt i khng tr li } MiniMapImage : Integer; { V tr bn c v trn mn hnh. } MiniMapPosX,MiniMapPosY : Integer; { Bin ny lu gi trng thi bn c c th hin hay khng, gip ngi chi c th tt th hin bn nhm tng khng gian iu khin cc unit ca h. } MiniMapVisible : Boolean; { Mu ca cc n v khi xut hin trn bn . } PlayerColor : Array[TPlayer] of LongWord; { y l cc thng tin tng t nh ca minimap nhng l ca thnh phn ti gi tm l Panel, ci ny th hin trng thi ca n v ang c la chn. } PanelImage : Integer; PanelPosX,PanelPosY : Integer; CommandPanelVisible : Boolean; { S hiu n v u tin trong nhm n v c la chn, khi chn bn c th chn tt c cc n v ca bn trong khi thanh Panel ch c th hin th thng tin v mt n v, chnh l n v ny. } FirstUnitSelect : TUnitCount; { S lng frame game chy (m theo s frame x l unit) v s lng frame hnh nh c cp nht (s hnh nh v ra). Thng tin ny dng tnh GFPS (Game Frame Per Second) v SFPS (Screen Frame Per Second). Trong chng trnh ny tui t thi gian nh trn nn SFPS t khong 28 FPS/1024x768x16bit color, s khung hnh nh th ny l chp nhn c vi game 2D (Hic, 3D m th ny chc git tung trng mt ra whix). } GameFrame,GameScreenFrame, { Thi im game bt u. Thi gian game chy. Thi im cui cng cp nht mn hnh. Thi im cui cng cp nht x l n v. Thi im cui cng cp nht x l input (keyboard, mouse). Thi im cui cng cp nht minimap. Thi im cui cng cp nht tin cho cc phe. } GameStart,GameTime, LastGameScreenTime, LastGameUnitTime, LastGameInputTime, LastGameMiniMapTime, LastGameMoneyTime : LongWord; CrazyBabe 2003. K-Outertainment Trang 15

Simple TS Gme Dsign & Cding { nh FirePlanet v qung sng bao quanh n, hix, ti ti ngi config cho kiu n v ny nn lm kiu li, h h. } GlobeImageNum,FlareImageNum : Integer; { Ln cui cng s dng loi m thanh (bn, n). y l thng tin dng hn ch vic gi mt m thanh lin tc qu nhiu ln dn n mt ti nguyn ca my tnh. ng ra vic qun l m thanh nn to lp mt class khc chuyn nghip hn nhng do t thi gian qu nn gn nh ti b qua vic x l m thanh. } LastMissileLauchSoundTime, LastMissileExploredSoundTime : LongWord; { D liu v m thanh trong game. } {$IfDef SoundPlaying} BackGroundMusic, MissileLauch, MissileExplored : Integer; {$EndIf} { Frame hin ti dng tm ch cho cc unit ? } IsFrameToFindTarget : Boolean; { Thng tin debug: Hin th FPS, hin th thng tin debug ? Tng s unit ang s dng ? } ShowFPS,ShowDebug : Boolean; UnitCounting : Integer; { Hng s nh ngha mu. } White,Green,Gray,BlueGray : LongWord; { Phng thc khi to v hu lp Game ny. } Constructor Create; Destructor Destroy; OverRide; { Hm x l xut nhp, x l cc unit, x l cc s kin v hm chnh gi khi bt u tin trnh x l mt trn. } Procedure ProcessInput; Procedure ProcessUnits; Procedure ProcessEvents; Procedure Play; { t quan h gia phe P1 v P2 l i ch. Cc n v s ch tm v tn cng cc n v thuc phe i ch m thi (D nhin !) } Procedure SetPlayerEnemy(P1,P2 : TPlayer); { Cu hnh cho phe Player: Tn phe, s tin c sn. CrazyBabe 2003. K-Outertainment Trang 16

Simple TS Gme Dsign & Cding } Procedure SetupPlayer(Player : TPlayer;Name : String;Money : Integer); { Thm tin cho tt c cc phe, hm ny gi khi chng trnh pht s kin cp nht ti nguyn cho cc phe. Trong game ny n gin ho vic x l ti b qua vic khai thc ti nguyn, sau mt khong thi gian xc nh game s cung cp cho mi phe mt s tin xc nh. } Procedure AddMoneyForAllPlayer; { Khi to li tt c cc bin m thi gian, m frame } Procedure RestartCount; { c cc cu hnh ca cc loi n v trong game (t file text). } Procedure LoadSetting; { To mt thng ip n ngi chi. } Procedure CreateMessage(Msg : String); { Hm x l cc s kin chut c nhn, th, iu khin t ngi chi } Procedure ProceedMouseLHolding; Procedure ProceedMouseRHolding; Procedure ProceedMouseLReleased; Procedure ProceedMouseRReleased; Procedure ProceedPlayerInput; { Ngi chi t lnh dng cho tt c cc n v h ang chn. } Procedure HumanSetCommandStop; { Ngi chi t lnh sinh qun cho tt c cc n v h ang chn. V mi n v ch c th sinh ra mt loi qun nht nh nn khng cn bit yu cu l sinh n v g. } Procedure HumanSetCommandCreate; { Ngi chi t lnh cho nhm qun ang chn di chuyn n ta [X,Y] trn map. } Procedure HumanSetCommandMove(X,Y : Integer); { Ngi chi t lnh cho nhm qun ang chn tn cng unit s hiu Target. } Procedure HumanSetCommandAttack(Target : TUnitCount); { Ngi chi t lnh cho nhm qun ang chn tn cng n v tr [X,Y] trn map, trong qu trnh di chuyn unit s tn cng bt c mc tiu no n gp mt. } Procedure HumanSetCommandAttackTo(X,Y : Integer); { Ngi chi t lnh cho nhm qun ang chn i tun n v tr [X,Y] trn map, trong qu trnh di chuyn unit s tn cng bt c mc tiu no n nhn thy. } Procedure HumanSetCommandPatrol(X,Y : Integer); CrazyBabe 2003. K-Outertainment Trang 17

Simple TS Gme Dsign & Cding { } { Cu hnh kch thc bn , kch thc bn bng: [ScaleSizeX * MiniMapSizeX , ScaleSizeY * MiniMapSizeY] } Procedure SetupWorldSize(ScaleSizeX,ScaleSizeY : Integer); { } { t v tr nhn trn bn [ViewX , ViewY] Procedure WorldViewAt(ViewX,ViewY : Integer); c bn t file, ci ny tuicha lm, mi ch t mt bn linh tinh v my unit test thi, ti ngh ci ny cc bn c th t lm c mt cch d dng. } Procedure LoadWorld(FileName : String); { Cp nht MiniMap } Procedure WorldMiniMapUpdate; { c cu hnh ca unit t file. } Procedure SetupUnitsSetting; { Cu hnh hnh nh ca cc unit khng c cu hnh bng file (FirePlanet). } Procedure SetupUnitsImage; { Ly cu hnh unit t file, tn v cc cu hnh ca unit c trong file cu hnh. } Procedure ProceedUnitSettingFile(FileName : String); { To mt unit UnitTyper mi ca Player v tr [PosX , PosY], hm tr v s hiu ca unit nu to lp thnh cng, cn nu khng cn v tr trng s dng cho unit ny th hm tr v Low(TunitCount) nh vy n v s hiu ny khng bao gi c s dng. } Function CreateNewUnit(UnitTyper : TSpaceShip; Player : TPlayer; PosX,PosY : Integer) : TUnitCount; { Hu unit s hiu UnitNum. } Function DestroyUnit(UnitNum : TUnitCount) : Boolean; { Khi to d liu chun ca kiu UnitTyper cho unit s hiu UnitNum. } Procedure SetupUnit(UnitNum : TUnitCount; UnitTyper : TSpaceShip; Player : TPlayer); { Thanh ton xin khi sinh unit mi, nu Player khng cn ti nguyn, hm tr v False cn nu s tr i s ti nguyn tng ng v tr v gi tr True. CrazyBabe 2003. K-Outertainment Trang 18 Cu hnh nh World (H, thc cht ch l load nh nn lin quan n WorldMap thi). Procedure SetupWorldImage;

Simple TS Gme Dsign & Cding } Function { } Procedure SelectUnit(UnitNum : TUnitCount); { } { B chn tt c cc unit. Procedure UnSelectAllUnit; Ly unit trn cng c chn t to [MX,MY]. Tham s HumanOwner ch n v c chn ch c php thuc nhm unit ca ngi chi. Hm tr v s hiu ca unit tm thy, cn nu khng thy s tr v gi tr Low(TunitCount). } Function GetUnitAtMouse(MX,MY : Integer; HumanOwner : Boolean) : TUnitCount; { Hm chn cc unit bng chut, tham s Add cho bit c thm unit vo nhm ang chn hay xo b tt c v chn li t u. } Procedure CallMouseSelectionUnit(Add : Boolean); { Hm ny cho bit unit cn xoay v hng no n c ch ca n. y ch n gin l xoay v hng c to thng nht. } Function UnitGetBestHeading(UnitNum : TUnitCount) : THeading; { Khong cc gia unit v ch nh hn Long ? } Function UnitCloseToTarget(UnitNum : TUnitCount; Long : Integer) : Boolean; { Chnh hng unit v pha ch ca n. } Procedure UnitPointToTarget(UnitNum : TUnitCount); { t lnh cho unit bn vo ch. Khi gi lnh ny, unit s sinh loi Missile tng ng nhm n ch ca n. } Procedure UnitFire(UnitNum : TUnitCount); { Tnh thit hi khi unit chm ch (y l dnh cho cc unit loi Missile). } Procedure UnitHit(UnitNum : TUnitCount); { Gim mu ca unit i Damage n v. } Procedure UnitDecHitPoint(UnitNum : TUnitCount;Damage : Integer); { Unit c trong tm nhn khng ? } Function UnitVisible(UnitNum : TUnitCount) : Boolean; { CrazyBabe 2003. K-Outertainment Trang 19 CostForNewUnit(Player : TPlayer; UnitTyper : TSpaceShip) : Boolean;

t unit s hiu UnitNum c a vo nhm chn.

Simple TS Gme Dsign & Cding Hng cnh StartHead gn vi EndHead nht. } Function { } Procedure PointNear(X,Y,Leng : Integer;Var DX,DY : Integer); { } { Sinh mt s hiu phe bt k. } Function { RandomPlayer : TPlayer; Ly lnh k tip cho unit: Khi ngi chi t lnh cho unit m unit ang thc thi mt lnh khc, lnh t vo UnitNextCmd v hm ny thc hin kim tra UnitNextCmd chuyn lnh ca unit sang lnh mi. } Function UnitGetNextCmd(UnitNum : TUnitCount) : Boolean; { Chuyn lnh ca unit v lnh trc n ang nhn ( Nu unit ang nhn lnh AttackPatrol th lnh trc l Patrol, nu unit ang nhn lnh AttackMove th lnh trc l AttackTo). } Procedure UnitResetCommand(UnitNum : TUnitCount); { t lnh to qun cho unit. } Procedure UnitSetCreate(UnitNum : TUnitCount); { t lnh cho unit di chuyn n v tr [DestX,DestY]. } Procedure UnitSetMove(UnitNum : TUnitCount;DestX,DestY : Integer); { t lnh cho unit i tun n v tr [DestX,DestY]. } Procedure UnitSetPatrol(UnitNum : TUnitCount;DestX,DestY : Integer); { t lnh cho unit tn cng n v tr [DestX,DestY]. } Procedure UnitSetAttackTo(UnitNum : TUnitCount;DestX,DestY : Integer); { t lnh cho unit tn cng Target. } Procedure UnitSetAttack(UnitNum : TUnitCount;Target : Integer); { t lnh cho unit ang trong trng thi i tun tn cng unit Target. } Procedure UnitSetAttackPatrol(UnitNum : TUnitCount;Target : Integer); { t lnh cho unit ang trong trng thi di chuyn tn cng unit Target. } Procedure UnitSetAttackMove(UnitNum : TUnitCount;Target : Integer); CrazyBabe 2003. K-Outertainment Trang 20 di t [X1,Y1] n [X2,Y2]. Function Long(X1,Y1,X2,Y2 : Single) : Single; HeadNear(StartHead,EndHead : THeading) : THeading; Ly mt im bt k trong khong cch Leng n to [X,Y]

Simple TS Gme Dsign & Cding { } { } { } Procedure ProcessSpecifyUnit(UnitNum : TUnitCount); { } { } { } Procedure ProceedUnitMove(UnitNum : TUnitCount); { } { } { } Procedure ProceedUnitAttackT(UnitNum : TUnitCount); { } { } { } Procedure ProceedUnitBurning(UnitNum : TUnitCount); { } { } V unit UnitNum. V nn bn . Procedure RenderWorld; X l unit ang nhn lnh Patrol. Procedure ProceedUnitPatrol(UnitNum : TUnitCount); X l unit ang nhn lnh Burn. X l unit ang nhn lnh AttackM (Attack while move to somewhere). Procedure ProceedUnitAttackM(UnitNum : TUnitCount); X l unit ang nhn lnh AttackP (Attack while patrol). Procedure ProceedUnitAttackP(UnitNum : TUnitCount); X l unit ang nhn lnh AttackT (Attack to somewhere). X l unit ang nhn lnh Attack. Procedure ProceedUnitAttack(UnitNum : TUnitCount); X l unit ang khng c lnh. Procedure ProceedUnitStand(UnitNum : TUnitCount); X l unit ang nhn lnh Move. X l cc unit bnh thng. Procedure ProcessNormalUnit(UnitNum : TUnitCount); Tm unit gn UnitNum, hm ny xy dng x dng khi dn i hnh ra. Function UnitFindNear(UnitNum : TUnitCount) : TUnitCount; Unit tm i phng trong tm tn cng (Tm i phng gn nht). Function UnitFindTarget(UnitNum : TUnitCount) : TUnitCount;

X l cc unit c bit (FirePlanet).

CrazyBabe 2003. K-Outertainment Trang 21

Simple TS Gme Dsign & Cding

Procedure RenderUnits(UnitNum : TUnitCount); OverLoad; { } Procedure RenderUnits; OverLoad; { } { } { } Function { } { } { } Function End; GetGun(Name : String) : TGun; Ly hng bng tn. Function GetHeading(Name : String) : THeading; Ly s hiu phe bng tn. Function GetPlayer(Name : String) : TPlayer; GetShipTyper(Name : String) : TSpaceShip; V ton b. Procedure RenderScene; Ly loi tu bng tn. V cc MiniMap, Panel, cc thng tin khc Procedure RenderInfos; V tt c cc unit.

Ly loi sng bng tn.

VAR MyGame : TGame; IMPLEMENTATION USES CommonFuncs; CONSTRUCTOR TGame.Create; Begin //Moving generating Moving[H01,1]:=+0; Moving[H01,2]:=-1; Moving[H02,1]:=+Abs(Sin(DegToRad(90/8*1))); Moving[H02,2]:=-Abs(Cos(DegToRad(90/8*1))); Moving[H03,1]:=+Abs(Sin(DegToRad(90/8*2))); Moving[H03,2]:=-Abs(Cos(DegToRad(90/8*2))); Moving[H04,1]:=+Abs(Sin(DegToRad(90/8*3))); Moving[H04,2]:=-Abs(Cos(DegToRad(90/8*3))); Moving[H05,1]:=+Abs(Sin(DegToRad(90/8*4))); Moving[H05,2]:=-Abs(Cos(DegToRad(90/8*4))); Moving[H06,1]:=+Abs(Sin(DegToRad(90/8*5))); Moving[H06,2]:=-Abs(Cos(DegToRad(90/8*5))); Moving[H07,1]:=+Abs(Sin(DegToRad(90/8*6))); Moving[H07,2]:=-Abs(Cos(DegToRad(90/8*6))); Moving[H08,1]:=+Abs(Sin(DegToRad(90/8*7))); Moving[H08,2]:=-Abs(Cos(DegToRad(90/8*7))); Moving[H09,1]:=+1; Moving[H09,2]:=+0; Moving[H10,1]:=+Abs(Sin(DegToRad(90/8*7))); CrazyBabe 2003. K-Outertainment Trang 22

Simple TS Gme Dsign & Cding

Moving[H10,2]:=+Abs(Cos(DegToRad(90/8*7))); Moving[H11,1]:=+Abs(Sin(DegToRad(90/8*6))); Moving[H11,2]:=+Abs(Cos(DegToRad(90/8*6))); Moving[H12,1]:=+Abs(Sin(DegToRad(90/8*5))); Moving[H12,2]:=+Abs(Cos(DegToRad(90/8*5))); Moving[H13,1]:=+Abs(Sin(DegToRad(90/8*4))); Moving[H13,2]:=+Abs(Cos(DegToRad(90/8*4))); Moving[H14,1]:=+Abs(Sin(DegToRad(90/8*3))); Moving[H14,2]:=+Abs(Cos(DegToRad(90/8*3))); Moving[H15,1]:=+Abs(Sin(DegToRad(90/8*2))); Moving[H15,2]:=+Abs(Cos(DegToRad(90/8*2))); Moving[H16,1]:=+Abs(Sin(DegToRad(90/8*1))); Moving[H16,2]:=+Abs(Cos(DegToRad(90/8*1))); Moving[H17,1]:=+0; Moving[H17,2]:=+1; Moving[H18,1]:=-Abs(Sin(DegToRad(90/8*1))); Moving[H18,2]:=+Abs(Cos(DegToRad(90/8*1))); Moving[H19,1]:=-Abs(Sin(DegToRad(90/8*2))); Moving[H19,2]:=+Abs(Cos(DegToRad(90/8*2))); Moving[H20,1]:=-Abs(Sin(DegToRad(90/8*3))); Moving[H20,2]:=+Abs(Cos(DegToRad(90/8*3))); Moving[H21,1]:=-Abs(Sin(DegToRad(90/8*4))); Moving[H21,2]:=+Abs(Cos(DegToRad(90/8*4))); Moving[H22,1]:=-Abs(Sin(DegToRad(90/8*5))); Moving[H22,2]:=+Abs(Cos(DegToRad(90/8*5))); Moving[H23,1]:=-Abs(Sin(DegToRad(90/8*6))); Moving[H23,2]:=+Abs(Cos(DegToRad(90/8*6))); Moving[H24,1]:=-Abs(Sin(DegToRad(90/8*7))); Moving[H24,2]:=+Abs(Cos(DegToRad(90/8*7))); Moving[H25,1]:=-1; Moving[H25,2]:=+0; Moving[H26,1]:=-Abs(Sin(DegToRad(90/8*7))); Moving[H26,2]:=-Abs(Cos(DegToRad(90/8*7))); Moving[H27,1]:=-Abs(Sin(DegToRad(90/8*6))); Moving[H27,2]:=-Abs(Cos(DegToRad(90/8*6))); Moving[H28,1]:=-Abs(Sin(DegToRad(90/8*5))); Moving[H28,2]:=-Abs(Cos(DegToRad(90/8*5))); Moving[H29,1]:=-Abs(Sin(DegToRad(90/8*4))); Moving[H29,2]:=-Abs(Cos(DegToRad(90/8*4))); Moving[H30,1]:=-Abs(Sin(DegToRad(90/8*3))); Moving[H30,2]:=-Abs(Cos(DegToRad(90/8*3))); Moving[H31,1]:=-Abs(Sin(DegToRad(90/8*2))); Moving[H31,2]:=-Abs(Cos(DegToRad(90/8*2))); Moving[H32,1]:=-Abs(Sin(DegToRad(90/8*1))); Moving[H32,2]:=-Abs(Cos(DegToRad(90/8*1))); //Debug and condition setting EndGame:=False; PauseGame:=False; ShowFPS:=False; ShowDebug:=False; UnitCounting:=0; FirstUnitSelect:=Low(TUnitCount); // {$IfDef FullScreen} CreateFullScreen(ScrWidth,ScrHeight,BD16Bit,Caption); {$Else} CreateWindow(ScrWidth,ScrHeight,Caption); {$EndIf} LoadFont(DataPath+'Font.png',16,20,8,16,$0); SetScreenBPP(32); //Mini map setting MiniMapVisible:=True; MiniMapImage:=CreateImage(MiniMapSizeX,MiniMapSizeY,FormatA1R5G5B5); MiniMapPosX:=ScrWidth-MiniMapSizeX-10; CrazyBabe 2003. K-Outertainment Trang 23

Simple TS Gme Dsign & Cding

MiniMapPosY:=10; //Panel setting CommandPanelVisible:=True; PanelImage:=CreateImage(PanelSizeX,PanelSizeY,FormatA1R5G5B5); PanelPosX:=10; PanelPosY:=ScrHeight-PanelSizeY-10; // SetupWorldImage; SetupUnitsImage; LoadSetting; //Colour setup White:=RGB2LongWord(255,255,255); Green:=RGB2LongWord(000,255,000); Gray:=RGB2LongWord(40,40,40); BlueGray:=RGB2LongWord(100,100,165); //Player color setting PlayerColor[PlayerNature]:=RGB2LongWord(255,255,255);//White PlayerColor[Player1]:=Color32To15(RGB2LongWord(255,000,000));//Red PlayerColor[Player2]:=Color32To15(RGB2LongWord(000,255,000));//Green PlayerColor[Player3]:=Color32To15(RGB2LongWord(000,000,255));//Blue PlayerColor[Player4]:=Color32To15(RGB2LongWord(255,255,128));//Yellow // //Sound setting // {$IfDef SoundPlaying} BackGroundMusic:=CreateSound(DataPath+'Sounds\BackGround.Mp3',False); MissileLauch:=CreateSound(DataPath+'Sounds\MissileLauch.Wav',False); MissileExplored:=CreateSound(DataPath+'Sounds\MissileExplored.Wav',False); {$EndIf} End; DESTRUCTOR TGame.Destroy; Begin DestroyScreen; End; PROCEDURE TGame.ProceedMouseLHolding; Begin If MouseCommand=MouseSelection then Begin SelectEnd.X:=MouseX; SelectEnd.Y:=MouseY; End Else Begin //Click on command panel ? If CommandPanelVisible then Begin End; //Click on mini map ? If MiniMapVisible then Begin If (MouseX>=MiniMapPosX) and (MouseX<=MiniMapPosX+MiniMapSizeX) and (MouseY>=MiniMapPosY) and (MouseY<=MiniMapPosY+MiniMapSizeY) then Begin WorldViewAt((MouseX-MiniMapPosX)*GameWorld.Scale.X, (MouseY-MiniMapPosY)*GameWorld.Scale.Y); Exit; End; End; If MouseCommand=NoCmd then CrazyBabe 2003. K-Outertainment Trang 24

Simple TS Gme Dsign & Cding

Begin MouseCommand:=MouseSelection; SelectStart.X:=MouseX; SelectStart.Y:=MouseY; SelectEnd.X:=MouseX; SelectEnd.Y:=MouseY; End; End; End; PROCEDURE TGame.ProceedMouseRHolding; Begin End; PROCEDURE TGame.ProceedMouseLReleased; Var UnitNum : TUnitCount; OnMiniMap : Boolean; X,Y : Integer; Begin OnMiniMap:=False; X:=0;Y:=0; If MiniMapVisible then Begin If (MouseX>=MiniMapPosX) and (MouseX<=MiniMapPosX+MiniMapSizeX) and (MouseY>=MiniMapPosY) and (MouseY<=MiniMapPosY+MiniMapSizeY) then Begin OnMiniMap:=True; X:=(MouseX-MiniMapPosX)*GameWorld.Scale.X; Y:=(MouseY-MiniMapPosY)*GameWorld.Scale.Y; End End; Case MouseCommand of MouseSelection : Begin CallMouseSelectionUnit(KeyDown(Key_LShift) or KeyDown(Key_LControl)); End; CmdAttack : Begin If OnMiniMap then Begin HumanSetCommandAttackTo(X,Y); End Else Begin UnitNum:=GetUnitAtMouse(MouseX,MouseY,False); If UnitNum=Low(TUnitCount) then Begin HumanSetCommandAttackTo(MouseX+GameWorld.ViewPos.X, MouseY+GameWorld.ViewPos.Y); End Else Begin HumanSetCommandAttack(UnitNum); End; End; End; CmdPatrol : Begin If OnMiniMap then Begin HumanSetCommandPatrol(X,Y); CrazyBabe 2003. K-Outertainment Trang 25

Simple TS Gme Dsign & Cding

End Else Begin HumanSetCommandPatrol(MouseX+GameWorld.ViewPos.X, MouseY+GameWorld.ViewPos.Y); End; End; End; MouseCommand:=NoCmd; End; PROCEDURE TGame.ProceedMouseRReleased; Var UnitNum : TUnitCount; Begin If MouseCommand=NoCmd then Begin //Click on mini map ? If MiniMapVisible then Begin If (MouseX>=MiniMapPosX) and (MouseX<=MiniMapPosX+MiniMapSizeX) and (MouseY>=MiniMapPosY) and (MouseY<=MiniMapPosY+MiniMapSizeY) then Begin HumanSetCommandMove((MouseX-MiniMapPosX)*GameWorld.Scale.X, (MouseY-MiniMapPosY)*GameWorld.Scale.Y); Exit; End; End; //Other wise UnitNum:=GetUnitAtMouse(MouseX,MouseY,False); If UnitNum=Low(TUnitCount) then Begin HumanSetCommandMove(MouseX+GameWorld.ViewPos.X, MouseY+GameWorld.ViewPos.Y); End Else Begin If GameUnits[UnitNum].Owner=HumanControl then Begin HumanSetCommandMove(MouseX+GameWorld.ViewPos.X, MouseY+GameWorld.ViewPos.Y); End Else Begin HumanSetCommandAttack(UnitNum); End; End; End Else Begin //Clear waiting command MouseCommand:=NoCmd; End; End; PROCEDURE TGame.ProceedPlayerInput; Begin //LeftAlt+X ? If KeyDown(Key_LAlt) and KeyPress(Key_X) then EndGame:=True; //Arrow key: Take map view scroll If KeyDown(Key_Up) then WorldViewAt(Round(GameWorld.ViewPos.X), CrazyBabe 2003. K-Outertainment Trang 26

Simple TS Gme Dsign & Cding

Round(GameWorld.ViewPos.Y)-ScrollSpeed); If KeyDown(Key_Down) then WorldViewAt(Round(GameWorld.ViewPos.X), Round(GameWorld.ViewPos.Y)+ScrollSpeed); If KeyDown(Key_Left) then WorldViewAt(Round(GameWorld.ViewPos.X)-ScrollSpeed, Round(GameWorld.ViewPos.Y)); If KeyDown(Key_Right) then WorldViewAt(Round(GameWorld.ViewPos.X)+ScrollSpeed, Round(GameWorld.ViewPos.Y)); //Static HotKey If KeyPress(Key_A) then MouseCommand:=CmdAttack; If KeyPress(Key_P) then MouseCommand:=CmdPatrol; If KeyPress(Key_S) then HumanSetCommandStop; If KeyPress(Key_C) then HumanSetCommandCreate; If KeyPress(Key_Space) then PauseGame:=Not PauseGame; //Mouse release If MouseReleasedL then ProceedMouseLReleased; If MouseReleasedR then ProceedMouseRReleased; //Toggle mini map visible If KeyPress(Key_Capslock) then MiniMapVisible:=Not MiniMapVisible; //Toggle command panel visible If KeyPress(Key_Tab) then CommandPanelVisible:=Not CommandPanelVisible; //Debug control Left Ctrl+P If KeyDown(Key_LControl) and KeyPress(Key_P) then ShowFPS:=Not ShowFPS; If KeyDown(Key_LControl) and KeyPress(Key_D) then ShowDebug:=Not ShowDebug; End; PROCEDURE TGame.ProcessInput; Begin If GameTime-LastGameInputTime>InputUpdate then LastGameInputTime:=GameTime Else Exit; GetInputStatus; If EventMessage=False then EndGame:=True; If MouseHoldL then ProceedMouseLHolding Else If MouseHoldR then ProceedMouseRHolding Else ProceedPlayerInput; End; PROCEDURE TGame.ProcessUnits; Var Z : TUnitCount; Begin If Not PauseGame then Begin If GameTime-LastGameUnitTime>UnitUpdate then Begin Inc(GameFrame); LastGameUnitTime:=GameTime; End Else Exit; CrazyBabe 2003. K-Outertainment Trang 27

Simple TS Gme Dsign & Cding

For Z:=Low(TUnitCount) to High(TUnitCount) do With GameUnits[Z] do If HitPoint>0 then Begin Case Typer of FirePlanet : Begin TransparentLevel:=TransparentLevel+TransparentSpeed; If TransparentLevel<64 then Begin TransparentLevel:=64; TransparentSpeed:=-TransparentSpeed; End; If TransparentLevel>255 then Begin TransparentLevel:=255; TransparentSpeed:=-TransparentSpeed; End; End Else ProcessNormalUnit(Z); End; End; End; End; PROCEDURE TGame.ProcessEvents; Begin //Update mini map If GameTime-LastGameMiniMapTime>MiniMapUpdate then Begin LastGameMiniMapTime:=GameTime; WorldMiniMapUpdate; End; //Update money If GameTime-LastGameMoneyTime>MoneyTime then Begin LastGameMoneyTime:=GameTime; AddMoneyForAllPlayer; End; IsFrameToFindTarget:=GameFrame mod FrameRateForFindTarget=0; GameTime:=MMSystem.TimeGetTime; End; PROCEDURE TGame.Play; Begin LoadWorld('Demo.World'); RestartCount; {$IfDef SoundPlaying} SoundPlay(BackGroundMusic); {$EndIf} Repeat ProcessInput; ProcessUnits; ProcessEvents; RenderScene; Until EndGame; End; PROCEDURE TGame.HumanSetCommandStop; Var Z : TUnitCount; Begin For Z:=Low(TUnitCount) to CrazyBabe 2003. K-Outertainment Trang 28

Simple TS Gme Dsign & Cding

High(TUnitCount) do //Unit is owner If (GameUnits[Z].Owner=HumanControl) and //Unit alive (GameUnits[Z].HitPoint>0) and //Unit selected (GameUnits[Z].UnitGroup and 128=128) then Begin //Set command moving ! UnitResetCommand(Z); End; End; PROCEDURE TGame.HumanSetCommandCreate; Var Z : TUnitCount; Begin For Z:=Low(TUnitCount) to High(TUnitCount) do //Unit is owner If (GameUnits[Z].Owner=HumanControl) and //Unit alive (GameUnits[Z].HitPoint>0) and //Unit selected (GameUnits[Z].UnitGroup and 128=128) then Begin //Set command moving ! UnitSetCreate(Z); End; End; PROCEDURE TGame.HumanSetCommandMove(X,Y : Integer); Var Z : TUnitCount; Begin For Z:=Low(TUnitCount) to High(TUnitCount) do //Unit is owner If (GameUnits[Z].Owner=HumanControl) and //Unit alive (GameUnits[Z].HitPoint>0) and //Unit selected (GameUnits[Z].UnitGroup and 128=128) then Begin //Set command moving ! UnitSetMove(Z,X+Random(AroundLeng)-AroundLeng ShR 1, Y+Random(AroundLeng)-AroundLeng ShR 1); End; End; PROCEDURE TGame.HumanSetCommandAttack(Target : TUnitCount); Var Z : TUnitCount; Begin For Z:=Low(TUnitCount) to High(TUnitCount) do //Unit is owner If (GameUnits[Z].Owner=HumanControl) and //Unit alive (GameUnits[Z].HitPoint>0) and //Unit selected (GameUnits[Z].UnitGroup and 128=128) then Begin //Set command attack ! UnitSetAttack(Z,Target); End; End; CrazyBabe 2003. K-Outertainment Trang 29

Simple TS Gme Dsign & Cding

PROCEDURE TGame.HumanSetCommandAttackTo(X,Y : Integer); Var Z : TUnitCount; Begin For Z:=Low(TUnitCount) to High(TUnitCount) do //Unit is owner If (GameUnits[Z].Owner=HumanControl) and //Unit alive (GameUnits[Z].HitPoint>0) and //Unit selected (GameUnits[Z].UnitGroup and 128=128) then Begin //Set command attack to point ! UnitSetAttackTo(Z,X+Random(AroundLeng)-AroundLeng ShR 1, Y+Random(AroundLeng)-AroundLeng ShR 1); End; End; PROCEDURE TGame.HumanSetCommandPatrol(X,Y : Integer); Var Z : TUnitCount; Begin For Z:=Low(TUnitCount) to High(TUnitCount) do //Unit is owner If (GameUnits[Z].Owner=HumanControl) and //Unit alive (GameUnits[Z].HitPoint>0) and //Unit selected (GameUnits[Z].UnitGroup and 128=128) then Begin //Set command patrol ! UnitSetPatrol(Z,X+Random(AroundLeng)-AroundLeng ShR 1, Y+Random(AroundLeng)-AroundLeng ShR 1); End; End; PROCEDURE TGame.SetPlayerEnemy(P1,P2 : TPlayer); Begin GamePlayers[P1].Enemy[P2]:=True; GamePlayers[P2].Enemy[P1]:=True; End; PROCEDURE TGame.SetupPlayer(Player : TPlayer;Name : String;Money : Integer); Begin GamePlayers[Player].Name:=Name; GamePlayers[Player].Money:=Money; GamePlayers[Player].CountUnit:=0; End; PROCEDURE TGame.AddMoneyForAllPlayer; Var Player : TPlayer; Begin For Player:=Low(TPlayer) to High(TPlayer) do GamePlayers[Player].Money:=DefaultMoney; End; PROCEDURE TGame.RestartCount; Begin GameStart:=MMSystem.TimeGetTime; LastGameScreenTime:=GameStart; LastGameUnitTime:=GameStart; LastGameInputTime:=GameStart; CrazyBabe 2003. K-Outertainment Trang 30

Simple TS Gme Dsign & Cding

LastGameMoneyTime:=GameStart; GameFrame:=0; GameScreenFrame:=0; End; PROCEDURE TGame.LoadSetting; Begin SetupUnitsSetting; With UnitsProperty[FirePlanet] do Begin _HitPoint:=1; End; End; PROCEDURE TGame.CreateMessage(Msg : String); Begin End; PROCEDURE TGame.SetupWorldImage; Begin With GameWorld do Begin StarBackGround:=LoadImage(DataPath+'Stars.Jpg',FormatR5G6B5); End; End; PROCEDURE TGame.SetupWorldSize(ScaleSizeX,ScaleSizeY : Integer); Begin With GameWorld do Begin //Scale out of range ? If ScaleSizeX>High(Integer) div MiniMapSizeX then ScaleSizeX:=High(Integer) div MiniMapSizeX; If ScaleSizeY>High(Integer) div MiniMapSizeY then ScaleSizeY:=High(Integer) div MiniMapSizeY; Scale.X:=ScaleSizeX; Scale.Y:=ScaleSizeY; Size.X:=Scale.X*MiniMapSizeX; Size.Y:=Scale.Y*MiniMapSizeY; NumTile.X:=ScrWidth div GetImageWidth(StarBackGround)+1; NumTile.Y:=ScrHeight div GetImageHeight(StarBackGround)+1; End; End; PROCEDURE TGame.WorldViewAt(ViewX,ViewY : Integer); Begin //Cal map view If ViewX<0 then ViewX:=0; If ViewY<0 then ViewY:=0; If ViewX+ScrWidth>GameWorld.Size.X then ViewX:=GameWorld.Size.X-ScrWidth; If ViewY+ScrHeight>GameWorld.Size.Y then ViewY:=GameWorld.Size.Y-ScrHeight; GameWorld.ViewPos.X:=ViewX; GameWorld.ViewPos.Y:=ViewY; End; PROCEDURE TGame.LoadWorld(FileName : String); Var Z : Integer; P : TPlayer; Begin For P:=Low(TPlayer) to High(TPlayer) do Begin CrazyBabe 2003. K-Outertainment Trang 31

Simple TS Gme Dsign & Cding

FillChar(GamePlayers[P].Enemy, SizeOf(GamePlayers[P].Enemy),True); GamePlayers[P].Enemy[P]:=False; GamePlayers[P].Enemy[NonePlayer]:=False; GamePlayers[P].Enemy[PlayerNature]:=False; End; HumanControl:=Player1; SetupPlayer(Player1,'',DefaultMoney*3); SetupPlayer(Player2,'',DefaultMoney*3); SetupPlayer(Player3,'',DefaultMoney*3); SetupPlayer(Player4,'',DefaultMoney*3); SetupPlayer(HumanControl,'',DefaultMoney); //Creating a map size 16000x16000 pixel SetupWorldSize(80,80); Randomize; CreateNewUnit(FirePlanet,PlayerNature, Random(GameWorld.Size.X),Random(GameWorld.Size.Y)); CreateNewUnit(FirePlanet,PlayerNature, Random(GameWorld.Size.X),Random(GameWorld.Size.Y)); CreateNewUnit(FirePlanet,PlayerNature, Random(GameWorld.Size.X),Random(GameWorld.Size.Y)); CreateNewUnit(FirePlanet,PlayerNature, Random(GameWorld.Size.X),Random(GameWorld.Size.Y)); CreateNewUnit(FirePlanet,PlayerNature, Random(GameWorld.Size.X),Random(GameWorld.Size.Y)); CreateNewUnit(FirePlanet,PlayerNature, Random(GameWorld.Size.X),Random(GameWorld.Size.Y)); For Z:=1 to 3 do Begin CreateNewUnit(Carrier ,Player1,Random(1000),Random(1000)); CreateNewUnit(BattleCruiseAmon ,Player1,Random(1000),Random(1000)); CreateNewUnit(BattleCruiseBaton,Player1,Random(1000),Random(1000)); End; For Z:=1 to 100 do CreateNewUnit(BattleCruiseBaton,Player2,14000+Z*40,14000+Z*40); WorldViewAt(100,100); End; PROCEDURE TGame.WorldMiniMapUpdate; Var X,Y : Integer; Z : TUnitCount; Begin ImageLock(MiniMapImage); ImageClear(MiniMapImage,0); For Z:=Low(TUnitCount) to High(TUnitCount) do With GameUnits[Z] do If (HitPoint>0) and (Owner<>NonePlayer) then Begin X:=Round(Pos.X) div GameWorld.Scale.X; Y:=Round(Pos.Y) div GameWorld.Scale.Y; ImageFillRect(MiniMapImage,X-1,Y-1,X+1,Y+1,PlayerColor[Owner]); End; X:=GameWorld.ViewPos.X div GameWorld.Scale.X; Y:=GameWorld.ViewPos.Y div GameWorld.Scale.Y; ImageRect(MiniMapImage,X,Y, X+ScrWidth div GameWorld.Scale.X, Y+ScrHeight div GameWorld.Scale.Y,White); ImageUnLock(MiniMapImage); End; PROCEDURE TGame.ProceedUnitSettingFile(FileName : String); Var St,Sub : String; CrazyBabe 2003. K-Outertainment Trang 32

Simple TS Gme Dsign & Cding

Typer : TSpaceShip; F : Text; Z : Integer; Procedure LoadAni(Var Data : TFrame); Var H : THeading; Z : Integer; Begin //Skip #Move#Attack#Somthing... ReadLn(F,St); For H:=H01 to H32 do Begin //Skip line [H#] ReadLn(F,St); ReadLn(F,Data[H].NumFrames); SetLength(Data[H].Ani,Data[H].NumFrames); For Z:=1 to Data[H].NumFrames do ReadLn(F,Data[H].Ani[Z-1].FramePos, Data[H].Ani[Z-1].FrameStyle); End; End; Begin Assign(F,FileName); Reset(F); ReadLn(F,St); St:=UpperCase(St); Sub:=GetSubString(St); If Sub=SettingStr then Begin Typer:=GetShipTyper(St); With UnitsProperty[Typer] do Begin _DrawLevel:=2; _ShipCanCreate:=Low(TSpaceShip); While Not EoF(F) do Begin ReadLn(F,St); //Ship comment or blank line If (St='') or (St[1]='#') then Continue; St:=UpperCase(St); Sub:=GetSubString(St); //Setting for image file If Sub=ImageFilesStr then Begin Sub:=GetSubString(St); _NumOfImages:=ToInt(Sub); SetLength(_Images,_NumOfImages); For Z:=1 to _NumOfImages do Begin ReadLn(F,St); _Images[Z-1]:=LoadImage(DataPath+St,FormatA1R5G5B5); SetAlphaMask(_Images[Z-1],0); End; End Else //Ship size If Sub=ShipSizeStr then Begin Sub:=GetSubString(St); _Size:=ToInt(Sub); _Size2:=_Size div 2; End Else //Ship hitpoint If Sub=ShipHitPointStr then CrazyBabe 2003. K-Outertainment Trang 33

Simple TS Gme Dsign & Cding

Begin Sub:=GetSubString(St); _HitPoint:=ToInt(Sub); End Else //Ship damage If Sub=ShipDamageStr then Begin Sub:=GetSubString(St); _Damage:=ToInt(Sub); End Else //Ship attack range If Sub=ShipAttackRangeStr then Begin Sub:=GetSubString(St); _AttackRange:=ToInt(Sub); End Else //Ship speed If Sub=ShipSpeedStr then Begin Sub:=GetSubString(St); _Speed:=ToInt(Sub); End Else //Ship wait If Sub=ShipWaitStr then Begin Sub:=GetSubString(St); _Wait:=ToInt(Sub); End Else //Ship turn wait If Sub=ShipTurnWaitStr then Begin Sub:=GetSubString(St); _TurnWait:=ToInt(Sub); End Else //Ship gun If Sub=ShipGunStr then Begin Sub:=GetSubString(St); _Gun:=GetGun(Sub); End Else //Ship explosion If Sub=ExplosionSkinStr then Begin Sub:=GetSubString(St); _Explosion:=GetShipTyper(Sub); End Else If Sub=ShipFrameStr then Begin LoadAni(_ShipAni.Move); LoadAni(_ShipAni.Attack); End Else If Sub=ShipCanCreate then Begin Sub:=GetSubString(St); _ShipCanCreate:=GetShipTyper(Sub); CrazyBabe 2003. K-Outertainment Trang 34

Simple TS Gme Dsign & Cding

End Else If Sub=ShipCreateTime then Begin Sub:=GetSubString(St); _BuildTime:=ToInt(Sub); End Else If Sub=ShipCost then Begin Sub:=GetSubString(St); _Cost:=ToInt(Sub); End; End; End; End; Close(F); End; PROCEDURE TGame.SetupUnitsSetting; Begin UnitsProperty[FirePlanet]._DrawLevel:=1; ProceedUnitSettingFile(DataPath+ShipsSettingDir+'ShipCarrier.Config'); ProceedUnitSettingFile(DataPath+ShipsSettingDir+'ShipBattleCruiseAmon.Config') ; ProceedUnitSettingFile(DataPath+ShipsSettingDir+'ShipBattleCruiseBaton.Config' ); ProceedUnitSettingFile(DataPath+ShipsSettingDir+'ShipCooNok.Config'); ProceedUnitSettingFile(DataPath+ShipsSettingDir+'ShipScout.Config'); ProceedUnitSettingFile(DataPath+ShipsSettingDir+'EvelMissile.Config'); ProceedUnitSettingFile(DataPath+ShipsSettingDir+'MileMissile.Config'); ProceedUnitSettingFile(DataPath+ShipsSettingDir+'MiniMissile.Config'); ProceedUnitSettingFile(DataPath+ShipsSettingDir+'Burn.Config'); End; PROCEDURE TGame.SetupUnitsImage; Begin GlobeImageNum:=LoadImage(DataPath+'Globe.jpg',FormatA1R5G5B5); FlareImageNum:=LoadImage(DataPath+'Flare.jpg',FormatA1R5G5B5); SetAlphaMask(GlobeImageNum,0); End; FUNCTION TGame.CreateNewUnit(UnitTyper : TSpaceShip; Player : TPlayer; PosX,PosY : Integer) : TUnitCount; Var Z : TUnitCount; Begin For Z:=Low(TUnitCount)+1 to High(TUnitCount) do If GameUnits[Z].HitPoint<=0 then Begin GameUnits[Z].Pos.X:=PosX; GameUnits[Z].Pos.Y:=PosY; SetupUnit(Z,UnitTyper,Player); Result:=Z; Inc(GamePlayers[Player].CountUnit); Inc(UnitCounting); Exit; End; Result:=Low(TUnitCount); End;

CrazyBabe 2003. K-Outertainment Trang 35

Simple TS Gme Dsign & Cding

FUNCTION TGame.DestroyUnit(UnitNum : TUnitCount) : Boolean; Var Z : TUnitCount; Begin Result:=True; With GameUnits[UnitNum] do Begin If HitPoint<=0 then Exit; If FirstUnitSelect=UnitNum then FirstUnitSelect:=Low(TUnitCount); For Z:=Low(TUnitCount) to High(TUnitCount) do If (GameUnits[Z].HitPoint>0) and (GameUnits[Z].UnitTarget=UnitNum) then Begin If (GameUnits[Z].Owner<>NonePlayer) then UnitResetCommand(Z) Else DestroyUnit(Z); End; Dec(GamePlayers[Owner].CountUnit); Dec(UnitCounting); HitPoint:=0; End; End; PROCEDURE TGame.SetupUnit(UnitNum : TUnitCount; UnitTyper : TSpaceShip; Player : TPlayer); Begin With GameUnits[UnitNum] do Begin Owner:=Player; Typer:=UnitTyper; HitPoint:=UnitsProperty[UnitTyper]._HitPoint; UnitCmd:=NoCmd; UnitNextCmd:=NoCmd; CurrentFrame:=0; CreationCounting:=0; Case Typer of FirePlanet : Begin TransparentLevel:=Random(255); TransparentSpeed:=1; End; Else Begin CurrentHead:=RandomHeading; UnitGroup:=0; End; End; End; End; FUNCTION TGame.CostForNewUnit(Player : TPlayer; UnitTyper : TSpaceShip) : Boolean;

Begin With GamePlayers[Player] do Begin If Money>=UnitsProperty[UnitTyper]._Cost then Begin Dec(Money,UnitsProperty[UnitTyper]._Cost); Result:=True; End Else Result:=False; End; CrazyBabe 2003. K-Outertainment Trang 36

Simple TS Gme Dsign & Cding

End; PROCEDURE TGame.SelectUnit(UnitNum : TUnitCount); Begin With GameUnits[UnitNum] do Begin If FirstUnitSelect=Low(TUnitCount) then FirstUnitSelect:=UnitNum; If UnitGroup and 128=0 then UnitGroup:=UnitGroup xor 128; End; End; PROCEDURE TGame.UnSelectAllUnit; Var Z : TUnitCount; Begin FirstUnitSelect:=Low(TUnitCount); For Z:=Low(TUnitCount) to High(TUnitCount) do With GameUnits[Z] do UnitGroup:=UnitGroup and 127; End; FUNCTION TGame.GetUnitAtMouse(MX,MY : Integer; HumanOwner : Boolean) : TUnitCount; Var Ok : Boolean; Z,Saved : TUnitCount; XX,YY : Single; SprNum : Integer; Begin Saved:=Low(TUnitCount); For Z:=Low(TUnitCount) to High(TUnitCount) do With GameUnits[Z], UnitsProperty[Typer] do If (HitPoint>0) and (Owner<>NonePlayer) then Begin If HumanOwner and (Owner<>HumanControl) then Continue; XX:=Pos.X-GameWorld.ViewPos.X; YY:=Pos.Y-GameWorld.ViewPos.Y; Ok:=(MX>=XX-_Size2) and (MX<=XX+_Size2) and (MY>=YY-_Size2) and (MY<=YY+_Size2); If Ok then Begin Case UnitCmd of NoCmd,CmdMove : Begin SprNum:=_ShipAni.Move[CurrentHead].Ani[0].FramePos; XX:=MX+GameWorld.ViewPos.X-Pos.X+ GetImageWidth(_Images[SprNum]) ShR 1; YY:=MY+GameWorld.ViewPos.Y-Pos.Y+ GetImageHeight(_Images[SprNum]) ShR 1; Ok:=ImageGetPixel(_Images[SprNum], Round(XX),Round(YY))<>0; End; End; If Ok then Saved:=Z; End; End; Result:=Saved; CrazyBabe 2003. K-Outertainment Trang 37

Simple TS Gme Dsign & Cding

End; PROCEDURE TGame.CallMouseSelectionUnit(Add : Boolean); Var Saved,Z : TUnitCount; X1,Y1,X2,Y2 : Single; Begin If (SelectStart.X=SelectEnd.X) and (SelectStart.Y=SelectEnd.Y) then Begin Saved:=GetUnitAtMouse(SelectStart.X,SelectStart.Y,True); If Saved<>Low(TUnitCount) then Begin If Not Add then UnSelectAllUnit; SelectUnit(Saved); End; End Else Begin If Not Add then UnSelectAllUnit; X1:=SelectStart.X+GameWorld.ViewPos.X; Y1:=SelectStart.Y+GameWorld.ViewPos.Y; X2:=SelectEnd.X+GameWorld.ViewPos.X; Y2:=SelectEnd.Y+GameWorld.ViewPos.Y; For Z:=Low(TUnitCount) to High(TUnitCount) do With GameUnits[Z], UnitsProperty[Typer] do If (HitPoint>0) and (Owner=HumanControl) then Begin If (X1<=Pos.X+_Size2) and (X2>=Pos.X-_Size2) and (Y1<=Pos.Y+_Size2) and (Y2>=Pos.Y-_Size2) then SelectUnit(Z); End; End; End; FUNCTION TGame.UnitGetBestHeading(UnitNum : TUnitCount) : THeading; Var H,Best : THeading; Len,Min,X,Y : Single; Begin Min:=High(Integer); Best:=Low(THeading); With GameUnits[UnitNum] do For H:=H01 to H32 do Begin X:=Pos.X+Moving[H,1]; Y:=Pos.Y+Moving[H,2]; Len:=Sqr(X-Dest.X)+Sqr(Y-Dest.Y); If Len<Min then Begin Min:=Len; Best:=H; End; End; Result:=Best; End; FUNCTION TGame.UnitCloseToTarget(UnitNum : TUnitCount; Long : Integer) : Boolean; Var Len : Single; CrazyBabe 2003. K-Outertainment Trang 38

Simple TS Gme Dsign & Cding

Begin With GameUnits[UnitNum] do Begin Len:=Sqr(Pos.X-Dest.X)+Sqr(Pos.Y-Dest.Y); Result:=Sqrt(Len)<=Long; End; End; PROCEDURE TGame.UnitPointToTarget(UnitNum : TUnitCount); Begin With GameUnits[UnitNum] do Begin Head:=UnitGetBestHeading(UnitNum); End; End; FUNCTION TGame.UnitVisible(UnitNum : TUnitCount) : Boolean; Begin With GameUnits[UnitNum], UnitsProperty[Typer] do Result:=(Pos.X-_Size2<GameWorld.ViewPos.X+ScrWidth) and (Pos.Y-_Size2<GameWorld.ViewPos.Y+ScrHeight) and (Pos.X+_Size2>GameWorld.ViewPos.X) and (Pos.Y+_Size2>GameWorld.ViewPos.Y); End; FUNCTION TGame.HeadNear(StartHead,EndHead : THeading) : THeading; Var L,R : Integer; Begin If StartHead>EndHead then Begin L:=Integer(StartHead)-Integer(EndHead); R:=Integer(High(THeading))-Integer(StartHead)+ Integer(EndHead)-Integer(Low(THeading)); End Else Begin R:=Integer(EndHead)-Integer(StartHead); L:=Integer(High(THeading))-Integer(EndHead)+ Integer(StartHead)-Integer(Low(THeading)); End; If L<R then Begin If StartHead>Low(THeading) then Dec(StartHead) Else StartHead:=High(THeading); End Else Begin If StartHead<High(THeading) then Inc(StartHead) Else StartHead:=Low(THeading); End; Result:=StartHead; End; PROCEDURE TGame.PointNear(X,Y,Leng : Integer;Var DX,DY : Integer); Var I,J : Integer; Begin I:=Random(Leng); J:=Random(Leng); Case Random(2) of 0 : DX:=X+I; 1 : DX:=X-I; End; Case Random(2) of CrazyBabe 2003. K-Outertainment Trang 39

Simple TS Gme Dsign & Cding

0 : DY:=Y+J; 1 : DY:=Y-J; End; End; FUNCTION TGame.Long(X1,Y1,X2,Y2 : Single) : Single; Begin Result:=Sqr(X1-X2)+Sqr(Y1-Y2); End; FUNCTION TGame.RandomPlayer : TPlayer; Begin Case Random(4) of 0 : Result:=Player1; 1 : Result:=Player2; 2 : Result:=Player3; 3 : Result:=Player4; Else Result:=NonePlayer; End; End; PROCEDURE TGame.UnitFire(UnitNum : TUnitCount); Var Num : TUnitCount; X,Y : Integer; Begin With GameUnits[UnitNum], UnitsProperty[Typer] do Begin Case _Gun of GunMiniMissile : Begin Num:=CreateNewUnit(MiniMissile,NonePlayer, Round(Pos.X),Round(Pos.Y)); If Num<>Low(TUnitCount) then Begin //Get a random point nearby target ! PointNear(Round(GameUnits[UnitTarget].Pos.X), Round(GameUnits[UnitTarget].Pos.Y), Min(_Size2 ShR 1,_Size2 ShR 1),X,Y); GameUnits[Num].Dest.Y:=Y; GameUnits[Num].Dest.X:=X; GameUnits[Num].UnitCmd:=CmdFire; GameUnits[Num].Head:=UnitGetBestHeading(Num); GameUnits[Num].CurrentHead:=GameUnits[Num].Head; GameUnits[Num].UnitTarget:=UnitTarget; // //Play missile lauched // {$IfDef SoundPlaying} If UnitVisible(Num) then If LastMissileLauchSoundTime<GameTime-2000 then Begin LastMissileLauchSoundTime:=GameTime; SoundPlay(MissileLauch); End; {$EndIf} End Else Begin CreateMessage('Unit limit exceed !'); End; End; GunEvelMissile : Begin CrazyBabe 2003. K-Outertainment Trang 40

Simple TS Gme Dsign & Cding

Num:=CreateNewUnit(EvelMissile,NonePlayer, Round(Pos.X),Round(Pos.Y)); If Num<>Low(TUnitCount) then Begin //Get a random point nearby target ! PointNear(Round(GameUnits[UnitTarget].Pos.X), Round(GameUnits[UnitTarget].Pos.Y), Min(_Size2 ShR 1,_Size2 ShR 1),X,Y); GameUnits[Num].Dest.Y:=Y; GameUnits[Num].Dest.X:=X; GameUnits[Num].UnitCmd:=CmdFire; GameUnits[Num].Head:=UnitGetBestHeading(Num); GameUnits[Num].CurrentHead:=GameUnits[Num].Head; GameUnits[Num].UnitTarget:=UnitTarget; // //Play missile lauched // {$IfDef SoundPlaying} If UnitVisible(Num) then If LastMissileLauchSoundTime<GameTime-2000 then Begin LastMissileLauchSoundTime:=GameTime; SoundPlay(MissileLauch); End; {$EndIf} End Else Begin CreateMessage('Unit limit exceed !'); End; End; GunMileMissile : Begin Num:=CreateNewUnit(MileMissile,NonePlayer, Round(Pos.X),Round(Pos.Y)); If Num<>Low(TUnitCount) then Begin //Get a random point nearby target ! PointNear(Round(GameUnits[UnitTarget].Pos.X), Round(GameUnits[UnitTarget].Pos.Y), Min(_Size2 ShR 1,_Size2 ShR 1),X,Y); GameUnits[Num].Dest.Y:=Y; GameUnits[Num].Dest.X:=X; GameUnits[Num].UnitCmd:=CmdFire; GameUnits[Num].Head:=UnitGetBestHeading(Num); GameUnits[Num].CurrentHead:=GameUnits[Num].Head; GameUnits[Num].UnitTarget:=UnitTarget; End Else Begin CreateMessage('Unit limit exceed !'); End; End; End; End; End; PROCEDURE TGame.UnitHit(UnitNum : TUnitCount); Begin With GameUnits[UnitNum], UnitsProperty[Typer] do Begin UnitDecHitPoint(UnitTarget,_Damage); End; CrazyBabe 2003. K-Outertainment Trang 41

Simple TS Gme Dsign & Cding

End; PROCEDURE TGame.UnitDecHitPoint(UnitNum : TUnitCount;Damage : Integer); Begin With GameUnits[UnitNum], UnitsProperty[Typer] do Begin If HitPoint>Damage then Dec(HitPoint,Damage) Else DestroyUnit(UnitNum); End; End; FUNCTION TGame.UnitGetNextCmd(UnitNum : TUnitCount) : Boolean; Begin With GameUnits[UnitNum] do Begin If UnitNextCmd<>NoCmd then Begin UnitCmd:=UnitNextCmd; UnitTarget:=UnitNextTarget; UnitNextCmd:=NoCmd; Case UnitCmd of CmdMove,CmdPatrol : Begin UnitPointToTarget(UnitNum); End; CmdAttack,CmdAttackP,CmdAttackM : Begin Dest:=GameUnits[UnitTarget].Pos; UnitPointToTarget(UnitNum); End; CmdAttackT : Begin UnitPointToTarget(UnitNum); End; End; Result:=True; End Else Result:=False; End; End; PROCEDURE TGame.UnitResetCommand(UnitNum : TUnitCount); Begin With GameUnits[UnitNum] do Begin If UnitCmd=CmdAttackP then Begin UnitCmd:=CmdPatrol; Dest:=PatrolDest; UnitPointToTarget(UnitNum); End Else If UnitCmd=CmdAttackM then Begin UnitCmd:=CmdAttackT; Dest:=PatrolDest; UnitPointToTarget(UnitNum); End Else UnitCmd:=NoCmd; UnitTarget:=Low(TUnitCount); End; End;

CrazyBabe 2003. K-Outertainment Trang 42

Simple TS Gme Dsign & Cding

PROCEDURE TGame.UnitSetCreate(UnitNum : TUnitCount); Begin With GameUnits[UnitNum], UnitsProperty[Typer] do Begin If _ShipCanCreate=Low(TSpaceShip) then Exit; If CreationCounting>0 then Exit; If CostForNewUnit(Owner,_ShipCanCreate) then CreationCounting:=1; End; End; PROCEDURE TGame.UnitSetMove(UnitNum : TUnitCount;DestX,DestY : Integer); Begin With GameUnits[UnitNum] do Begin If UnitCmd=NoCmd then Begin UnitCmd:=CmdMove; UnitTarget:=Low(TUnitCount); Dest.X:=DestX; Dest.Y:=DestY; UnitPointToTarget(UnitNum); End Else Begin UnitNextCmd:=CmdMove; UnitNextTarget:=Low(TUnitCount); Dest.X:=DestX; Dest.Y:=DestY; End; End; End; PROCEDURE TGame.UnitSetPatrol(UnitNum : TUnitCount;DestX,DestY : Integer); Begin With GameUnits[UnitNum] do Begin If (UnitCmd=NoCmd) or (UnitCmd=CmdPatrol) then Begin UnitCmd:=CmdPatrol; UnitTarget:=Low(TUnitCount); PatrolStart:=Pos; PatrolDest.X:=DestX; PatrolDest.Y:=DestY; Dest:=PatrolDest; UnitPointToTarget(UnitNum); End Else Begin UnitNextCmd:=CmdPatrol; UnitNextTarget:=Low(TUnitCount); PatrolStart:=Pos; PatrolDest.X:=DestX; PatrolDest.Y:=DestY; End; End; End; PROCEDURE TGame.UnitSetAttackTo(UnitNum : TUnitCount;DestX,DestY : Integer); Begin With GameUnits[UnitNum] do Begin CrazyBabe 2003. K-Outertainment Trang 43

Simple TS Gme Dsign & Cding

If (UnitCmd=NoCmd) or (UnitCmd=CmdPatrol) then Begin UnitCmd:=CmdAttackT; UnitTarget:=Low(TUnitCount); Dest.X:=DestX; Dest.Y:=DestY; UnitPointToTarget(UnitNum); End Else Begin UnitNextCmd:=CmdAttackT; UnitNextTarget:=Low(TUnitCount); Dest.X:=DestX; Dest.Y:=DestY; End; End; End; PROCEDURE TGame.UnitSetAttack(UnitNum : TUnitCount;Target : Integer); Begin If Target=UnitNum then Exit; With GameUnits[UnitNum] do Begin If UnitCmd=NoCmd then Begin UnitCmd:=CmdAttack; UnitTarget:=Target; Dest:=GameUnits[Target].Pos; UnitPointToTarget(UnitNum); End Else Begin UnitNextCmd:=CmdAttack; UnitNextTarget:=Target; End; End; End; PROCEDURE TGame.UnitSetAttackPatrol(UnitNum : TUnitCount;Target : Integer); Begin If Target=UnitNum then Exit; With GameUnits[UnitNum] do Begin If UnitCmd=NoCmd then Begin UnitCmd:=CmdAttackP; UnitTarget:=Target; Dest:=GameUnits[Target].Pos; UnitPointToTarget(UnitNum); End Else Begin UnitNextCmd:=CmdAttackP; UnitNextTarget:=Target; End; End; End; PROCEDURE TGame.UnitSetAttackMove(UnitNum : TUnitCount;Target : Integer); Begin If Target=UnitNum then Exit; With GameUnits[UnitNum] do Begin CrazyBabe 2003. K-Outertainment Trang 44

Simple TS Gme Dsign & Cding

If UnitCmd=NoCmd then Begin UnitCmd:=CmdAttackM; UnitTarget:=Target; PatrolDest:=Dest; Dest:=GameUnits[Target].Pos; UnitPointToTarget(UnitNum); End Else Begin PatrolDest:=Dest; UnitNextCmd:=CmdAttackM; UnitNextTarget:=Target; End; End; End; FUNCTION TGame.UnitFindTarget(UnitNum : TUnitCount) : TUnitCount; Var Z,Saved : TUnitCount; Min,Leng : Single; Begin Min:=High(Integer); Saved:=Low(TUnitCount); With GameUnits[UnitNum], UnitsProperty[Typer] do For Z:=Low(TUnitCount) to High(TUnitCount) do If (GamePlayers[Owner].Enemy[GameUnits[Z].Owner]) and (GameUnits[Z].HitPoint>0) then Begin Leng:=Long(Pos.X,Pos.Y, GameUnits[Z].Pos.X, GameUnits[Z].Pos.Y); If (Leng<Min) and (Leng<Sqr(_AttackRange)) then Begin Min:=Leng; Saved:=Z; End; End; Result:=Saved; End; FUNCTION TGame.UnitFindNear(UnitNum : TUnitCount) : TUnitCount; Var Z,Saved : TUnitCount; Min,Leng : Single; Begin Min:=High(Integer); Saved:=Low(TUnitCount); With GameUnits[UnitNum], UnitsProperty[Typer] do For Z:=Low(TUnitCount) to High(TUnitCount) do If (Z<>UnitNum) and (GameUnits[Z].Owner=Owner) and (GameUnits[Z].HitPoint>0) then Begin Leng:=Long(Pos.X,Pos.Y, GameUnits[Z].Pos.X, GameUnits[Z].Pos.Y); If (Leng<Min) and (Leng<Sqr(TooNearLeng)) then Begin Min:=Leng; CrazyBabe 2003. K-Outertainment Trang 45

Simple TS Gme Dsign & Cding

Saved:=Z; End; End; Result:=Saved; End; PROCEDURE TGame.ProcessSpecifyUnit(UnitNum : TUnitCount); Begin With GameUnits[UnitNum] do Begin End; End; PROCEDURE TGame.ProcessNormalUnit(UnitNum : TUnitCount); Var Num : TUnitCount; Begin With GameUnits[UnitNum], UnitsProperty[Typer] do Begin //Unit is owner by computer ? If Owner<>HumanControl then Begin //Can be create ? If (_ShipCanCreate<>Low(TSpaceShip)) and //Now not create ? (CreationCounting=0) then Begin //Create unit ! UnitSetCreate(UnitNum); End; End; //Unit creation process If CreationCounting>0 then Begin Inc(CreationCounting); If CreationCounting>UnitsProperty[_ShipCanCreate]._BuildTime then Begin CreationCounting:=0; Num:=CreateNewUnit(_ShipCanCreate,Owner, Round(Pos.X),Round(Pos.Y)); UnitSetMove(Num,Round(Pos.X)-150+Random(300), Round(Pos.Y)-150+Random(300)); End; End; //Unit command process Case UnitCmd of CmdMove,CmdFire : ProceedUnitMove(UnitNum); CmdAttack : ProceedUnitAttack(UnitNum); CmdAttackP : ProceedUnitAttackP(UnitNum); CmdAttackT : ProceedUnitAttackT(UnitNum); CmdAttackM : ProceedUnitAttackM(UnitNum); CmdPatrol : ProceedUnitPatrol(UnitNum); CmdBurn : ProceedUnitBurning(UnitNum); Else ProceedUnitStand(UnitNum); End; End; End; PROCEDURE TGame.ProceedUnitStand(UnitNum : TUnitCount); Var Num : TUnitCount; Begin With GameUnits[UnitNum], UnitsProperty[Typer] do Begin CrazyBabe 2003. K-Outertainment Trang 46

Simple TS Gme Dsign & Cding

If IsFrameToFindTarget then Begin Num:=UnitFindTarget(UnitNum); If Num<>Low(TUnitCount) then Begin UnitSetAttack(UnitNum,Num); Exit; End Else Begin End; End; If WaitTimeForMove>0 then Begin Dec(WaitTimeForMove); Exit; End; If UnitGetNextCmd(UnitNum) then Exit; //Unit is owner by computer ? If Owner<>HumanControl then Begin UnitSetPatrol(UnitNum,Random(GameWorld.Size.X), Random(GameWorld.Size.Y)); End; WaitTimeForMove:=_TurnWait; End; End; PROCEDURE TGame.ProceedUnitMove(UnitNum : TUnitCount); Var _Heading : THeading; Num : TUnitCount; Z : Integer; Begin With GameUnits[UnitNum], UnitsProperty[Typer] do Begin If WaitTimeForMove>0 then Begin Dec(WaitTimeForMove); Exit; End; If UnitGetNextCmd(UnitNum) then Exit; If UnitCloseToTarget(UnitNum,MoveFarLeng) then Begin If UnitCmd=CmdFire then Begin {$IfDef SoundPlaying} If UnitVisible(UnitNum) then If LastMissileExploredSoundTime<GameTime-2000 then Begin LastMissileExploredSoundTime:=GameTime; SoundPlay(MissileExplored); End; {$EndIf} UnitHit(UnitNum); DestroyUnit(UnitNum); Exit; End Else If UnitGetNextCmd(UnitNum) then Else UnitCmd:=NoCmd; End Else //Turn ship ? CrazyBabe 2003. K-Outertainment Trang 47

Simple TS Gme Dsign & Cding

If CurrentHead<>Head then Begin CurrentHead:=HeadNear(CurrentHead,Head); WaitTimeForMove:=_TurnWait; End Else Begin For Z:=1 to _Speed do Begin _Heading:=UnitGetBestHeading(UnitNum); Pos.X:=Pos.X+Moving[_Heading,1]; Pos.Y:=Pos.Y+Moving[_Heading,2]; End; WaitTimeForMove:=_Wait; //Increase unit frame If CurrentFrame< _ShipAni.Move[CurrentHead].NumFrames-1 then Inc(CurrentFrame) Else CurrentFrame:=0; //Missile generating the burning If UnitCmd=CmdFire then Begin Num:=CreateNewUnit(Burn,NonePlayer, Round(Pos.X),Round(Pos.Y)); If Num<>Low(TUnitCount) then Begin //Unit is burning ! GameUnits[Num].UnitCmd:=CmdBurn; End; End; End; End; End; PROCEDURE TGame.ProceedUnitAttack(UnitNum : TUnitCount); Var _Heading : THeading; Z : Integer; Begin With GameUnits[UnitNum], UnitsProperty[Typer] do Begin If WaitTimeForMove>0 then Begin Dec(WaitTimeForMove); Exit; End; If UnitGetNextCmd(UnitNum) then Exit; If GameUnits[UnitTarget].HitPoint<=0 then Begin UnitCmd:=NoCmd; Exit; End Else Begin If (UnitTarget<>0) and ((Dest.X<>GameUnits[UnitTarget].Pos.X) or (Dest.Y<>GameUnits[UnitTarget].Pos.Y))then Begin Dest:=GameUnits[UnitTarget].Pos; Head:=UnitGetBestHeading(UnitNum); End; End; If UnitCloseToTarget(UnitNum,_AttackRange) then Begin UnitFire(UnitNum); CrazyBabe 2003. K-Outertainment Trang 48

Simple TS Gme Dsign & Cding

WaitTimeForMove:=_TurnWait*20; End Else //Turn ship ? If CurrentHead<>Head then Begin CurrentHead:=HeadNear(CurrentHead,Head); WaitTimeForMove:=_TurnWait; End Else Begin For Z:=1 to _Speed do Begin _Heading:=UnitGetBestHeading(UnitNum); Pos.X:=Pos.X+Moving[_Heading,1]; Pos.Y:=Pos.Y+Moving[_Heading,2]; End; WaitTimeForMove:=_Wait; End; End; End; PROCEDURE TGame.ProceedUnitAttackP(UnitNum : TUnitCount); Var _Heading : THeading; Z : Integer; Begin With GameUnits[UnitNum], UnitsProperty[Typer] do Begin If WaitTimeForMove>0 then Begin Dec(WaitTimeForMove); Exit; End; If UnitGetNextCmd(UnitNum) then Exit; If GameUnits[UnitTarget].HitPoint<=0 then Begin //Back to patrol command UnitCmd:=CmdPatrol; Dest:=PatrolDest; UnitPointToTarget(UnitNum); Exit; End Else Begin If (UnitTarget<>0) and ((Dest.X<>GameUnits[UnitTarget].Pos.X) or (Dest.Y<>GameUnits[UnitTarget].Pos.Y))then Begin Dest:=GameUnits[UnitTarget].Pos; Head:=UnitGetBestHeading(UnitNum); End; End; If UnitCloseToTarget(UnitNum,_AttackRange) then Begin UnitFire(UnitNum); WaitTimeForMove:=_TurnWait*20; End Else //Turn ship ? If CurrentHead<>Head then Begin CurrentHead:=HeadNear(CurrentHead,Head); WaitTimeForMove:=_TurnWait; CrazyBabe 2003. K-Outertainment Trang 49

Simple TS Gme Dsign & Cding

End Else Begin For Z:=1 to _Speed do Begin _Heading:=UnitGetBestHeading(UnitNum); Pos.X:=Pos.X+Moving[_Heading,1]; Pos.Y:=Pos.Y+Moving[_Heading,2]; End; WaitTimeForMove:=_Wait; End; End; End; PROCEDURE TGame.ProceedUnitAttackM(UnitNum : TUnitCount); Var _Heading : THeading; Z : Integer; Begin With GameUnits[UnitNum], UnitsProperty[Typer] do Begin If WaitTimeForMove>0 then Begin Dec(WaitTimeForMove); Exit; End; If UnitGetNextCmd(UnitNum) then Exit; If GameUnits[UnitTarget].HitPoint<=0 then Begin //Back to patrol command UnitCmd:=CmdAttackT; Dest:=PatrolDest; UnitPointToTarget(UnitNum); Exit; End Else Begin If (UnitTarget<>0) and ((Dest.X<>GameUnits[UnitTarget].Pos.X) or (Dest.Y<>GameUnits[UnitTarget].Pos.Y))then Begin Dest:=GameUnits[UnitTarget].Pos; Head:=UnitGetBestHeading(UnitNum); End; End; If UnitCloseToTarget(UnitNum,_AttackRange) then Begin UnitFire(UnitNum); WaitTimeForMove:=_TurnWait*20; End Else //Turn ship ? If CurrentHead<>Head then Begin CurrentHead:=HeadNear(CurrentHead,Head); WaitTimeForMove:=_TurnWait; End Else Begin For Z:=1 to _Speed do Begin _Heading:=UnitGetBestHeading(UnitNum); Pos.X:=Pos.X+Moving[_Heading,1]; Pos.Y:=Pos.Y+Moving[_Heading,2]; CrazyBabe 2003. K-Outertainment Trang 50

Simple TS Gme Dsign & Cding

End; WaitTimeForMove:=_Wait; End; End; End; PROCEDURE TGame.ProceedUnitAttackT(UnitNum : TUnitCount); Var _Heading : THeading; Num : TUnitCount; Z : Integer; Begin With GameUnits[UnitNum], UnitsProperty[Typer] do Begin If WaitTimeForMove>0 then Begin Dec(WaitTimeForMove); Exit; End; If UnitGetNextCmd(UnitNum) then Exit; If UnitCloseToTarget(UnitNum,MoveFarLeng) then Begin If UnitGetNextCmd(UnitNum) then Else UnitCmd:=NoCmd; End Else //Turn ship ? If CurrentHead<>Head then Begin CurrentHead:=HeadNear(CurrentHead,Head); WaitTimeForMove:=_TurnWait; End Else Begin For Z:=1 to _Speed do Begin _Heading:=UnitGetBestHeading(UnitNum); Pos.X:=Pos.X+Moving[_Heading,1]; Pos.Y:=Pos.Y+Moving[_Heading,2]; End; If IsFrameToFindTarget then Begin Num:=UnitFindTarget(UnitNum); If Num<>Low(TUnitCount) then Begin UnitCmd:=NoCmd; UnitSetAttackMove(UnitNum,Num); Exit; End; End; WaitTimeForMove:=_Wait; //Increase unit frame If CurrentFrame< _ShipAni.Move[CurrentHead].NumFrames-1 then Inc(CurrentFrame) Else CurrentFrame:=0; End; End; End; PROCEDURE TGame.ProceedUnitPatrol(UnitNum : TUnitCount); Var _Heading : THeading; Z : Integer; Num : TUnitCount; Begin CrazyBabe 2003. K-Outertainment Trang 51

Simple TS Gme Dsign & Cding

With GameUnits[UnitNum], UnitsProperty[Typer] do Begin If WaitTimeForMove>0 then Begin Dec(WaitTimeForMove); Exit; End; If UnitGetNextCmd(UnitNum) then Exit; If UnitCloseToTarget(UnitNum,MoveFarLeng) then Begin If UnitGetNextCmd(UnitNum) then Else Begin Dest:=PatrolStart; PatrolStart:=PatrolDest; PatrolDest:=Dest; UnitPointToTarget(UnitNum); End; End Else //Turn ship ? If CurrentHead<>Head then Begin CurrentHead:=HeadNear(CurrentHead,Head); WaitTimeForMove:=_TurnWait; End Else Begin For Z:=1 to _Speed do Begin _Heading:=UnitGetBestHeading(UnitNum); Pos.X:=Pos.X+Moving[_Heading,1]; Pos.Y:=Pos.Y+Moving[_Heading,2]; End; If IsFrameToFindTarget then Begin Num:=UnitFindTarget(UnitNum); If Num<>Low(TUnitCount) then Begin UnitCmd:=NoCmd; UnitSetAttackPatrol(UnitNum,Num); Exit; End; End; WaitTimeForMove:=_Wait; //Increase unit frame If CurrentFrame< _ShipAni.Move[CurrentHead].NumFrames-1 then Inc(CurrentFrame) Else CurrentFrame:=0; End; End; End; PROCEDURE TGame.ProceedUnitBurning(UnitNum : TUnitCount); Begin //When unit burning, unit do nothing else burning ! With GameUnits[UnitNum], UnitsProperty[Typer] do Begin If WaitTimeForMove>0 then Begin Dec(WaitTimeForMove); Exit; CrazyBabe 2003. K-Outertainment Trang 52

Simple TS Gme Dsign & Cding

End; WaitTimeForMove:=_Wait; //Increase unit frame If CurrentFrame<_ShipAni.Move[CurrentHead].NumFrames-1 then Begin Inc(CurrentFrame); Pos.X:=Pos.X-Random(3); Pos.Y:=Pos.Y-Random(3); End Else Begin DestroyUnit(UnitNum); End; End; End; PROCEDURE TGame.RenderWorld; Var I,J,X,Y : Integer; Begin With GameWorld do Begin X:=ViewPos.X mod GetImageWidth(StarBackGround); Y:=ViewPos.Y mod GetImageHeight(StarBackGround); For I:=-1 to NumTile.X+1 do For J:=-1 to NumTile.Y+1 do ImageRenderEffect(I*GetImageWidth(StarBackGround)-X, J*GetImageHeight(StarBackGround)-Y, StarBackGround,EffectNone); End; End; PROCEDURE TGame.RenderUnits; Var DrawLevel : Integer; Z : TUnitCount; Begin For DrawLevel:=1 to 2 do For Z:=Low(TUnitCount) to High(TUnitCount) do With GameUnits[Z], UnitsProperty[Typer] do If (HitPoint>0) and (_DrawLevel=DrawLevel) then Begin RenderUnits(Z); End; End; PROCEDURE TGame.RenderUnits(UnitNum : TUnitCount); Var X,Y,X1,Y1,X2,Y2, SprNum,Effects : Integer; Visible : Boolean; Begin With GameUnits[UnitNum], UnitsProperty[Typer] do If HitPoint>0 then Begin //Unit visible ? Visible:=UnitVisible(UnitNum); //Drawing unit X:=Round(Pos.X)-GameWorld.ViewPos.X; Y:=Round(Pos.Y)-GameWorld.ViewPos.Y; If Visible then Case Typer of FirePlanet : CrazyBabe 2003. K-Outertainment Trang 53

Simple TS Gme Dsign & Cding

Begin ImageRenderEffect(X-GetImageWidth(GlobeImageNum) ShR 1, Y-GetImageHeight(GlobeImageNum) ShR 1, GlobeImageNum,EffectSrcAlpha); ImageRenderEffectColor(X-GetImageWidth(FlareImageNum) ShR 1, Y-GetImageHeight(FlareImageNum) ShR 1, TransparentLevel ShL 16+ TransparentLevel ShR 8+ TransparentLevel, FlareImageNum,EffectAdd); End; Else Begin //Unit is selection ? If UnitGroup and 128=128 then Begin Rect(X-_Size2,Y-_Size2, X+_Size2,Y+_Size2,Green,EffectNone); TextOut(X-_Size2,Y-_Size2, Format('HP: %d/%d',[HitPoint,_HitPoint]),White); End; Case UnitCmd of NoCmd, CmdFire, CmdMove, CmdAttack, CmdAttackP, CmdAttackT, CmdAttackM, CmdPatrol, CmdBurn : Begin SprNum:=_ShipAni.Move[CurrentHead]. Ani[CurrentFrame].FramePos; Case _ShipAni.Move[CurrentHead]. Ani[CurrentFrame].FrameStyle of 02 : Effects:=EffectAdd; Else Effects:=EffectSrcAlpha; End; ImageRenderEffect(X-GetImageWidth(_Images[SprNum]) ShR 1, Y-GetImageHeight(_Images[SprNum]) ShR 1, _Images[SprNum],Effects); End; End; End; End; If ShowDebug then Begin If UnitCmd in [CmdMove,CmdAttack,CmdAttackP, CmdAttackT,CmdAttackM,CmdPatrol] then Begin TextOut(X,Y,HeadingName[CurrentHead], White,EffectNone); X1:=Round(Pos.X)-GameWorld.ViewPos.X; Y1:=Round(Pos.Y)-GameWorld.ViewPos.Y; X2:=Round(Dest.X)-GameWorld.ViewPos.X; Y2:=Round(Dest.Y)-GameWorld.ViewPos.Y; Line(X1,Y1,X2,Y2,White,EffectNone); End; End; RenderBuffer; CrazyBabe 2003. K-Outertainment Trang 54

Simple TS Gme Dsign & Cding

End; End; PROCEDURE TGame.RenderInfos; Var Tick : LongWord; Begin Case MouseCommand of MouseSelection : Begin Rect(SelectStart.X,SelectStart.Y, SelectEnd.X,SelectEnd.Y, White,EffectNone); End; End; If ShowFPS then Begin Tick:=MMSystem.TimeGetTime-GameStart; If Tick<>0 then Begin TextOut(0,40,Format('UFPS : %0.2f',[GameFrame/Tick*1000]),White); TextOut(0,60,Format('SFPS : %0.2f',[GameScreenFrame/Tick*1000]),White); TextOut(0,80,Format('Unit used : %d',[UnitCounting]),White); End; End; //Show mini map ? If MiniMapVisible then Begin Bar(MiniMapPosX-1,MiniMapPosY-1, MiniMapPosX+MiniMapSizeX+1, MiniMapPosY+MiniMapSizeY+1, Gray,EffectAdd); ImageRenderEffect(MiniMapPosX,MiniMapPosY, MiniMapImage,EffectAdd); End; //Show command panel ? If CommandPanelVisible then Begin Bar(PanelPosX-1,PanelPosY-1, PanelPosX+PanelSizeX+1, PanelPosY+PanelSizeY+1, BlueGray,EffectAdd); If FirstUnitSelect<>Low(TUnitCount) then Begin With GameUnits[FirstUnitSelect], UnitsProperty[Typer] do Begin TextOut(PanelPosX,PanelPosY, ShipName[Typer],White); TextOut(PanelPosX,PanelPosY+20, Format('HP: %d/%d',[HitPoint,_HitPoint]),White); TextOut(PanelPosX,PanelPosY+40, Format('Damage: %d. Speed: %d', [_Damage,_Speed]),White); TextOut(PanelPosX,PanelPosY+60, Format('Range: %d. Gun: %s', [_AttackRange,GunName[_Gun]]),White); If _ShipCanCreate<>Low(TSpaceShip) then Begin If CreationCounting=0 then Begin TextOut(PanelPosX+400,PanelPosY, Format('Press C to create %s', [ShipName[_ShipCanCreate]]),White); CrazyBabe 2003. K-Outertainment Trang 55

Simple TS Gme Dsign & Cding

End Else Begin TextOut(PanelPosX+400,PanelPosY, Format('Create %s: %d/%d', [ShipName[_ShipCanCreate], CreationCounting, UnitsProperty[_ShipCanCreate]. _BuildTime]),White); End; End; End; End; End; //Show player's money and units counting TextOut(0,0,Format('Money: %d. Units: %d', [GamePlayers[HumanControl].Money, GamePlayers[HumanControl].CountUnit]),White); End; PROCEDURE TGame.RenderScene; Begin If GameTime-LastGameScreenTime>ScreenUpdate then Begin LastGameScreenTime:=GameTime; Inc(GameScreenFrame); BeginRender; RenderWorld; RenderUnits; RenderInfos; EndRender; End; End; FUNCTION TGame.GetShipTyper(Name : String) : TSpaceShip; Var Z : TSpaceShip; Begin For Z:=Low(TSpaceShip) to High(TSpaceShip) do If ShipName[Z]=Name then Begin Result:=Z; Exit; End; Result:=Low(TSpaceShip); End; FUNCTION TGame.GetPlayer(Name : String) : TPlayer; Var Z : TPlayer; Begin For Z:=Low(TPlayer) to High(TPlayer) do If PlayerName[Z]=Name then Begin Result:=Z; Exit; End; Result:=Low(TPlayer); End; FUNCTION TGame.GetHeading(Name : String) : THeading; Var Z : THeading; Begin For Z:=Low(THeading) to CrazyBabe 2003. K-Outertainment Trang 56

Simple TS Gme Dsign & Cding

High(THeading) do If HeadingName[Z]=Name then Begin Result:=Z; Exit; End; Result:=Low(THeading); End; FUNCTION TGame.GetGun(Name : String) : TGun; Var Z : TGun; Begin For Z:=Low(TGun) to High(TGun) do If GunName[Z]=Name then Begin Result:=Z; Exit; End; Result:=Low(TGun); End; END.

CrazyBabe 2003. K-Outertainment Trang 57

Simple TS Gme Dsign & Cding

Chapter IV: Sumary

Final ?
Nh vy l chng ta c mt game RTS (xo) khng hon chnh. Vi game ny m tung ra th trng th cm chc lcht thm, he he. Nhng hi vng vi code ny cc bn c th hiu s s vic vit m cho mt game th phn r nh th no. Vi game ny cha th gi l mt game RTS, hn na do thi gian pht trin qu t nn n s cha y li. Nh vy cng vic ca bn by gi l sa li v nng cp trn khung ny. Vi chng trnh ny, hin ti ti vn cha comment mt cch y v thiu thi gian, nhng ti ngh rng cc bn c th hiu c v cch vit ca ti kh d hiu. Nu khng hiu r lm, hy mail cho ti, ti s dnh thi gian ch thch r rng hn.

Upgrade
Mc d khng test nhiu tui cng chc chn chng trnh cha mt s li nh sau: C lc ko chut chn qun li khng c (K cha ?). C lc t lnh (khng nh lnh g) th cc unit li chy ra mt ch khc (K na ?) .Chc l cn nhu li na tui cha tm ra. Cng vic ca bn l sa nhng li ny v ti u ho chng trnh. Cnh ti ngh chng trnh cn cn nng cp mt s tnh nng nh sau: Mc d khi t lnh cho mt nhm qun (Move, Patrol) ti c tnh t cho v tr ch ca lnh lch i mt cht, nhng chc chn s c trng hp cc unit s nm rt rt ln nhau (hic). Bn cn thm tnh nng t dn ra cho cc n v ny. Gi : Hix, kim sot s lng cc unit b coi l chng nhau chng ? C th c nhng cch ny thc thi kh chm. Ton b cc n v trn bn u b nhn thy (?) tc l chng trnh cha tnh n fog of war. Gi : cp nht theo thi gian nh MiniMap, nhng unit no trong

CrazyBabe 2003. K-Outertainment Trang 58

Simple TS Gme Dsign & Cding tm nhn ca n v thuc phe ngi chi th nh du n li. Vn l phi vit hm ny sao cho nhanh (hix). Cc n v trong game gii hn ch c th sinh mt loi qun hoc khng, tnh nng ny c th nng cp thnh cho php chn loi qun c th sinh. Bn cn thm mt list cc loi qun c th sinh vo d liu c tnh ca unit trong game, sau xy dng h thng menu cho game ngi chi c th la chn nhng tnh nng sinh qun ny. Cc tnh nng nh di chuyn, tn cng cng cn c hin th r rng hn thng qua h thng menu. Trong game cha c khai thc ti nguyn, thm cng vic ny s khin game c tnh cnh tranh hn, mc d nh vy s kh tnh ton AI cho my hn v nhiu game hin ti thng gim nh s quan tm n vn ny (?). Nng cp tnh nng AI: Hin ti game hon ton cha c AI, cc n v qun my ch n gin l sinh qun m m ri chy ton lon quanh bn . Bn nn xy dng modun cho php my iu khin qun tp trung li ri lng git qun ca ngi chi s hiu qu hn. Hon thin tnh nng m thanh ca game. Game cn xy dng mt modun qun l m thanh ring, cc thc thi m thanh c gi nn c cc thng s i loi nh v tr, kiu m thanh nhm xc nh to nh v loi b bt cc m thanh cng loi c gi lin tc, v d nh mt m tu cng bn tn la chng hn, modun ny c th ch pht 2/3 m thanh bn m cng t c hiu qu tng ng. .Tip tc l ty bn.Hix, cng vic vn cn rt nhu pha trc hix hix

Di y l screen shot t mt game RTS ti ang pht trin:

CrazyBabe 2003. K-Outertainment Trang 59

Simple TS Gme Dsign & Cding

Reference

AvenusHelper
nh ngha kiu: o TBitDepth: Kiu su mu ca mn hnh. BD16Bit: su mu 16bit. BD32Bit: su mu 32bit. o TImageFormat: Kiu format ca nh. FormatR3G3B2: nh 8bit (Red 3bit, Green 3bit, Blue 2bit). FormatX4R4G4B4: nh 16bit (Mask 4bit, Red 4bit, Green 4bit, Blue 4bit). FormatA4R4G4B4: nh 16bit (Alpha 4bit, Red 4bit, Green 4bit, Blue 4bit). FormatA8R3G3B2: nh 16bit (Alpha 8bit, Red 3bit, Green 3bit, Blue 2bit). FormatR5G6B5: nh 16bit (Red 5bit, Green 6bit, Blue 5bit). FormatX1R5G5B5: nh 16bit (Mask 1bit, Red 5bit, Green 5bit, Blue 5bit). FormatA1R5G5B5:nh 16bit (Alpha 1bit, Red 5bit, Green 5bit, Blue 5bit). FormatX8R8G8B8: nh 32bit (Mask 8bit, Red 8bit, Green 8bit, Blue 8bit). FormatA8R8G8B8:nh 32bit (Alpha 8bit, Red 8bit, Green 8bit, Blue 8bit). nh ngha hng: o EffectNone: V khng hiu ng. o EffectAdd: V kiu cng. o EffectSrcAlpha: V theo knh alpha ca nh, ch p dng vi nhng nh c knh alpha. o EffectSrcAlphaAdd: V kiu cng theo knh alpha ca nh, ch p dng vi nhng nh c knh alpha. o EffectMul: V theo kiu nhn. o EffectSrcColor: V s dng mu source nh l knh alpha. o EffectSrcColorAdd: V kiu cng, s dng mu source nh l knh alpha. o EffectInvSrcColor: V vi gi tr mu ngun o ngc. o EffectInvSrcAlpha: V vi gi tr knh alpha o ngc. CrazyBabe 2003. K-Outertainment Trang 60

Simple TS Gme Dsign & Cding EffectInvSrcMask: V vi gi tr mask o ngc. EffectBlend1, EffectBlend2, EffectBlend3, EffectBlend4: Cc kiu hiu ng blend nh ang th nghim. EffectShadow: V bng. EffectBlendColor: V blend vi mu ngun. EffectBlendColorAlphaChannel: V blend s dng knh alpha. EffectAddDiffuse, EffectDiffuseAlpha: V khuch tn vi knh alpha. EffectMirror, EffectFlip: V lt hnh, hiu ng ny c th kt hp vi cc hiu ng trn. Cc hng s Key_# l cc hng s nh ngha s hiu phm, bn c th d dng on ra n i din cho phm no, ti khng ch thch y do n di qu .

o o o o o o o o

Cc hm, lnh: o Hm CreateWindow(Width,Height : Integer;Title : PChar) : Boolean To mt ca s kch thc Width x Height c caption l Title. Hm tr v true nu to thnh cng, tr v false nu khng to c ca s. o Hm CreateFullScreen(Width,Height : Integer;ScreenDepth : TBitDepth;Title : PChar) : Boolean Khi to ch mn hnh Width x Height su mu l ScreenDepth c caption l Title. Hm tr v true nu khi to thnh cng, tr v false nu khng khi to c ch . o Lnh DestroyScreen Hu ca s/ch to trc , sau khi gi lnh ny tt c cc hm v, ly phm u sinh li do chng trnh hu handle qun l tt c cc dch v ny. o Hm EventMessage : Boolean Kim tra cc events, tr v false nu xut hin event Quit. o Lnh LoadFont(FileName : String;SizeX,SizeY,Width,Height,TransColor : LongWord) c font ch t file nh FileName o Lnh TextOut(X,Y : Integer;Text : String;Color : LongWord) Vit xu Text ra mn hnh, to [X,Y], mu Color. o Lnh TextOut(X,Y : Integer;Text : String;Color : LongWord;Effect : Integer) Vit xu Text ra mn hnh, to [X,Y], mu Color. Hiu ng Effect o Hm CreateImage(SizeX,SizeY : Integer;Format : TImageFormat) : Integer To mt nh c kch thc SizeX x SizeY vi format l Format. S tr v l s hiu ca nh to. o Hm LoadImage(FileName : String;Format : TImageFormat) : Integer c nh t FileName, nh c vo vi format l Format. H tr cc nh dng nh JPEG, PNG, BMP. S tr v l s hiu ca nh c. o Hm SetAlphaMask(ImageNum,TransparentColor : Integer) : Integer t knh Alpha cho tt c cc im nh c mu Transparent. Ch h tr format nh FormatA1R5G5B5. o Hm GetImageWidth(ImageNum : Integer) : Integer Ly rng ca nh s hiu ImageNum. o Hm GetImageHeight(ImageNum : Integer) : Integer Ly cao ca nh s hiu ImageNum. o Hm ImageLock(ImageNum : Integer) : Integer CrazyBabe 2003. K-Outertainment Trang 61

Simple TS Gme Dsign & Cding Lock nh s hiu ImageNum. Hm ImageUnLock(ImageNum : Integer) : Integer UnLock nh s hiu ImageNum. o Lnh ImageClear(ImageNum : Integer;Color : Cardinal) Xo nh ImageNum bng mu Color. o Lnh ImagePutPixel(ImageNum,X,Y : Integer;Color : Cardinal) V im nh mu Color to [X,Y] trong nh ImageNum. o Hm ImageGetPixel(ImageNum,X,Y : Integer) : Cardinal Ly mu im nh Color to [X,Y] trong nh ImageNum. o Lnh ImageLine(ImageNum,X1,Y1,X2,Y2 : Integer;Color : Cardinal) V ng thng mu Color t [X1,Y1] n [X2,Y2] trong nh ImageNum. o Lnh ImageRect(ImageNum,X1,Y1,X2,Y2 : Integer;Color : Cardinal) V hnh ch nht mu Color t [X1,Y1] n [X2,Y2] trong nh ImageNum. o Lnh ImageFillRect(ImageNum,X1,Y1,X2,Y2 : Integer;Color : Cardinal) T hnh ch nht mu Color t [X1,Y1] n [X2,Y2] trong nh ImageNum. o Lnh BeginRender Bt u v scene mi (xo buffer, xo render buffer). o Lnh EndRender Kt thc v scene. o Lnh ClearScreen(Color : Cardinal) Xo mn hnh bng mu Color. o Hm RenderBuffer : Integer Dng ton b hnh trong render buffer. o Lnh SetClipRect(X1,Y1,X2,Y2 : Integer) t clip rect. o Lnh Rect(X1,Y1,X2,Y2 : Integer;Color : Cardinal;Effect : Integer) V hnh ch nht. o Lnh Bar(X1,Y1,X2,Y2 : Integer;Color : Cardinal;Effect : Integer) T hnh ch nht. o Lnh Line(X1,Y1,X2,Y2 : Integer;Color : Cardinal;Effect : Integer) V ng thng. o Lnh SmoothLine(X1,Y1,X2,Y2 : Integer;Color : Cardinal) V ng thng smooth (mn). o Hm ImageRenderEffect(XPos,YPos,Pattern,Effect : Integer) : Boolean Dng nh Pattern v tr [XPos, YPos] vi hiu ng Effect. o Hm ImageRenderEffect(X1,Y1,X2,Y2,Pattern,Effect : Integer) : Boolean Dng nh Pattern thnh hnh ch nht [X1,Y1,X2,Y2] vi hiu ng Effect. o Hm ImageRenderEffect(XPos,YPos,Scale,Pattern,Effect : Integer) : Boolean Dng nh Pattern v tr [XPos, YPos] vi hiu ng Effect. T l zoom l Scale/256. o Hm ImageRenderEffectColor(XPos,YPos : Integer;Color : Cardinal;Pattern,Effect : Integer) : Boolean Dng nh Pattern v tr [XPos, YPos] vi hiu ng Effect. Mu p l Color. o Hm ImageRenderEffectColor(X1,Y1,X2,Y2 : Integer;Color : Cardinal;Pattern,Effect : Integer) : Boolean Dng nh Pattern thnh hnh ch nht [X1,Y1,X2,Y2] vi hiu ng Effect. Mu p l Color. o

CrazyBabe 2003. K-Outertainment Trang 62

Simple TS Gme Dsign & Cding o Hm ImageRenderEffectColor(XPos,YPos : Integer;C1,C2,C3,C4 : LongWord;Pattern,Effect : Integer) : Boolean Dng nh Pattern v tr [XPos, YPos] vi hiu ng Effect. Mu p bn gc ln lt l C1, C2, C3, C4. o Hm ImageRenderEffectColor(XPos,YPos,Scale : Integer;Color : Cardinal;Pattern,Effect : Integer) : Boolean Dng nh Pattern v tr [XPos, YPos] vi hiu ng Effect. T l zoom l Scale/256. Mu p l Color. o Lnh GetInputStatus Cp nht input (Trng thi mouse, keyboard) o Hm KeyDown(Key : Byte) : Boolean Kim tra phm Key c b nhn hay khng ? o Hm KeyPress(Key : Byte) : Boolean Kim tra phm Key c b g hay khng ? o Hm MouseFirstClickL : Boolean Click chut tri ? o Hm MouseFirstClickR : Boolean Click chut phi ? o Hm MouseFirstClickM : Boolean Click chut gia ? o Hm MouseReleasedL : Boolean Th chut tri ? o Hm MouseReleasedR : Boolean Th chut phi ? o Hm MouseReleasedM : Boolean Th chut gia ? o Hm MouseHoldL : Boolean Nhn chut tri ? o Hm MouseHoldR : Boolean Nhn chut phi ? o Hm MouseHoldM : Boolean Nhn chut gia ? o Hm MouseX : Integer To X ca chut. o Hm MouseY : Integer To Y ca chut. o Hm CreateSound(FileName : String;Loop : Boolean) : Integer To handle cho sound FileName. Tr v handle qun l sound ny. o Lnh SoundPlay(Slot : Integer) Chi sound s hiu slot. o Lnh SoundPause(Slot : Integer) Tm dng sound s hiu slot. o Lnh SoundStop(Slot : Integer) Dng sound s hiu slot. o Lnh SoundSetVolume(Slot : Integer;Value : Byte) t cng m thanh cho Slot. o Hm SoundGetVolume(Slot : Integer) : Byte Ly cng m thanh ca Slot.

CrazyBabe 2003. K-Outertainment Trang 63

You might also like