Simple ЯTS G∆me Dεsign & CΘding

Simple ЯTS G∆me Dεsign

& CΘding
e

OpenEdition Copyright © 2θθ3 by CΓ∂z¥Bab ζ All rights reserved June 6th, 2003

© CrazyBabe 2003. K-Outertainment™ Trang 1

Simple ЯTS G∆me Dεsign & CΘding

Chapter I: Introduction

Why did I write this book ?
Trong thời điểm hiện tại, có rất nhiều bạn trẻ hướng sự quan tâm của mình vào thiết kế và lập trình game, phải công nhận một điều rằng chơi game đã là một sự hấp dẫn, nhưng chơi game mình làm ra còn hấp dẫn hơn nhiều, cho dù đó là một trò chơi dở ẹc. Trên những diễn đàn tin học trên Internet đầy rẫy những topic kiểu như là “Lập trình game với..” hay là “Ai chỉ giúp em lập trình game như thế nào”, tất cả đều là sự quan tâm đến mục đích “Làm thế nào để viết nên một game ?”. Những ý kiến xoay quanh vấn đề này rất đa dạng, nói khó cũng có mà nói…dễ cũng có. Với kinh nghiệm và trình độ hiện tại, tôi công nhận một điều là khó, nhưng không phải là quá khó nếu bạn biết đặt mục tiêu vừa tầm và tìm cách tiếp cận nó. Nếu ai cũng hi vọng mình viết ra game tương đương với Quake hay là Warcraft – là sản phẩm của cả một tập thể chuyên nghiệp được xây dựng trong một thời gian dài - ngay lập tức thì quá là viển vông, nhưng nếu bạn hạ thấp mục tiêu xuống một chút như là làm những game đơn giản kiểu như bắn tăng hay Mario, IQ hoặc là những game cho trẻ em trước thì không quá khó nếu bạn biết lập trình. Cá nhân tôi dường như đã nhận thức được điều này và đã có được một số thành công nhỏ trong việc thiết kế và lập trình game. Trong thời điểm này tôi đang được nghỉ ôn thi và tôi quyết định dành một thời gian ngắn để viết cuốn sách này, trong cuốn sách này tôi trình bày một cách đầy đủ quá trình tôi thiết kế và viết mã cho một game RTS đơn giản (được lược bỏ khá nhiều tính năng ví dụ như chơi mạng) nhằm giúp các bạn hiểu được phần nào quá trình “ziết game tại gia”. Hi vọng cuốn sách có thể giúp các bạn trong quá trình thiết kế và viết game của chính mình. Chúc tất cả các bạn thành công trong dự án viết game của mình.

What is RTS game ?
RTS – Realtime Strategy - Thể loại game chiến thuật thời gian thực mà khởi đầu với dòng game Dune, Command & Conquer của Westwood Studio và đã nhanh chóng trở thành dòng © CrazyBabe 2003. K-Outertainment™ Trang 2

do không có nhiều tiến bộ vượt bậc như thời điểm Starcraft (Blizzard Entertainment) ra đời mà chỉ xuất hiện những game lai tạp với các thể loại khác (Warcraft III là thể loại Roleplay Strategy) nên dường như dòng game này đang dần nhường bước cho các dòng game ăn khách khác.Simple ЯTS G∆me Dεsign & CΘding game ăn khách trên toàn thế giới và cả tại Việt Nam. nhưng không nói đâu. C# hoặc Java. Nhưng cá nhân tôi vẫn ôm ước vọng có thể xây dựng một game RTS ăn vào bối cảnh lịch sử Việt Nam và đem lại cho người chơi nhiều cải tiến quan trọng trong cách chơi (He he. How this book will help you Cuốn sách này tôi viết lại quá trình thiết kế. nếu như cuốn sách này làm bạn cảm thấy hứng thú hoặc muốn trao đổi thêm với tôi các bạn có thể liên lạc qua địa chỉ e-mail kimngan2508@yahoo.1 trở lên. 2000 hoặc XP. Misc • Tôi viết cuốn sách này chủ yếu hướng đến các bạn gần như chưa biết gì về lập trình game và chỉ có dụng ý chia sẻ chút kiến thức ít ỏi của bản thân. tôi cố gắng viết mã một cách chân phương nhất có thể – không hề tối ưu. nếu trong quá trình biên tập có chút sơ sót mong các bạn lượng thứ. card màn hình 8MB. viết mã – dĩ nhiên là chú thích tương đối cụ thể – cho một game RTS được thiết kế đơn giản tối đa. theo tính toán của tôi thì chương trình này có thể chuyển sang mọi ngôn ngữ lập trình bậc cao thông dụng như là VB. Bên cạnh đó tôi cũng đưa ra một số kinh nghiệm cá nhân có được trong quá trình làm việc nhằm giúp các bạn có thể hiểu được phần nào công việc thiết kế và lập trình game (Không chuyên nghiệp). đừng bomb tui nha. NT. chắc chắn đa số các bạn có thể hiểu được kĩ thuật thô sơ này. lúc nào làm xong sẽ…nói. C++. hì hì). Còn cuốn sách này giúp gì được bạn thì còn tuỳ thuộc vào bạn. Mã nguồn và dữ liệu của game được cung cấp kèm theo đầy đủ. System & Software requirements • • • • • Hệ thống PIII 500Mhz. ACD FotoCanvas…). Tất cả những gì còn lại đều phụ thuộc vào bạn. Về mặt đồ hoạ tôi không sử dụng những hệ thống 3D phức tạp mà chỉ thiết kế với hệ thống 2D và sprite animation đơn giản. tôi có ít thời gian wé . he he) hoặc qua YIM: kimngan2508. màn hình hỗ trợ chế độ phân giải 800x600x16bit màu. DirectX 8. tôi sử dụng ngôn ngữ Delphi để viết chương trình. Thời điểm hiện tại sự phát triển của dòng trò chơi này dường như chững lại. có card sound (Thực tế tôi chưa chạy thử trên máy có cấu hình yếu hơn nên không rõ có chạy được hay không). Biên dịch bằng Borland Delphi 6 hoặc Borland Delphi 7. nếu mà bạn thuộc hàng cao thủ bít hết rùi hoặc là bạn dumb quá đọc chẳng hiểu gì thì dĩ nhiên là nó chẳng giúp gì được bạn đâu. K-Outertainment™ Trang 3 . 64MB RAM. các bạn chỉ cần biên dịch lại là có thể chạy được ngay lập tức. 98SE. Windows 95. Readers requirements Trong cuốn sách này. Nhưng thực tế hoàn toàn lập trình không hề sử dụng đến các component và cũng không hề sử dụng đến Window API mà thông qua thư viện xây dựng riêng nên gần như các bạn chỉ cần biết Object Pascal là có thể hiểu được mã của chương trình làm việc như thế nào. cải tiến quan trọng à nha.com (Đây là địa chỉ mirror thôi. © CrazyBabe 2003. Nếu các bạn cần chỉnh sửa dữ liệu của game thì cần thêm một trình soạn thảo ảnh (Photoshop. C.nhằm mục đích để mọi người đều có thể cảm thấy dễ hiểu và có thể chuyển sang ngôn ngữ khác. 98. Tôi sẽ cố gắng giải thích cặn kẽ nhất nhằm giúp các bạn có thể hiểu được chương trình làm việc như thế nào.

tôi không chấp nhận mọi hành vi kinh doanh dựa trên tập sách và chương trình này. vì ngại thiết kế hình ảnh và âm thanh nên tôi mượn tạm hình ảnh và âm thanh trong loạt game Starcraft của nhà sản xuất Blizzard Entertainment (Hì hì. Nhưng tôi nghĩ các bạn nên viết lại hoàn toàn thì hơn (nếu muốn làm game thực sự) vì chương trình này không được tốt.. nâng cấp. chắc là chả ai bít nên sẽ không bị. các bạn có thể tuỳ nghi sử dụng. toàn bộ mã nguồn chương trình và cuốn sách này được phân phối miễn phí. Đối với chương trình.Simple ЯTS G∆me Dεsign & CΘding • Cuốn sách này tôi viết hoàn toàn không nhằm mục đích thương mại. © CrazyBabe 2003. K-Outertainment™ Trang 4 . • Trong chương trình.kiện). chỉ cần để một record ghi chú là nâng cấp từ chương trình của CrazyBabe là được.

tức là tôi chỉ quan tâm duy nhất đến chế độ battle của trò chơi mà thôi. hì hì…). tấn công. khai thác. Và tôi cũng loại bỏ một số yếu tố mà tôi cho là đơn giản như là chế độ menu. • Hệ thống phím tắt cố định (Tôi bỏ qua việc xây dựng hệ thống menu điều khiển). khai thác… • Các đơn vị tàu có các tính năng như là di chuyển. tấn công. Cái này cũng nhằm để dễ lập trình nữa. K-Outertainment™ Trang 5 . cơ chế sinh sản các đơn vị quân. loại bỏ bớt yếu tố phức tạp cho địa hình. © CrazyBabe 2003. tính năng của các đơn vị quân và cách chúng tấn công. bỏ qua tất cả các yếu tố khác.Simple ЯTS G∆me Dεsign & CΘding Chapter II: Game Design Design a very simple RTS game Như đã nói trước đây. chán wá thoát ra ngoài – he he . Game này tôi thiết kế sơ bộ như sau: • Thể loại chiến tranh trong không gian . xây tàu con. Tàu mẹ là trung tâm đảm nhận việc xây dựng tàu con. lưu giữ tài nguyên… Tàu con thì đảm nhận nhiều nhiệm vụ khác nhau như là tuần tiễu. • Hệ thống xây dựng game là 2D. Ở đây tôi thiết kế một game thể loại RTS 2D nhưng tính năng rất hạn chế. tuần tiễu. tôi viết cuốn sách này trong một khoảng thời gian ngắn (Chỉ bốn ngày cả viết mã và viết tài liệu) nên đối tượng game tôi sử dụng phải tương đối đơn giản (Do lí do hạn chế thời gian và cả trình độ nữa. kiểu địa hình cũng là một yếu tố quan trọng. chọn bản đồ. loại quân… mà nhảy vào là chương trình load một bản đồ mặc định và chạy luôn bản đồ này cho đến khi trận chiến kết thúc hoặc là bạn.Starwars lun. Một game RTS cơ bản thì xoay quanh một số yếu tố như sau: cơ chế khai thác tài nguyên. nhưng hi vọng trong thời gian đến tôi sẽ có thời gian để nâng cấp game lên hỗ trợ chế độ này. Tôi xây dựng game này hiện tại hoàn toàn không hỗ trợ chế độ multiplayer.. chiến chưa ? :) • Không có địa hình. • Game gồm hai loại đơn vị chính là tàu mẹ và tàu con.

tôi sử dụng bộ thư viện AvenusHelper được tôi thiết kế nhằm giảm tối đa các công việc các bạn cần thực thi chi tiết với hệ thống như là khởi tạo đồ hoạ. sub.ở một tập sách khác. Dưới đây là một screen shot từ game này: Game programming environment Các bạn khi trao đổi với nhau về lập trình game thường trao đổi với nhau về những vấn đề cụ tỉ như là vẽ bằng DirectX hay OpenGL. các unit được xử lý như thế nào.Simple ЯTS G∆me Dεsign & CΘding Sơ bộ là như vậy. K-Outertainment™ Trang 6 . máy tính chơi ra sao. những sự kiện được xử lý thế nào…mà thôi. mul…Ở đây các bạn chỉ cần chú ý đến việc làm thế nào game chạy được. Nếu muốn nâng cấp game thành 3D tôi nghĩ cũng có thể làm được. các tính năng khác tôi nghĩ rằng các bạn có thể thêm vào đơn giản nếu như hiểu được chương trình. đọc ảnh và vẽ ảnh bằng những hiệu ứng đơn giản như là add. © CrazyBabe 2003. làm thế nào để lấy một sprite hay là vẽ sprite đấy bằng hiệu ứng như thế nào…thiết nghĩ những thứ đó quá lặt vặt – dĩ nhiên là không nói đến chuyện thiết kế các engine 3D lớn rùi – Trong khi lập trình game này. Nếu cần quan tâm đến những chi tiết nhưng là làm thế nào để thực hiện hiệu ứng alpha blend chẳng hạn chúng ta sẽ bàn sau .

Simple ЯTS G∆me Dεsign & CΘding

Chapter III: Game Coding

Chương này chỉ đơn giản là tôi chú thích mã nguồn của chương trình. Dưới đây là mã nguồn của đơn vị Game, là thành phần chính của chương trình. { Tôi đặt định nghĩa này nhằm chỉ chương trình chạy trong chế độ toàn màn hình hay chế độ cửa sổ } {$Define FullScreen} { Định nghĩa này nhằm xác định chương trình có hỗ trợ âm thanh hay không } {$Define SoundPlaying} UNIT Game; INTERFACE { Ở đây tôi khai báo các đơn vị mà chương trình sử dụng } USES Windows, MMSystem, SysUtils, Math, FireStormDLL, AvenusHelperDLL; CONST { ScrWidth x ScrHeight là hằng định nghĩa kích thước cửa sổ hoặc độ phân giải ở chế độ toàn màn hình. Chú ý là khi chương trình ở chế độ cửa sổ tức là biên dịch không có chỉ thị FullScreen thì kích thước là tuỳ ý, nhưng nếu chương trình chạy ở chế độ toàn màn hình thì kích thước độ phân giải này phải được màn hình hỗ trợ và thường là các độ phân giải thông dụng như là: 640x480, 800x600, 1024x768, 1152x864, 1280x1024… © CrazyBabe 2003. K-Outertainment™ Trang 7

Simple ЯTS G∆me Dεsign & CΘding } ScrWidth ScrHeight { } Caption { MaxUnit là hằng số định nghĩa số lượng unit lớn nhất mà chương trình hỗ trợ xử lý, con số này là tui đặt đại như zậy chớ nếu mà xử lý thực tế như thế (chương trình hoàn toàn không tối ưu) thì chỉ cần khoảng 4000 chắc là con P4 của tui cũng die hard lun chứ không cần phải thử trên máy cấu hình yếu đâu :> } MaxUnit = 8000; { DataPath là đường dẫn đến thư mục chứa dữ liệu của chương trình } DataPath = 'Data\'; { ShipsSettingDir là đường dẫn đến thư mục con chứa các file dữ liệu về các loại tàu trong game. } ShipsSettingDir = 'ShipsSetting\'; { ScrollSpeed là tốc độ di chuyển minimap trong game, tôi đặt nó là biến số nhằm mục đích có thể thay đổi tốc độ nhưng phần này tui chưa viết, các bạn tự thêm vào nha. } ScrollSpeed : Word = 15; { MoveFarLeng, TooNearLeng, AroundLeng là các hằng số chỉ độ lớn giới hạn ví dụ như là giới hạn của các tàu quá gần nhau… } MoveFarLeng = 10; TooNearLeng = 3; AroundLeng = 100; { ScreenUpDate là khoảng thời gian (phần nghìn giây) mà chương trình thực thi cập nhật lại màn hình. Với giá trị 33 chương trình cập nhật khoảng 28-30 lần một giây. UnitUpDate là khoảng thời gian mà chương trình thực hiện xử lý cho các đơn vị, với giá trị 10 thì chương trình xử lý các đơn vị trung bình khoảng 70 lần một giây. InputUpDate, MiniMapUpDate lần lượt là khoảng thời gian chương trình thực hiện cập nhật bàn phím, chuột… và cập nhật lại minimap (Bản đồ con). MoneyTime là khoảng thời gian chương trình thêm xiền cho các phe. } ScreenUpdate : LongWord = 33; UnitUpdate : LongWord = 10; InputUpdate : LongWord = 10; MiniMapUpdate : LongWord = 10; MoneyTime : LongWord = 120000; { DefaultMoney là số xiền game cho mỗi phe mỗi lần “cấp phát”. } DefaultMoney = 10000; { PanelSizeX, PanelSizeY là kích thước Panel thể hiện thông tin về đơn vị đang được chọn. MiniMapSizeX, MiniMapSizeY là kích thước bản đồ nhỏ hiển thị trên màn hình. © CrazyBabe 2003. K-Outertainment™ Trang 8 = 'Simple RTS Game Demo [C]CrazyBabe.2003'; = 1024; = 768;

Caption là hằng xâu định nghĩa tên cửa sổ của chương trình tạo ra

Simple ЯTS G∆me Dεsign & CΘding } PanelSizeX PanelSizeY MiniMapSizeX MiniMapSizeY { Cứ sau khoảng FrameRateForFindTarget frame thì chương trình thực hiện tìm kiếm mục tiêu cho các đơn vị đang không có lệnh. } FrameRateForFindTarget = 40; TYPE { Định nghĩa kiểu để đánh số các đơn vị trong game. } TUnitCount = 1..MaxUnit; { Định nghĩa kiểu toạ độ nguyên và toạ độ thực. } TRPoint = Record X,Y : Single; End; TPoint = Record X,Y : Integer; End; { Định nghĩa số hướng đơn vị có thể xoay là 32 hướng. Số hướng này càng nhiều thì đơn vị xoay càng mịn, nếu xây dựng với 3D thì không cần đến định nghĩa số hướng này mà chỉ cần lưu lại góc nhìn của đơn vị. Hic, chóng mẹt 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 nghĩa số kiểu tàu có trong game, hik, bạn bịa tên gì cũng 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

'[H26]'.'[H30]'. '[H17]'. chuyển dịch (đi đến đích cụ thể nhưng tấn công địch gặp trên đường)… } TCommand = ( NoCmd. đi tuần. GunMileMissile ). } //Defined a name of types for configuration getting types CONST HeadingName : Array[THeading] of String[5] = ( '[H01]'. CmdEnd//Temporary command ).'[H19]'.'[H23]'.'[H11]'. CmdBurn.'[H03]'. © CrazyBabe 2003. CmdAttackT. CmdAttackP. '[H05]'. tên lửa… PlayerNature để đánh dấu các vật thể như là các hành tinh.'[H20]'. Player4 ). // //Unit command // CmdMove.Simple ЯTS G∆me Dεsign & CΘding Định nghĩa số lệnh mà unit có thể thực hiện trong game. Player3.'[H14]'.'[H18]'. CmdPatrol. '[H25]'. '[H29]'.'[H08]'. '[H09]'.'[H12]'. thiên thạch… } TPlayer = ( NonePlayer.'[H27]'.'[H32]'). '[H13]'. Player1. GunEvelMissile.'[H22]'.'[H06]'. tấn công. bốn phe Player1-4 dùng để đánh dấu các phe chơi. { Định nghĩa số phe trong game. { Định nghĩa các tên kiểu.'[H07]'. K-Outertainment™ Trang 10 .'[H24]'.'[H16]'. do game tôi thiết kế rất đơn giản nên unit mới chỉ có thể nhận các lệnh như là di chuyển.'[H15]'.'[H04]'. '[H21]'.'[H28]'.//NonePlayer 'NATURE'.'[H10]'. CmdAttack. còn NonePlayer dùng để đánh dấu những unit misc như là khói. CmdAttackM. tên hướng… để lấy giá trị từ file config. Player2. CmdFire. // //Mouse command // MouseSelection. PlayerNature. { Định nghĩa các kiểu súng mà unit sử dụng } TGun = ( GunMiniMissile. PlayerName : Array[TPlayer] of String[8] = ( ''.'[H31]'.'[H02]'.

ImageFilesStr = 'IMAGEFILES'. 'COONOK'. ShipCost = 'SHIPCOST'. K-Outertainment™ Trang 11 . ShipCanCreate = 'SHIPCANCREATE'. 'INTERCEPTOR'. GunName : Array[TGun] of String[20] = ( 'MINIMISSILE'. 'PLAYER04' ). ShipTurnWaitStr = 'SHIPTURNWAIT'.//NoneShip 'FIREPLANET'.Simple ЯTS G∆me Dεsign & CΘding 'PLAYER01'. ShipName : Array[TSpaceShip] of String[20] = ( ''. 'PLAYER03'. Ani : Array of Record FramePos : Integer. 'MILEMISSILE' ). ShipSpeedStr = 'SHIPSPEED'. ShipNameStr = 'SHIPNAME'. ShipWaitStr = 'SHIPWAIT'. 'EVELMISSILE'. 'BATTLECRUISEAMON'. 'MILEMISSILE'. 'EVELMISSILE'. 'SCOUT'. ExplosionSkinStr = 'EXPLOSIONSKIN'. 'CARRIER'. } TFrame = Array[THeading] of Record NumFrames : Integer. FrameStyle : Integer. 'SUPPERBATTLESHIP'. kiểu vẽ frame. ShipCreateTime = 'SHIPCREATETIME'. ShipSizeStr = 'SHIPSIZE'. ShipAttackRangeStr = 'ATTACKRANGE'. 'BURN' ). 'PLAYER02'. ShipFrameStr = 'SHIPFRAME'. { Định nghĩa một số tên chỉ thị để lấy thông tin từ file config. ShipHitPointStr = 'SHIPHITPOINT'. End. } //Constant name of script directive CONST SettingStr = 'SETTING'. End. 'MINIMISSILE'. { © CrazyBabe 2003. 'BATTLECRUISEBATON'. ShipGunStr = 'SHIPGUN'. TYPE { Định nghĩa kiểu frame animation: Mỗi hướng có một bản ghi riêng Bản ghi ghi lại số frame animation và một mảng lưu chi tiết thông tin về frame animation đó: số hiệu của frame. ShipDamageStr = 'SHIPDAMAGE'.

_Size. _Images: Mảng lưu số hiệu các ảnh của đơn vị (Do AvenusHelper quản lý các ảnh theo số hiệu nên phải lưu trữ theo cách này để truy cập lại) _ShipCanCreate: Tàu con mà unit này có thể sinh. _Wait. _TurnWait: Thời gian chờ di chuyển và xoay đầu của đơn vị. nếu là NoneShip thì unit không có khả năng sinh tàu mới. _Cost: là chi phí để sinh loại đơn vị này. _Damage : Integer. Với đơn vị là FirePlanet: Mức độ mờ. _Cost : Integer. _BuildTime: là thời gian sinh ra loại đơn vị này. _Size2: Kích thước của đơn vị/kích thước chia hai của đơn vị. hè hè… } TShipAni = Record Move. _Speed: Tốc độ của đơn vị. _Speed : Integer. _AttackRange: Giới hạn tấn công của đơn vị.Simple ЯTS G∆me Dεsign & CΘding Định nghĩa kiểu dữ liệu animator của một biến tàu. © CrazyBabe 2003. Với các đơn vị tàu: Dest: Đích đến của unit. K-Outertainment™ Trang 12 . _ShipCanCreate : TSpaceShip._Size2 : Integer. _BuildTime : Integer. _Damage: Số damage (tạm dịch: chỉ số sát thương) của đơn vị. _Gun: Kiểu súng của đơn vị. } TUnitProperty = Record _HitPoint : Integer. Ở đây có hai trường là Move và Attack nhưng tui mới dùng có trường Move thui. gợi ý các bạn khai báo thêm vài unit kiểu nổ rùi thêm nó vào khi unit tiêu tùng giống như là thêm khói Burn khi tên lửa bắn đi vậy). _NumOfImages : Integer. _Size. cái này nhằm chỉnh lại các hành tinh không được vẽ sau các tàu chẳng hạn. _Wait._TurnWait : Integer. đỡ phải tính lại. _Images : Array of Integer.Attack : TFrame. End. _AttackRange : Integer. tốc độ mờ để vẽ viền của unit này. _DrawLevel: càng thấp thì được vẽ trước. biến này lưu vì nhiều khi dùng biến này lém. { Định nghĩa kiểu dữ liệu lưu trữ thông tin về một đơn vị: Owner: Unit thuộc phe nào ? HitPoint: Máu hiện tại của đơn vị. End. _Explosion : TSpaceShip. _Gun : TGun. _ShipAni : TShipAni. TYPE { Định nghĩa kiểu dữ liệu lưu trữ những thông tin cơ bản về một kiểu unit: _HitPoint: Số máu mặc định của đơn vị. _Explosion: Kiểu nổ của đơn vị (Hiện tại chưa để làm gì cả. _DrawLevel : Byte. Pos: Vị trí của đơn vị trên bản đồ. _NumOfImages: Số lượng ảnh của đơn vị.

Enemy: Đánh dấu xem chú nào là địch ? } TYPE TPlayersData = Record Name : String[20]. TransparentSpeed : Integer. K-Outertainment™ Trang 13 . UnitNextTarget: Unit đích hiện tại và unit đích tiếp theo. } TYPE © CrazyBabe 2003. ). UnitTarget. PatrolDest: Điểm xuất phát và kết thúc của lệnh đi tuần (Patrol) CurrentHead. BattleCruiseAmon. HitPoint : Integer. Money: Bi chừ em đang có bao nhiu xiền hỉ ? CountUnit: Tổng số unit player này hiện đang có. CurrentHead. UnitCmd. UnitGroup: Số hiệu nhóm của unit. UnitCmd. { Định nghĩa kiểu dữ liệu lưu thông tin về bản đồ: Scale: Kích cỡ zoom của bản đồ này. ). CountUnit : Integer. Size: Kích cỡ của bản đồ. { Định nghĩa kiểu dữ liệu lưu thông tin cho từng player trong game: Name: Dĩ nhiên là lưu…tên roài. NumTile: Số lượng ảnh nhìn thấy được trên màn hình. CurrentFrame. UnitTarget.PatrolStart. Pos : TRPoint. Enemy : Array[TPlayer] of Boolean.UnitNextCmd : TCommand. End. Head: Hướng hiện tại. hướng cần xoay đến. UnitNextCmd: Command của unit hiện tại và command kế tiếp. WaitTimeForMove : Integer. Money : Integer. SupperBattleShip. ViewPos: Vị trí nhìn hiện tại. Case Typer : TSpaceShip of FirePlanet : ( TransparentLevel : Integer. CurrentFrame: Frame ảnh hiện tại. map này được dựng đơn giản với toàn các ảnh nền này xắp xếp bên cạnh nhau. Interceptor : ( Dest.Simple ЯTS G∆me Dεsign & CΘding PatrolStart. CooNok. CreationCounting : Integer. CreationCounting: Số bước thực hiện tạo tàu mới (Khi unit thực hiện lệnh tạo quân). Scout. UnitGroup : Byte. End.Head : THeading. Size = Scale * DefaultMiniMapSize StarBackGround: Ảnh nền. WaitTimeForMove: Số game frame cần để di chuyển.UnitNextTarget : TUnitCount. } TUnit = Record Owner : TPlayer.PatrolDest : TRPoint. BattleCruiseBaton.

} EndGame : Boolean. Số lượng hướng càng nhìu thì unit xoay càng mịn và tôi sử dụng toạ độ của unit kiểu số thực do nếu dùng số nguyên thì bước di chuyển của unit sẽ có độ dài không đều nhau và khi chuyển lên toạ độ nguyên của màn hình unit sẽ di chuyển trông giựt giựt kì lém á… } Moving : Array[THeading.2] of Single.Simple ЯTS G∆me Dεsign & CΘding TWorld = Record Scale. K-Outertainment™ Trang 14 . { Đối tượng chính: GamePlay. } GameWorld : TWorld. } UnitsProperty : Array[TSpaceShip] of TUnitProperty.ViewPos. { Đánh dấu game đang trong chế độ tạm dừng. } GamePlayers : Array[TPlayer] of TPlayersData. { Dữ liệu về những người chơi trong game. StarBackGround : Integer.. } GameUnits : Array[TUnitCount] of TUnit. { © CrazyBabe 2003. { Dữ liệu về tính năng chuẩn của các unit trong game. } MouseCommand : TCommand. { Vị trí đầu và vị trí cuối cùng người chơi kéo chuột (Khi chọn các đơn vị). { Dữ liệu về lệnh đang chờ đặt thực hiện (Bằng chuột . } SelectStart.SelectEnd : TPoint. NumTile : TPoint. } TYPE TGame = Class { Đánh dấu game đã kết thúc. } HumanControl : TPlayer. { Dữ liệu về các unit trong game. { Toạ độ unit dịch chuyển trong từng bước đi. { Phe mà người chơi điều khiển.1.Size : TPoint. } PauseGame : Boolean. { Dữ liệu về bản đồ trong game.Giống như khi bạn ra lệnh Patrol trong game Warcraft thì chương trình cần chờ bạn chọn vị trí bằng chuột mới thực hiện lệnh điều khiển này). End.

} PanelImage : Integer.Simple ЯTS G∆me Dεsign & CΘding Ảnh lưu bản đồ nhỏ. khi vẽ lại bản đồ nhỏ tôi chỉ vẽ lại ảnh này. { Biến này lưu giữ trạng thái bản đồ có được thể hiện hay không. { Đây là các thông tin tương tự như của minimap nhưng là của thành phần tôi gọi tạm là Panel. khi chọn bạn có thể chọn tất cả các đơn vị của bạn trong khi thanh Panel chỉ có thể hiển thị thông tin về một đơn vị. LastGameMiniMapTime. } GameStart. { Số hiệu đơn vị đầu tiên trong nhóm đơn vị được lựa chọn. Hàm này chỉ cập nhật bản đồ sau một khoảng thời gian cố định bởi nếu cập nhật liên tục thì tốc độc chương trình giảm thảm hại và kết quả sẽ là một đi không trở lại… } MiniMapImage : Integer. Thời điểm cuối cùng đã cập nhật tiền cho các phe. } PlayerColor : Array[TPlayer] of LongWord. mouse). 3D mà thế này chắc giựt tung tròng mắt ra wé…hix). Thời điểm cuối cùng đã cập nhật minimap. } MiniMapPosX. Thời điểm cuối cùng đã cập nhật xử lý đơn vị. LastGameMoneyTime : LongWord.PanelPosY : Integer. Thời điểm cuối cùng đã cập nhật xử lý input (keyboard. } MiniMapVisible : Boolean. } FirstUnitSelect : TUnitCount. Thời điểm cuối cùng đã cập nhật màn hình. Thời gian game đã chạy. Thông tin này dùng để tính GFPS (Game Frame Per Second) và SFPS (Screen Frame Per Second). LastGameUnitTime. còn việc cập nhật ảnh dùng bằng một hàm khác. K-Outertainment™ Trang 15 . { Số lượng frame game đã chạy (đếm theo số frame xử lý unit) và số lượng frame hình ảnh đã được cập nhật (số hình ảnh vẽ ra). đó chính là đơn vị này. CommandPanelVisible : Boolean. © CrazyBabe 2003.MiniMapPosY : Integer.GameScreenFrame. { Thời điểm game bắt đầu. giúp người chơi có thể tắt thể hiện bản đồ nhằm tăng không gian điều khiển các unit của họ. { Màu của các đơn vị khi xuất hiện trên bản đồ. { Vị trí bản đồ được vẽ trên màn hình. LastGameScreenTime. } GameFrame. cái này thể hiện trạng thái của đơn vị đang được lựa chọn. PanelPosX. Trong chương trình này tui đặt thời gian như trên nên SFPS đạt khoảng 28 FPS/1024x768x16bit color. số khung hình như thế này là chấp nhận được với game 2D (Hic.GameTime. LastGameInputTime.

OverRide.P2 : TPlayer). số tiền có sẵn. } Procedure ProcessInput. Các đơn vị sẽ chỉ tìm và tấn công các đơn vị thuộc phe đối địch mà thôi (Dĩ nhiên !) } Procedure SetPlayerEnemy(P1. UnitCounting : Integer. Procedure ProcessEvents.FlareImageNum : Integer. Procedure Play. Procedure ProcessUnits. { Đặt quan hệ giữa phe P1 và P2 là đối địch.Gray. hix. © CrazyBabe 2003. nổ). } White.Simple ЯTS G∆me Dεsign & CΘding { Ảnh FirePlanet và quầng sáng bao quanh nó.ShowDebug : Boolean. { Hàm xử lý xuất nhập. { Cấu hình cho phe Player: Tên phe. Đáng ra việc quản lý âm thanh nên tạo lập một class khác chuyên nghiệp hơn nhưng do ít thời gian quá nên gần như tôi bỏ qua việc xử lý âm thanh. {$EndIf} { Frame hiện tại dùng để tìm đích cho các unit ? } IsFrameToFindTarget : Boolean. xử lý các sự kiện và hàm chính gọi khi bắt đầu tiến trình xử lý một trận. { Phương thức khởi tạo và huỷ lớp Game này. } {$IfDef SoundPlaying} BackGroundMusic. K-Outertainment™ Trang 16 . } LastMissileLauchSoundTime.BlueGray : LongWord. LastMissileExploredSoundTime : LongWord. Đây là thông tin dùng để hạn chế việc gọi một âm thanh liên tục quá nhiều lần dẫn đến mất tài nguyên của máy tính. { Lần cuối cùng sử dụng loại âm thanh (bắn. hì hì. { Hằng số định nghĩa màu. { Thông tin debug: Hiển thị FPS. { Dữ liệu về âm thanh trong game.Green. } GlobeImageNum. MissileLauch. Destructor Destroy. tại tôi ngại config cho kiểu đơn vị này nên làm kiểu lười. } Constructor Create. xử lý các unit. hiển thị thông tin debug ? Tổng số unit đang sử dụng ? } ShowFPS. MissileExplored : Integer.

} Procedure HumanSetCommandAttack(Target : TUnitCount).Y] trên map. Vì mỗi đơn vị chỉ có thể sinh ra một loại quân nhất định nên không cần biết yêu cầu là sinh đơn vị gì. } Procedure HumanSetCommandCreate. { Tạo một thông điệp đến người chơi. Procedure ProceedMouseLReleased. K-Outertainment™ Trang 17 .Simple ЯTS G∆me Dεsign & CΘding } Procedure SetupPlayer(Player : TPlayer. đếm frame… } Procedure RestartCount. } Procedure HumanSetCommandAttackTo(X. { Hàm xử lý các sự kiện chuột được nhấn.Y : Integer). { Người chơi đặt lệnh dừng cho tất cả các đơn vị họ đang chọn.Y : Integer). { Người chơi đặt lệnh cho nhóm quân đang chọn tấn công đến vị trí [X. trong quá trình di chuyển unit sẽ tấn công bất cứ mục tiêu nào nó nhìn thấy. thả. { Thêm tiền cho tất cả các phe. trong quá trình di chuyển unit sẽ tấn công bất cứ mục tiêu nào nó gặp mặt.Y] trên map. Procedure ProceedPlayerInput. { Người chơi đặt lệnh cho nhóm quân đang chọn đi tuần đến vị trí [X. { Người chơi đặt lệnh cho nhóm quân đang chọn di chuyển đến tọa độ [X. } Procedure AddMoneyForAllPlayer. { Người chơi đặt lệnh sinh quân cho tất cả các đơn vị họ đang chọn.Y : Integer). điều khiển từ người chơi… } Procedure ProceedMouseLHolding. Trong game này để đơn giản hoá việc xử lý tôi bỏ qua việc khai thác tài nguyên. { Đọc các cấu hình của các loại đơn vị trong game (từ file text). } Procedure CreateMessage(Msg : String). } Procedure HumanSetCommandStop. © CrazyBabe 2003. { Khởi tạo lại tất cả các biến đếm thời gian.Name : String. } Procedure HumanSetCommandMove(X.Y] trên map. Procedure ProceedMouseRHolding. hàm này gọi khi chương trình phát sự kiện cập nhật tài nguyên cho các phe. Procedure ProceedMouseRReleased. } Procedure LoadSetting. sau một khoảng thời gian xác định game sẽ cung cấp cho mỗi phe một số tiền xác định. } Procedure HumanSetCommandPatrol(X. { Người chơi đặt lệnh cho nhóm quân đang chọn tấn công unit số hiệu Target.Money : Integer).

mới chỉ đặt một bản đồ linh tinh và mấy unit để test thôi. } Procedure ProceedUnitSettingFile(FileName : String). } Function DestroyUnit(UnitNum : TUnitCount) : Boolean. { Cấu hình hình ảnh của các unit không được cấu hình bằng file (FirePlanet). K-Outertainment™ Trang 18 Cấu hình ảnh World (Hè. } Procedure SetupUnitsSetting. ScaleSizeY * MiniMapSizeY] } Procedure SetupWorldSize(ScaleSizeX. UnitTyper : TSpaceShip. cái này tui…chưa làm.PosY : Integer) : TUnitCount.ScaleSizeY : Integer). Player : TPlayer. { Khởi tạo dữ liệu chuẩn của kiểu UnitTyper cho unit số hiệu UnitNum. } Procedure LoadWorld(FileName : String).ViewY : Integer). { “Thanh toán xiền” khi sinh unit mới. Procedure SetupWorldImage. } Procedure SetupUnitsImage. { Đọc cấu hình của unit từ file. { Tạo một unit UnitTyper mới của Player ở vị trí [PosX . } Function CreateNewUnit(UnitTyper : TSpaceShip. PosY].Simple ЯTS G∆me Dεsign & CΘding { } { Cấu hình kích thước bản đồ. { Lấy cấu hình unit từ file. { Huỷ unit số hiệu UnitNum. tên và các cấu hình của unit đã có đủ trong file cấu hình. thực chất chỉ là load ảnh nền liên quan đến WorldMap thôi). PosX. { Cập nhật MiniMap } Procedure WorldMiniMapUpdate. . Đọc bản đồ từ file. { } { Đặt vị trí nhìn trên bản đồ ở [ViewX . ViewY] Procedure WorldViewAt(ViewX. © CrazyBabe 2003. nếu Player không còn đủ tài nguyên. còn nếu không còn vị trí trống để sử dụng cho unit này thì hàm trả về Low(TunitCount) như vậy đơn vị số hiệu này không bao giờ được sử dụng. kích thước bản đồ bằng: [ScaleSizeX * MiniMapSizeX . } Procedure SetupUnit(UnitNum : TUnitCount. hàm trả về số hiệu của unit nếu tạo lập thành công. tôi nghĩ cái này các bạn có thể tự làm được một cách dễ dàng. hàm trả về False còn nếu đủ sẽ trừ đi số tài nguyên tương ứng và trả về giá trị True. Player : TPlayer).

} Procedure UnitHit(UnitNum : TUnitCount). } Procedure UnitFire(UnitNum : TUnitCount). Khi gọi lệnh này. Lấy unit trên cùng được chọn từ toạ độ [MX. { Tính thiệt hại khi unit chạm đích (đây là dành cho các unit loại Missile). Long : Integer) : Boolean. { } { Bỏ chọn tất cả các unit. HumanOwner : Boolean) : TUnitCount. { Hàm này cho biết unit cần xoay về hướng nào để đến được đích của nó. còn nếu không thấy sẽ trả về giá trị Low(TunitCount). { Hàm chọn các unit bằng chuột. { Unit có trong tầm nhìn không ? } Function UnitVisible(UnitNum : TUnitCount) : Boolean. . Hàm trả về số hiệu của unit tìm thấy. { Chỉnh hướng unit về phía đích của nó.MY].Simple ЯTS G∆me Dεsign & CΘding } Function { } Procedure SelectUnit(UnitNum : TUnitCount). } Procedure UnitPointToTarget(UnitNum : TUnitCount). Procedure UnSelectAllUnit. { Khoảng các giữa unit và đích nhỏ hơn Long ? } Function UnitCloseToTarget(UnitNum : TUnitCount. Tham số HumanOwner để chỉ đơn vị được chọn chỉ được phép thuộc nhóm unit của người chơi. Đặt unit số hiệu UnitNum được đưa vào nhóm chọn. unit sẽ sinh loại Missile tương ứng nhắm đến đích của nó. K-Outertainment™ Trang 19 CostForNewUnit(Player : TPlayer. tham số Add cho biết có thêm unit vào nhóm đang chọn hay xoá bỏ tất cả và chọn lại từ đầu. } Function GetUnitAtMouse(MX. } Procedure CallMouseSelectionUnit(Add : Boolean). { Giảm máu của unit đi Damage đơn vị.MY : Integer. } Function UnitGetBestHeading(UnitNum : TUnitCount) : THeading. { © CrazyBabe 2003. { Đặt lệnh cho unit “bắn” vào đích. Ở đây chỉ đơn giản là xoay về hướng có toạ độ thẳng nhất.Damage : Integer). UnitTyper : TSpaceShip) : Boolean. } Procedure UnitDecHitPoint(UnitNum : TUnitCount.

DestY : Integer). { Đặt lệnh cho unit đang trong trạng thái di chuyển tấn công unit Target. } Procedure UnitSetMove(UnitNum : TUnitCount. Lấy lệnh kế tiếp cho unit: Khi người chơi đặt lệnh cho unit mà unit đang thực thi một lệnh khác. } Procedure UnitSetAttackPatrol(UnitNum : TUnitCount.Y.Leng : Integer.Target : Integer).DestY].DestY]. { Đặt lệnh tạo quân cho unit. { Chuyển lệnh của unit về lệnh trước đó nó đang nhận ( Nếu unit đang nhận lệnh AttackPatrol thì lệnh trước đó là Patrol.Var DX.Y1.DestY]. } Function { RandomPlayer : TPlayer. } Procedure UnitSetCreate(UnitNum : TUnitCount).Target : Integer). © CrazyBabe 2003.Y2 : Single) : Single. nếu unit đang nhận lệnh AttackMove thì lệnh trước đó là AttackTo).EndHead : THeading) : THeading. } Function { } Procedure PointNear(X. } Procedure UnitSetAttack(UnitNum : TUnitCount.DY : Integer). HeadNear(StartHead. } Procedure UnitResetCommand(UnitNum : TUnitCount). Lấy một điểm bất kì trong khoảng cách Leng đến toạ độ [X. Function Long(X1.Y1] đến [X2.Y] . lệnh đặt vào UnitNextCmd và hàm này thực hiện kiểm tra UnitNextCmd để chuyển lệnh của unit sang lệnh mới.DestX.DestX.DestY : Integer).DestY : Integer). { Đặt lệnh cho unit đi tuần đến vị trí [DestX. } Function UnitGetNextCmd(UnitNum : TUnitCount) : Boolean.Simple ЯTS G∆me Dεsign & CΘding Hướng cạnh StartHead gần với EndHead nhất. { Đặt lệnh cho unit tấn công Target. { Đặt lệnh cho unit đang trong trạng thái đi tuần tấn công unit Target. } Procedure UnitSetPatrol(UnitNum : TUnitCount.DestX. { Đặt lệnh cho unit tấn công đến vị trí [DestX. { Đặt lệnh cho unit di chuyển đến vị trí [DestX. { } { Sinh một số hiệu phe bất kì. } Procedure UnitSetAttackMove(UnitNum : TUnitCount. K-Outertainment™ Trang 20 Độ dài từ [X1.Y2]. } Procedure UnitSetAttackTo(UnitNum : TUnitCount.Target : Integer).X2.

Xử lý unit đang nhận lệnh Move. Xử lý unit đang nhận lệnh Patrol.Simple ЯTS G∆me Dεsign & CΘding { } { } { } Procedure ProcessSpecifyUnit(UnitNum : TUnitCount). Procedure RenderWorld. Procedure ProceedUnitAttack(UnitNum : TUnitCount). Procedure ProcessNormalUnit(UnitNum : TUnitCount). Xử lý các unit đặc biệt (FirePlanet). Vẽ nền bản đồ. { } { } { } Procedure ProceedUnitBurning(UnitNum : TUnitCount). Xử lý unit đang không có lệnh. Xử lý unit đang nhận lệnh AttackT (Attack to somewhere). Xử lý unit đang nhận lệnh AttackM (Attack while move to somewhere). { } { } { } Procedure ProceedUnitAttackT(UnitNum : TUnitCount). Procedure ProceedUnitPatrol(UnitNum : TUnitCount). Procedure ProceedUnitStand(UnitNum : TUnitCount). Xử lý unit đang nhận lệnh Burn. { } { } { } Procedure ProceedUnitMove(UnitNum : TUnitCount). K-Outertainment™ Trang 21 . Tìm unit ở gần UnitNum. Xử lý unit đang nhận lệnh Attack. { } { } Vẽ unit UnitNum. Procedure ProceedUnitAttackM(UnitNum : TUnitCount). Xử lý các unit bình thường. Function UnitFindNear(UnitNum : TUnitCount) : TUnitCount. Procedure ProceedUnitAttackP(UnitNum : TUnitCount). hàm này xây dựng để xử dụng khi dãn đội hình ra. Function UnitFindTarget(UnitNum : TUnitCount) : TUnitCount. Xử lý unit đang nhận lệnh AttackP (Attack while patrol). © CrazyBabe 2003. Unit tìm đối phương trong tầm tấn công (Tìm đối phương gần nhất).

Moving[H04. Lấy loại tàu bằng tên. Moving[H09. các thông tin khác… Procedure RenderInfos. Lấy số hiệu phe bằng tên. Moving[H02.Create. { } Procedure RenderUnits. Begin //Moving generating Moving[H01. Moving[H05. IMPLEMENTATION USES CommonFuncs. Moving[H06. Moving[H02.1]:=+Abs(Sin(DegToRad(90/8*3))). Moving[H03.2]:=-Abs(Cos(DegToRad(90/8*2))).1]:=+Abs(Sin(DegToRad(90/8*4))).1]:=+0.2]:=-Abs(Cos(DegToRad(90/8*7))).Simple ЯTS G∆me Dεsign & CΘding Procedure RenderUnits(UnitNum : TUnitCount).1]:=+Abs(Sin(DegToRad(90/8*6))). Lấy hướng bằng tên. Procedure RenderScene. K-Outertainment™ Trang 22 . © CrazyBabe 2003.2]:=-Abs(Cos(DegToRad(90/8*6))). GetGun(Name : String) : TGun. Moving[H07. CONSTRUCTOR TGame. Moving[H06. GetShipTyper(Name : String) : TSpaceShip.2]:=-Abs(Cos(DegToRad(90/8*3))). Vẽ các MiniMap.1]:=+Abs(Sin(DegToRad(90/8*2))). Panel.2]:=-Abs(Cos(DegToRad(90/8*4))). Moving[H07. Lấy loại súng bằng tên. Function GetPlayer(Name : String) : TPlayer. OverLoad. Moving[H08.1]:=+Abs(Sin(DegToRad(90/8*7))).2]:=-Abs(Cos(DegToRad(90/8*1))).1]:=+Abs(Sin(DegToRad(90/8*7))). Moving[H10. Moving[H09. Moving[H03. Moving[H08. { } { } { } Function { } { } { } Function End.1]:=+Abs(Sin(DegToRad(90/8*1))).1]:=+Abs(Sin(DegToRad(90/8*5))). Moving[H04. Vẽ toàn bộ. Vẽ tất cả các unit.2]:=-Abs(Cos(DegToRad(90/8*5))). Moving[H05. VAR MyGame : TGame. Moving[H01.1]:=+1.2]:=+0.2]:=-1. OverLoad. Function GetHeading(Name : String) : THeading.

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

255.000)).000).Destroy. Begin If MouseCommand=MouseSelection then Begin SelectEnd. {$EndIf} End.False).255. LoadSetting. PanelPosX:=10.255.//Green PlayerColor[Player3]:=Color32To15(RGB2LongWord(000. // SetupWorldImage.Mp3'.X.255).100. //Colour setup White:=RGB2LongWord(255.//White PlayerColor[Player1]:=Color32To15(RGB2LongWord(255. PanelPosY:=ScrHeight-PanelSizeY-10. End.Simple ЯTS G∆me Dεsign & CΘding MiniMapPosY:=10.165). BlueGray:=RGB2LongWord(100. K-Outertainment™ Trang 24 . MissileExplored:=CreateSound(DataPath+'Sounds\MissileExplored. //Player color setting PlayerColor[PlayerNature]:=RGB2LongWord(255.40. DESTRUCTOR TGame.000)). Begin DestroyScreen.//Yellow // //Sound setting // {$IfDef SoundPlaying} BackGroundMusic:=CreateSound(DataPath+'Sounds\BackGround. Exit. Green:=RGB2LongWord(000. (MouseY-MiniMapPosY)*GameWorld.False).Y).Y:=MouseY.Scale.255.ProceedMouseLHolding.255. Gray:=RGB2LongWord(40. //Panel setting CommandPanelVisible:=True.False). End.PanelSizeY.255).000. If MouseCommand=NoCmd then © CrazyBabe 2003. PanelImage:=CreateImage(PanelSizeX.128)).Wav'.//Red PlayerColor[Player2]:=Color32To15(RGB2LongWord(000. SelectEnd. End Else Begin //Click on command panel ? If CommandPanelVisible then Begin End. SetupUnitsImage. PROCEDURE TGame.255)).40). End.000.//Blue PlayerColor[Player4]:=Color32To15(RGB2LongWord(255.FormatA1R5G5B5).Wav'. //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:=MouseX. MissileLauch:=CreateSound(DataPath+'Sounds\MissileLauch.

End Else Begin HumanSetCommandAttack(UnitNum). OnMiniMap : Boolean.X:=MouseX.X:=MouseX. End.Y). End End. Y:=(MouseY-MiniMapPosY)*GameWorld. SelectStart. End. CmdPatrol : Begin If OnMiniMap then Begin HumanSetCommandPatrol(X. MouseY+GameWorld. End. Case MouseCommand of MouseSelection : Begin CallMouseSelectionUnit(KeyDown(Key_LShift) or KeyDown(Key_LControl)). If UnitNum=Low(TUnitCount) then Begin HumanSetCommandAttackTo(MouseX+GameWorld.False).Scale.ViewPos. End.MouseY. SelectStart. SelectEnd. If MiniMapVisible then Begin If (MouseX>=MiniMapPosX) and (MouseX<=MiniMapPosX+MiniMapSizeX) and (MouseY>=MiniMapPosY) and (MouseY<=MiniMapPosY+MiniMapSizeY) then Begin OnMiniMap:=True. © CrazyBabe 2003. Var UnitNum : TUnitCount.Y:=MouseY.Y).Y : Integer.Simple ЯTS G∆me Dεsign & CΘding Begin MouseCommand:=MouseSelection.Y:=0. K-Outertainment™ Trang 25 . X. End. End. End. Begin End.Y). X:=0.Y. SelectEnd.ProceedMouseRHolding.Scale.ProceedMouseLReleased. PROCEDURE TGame. PROCEDURE TGame.ViewPos. CmdAttack : Begin If OnMiniMap then Begin HumanSetCommandAttackTo(X. X:=(MouseX-MiniMapPosX)*GameWorld. End Else Begin UnitNum:=GetUnitAtMouse(MouseX.X.X. Begin OnMiniMap:=False.Y:=MouseY.

ViewPos.ViewPos. End.X.Y).ViewPos. MouseCommand:=NoCmd. End.X).X.X. MouseY+GameWorld. © CrazyBabe 2003. End Else Begin //Clear waiting command MouseCommand:=NoCmd.Y). Begin //LeftAlt+X ? If KeyDown(Key_LAlt) and KeyPress(Key_X) then EndGame:=True. End.MouseY. MouseY+GameWorld.Simple ЯTS G∆me Dεsign & CΘding End Else Begin HumanSetCommandPatrol(MouseX+GameWorld. //Other wise UnitNum:=GetUnitAtMouse(MouseX. End. End Else Begin If GameUnits[UnitNum]. End. (MouseY-MiniMapPosY)*GameWorld.ViewPos. End. //Arrow key: Take map view scroll If KeyDown(Key_Up) then WorldViewAt(Round(GameWorld.Y). Var UnitNum : TUnitCount.ProceedMouseRReleased. End.ProceedPlayerInput. MouseY+GameWorld.ViewPos.Owner=HumanControl then Begin HumanSetCommandMove(MouseX+GameWorld. PROCEDURE TGame. If UnitNum=Low(TUnitCount) then Begin HumanSetCommandMove(MouseX+GameWorld. K-Outertainment™ Trang 26 .False).Scale.ViewPos. End. End. End Else Begin HumanSetCommandAttack(UnitNum).Scale. 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. End. PROCEDURE TGame.Y).X.ViewPos. Exit.

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

World'). WorldMiniMapUpdate.HumanSetCommandStop. End. {$EndIf} Repeat ProcessInput.Simple ЯTS G∆me Dεsign & CΘding 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>255 then Begin TransparentLevel:=255. //Update money If GameTime-LastGameMoneyTime>MoneyTime then Begin LastGameMoneyTime:=GameTime. If TransparentLevel<64 then Begin TransparentLevel:=64. End Else ProcessNormalUnit(Z). PROCEDURE TGame. End. RestartCount. End. AddMoneyForAllPlayer. PROCEDURE TGame. Var Z : TUnitCount. Until EndGame.ProcessEvents. TransparentSpeed:=-TransparentSpeed. End. {$IfDef SoundPlaying} SoundPlay(BackGroundMusic). RenderScene. Begin //Update mini map If GameTime-LastGameMiniMapTime>MiniMapUpdate then Begin LastGameMiniMapTime:=GameTime. ProcessUnits. ProcessEvents. Begin For Z:=Low(TUnitCount) to © CrazyBabe 2003. End. TransparentSpeed:=-TransparentSpeed. K-Outertainment™ Trang 28 . End.TimeGetTime. End. Begin LoadWorld('Demo.Play. End. PROCEDURE TGame. GameTime:=MMSystem. IsFrameToFindTarget:=GameFrame mod FrameRateForFindTarget=0. End. End.

Y+Random(AroundLeng)-AroundLeng ShR 1).HitPoint>0) and //Unit selected (GameUnits[Z]. End.UnitGroup and 128=128) then Begin //Set command moving ! UnitResetCommand(Z). End.HumanSetCommandCreate. Var Z : TUnitCount. PROCEDURE TGame.Owner=HumanControl) and //Unit alive (GameUnits[Z]. End.Target). Var Z : TUnitCount.HitPoint>0) and //Unit selected (GameUnits[Z].Owner=HumanControl) and //Unit alive (GameUnits[Z]. End. End.HitPoint>0) and //Unit selected (GameUnits[Z].Owner=HumanControl) and //Unit alive (GameUnits[Z].Y : Integer). Begin For Z:=Low(TUnitCount) to High(TUnitCount) do //Unit is owner If (GameUnits[Z]. Begin For Z:=Low(TUnitCount) to High(TUnitCount) do //Unit is owner If (GameUnits[Z]. End. Begin For Z:=Low(TUnitCount) to High(TUnitCount) do //Unit is owner If (GameUnits[Z]. PROCEDURE TGame.HitPoint>0) and //Unit selected (GameUnits[Z]. PROCEDURE TGame. © CrazyBabe 2003. End.UnitGroup and 128=128) then Begin //Set command moving ! UnitSetMove(Z.UnitGroup and 128=128) then Begin //Set command moving ! UnitSetCreate(Z).HumanSetCommandAttack(Target : TUnitCount). Var Z : TUnitCount.UnitGroup and 128=128) then Begin //Set command attack ! UnitSetAttack(Z.HumanSetCommandMove(X.Simple ЯTS G∆me Dεsign & CΘding High(TUnitCount) do //Unit is owner If (GameUnits[Z].X+Random(AroundLeng)-AroundLeng ShR 1. K-Outertainment™ Trang 29 .Owner=HumanControl) and //Unit alive (GameUnits[Z]. End.

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

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

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

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

_Damage:=ToInt(Sub).Simple ЯTS G∆me Dεsign & CΘding Begin Sub:=GetSubString(St).Move). End Else If Sub=ShipCanCreate then Begin Sub:=GetSubString(St). _ShipCanCreate:=GetShipTyper(Sub). _Explosion:=GetShipTyper(Sub). _TurnWait:=ToInt(Sub). _Wait:=ToInt(Sub). End Else If Sub=ShipFrameStr then Begin LoadAni(_ShipAni. End Else //Ship damage If Sub=ShipDamageStr then Begin Sub:=GetSubString(St). End Else //Ship attack range If Sub=ShipAttackRangeStr then Begin Sub:=GetSubString(St). End Else //Ship wait If Sub=ShipWaitStr then Begin Sub:=GetSubString(St). _Gun:=GetGun(Sub). End Else //Ship turn wait If Sub=ShipTurnWaitStr then Begin Sub:=GetSubString(St). © CrazyBabe 2003. LoadAni(_ShipAni. _HitPoint:=ToInt(Sub).Attack). End Else //Ship gun If Sub=ShipGunStr then Begin Sub:=GetSubString(St). _AttackRange:=ToInt(Sub). _Speed:=ToInt(Sub). End Else //Ship speed If Sub=ShipSpeedStr then Begin Sub:=GetSubString(St). End Else //Ship explosion If Sub=ExplosionSkinStr then Begin Sub:=GetSubString(St). K-Outertainment™ Trang 34 .

End Else If Sub=ShipCost then Begin Sub:=GetSubString(St). End.Config'). End. PROCEDURE TGame. FUNCTION TGame.Pos.Config').SetupUnitsSetting. Inc(UnitCounting).Player).0). End. ProceedUnitSettingFile(DataPath+ShipsSettingDir+'Burn.Config') .FormatA1R5G5B5).Config'). End. ProceedUnitSettingFile(DataPath+ShipsSettingDir+'ShipCooNok. End. FlareImageNum:=LoadImage(DataPath+'Flare. End.Config' ). Exit.HitPoint<=0 then Begin GameUnits[Z]. End.Config'). SetupUnit(Z. End. Close(F).Simple ЯTS G∆me Dεsign & CΘding End Else If Sub=ShipCreateTime then Begin Sub:=GetSubString(St).CountUnit). ProceedUnitSettingFile(DataPath+ShipsSettingDir+'MiniMissile. Player : TPlayer.PosY : Integer) : TUnitCount.Y:=PosY. ProceedUnitSettingFile(DataPath+ShipsSettingDir+'ShipBattleCruiseBaton. Result:=Low(TUnitCount). Var Z : TUnitCount. _Cost:=ToInt(Sub). Inc(GamePlayers[Player]. Begin GlobeImageNum:=LoadImage(DataPath+'Globe.Config').Config'). ProceedUnitSettingFile(DataPath+ShipsSettingDir+'EvelMissile. © CrazyBabe 2003. ProceedUnitSettingFile(DataPath+ShipsSettingDir+'ShipScout.FormatA1R5G5B5). Result:=Z. ProceedUnitSettingFile(DataPath+ShipsSettingDir+'ShipBattleCruiseAmon. Begin UnitsProperty[FirePlanet].X:=PosX.Pos. End.SetupUnitsImage. K-Outertainment™ Trang 35 . PosX. SetAlphaMask(GlobeImageNum. ProceedUnitSettingFile(DataPath+ShipsSettingDir+'ShipCarrier. _BuildTime:=ToInt(Sub).UnitTyper.jpg'. ProceedUnitSettingFile(DataPath+ShipsSettingDir+'MileMissile.Config')._DrawLevel:=1.jpg'.CreateNewUnit(UnitTyper : TSpaceShip. Begin For Z:=Low(TUnitCount)+1 to High(TUnitCount) do If GameUnits[Z]. PROCEDURE TGame. GameUnits[Z].

UnitCmd:=NoCmd. End. CreationCounting:=0. Else Begin CurrentHead:=RandomHeading. CurrentFrame:=0.DestroyUnit(UnitNum : TUnitCount) : Boolean. UnitGroup:=0. End. UnitNextCmd:=NoCmd. Dec(UnitCounting). Begin With GameUnits[UnitNum] do Begin Owner:=Player._Cost then Begin Dec(Money. UnitTyper : TSpaceShip.SetupUnit(UnitNum : TUnitCount. End. For Z:=Low(TUnitCount) to High(TUnitCount) do If (GameUnits[Z]. End.Simple ЯTS G∆me Dεsign & CΘding FUNCTION TGame. End. End Else Result:=False. End. HitPoint:=0._HitPoint.UnitTarget=UnitNum) then Begin If (GameUnits[Z]. End. Dec(GamePlayers[Owner]. Case Typer of FirePlanet : Begin TransparentLevel:=Random(255). Result:=True. Var Z : TUnitCount.Owner<>NonePlayer) then UnitResetCommand(Z) Else DestroyUnit(Z).HitPoint>0) and (GameUnits[Z]. Player : TPlayer). End._Cost). Begin With GamePlayers[Player] do Begin If Money>=UnitsProperty[UnitTyper]. End. If FirstUnitSelect=UnitNum then FirstUnitSelect:=Low(TUnitCount). TransparentSpeed:=1. Begin Result:=True. With GameUnits[UnitNum] do Begin If HitPoint<=0 then Exit. Typer:=UnitTyper.CostForNewUnit(Player : TPlayer.CountUnit). FUNCTION TGame.UnitsProperty[UnitTyper]. UnitTyper : TSpaceShip) : Boolean. © CrazyBabe 2003. K-Outertainment™ Trang 36 . HitPoint:=UnitsProperty[UnitTyper]. PROCEDURE TGame.

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

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

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

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

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

K-Outertainment™ Trang 42 .UnitGetNextCmd(UnitNum : TUnitCount) : Boolean. End. UnitPointToTarget(UnitNum). UnitNextCmd:=NoCmd. UnitTarget:=UnitNextTarget. Begin With GameUnits[UnitNum]. End.Simple ЯTS G∆me Dεsign & CΘding End. Begin With GameUnits[UnitNum] do Begin If UnitNextCmd<>NoCmd then Begin UnitCmd:=UnitNextCmd.CmdAttackM : Begin Dest:=GameUnits[UnitTarget]. PROCEDURE TGame.Damage) Else DestroyUnit(UnitNum). End. Result:=True. End Else UnitCmd:=NoCmd. End Else Result:=False. End. End Else If UnitCmd=CmdAttackM then Begin UnitCmd:=CmdAttackT. FUNCTION TGame. Case UnitCmd of CmdMove. End.CmdPatrol : Begin UnitPointToTarget(UnitNum).Damage : Integer). © CrazyBabe 2003. End. Dest:=PatrolDest. CmdAttackT : Begin UnitPointToTarget(UnitNum). UnitPointToTarget(UnitNum). End. Begin With GameUnits[UnitNum] do Begin If UnitCmd=CmdAttackP then Begin UnitCmd:=CmdPatrol.UnitDecHitPoint(UnitNum : TUnitCount. End. UnitPointToTarget(UnitNum).UnitResetCommand(UnitNum : TUnitCount). PROCEDURE TGame. CmdAttack. UnitTarget:=Low(TUnitCount).CmdAttackP. Dest:=PatrolDest.Pos. End. UnitsProperty[Typer] do Begin If HitPoint>Damage then Dec(HitPoint. End.

K-Outertainment™ Trang 43 .DestY : Integer). Begin With GameUnits[UnitNum] do Begin © CrazyBabe 2003. PatrolDest.X:=DestX.X:=DestX. Begin With GameUnits[UnitNum]. UnitTarget:=Low(TUnitCount). End. End Else Begin UnitNextCmd:=CmdPatrol. PatrolDest. PROCEDURE TGame.UnitSetAttackTo(UnitNum : TUnitCount. If CreationCounting>0 then Exit. UnitTarget:=Low(TUnitCount). Dest.Y:=DestY. End. PatrolStart:=Pos.Simple ЯTS G∆me Dεsign & CΘding PROCEDURE TGame. Begin With GameUnits[UnitNum] do Begin If (UnitCmd=NoCmd) or (UnitCmd=CmdPatrol) then Begin UnitCmd:=CmdPatrol.UnitSetPatrol(UnitNum : TUnitCount. PROCEDURE TGame. If CostForNewUnit(Owner. UnitsProperty[Typer] do Begin If _ShipCanCreate=Low(TSpaceShip) then Exit. End Else Begin UnitNextCmd:=CmdMove.DestX. Dest. UnitNextTarget:=Low(TUnitCount). End.Y:=DestY._ShipCanCreate) then CreationCounting:=1. UnitPointToTarget(UnitNum). End. UnitPointToTarget(UnitNum).DestX.DestY : Integer). UnitNextTarget:=Low(TUnitCount). End.Y:=DestY. PatrolStart:=Pos.X:=DestX.X:=DestX.UnitSetCreate(UnitNum : TUnitCount). End.DestX.Y:=DestY. Dest.UnitSetMove(UnitNum : TUnitCount. Begin With GameUnits[UnitNum] do Begin If UnitCmd=NoCmd then Begin UnitCmd:=CmdMove. PatrolDest. Dest:=PatrolDest.DestY : Integer). End. Dest. PROCEDURE TGame. End. PatrolDest.

End. K-Outertainment™ Trang 44 . UnitTarget:=Low(TUnitCount). UnitNextTarget:=Target. With GameUnits[UnitNum] do Begin © CrazyBabe 2003. UnitTarget:=Target.X:=DestX. End. End.UnitSetAttackPatrol(UnitNum : TUnitCount. Dest. UnitPointToTarget(UnitNum). UnitPointToTarget(UnitNum). End.Pos.Y:=DestY.UnitSetAttack(UnitNum : TUnitCount. Dest. Dest:=GameUnits[Target]. Begin If Target=UnitNum then Exit. With GameUnits[UnitNum] do Begin If UnitCmd=NoCmd then Begin UnitCmd:=CmdAttack. UnitNextTarget:=Low(TUnitCount). UnitPointToTarget(UnitNum). With GameUnits[UnitNum] do Begin If UnitCmd=NoCmd then Begin UnitCmd:=CmdAttackP. Dest:=GameUnits[Target]. Dest. UnitTarget:=Target. End Else Begin UnitNextCmd:=CmdAttackT. End.Target : Integer). PROCEDURE TGame. End. Dest.X:=DestX. Begin If Target=UnitNum then Exit. UnitNextTarget:=Target.Y:=DestY.UnitSetAttackMove(UnitNum : TUnitCount. End. PROCEDURE TGame. End Else Begin UnitNextCmd:=CmdAttack. End.Target : Integer). PROCEDURE TGame.Pos.Simple ЯTS G∆me Dεsign & CΘding If (UnitCmd=NoCmd) or (UnitCmd=CmdPatrol) then Begin UnitCmd:=CmdAttackT. Begin If Target=UnitNum then Exit. End. End Else Begin UnitNextCmd:=CmdAttackP.Target : Integer).

Owner]) and (GameUnits[Z]. FUNCTION TGame. Min.Pos. UnitTarget:=Target. Var Z.HitPoint>0) then Begin Leng:=Long(Pos.UnitFindTarget(UnitNum : TUnitCount) : TUnitCount. Begin Min:=High(Integer).HitPoint>0) then Begin Leng:=Long(Pos.UnitFindNear(UnitNum : TUnitCount) : TUnitCount.Y).Y. If (Leng<Min) and (Leng<Sqr(_AttackRange)) then Begin Min:=Leng. Result:=Saved. GameUnits[Z].X. If (Leng<Min) and (Leng<Sqr(TooNearLeng)) then Begin Min:=Leng. Saved:=Low(TUnitCount).Pos. With GameUnits[UnitNum]. K-Outertainment™ Trang 45 . End. UnitsProperty[Typer] do For Z:=Low(TUnitCount) to High(TUnitCount) do If (Z<>UnitNum) and (GameUnits[Z]. End. UnitPointToTarget(UnitNum). End.Pos. GameUnits[Z].Y). GameUnits[Z].Pos.X. End. With GameUnits[UnitNum]. © CrazyBabe 2003.Pos.X.Simple ЯTS G∆me Dεsign & CΘding If UnitCmd=NoCmd then Begin UnitCmd:=CmdAttackM.Owner=Owner) and (GameUnits[Z]. Saved:=Low(TUnitCount). End. UnitNextTarget:=Target. End.Leng : Single. GameUnits[Z].Leng : Single. Saved:=Z.Saved : TUnitCount. UnitNextCmd:=CmdAttackM.Pos. FUNCTION TGame. Dest:=GameUnits[Target].Enemy[GameUnits[Z]. PatrolDest:=Dest. Begin Min:=High(Integer). Var Z.Y.Pos. Min. UnitsProperty[Typer] do For Z:=Low(TUnitCount) to High(TUnitCount) do If (GamePlayers[Owner]. End Else Begin PatrolDest:=Dest.X.Saved : TUnitCount.

End. End. End. If CreationCounting>UnitsProperty[_ShipCanCreate]. Var Num : TUnitCount.ProceedUnitStand(UnitNum : TUnitCount). End. PROCEDURE TGame. End. End. CmdAttackM : ProceedUnitAttackM(UnitNum). Round(Pos. Begin With GameUnits[UnitNum]. //Unit creation process If CreationCounting>0 then Begin Inc(CreationCounting). Begin With GameUnits[UnitNum]. PROCEDURE TGame.ProcessSpecifyUnit(UnitNum : TUnitCount). K-Outertainment™ Trang 46 . CmdAttack : ProceedUnitAttack(UnitNum). CmdAttackT : ProceedUnitAttackT(UnitNum). CmdBurn : ProceedUnitBurning(UnitNum). Result:=Saved.Simple ЯTS G∆me Dεsign & CΘding Saved:=Z. End. Num:=CreateNewUnit(_ShipCanCreate. UnitSetMove(Num. End.Y)-150+Random(300)). PROCEDURE TGame. Round(Pos. Else ProceedUnitStand(UnitNum).X)-150+Random(300).Round(Pos.ProcessNormalUnit(UnitNum : TUnitCount). //Unit command process Case UnitCmd of CmdMove._BuildTime then Begin CreationCounting:=0. End. Var Num : TUnitCount.Owner. UnitsProperty[Typer] do Begin © CrazyBabe 2003.X).Y)). CmdAttackP : ProceedUnitAttackP(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. Begin With GameUnits[UnitNum] do Begin End.Round(Pos. CmdPatrol : ProceedUnitPatrol(UnitNum).CmdFire : ProceedUnitMove(UnitNum). End.

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

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

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

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

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

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

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

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

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

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

FUNCTION TGame. Exit. Result:=Low(TGun). END. End. K-Outertainment™ Trang 57 .Simple ЯTS G∆me Dεsign & CΘding High(THeading) do If HeadingName[Z]=Name then Begin Result:=Z. © CrazyBabe 2003. Exit. End. Var Z : TGun. Result:=Low(THeading). End. Begin For Z:=Low(TGun) to High(TGun) do If GunName[Z]=Name then Begin Result:=Z.GetGun(Name : String) : TGun. End.

hãy mail cho tôi. kiểm soát số lượng các unit bị coi là “chồng nhau” chăng ? Có thể được nhưng cách này thực thi khá chậm. Patrol…) tôi đã cố tình đặt cho vị trí đích của lệnh lệch đi một chút. Bạn cần thêm tính năng tự “dãn” ra cho các đơn vị này.Simple ЯTS G∆me Dεsign & CΘding Chapter IV: Sumary Final ? Như vậy là chúng ta đã có một game RTS (xạo) không hoàn chỉnh. Với game này mà tung ra “thị trường” thì cầm chắc là…chít thảm. nhưng tôi nghĩ rằng các bạn có thể hiểu được vì cách viết của tôi khá dễ hiểu. Nếu không hiểu rõ lắm. • Toàn bộ các đơn vị trên bản đồ đều bị nhìn thấy (?) tức là chương trình chưa tính đến “fog of war”. Gợi ý: cập nhật theo thời gian như MiniMap.Chắc là còn nhìu lỗi nữa tui chưa tìm ra…. những unit nào trong © CrazyBabe 2003. tôi sẽ dành thời gian chú thích rõ ràng hơn. hơn nữa do thời gian phát triển quá ít nên nó sẽ chứa đầy lỗi. hiện tại tôi vẫn chưa comment một cách đầy đủ vì thiếu thời gian. K-Outertainment™ Trang 58 . Với game này chưa thể gọi là một game RTS. Công việc của bạn là sửa những lỗi này và tối ưu hoá chương trình. Như vậy công việc của bạn bây giờ là sửa lỗi và nâng cấp trên khung này. Nhưng hi vọng với code này các bạn có thể hiểu sơ sơ việc viết mã cho một game thì phân rã như thế nào. Với chương trình này. nhưng chắc chắn sẽ có trường hợp các unit sẽ nằm đè rít rịt lên nhau (hic). Gợi ý: Hix. Cạnh đó tôi nghĩ chương trình còn cần nâng cấp một số tính năng như sau: • Mặc dù khi đặt lệnh cho một nhóm quân (Move. • Có lúc đặt lệnh (không nhớ lệnh gì) thì các unit lại chạy ra một chỗ khác (Kì nữa ?) • …. Upgrade Mặc dù không test nhiều tui cũng chắc chắn chương trình chứa một số lỗi như sau: • Có lúc kéo chuột để chọn quân lại không được (Kì chưa ?). he he.

Bạn nên xây dựng modun cho phép máy điều khiển quân tập trung lại rùi “lùng giết” quân của người chơi sẽ hiệu quả hơn. Game cần xây dựng một modun quản lý âm thanh riêng. Nâng cấp tính năng AI: Hiện tại game hoàn toàn chưa có AI. kiểu âm thanh… nhằm xác định độ to nhỏ và loại bỏ bớt các âm thanh cùng loại được gọi liên tục.Tiếp tục là tùy ý bạn…. tấn công cũng cần được hiển thị rõ ràng hơn thông qua hệ thống menu. thêm công việc này sẽ khiến game có tính cạnh tranh hơn. modun này có thể chỉ phát 2/3 âm thanh bắn mà cũng đạt được hiệu quả tương đương. …. Trong game chưa có khai thác tài nguyên. mặc dù như vậy sẽ khó tính toán AI cho máy hơn và nhiều game hiện tại thường giảm nhẹ sự quan tâm đến vấn đề này (?). tính năng này có thể nâng cấp thành cho phép chọn loại quân có thể sinh. Các tính năng như di chuyển. K-Outertainment™ Trang 59 . ví dụ như một đám tàu cùng bắn tên lửa chẳng hạn. công việc vẫn còn rất nhìu ở phía trước hix hix… • • • • • Dưới đây là screen shot từ một game RTS tôi đang phát triển: © CrazyBabe 2003. Các đơn vị trong game giới hạn chỉ có thể sinh một loại quân hoặc không. Vấn đề là phải viết hàm này sao cho nhanh (hix). Bạn cần thêm một list các loại quân có thể sinh vào dữ liệu đặc tính của unit trong game.Hix. các đơn vị quân máy chỉ đơn giản là sinh quân ầm ầm rùi chạy toán loạn quanh bản đồ. các thực thi âm thanh được gọi nên có các thông số đại loại như vị trí. Hoàn thiện tính năng âm thanh của game.Simple ЯTS G∆me Dεsign & CΘding tầm nhìn của đơn vị thuộc phe người chơi thì đánh dấu nó lại. sau đó xây dựng hệ thống menu cho game để người chơi có thể lựa chọn những tính năng sinh quân này.

Red 3bit. FormatX4R4G4B4: Ảnh 16bit (Mask 4bit. BD16Bit: Độ sâu màu 16bit. Blue 4bit). Green 6bit. Blue 8bit). Green 4bit. FormatX1R5G5B5: Ảnh 16bit (Mask 1bit. o EffectAdd: Vẽ kiểu cộng. FormatA1R5G5B5:Ảnh 16bit (Alpha 1bit. Red 4bit. FormatR5G6B5: Ảnh 16bit (Red 5bit. o EffectInvSrcAlpha: Vẽ với giá trị kênh alpha đảo ngược. Red 5bit. Blue 2bit). Blue 5bit). Green 4bit. chỉ áp dụng với những ảnh có kênh alpha. o EffectSrcAlpha: Vẽ theo kênh alpha của ảnh. o EffectInvSrcColor: Vẽ với giá trị màu nguồn đảo ngược. Red 4bit. Red 5bit. o EffectSrcColor: Vẽ sử dụng màu source như là kênh alpha. o EffectSrcColorAdd: Vẽ kiểu cộng. K-Outertainment™ Trang 60 • . FormatA8R3G3B2: Ảnh 16bit (Alpha 8bit. o TImageFormat: Kiểu format của ảnh. Red 8bit. FormatX8R8G8B8: Ảnh 32bit (Mask 8bit. Green 8bit. Blue 5bit). o EffectSrcAlphaAdd: Vẽ kiểu cộng theo kênh alpha của ảnh. FormatA8R8G8B8:Ảnh 32bit (Alpha 8bit. Định nghĩa hằng: o EffectNone: Vẽ không hiệu ứng. Green 5bit. Green 3bit. chỉ áp dụng với những ảnh có kênh alpha. Blue 2bit). Blue 8bit). © CrazyBabe 2003. Blue 5bit). BD32Bit: Độ sâu màu 32bit. Blue 4bit). Green 3bit. o EffectMul: Vẽ theo kiểu nhân.Simple ЯTS G∆me Dεsign & CΘding Reference AvenusHelper • Định nghĩa kiểu: o TBitDepth: Kiểu độ sâu màu của màn hình. FormatR3G3B2: Ảnh 8bit (Red 3bit. FormatA4R4G4B4: Ảnh 16bit (Alpha 4bit. Red 8bit. sử dụng màu source như là kênh alpha. Green 8bit. Green 5bit.

Số trả về là số hiệu của ảnh đã đọc. o Hàm EventMessage : Boolean Kiểm tra các events.Y : Integer. màu Color.Width. EffectBlendColor: Vẽ blend với màu nguồn. Hỗ trợ các định dạng ảnh JPEG.Format : TImageFormat) : Integer Tạo một ảnh có kích thước SizeX x SizeY với format là Format. EffectDiffuseAlpha: Vẽ khuếch tán với kênh alpha. EffectBlend4: Các kiểu hiệu ứng blend ảnh đang thử nghiệm. trả về false nếu xuất hiện event Quit.Text : String.Height : Integer. o Hàm CreateFullScreen(Width. trả về false nếu không tạo được cửa sổ. Hàm trả về true nếu khởi tạo thành công.Title : PChar) : Boolean Tạo một cửa sổ kích thước Width x Height có caption là Title. K-Outertainment™ Trang 61 . EffectAddDiffuse. lệnh: o Hàm CreateWindow(Width. BMP.Text : String. o Hàm LoadImage(FileName : String. Hiệu ứng Effect o Hàm CreateImage(SizeX. o Lệnh TextOut(X.SizeY.Simple ЯTS G∆me Dεsign & CΘding EffectInvSrcMask: Vẽ với giá trị mask đảo ngược. EffectBlend1.Format : TImageFormat) : Integer Đọc ảnh từ FileName.TransparentColor : Integer) : Integer Đặt kênh Alpha cho tất cả các điểm ảnh có màu Transparent. tôi không chú thích ở đây do nó dài quá . màu Color. EffectMirror. EffectFlip: Vẽ lật hình. o Lệnh LoadFont(FileName : String.Title : PChar) : Boolean Khởi tạo chế độ màn hình Width x Height độ sâu màu là ScreenDepth có caption là Title.Y]. EffectShadow: Vẽ bóng. o o o o o o o o • Các hàm. o Lệnh DestroyScreen Huỷ cửa sổ/chế độ đã tạo trước đó. ở toạ độ [X. Các hằng số Key_# là các hằng số định nghĩa số hiệu phím.ScreenDepth : TBitDepth. EffectBlend2. Số trả về là số hiệu của ảnh đã tạo. lấy phím… đều sinh lỗi do chương trình đã huỷ handle quản lý tất cả các dịch vụ này.Y]. sau khi gọi lệnh này tất cả các hàm vẽ. ở toạ độ [X. o Hàm ImageLock(ImageNum : Integer) : Integer © CrazyBabe 2003.TransColor : LongWord) Đọc font chữ từ file ảnh FileName o Lệnh TextOut(X. trả về false nếu không khởi tạo được chế độ đó. Chỉ hỗ trợ format ảnh FormatA1R5G5B5.Effect : Integer) Viết xâu Text ra màn hình.Height. hiệu ứng này có thể kết hợp với các hiệu ứng ở trên.Y : Integer.Color : LongWord) Viết xâu Text ra màn hình. Hàm trả về true nếu tạo thành công.Color : LongWord. EffectBlendColorAlphaChannel: Vẽ blend sử dụng kênh alpha. o Hàm GetImageWidth(ImageNum : Integer) : Integer Lấy độ rộng của ảnh số hiệu ImageNum. PNG. o Hàm SetAlphaMask(ImageNum. bạn có thể dễ dàng đoán ra nó đại diện cho phím nào. ảnh đọc vào với format là Format.Height : Integer. o Hàm GetImageHeight(ImageNum : Integer) : Integer Lấy độ cao của ảnh số hiệu ImageNum.SizeY : Integer. EffectBlend3.SizeX.

YPos] với hiệu ứng Effect.Color : Cardinal) Vẽ hình chữ nhật màu Color từ [X1.Effect : Integer) Vẽ đường thẳng. YPos] với hiệu ứng Effect.X1.Color : Cardinal.Pattern.Y1.Y2 : Integer.Y1. K-Outertainment™ Trang 62 .Color : Cardinal.X2.Y1. YPos] với hiệu ứng Effect.Y2 : Integer) Đặt clip rect.Y1. o Hàm ImageRenderEffect(XPos.YPos.Pattern.X2. Tỉ lệ zoom là Scale/256.X2.Color : Cardinal) Vẽ điểm ảnh màu Color ở toạ độ [X.Color : Cardinal) Vẽ đường thẳng smooth (mịn).Y2] trong ảnh ImageNum.Y2 : Integer.YPos. o Hàm ImageRenderEffect(XPos.Y1.Scale.Pattern.Pattern.Y2 : Integer.Color : Cardinal. o Hàm ImageRenderEffectColor(X1.Effect : Integer) : Boolean Dựng ảnh Pattern thành hình chữ nhật [X1.X2.YPos : Integer. o Lệnh ImagePutPixel(ImageNum. o Hàm ImageRenderEffectColor(XPos.Y : Integer) : Cardinal Lấy màu điểm ảnh Color ở toạ độ [X.Effect : Integer) Tô hình chữ nhật.Y1.Color : Cardinal) Xoá ảnh ImageNum bằng màu Color.X2.Y1.Simple ЯTS G∆me Dεsign & CΘding Lock ảnh số hiệu ImageNum.Y1] đến [X2.Y] trong ảnh ImageNum. o Lệnh SetClipRect(X1.X2. o Hàm ImageGetPixel(ImageNum. o Lệnh Line(X1.Y1. o Lệnh Bar(X1. o Lệnh ClearScreen(Color : Cardinal) Xoá màn hình bằng màu Color. xoá render buffer).X. o Lệnh EndRender Kết thúc vẽ scene.X2.Color : Cardinal.X1.Y2 : Integer.Y1] đến [X2. o Hàm ImageRenderEffect(X1.Y1.Y2] với hiệu ứng Effect.Y : Integer. o Lệnh SmoothLine(X1. o Lệnh ImageClear(ImageNum : Integer.Y2 : Integer.X2.Y2 : Integer.X2.Color : Cardinal. o Hàm RenderBuffer : Integer Dựng toàn bộ hình trong render buffer.X. o Lệnh ImageLine(ImageNum. Màu áp là Color. Màu áp là Color. o Lệnh ImageFillRect(ImageNum.Y2] trong ảnh ImageNum. Hàm ImageUnLock(ImageNum : Integer) : Integer UnLock ảnh số hiệu ImageNum.X1. o Lệnh ImageRect(ImageNum.Effect : Integer) Vẽ hình chữ nhật.Y1.X2.Y2.Y1.Y1.Y1] đến [X2. o © CrazyBabe 2003.Y2] trong ảnh ImageNum. o Lệnh Rect(X1.Y2] với hiệu ứng Effect.Effect : Integer) : Boolean Dựng ảnh Pattern ở vị trí [XPos.Pattern.Y] trong ảnh ImageNum.Effect : Integer) : Boolean Dựng ảnh Pattern thành hình chữ nhật [X1.X2. o Lệnh BeginRender Bắt đầu vẽ scene mới (xoá buffer.Color : Cardinal) Vẽ đường thẳng màu Color từ [X1.Color : Cardinal) Tô hình chữ nhật màu Color từ [X1.X2.Effect : Integer) : Boolean Dựng ảnh Pattern ở vị trí [XPos.Effect : Integer) : Boolean Dựng ảnh Pattern ở vị trí [XPos.Y2 : Integer.Y2 : Integer.

o Hàm CreateSound(FileName : String. o Lệnh GetInputStatus Cập nhật input (Trạng thái mouse.C1. Trả về handle quản lý sound này.Scale : Integer. o Hàm MouseY : Integer Toạ độ Y của chuột. Màu áp là Color.Color : Cardinal. YPos] với hiệu ứng Effect. YPos] với hiệu ứng Effect. C3.C3.Simple ЯTS G∆me Dεsign & CΘding o Hàm ImageRenderEffectColor(XPos. o Hàm SoundGetVolume(Slot : Integer) : Byte Lấy cường độ âm thanh của Slot.C4 : LongWord.YPos : Integer. Màu áp ở bốn góc lần lượt là C1.Value : Byte) Đặt cường độ âm thanh cho Slot. C2.Loop : Boolean) : Integer Tạo handle cho sound FileName.Pattern. o Lệnh SoundSetVolume(Slot : Integer.YPos. Tỉ lệ zoom là Scale/256. o Lệnh SoundPlay(Slot : Integer) Chơi sound số hiệu slot.Effect : Integer) : Boolean Dựng ảnh Pattern ở vị trí [XPos. o Lệnh SoundStop(Slot : Integer) Dừng sound số hiệu slot.Effect : Integer) : Boolean Dựng ảnh Pattern ở vị trí [XPos. keyboard…) o Hàm KeyDown(Key : Byte) : Boolean Kiểm tra phím Key có bị nhấn hay không ? o Hàm KeyPress(Key : Byte) : Boolean Kiểm tra phím Key có bị gõ hay không ? o Hàm MouseFirstClickL : Boolean Click chuột trái ? o Hàm MouseFirstClickR : Boolean Click chuột phải ? o Hàm MouseFirstClickM : Boolean Click chuột giữa ? o Hàm MouseReleasedL : Boolean Thả chuột trái ? o Hàm MouseReleasedR : Boolean Thả chuột phải ? o Hàm MouseReleasedM : Boolean Thả chuột giữa ? o Hàm MouseHoldL : Boolean Nhấn chuột trái ? o Hàm MouseHoldR : Boolean Nhấn chuột phải ? o Hàm MouseHoldM : Boolean Nhấn chuột giữa ? o Hàm MouseX : Integer Toạ độ X của chuột. © CrazyBabe 2003.C2. o Lệnh SoundPause(Slot : Integer) Tạm dừng sound số hiệu slot. C4.Pattern. K-Outertainment™ Trang 63 . o Hàm ImageRenderEffectColor(XPos.