C » M ® * e i * 1* cans » fH ! C T ĩ in h ầS ' E i? I F ® Sách ẩm t h f T ro L ệ « V N a r a Sách k»«h tê Ý Sách °ểỸại ũ ý Thơ ca tiẽu T y ệ ” , ln g o " T rH s ỉc h ”o ^ c Sách tâm ly học k K u * f l* » \ ! L E i ễ n p w - ní5 c ấ p s b ° * y ^ n h ip 5009 Sim ple ATS GAme Dssign & Ceding Simple RTS GAme Dssign & Ceding OpenEdition Copyright © 2003 by Z\dz\fBabe ^ All rights reserved June 6th, 2003 © CrazyBabe 2003 K-Outertainm ent™ Trang Sim ple ATS GAine DESign & Ceding Chapter I: Introduction W hy did I write this book ? Trong thời điếm tại, có nhiều bạn trẻ hướng quan tâm vào thiết kế lập trình game, phải cơng nhận điều chơi game hấp dẫn, chơi gam e làm cịn hấp dẫn nhiều, cho dù trị chơi dở ẹc Trên diễn đàn tin học Internet đầy rẫy topic kiểu "Lập trình game với " "Ai giúp em lập trình gam e nào", tất quan tâm đến mục đích "Làm đế viết nến gam e ?" Những ý kiến xoay quanh vấn đề đa dạng, nói khó có mà nói dễ có với kinh nghiệm trình độ tại, tơi cơng nhận điều khó, khơng phải q khó bạn biết đặt mục tiêu vừa tầm tìm cách tiếp cận Nếu hi vọng viết gam e tương đương với Quake W arcraft - sản phẩm tập thể chuyên nghiệp xây dựng thời gian dài - viến vong, bạn hạ thấp mục tiểu xuống chút làm gam e đơn giản kiểu bắn tăng hay Mario, IQ gam e cho trẻ em trước khơng q khó bạn biết lập trình Cá nhân dường nhận thức điều co số thành cổng nhỏ việc thiết kế lập trình game Trong thời điếm nghỉ ôn thi định dành thời gian ngắn đế viết sách này, sách tơi trình bày cách đầy đủ q trình tơi thiết kế viết mã cho gam e RTS đơn giản (được lược bỏ nhiều tính v í dụ chơi mạng) nhằm giúp bạn hiếu phần trình "ziết game gia" Hi vọng sách giúp bạn trình thiết kế viết gam e Chúc tất bạn thành cơng dự án viết game W hat is RTS game ? RTS - Realtim e strateg y - Thể loại gam e chiến thuật thời gian thực mà khởi đầu với dòng gam e Dune, Command & Conquer Westwood stu dio nhanh chóng trở thành dịng © CrazyBabe 2003 K-Outertainm ent™ Trang Sim ple ATS GAme Dssign & Ceding gam e ăn khách toàn giới Việt Nam Thời điểm phát triển dòng trò chơi dường chững lại, khơng có nhiều tiến vượt bậc thời điểm starcraft (Blizzard Entertainm ent) đời mà xuất game lai tạp với loại khác (W arcraft III thể loại Roleplay strateg y) nên dường dòng j a m e dần nhường bước cho dịng game ăn khách khác Nhưng cá nhân tơi vân ôm ước vọng xây dựng game RTS ăn vào bối cảnh lịch sử Việt Nam đem lại cho người chơi nhiều cải tiến quan trọng cách chơi (He he, cải tiến quan trọng nha, khơng nói đâu, lúc làm xong nói, hì hì) How this book will help you Cuốn sách tơi viết lại q trình thiết kế, viết mã - dĩ nhiên thích tương đối cụ thể - cho game RTS thiết kế đơn giản tối đa Bên cạnh tơi đưa số kinh nghiệm cá nhân có q trình làm việc nhằm giúp bạn co hiếu phần cơng việc thiết kế lập trình game (Khơng chun nghiệp) Cịn sách giúp bạn cịn tuỳ thuộc vào bạn, mà bạn thuộc hàng cao thủ bít hết rùi bạn dumb đọc chẳng hiếu dĩ nhiên chẳng giúp bạn đâu Tơi cố gắng giải thích cặn kẽ nhằm giúp bạn hiểu chương trình làm việc th ế Tất cịn lại phụ thuộc vào bạn Readers requirements Trong sách này, sử dụng ngơn ngữ Delphi đế viết chương trình Nhưng thực tế hồn tồn lập trình khơng sử dụng đến com ponent không sử dụng đến W indow API mà thông qua thư viện xây dựng riêng nên gần bạn cần biết Object Pascal hiếu mã chương trình làm việc th ế nào, tơi cố gắng viết mã cách chân phương - khơng tối Ưu, tơi có thời gian wé - nhằm mục đích đế người cảm thấy dễ hiếu chuyến sang ngơn ngữ khác, theo tính tốn tơi chương trình chuyển sang ngơn ngữ lập trình bậc cao thông dụng VB, c, c++, C# Java, v ề mặt đồ hoạ không sử dụng hệ thống 3D phức tạp mà thiết kế với hệ thống 2D sprite anim ation đơn giản, chắn đa số bạn hiểu kĩ thuật thô sơ Mã nguồn liệu game cung cấp kèm theo đầy đủ, bạn cần biên dịch lại chạy System & Software requirements • • • • • Hệ thống PIII 500Mhz, 64MB RAM, card hình 8MB, hình hỗ trợ chế độ phân giải 0 x 0 x l6 b it màu, có card sound (Thực tế tơi chưa chạy thử máy có cấu hình yếu nên khơng rõ có chạy hay khơng) Windows 95, 98, 98SE, NT, 2000 XP DirectX 8.1 trở len Biên dịch Borland Delphi Borland Delphi Nếu cắc bạn cần chỉnh sửa liệu gam e cần thêm trình soạn thảo ảnh (Photoshop, ACD FotoCanvas )- Mise • Tơi viết sách chủ yếu hướng đến cắc bạn gần chưa biết lập trình game có dụng ý chia sẻ chút kiến thức ỏi thân, q trình biên tập có chút s sót mong bạn lượng thứ, sách làm bạn cảm thấy hứng thú muốn trao đổi thêm với tơi bạn liên lạc qua địa e-m ail kim nqan2508@ vahoo.com (Đây địa m irror thôi, đừng bomb tui nha, he he) qua YIM: kim ngan2508 © CrazyBabe 2003 K-Outertainm ent™ Trang Sim ple ATS GAine Dssign & Ceding Cuốn sách tơi viết hồn tồn khơng nhằm mục đích thương mại, tồn mã nguồn chương trình sách phân phối miễn phí, tơi khơng chấp nhận hành vi kinh doanh dựa tập sách chương trình Đối với chương trình, bạn tuỳ nghi sử dụng, nâng cấp, cần để record ghi nâng cấp từ chương trình CrazyBabe Nhưng tơi nghĩ bạn nên viết lại hồn tồn (nếu muốn làm game thực sự) chương trình khơng tốt Trong chương trình, ngại thiết kế hình ảnh âm nên tơi mượn tạm hình ảnh âm loạt gam e starcraft nhà sản xuất Blizzard Entertainm ent (Hì hì, chả bit nển khơng bị kiện) © CrazyBabe 2003 K-Outertainm ent™ Trang Sim ple ATS GAme Dssign & Ceding Chapter II: Game Design Design a very sim ple RTS game Như nói trước đây, tơi viết sách khoảng thời gian ngắn (Chỉ bốn ngày viết mã 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í hạn chế thời gian ca trình độ nữã, hì hì ) Ở tối thiết kế gam e thể loại RTS 2D tính hạn chế Tơi xây dựng game hồn tồn khơng hỗ trợ chế độ m ultiplayer, hi vọng thời gian đến tơi có thời gian đế nâng cấp gam e lên hỗ trợ chế độ v loại bỏ số yếu tố mà cho đơn giản chế độ menu, chọn đồ, loại quân mà nhảy vào chương trình load đồ mặc định chạy đồ trận chiến kết thúc bạn., chán wá thoát ngồi - he he - tức tơi quan tâm đến chế độ battle trò chơi mà thôi, bỏ qua tất yếu tố khác Một game RTS xoay quanh số yếu tố sau: chế khai thác tài nguyên, chế sinh sản đơn vị quân, tính đơn vị quân cách chúng công, kiểu địa hình yếu tố quan trọng Gam e thiết kế sơ sau: • Thể loại chiến tranh không gian - Starw ars lun, chiến chưa ? :) • Khơng có địa hình, loại bỏ bớt yếu tố phức tạp cho địa hình Cái nhằm đế dễ lập trình • Gam e gồm hai loại đơn vị tàu mẹ tàu Tàu mẹ trung tâm đảm nhận việc xây dựng tàu con, lưu giữ tài nguyên Tàu đảm nhận nhiều nhiệm vụ khắc tuần tiễu, công, khai thác • Các đơn vị tàu có tính di chuyến, công, tuần tiễu, khai thác, xây tàu • 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 khin) ã H thng xõy dng game l 2D â CrazyBabe 2003 K-Outertainm ent™ Trang Sim ple ATS GAme Dssign & Ceding Sơ vậy, tính khắc tơi nghĩ cắc bạn thêm vào đơn giản hiểu chương trình Nếu muốn nâng cấp gam e thành 3D nghĩ làm Dưới screen shot từ gam e này: ĩ S im p le R T S G a m e D e m o [ ' ] C r a z y B a b e 2003 - Game programming environm ent Các bạn trao đổi với lập trình gam e thường trao đổi với vấn đề cụ tỉ vẽ DirectX hay OpenGL, làm để lấy sprite vẽ sprite hiệu ứng th ế thiết nghĩ thứ lặt vặt - dĩ nhiên khơng nói đến chuyện thiết kế engine 3D lớn rùi - Trong lập trình game này, tơi sử dụng thư viện AvenusHelper thiết kế nhằm giảm tối đa công việc cắc bạn cần thực thi chi tiết với hệ thống khởi tạo đồ hoạ, đọc ảnh vẽ ảnh hiệu ứng đơn giản add, sub, mul bạn cần ý đến việc làm th ế gam e chạy được, unit x lý nào, máy tính chơi sao, kiện x lý mà Nếu cần quan tâm đến chi tiết làm đế thực hiệu ứng alpha blend chẳng hạn bàn sau - tập sách khác © CrazyBabe 2003 K-Outertainm ent™ Trang Sim ple ATS GAme Dssign & Ceding Chapter III: Game Coding Chương đơn giản thích mã nguồn chương trình Dưới mã nguồn đơn vị Gam e, thành phần chương trình { Tơi đặt định nghĩa nhằm chương trình chạy chế độ tồn hình hay chế độ cửa sổ }' {$Define Fullscreen} { , Định nghĩa nhằm xác định chương trình có hỗ trợ âm hay không {$Define SoundPlaying} UNIT Game; INTERFACE Ở khai báo đơn vị mà chương trình sử dụng > USES Windows, MMSystem, SysUtils, Math, FireStormDLL, AvenusHelperDLL; CONST { ScrW idth X ScrHeight định nghĩa kích thước cửa s ổ đ ộ phân giải chế đ ộ tồn hình Chú ý chương trình chế độ cửa sổ tức biên dịch khơng có thị Fullscreen kích thước tuỳ ý, chương trình chạy chế độ tồn hình kích thước độ phân giải phải hình hỗ trợ thường độ phân giải thông dụng là: 640x480, 800x600, 1024x768, 1152x864, 1280x1024 © CrazyBabe 2003 K-Outertainm ent™ Trang Sim ple ATS GAine Dssign & Ceding > ScrWidth ScrHeight = 1024; = 768; { Caption xâu định nghĩa tên cửa sổ chương trình tạo } Caption = 'Simple RTS Game Demo[C]CrazyBabe.2003'; x MaxUnit số định nghĩa số lượng unit lớn mà chương trình hỗ trợ xử lý, số tui đặt đại zậy mà xử lý thực tế th ế (chương trình hồn tồn khơng tối Ưu) cần khoảng 4000 P4 tui die hard lun khơng cần phải thử máy cấu hình yếu đâu :> } MaxUnit = 8000; { Datapath đường dẫn đến thư mục chứa liệu chương trình > Datapath = 'DataV; { ShipsSettingD ir đường dẫn đến thư mục chứa file liệu loại tàu game > ShipsSettingDir = 'ShipsSetting\' ; { ScrollSpeed tốc độ di chuyến m inim ap game, tơi đặt biến số nhằm mục đích thay đổi tốc độ phần tui chưa viết, bạn tự thêm vào nha } ScrollSpeed : Word = 15; { MoveFarLeng, TooNearLeng, AroundLeng số độ lớn giới hạn v í dụ giới hạn tàu gần } MoveFarLeng = 10; TooNearLeng = 3; AroundLeng = 100; { Screen llp D ate 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 hình, với giá trị 33 chương trình cập nhật khoảng 28-30 lần giây UnitUpDate khoảng thời gian mà chương trình thực xử lý cho đơn vị, với giá trị 10 chương trình xử lý đơn vị trung bình khoảng 70 lần giây InputUpDate, MiniMapUpDate khoảng thời gian chương trình thực cập nhật bàn phím, chuột cập nhật lại m inim ap (Bản đồ con) MoneyTime khoảng thời gian chương trình thêm xiền cho phe > ScreenUpdate LongWord =33; LongWord = 10; UnitUpdate InputUpdate LongWord = 10; MiniMapUpdate LongWord = 10; LongWord = 120000; MoneyTime { , DefaultMoney số xiền gam e cho phe lần "cấp phát" > DefaultMoney = 10000; { PanelSizeX, PanelSizeY kích thước Panel thể thông tin đơn vị chọn MiniMapSizeX, MiniMapSizeY kích thước đồ nhỏ hiến thị hình © CrazyBabe 2003 K-Outertainm ent™ Trang Sim ple ATS GAine Dssign & Ceding } PanelSizeX PanelSizeY MiniMapSizeX MiniMapSizeY = = = = 700; 80; 200; 200; { Cứ sau khoảng Fram eRateForFindTarget fram e chương trình thực tìm kiếm mục tiêu cho đơn vị khơng có lệnh >_ FrameRateForFindTarget = 40; TYPE { Định nghĩa kiểu đế đánh số đơn vị game > TUnitCount = l MaxUnit; { Định nghĩa kiểu toạ độ nguyên toạ độ thực } TRPoint = Record X,Y : Single; End; TPoint = Record X,Y : Integer; End; { Định nghĩa số hướng đơn vị xoay 32 hướng Số hướng nhiều đơn vị xoay mịn, xây dựng với 3D khơng cần đến định nghĩa số hướng mà cần lưu lại góc nhìn đơn vị Hic, chóng mẹt wé > THeading = ( H01, H02,H03,H04, H05, H06, H07, H08, H09, H10,Hll,H12, H13, HI4, HI5, HI6, H17,H18,H19,H20, H21, H2 2, H2 3, H2 4, H25,H26,H27,H28, H2 9,H30,H31,H32) ; { Định nghĩa số kiểu tàu có game, hik, bạn bịa tên ok >TSpaceShip = ( NoneShip, FirePlanet, SupperBattleShip, BattleCruiseAmon, BattleCruiseBaton, CooNok, Scout, Interceptor, Carrier, MiniMissile, EvelMissile, MileMissile, Burn { © CrazyBabe 2003 K-Outertainm ent™ Trang Sim ple ATS GAme Dssign & Ceding WaitTimeForMove:=_TurnWait*20; End Else //Turn ship ? If CurrentHeadoHead then Begin CurrentHead:=HeadNear(CurrentHead,Head) ; WaitTimeForMove:=_TurnWait; End Else Begin For Z:=l to _Speed Begin _Heading:=UnitGetBestHeading(UnitNum) ; Pos.X :=Pos.X+Moving[_Heading, 1] ; Pos.Y :=Pos.Y+Moving[_Heading, 2] ; End; WaitTimeForMove:=_Wait; End; End; End; PROCEDURE TGame.ProceedUnitAttackP(UnitNum : TUnitCount); Var _Heading : THeading; Z : Integer; Begin With GameUnits[UnitNum], UnitsProperty[Typer] Begin If WaitTimeForMove>0 then Begin Dec(WaitTimeForMove) ; Exit; End; If UnitGetNextCmd(UnitNum) then Exit; If GameUnits[UnitTarget].HitPoint0 then Begin Dec(WaitTimeForMove) ; Exit ; End; If UnitGetNextCmd(UnitNum) then Exit; If GameUnits[UnitTarget].HitPoint0 then Begin Dec(WaitTimeForMove) ; Exit; End; If UnitGetNextCmd(UnitNum) then Exit; If UnitCloseToTarget(UnitNum,MoveFarLeng) then Begin If UnitGetNextCmd(UnitNum) then Else UnitCmd:=NoCmd; End Else //Turn ship ? If CurrentHeadoHead then Begin CurrentHead:=HeadNear(CurrentHead, Head) ; WaitTimeForMove:=_TurnWait; End Else Begin For Z:=l to _Speed Begin _Heading:=UnitGetBestHeading(UnitNum) ; Pos.X :=Pos.X+Moving[_Heading, 1] ; Pos.Y :=Pos.Y+Moving[_Heading, 2] ; End; If IsFrameToFindTarget then Begin Num:=UnitFindTarget(UnitNum) ; If NumoLow (TUnitCount) then Begin UnitCmd:=NoCmd; Unit SetAttackMove(UnitNum,Num) ; Exit; End; End; WaitTimeForMove:=_Wait; //Increase unit frame If CurrentFrame< _ShipAni.Move[CurrentHead].NumFrames-1 then Inc(CurrentFrarae) Else CurrentFrame:=0; End; End; End; PROCEDURE TGame.ProceedUnitPatrol(UnitNum : TUnitCount); Var _Heading : THeading; Z : Integer; Num : TUnitCount; Begin © CrazyBabe 2003 K-Outertainm ent™ Trang 51 Sim ple ATS GAme Dssign & Ceding With GameUnits[UnitNum], UnitsProperty[Typer] Begin If WaitTimeForMove>0 then Begin Dec(WaitTimeForMove) ; Exit ; End; If UnitGetNextCmd(UnitNum) then Exit; If UnitCloseToTarget(UnitNum,MoveFarLeng) then Begin If UnitGetNextCmd(UnitNum) then Else Begin Dest:=PatrolStart ; PatrolStart :=PatrolDest; PatrolDest:=Dest ; UnitPointToTarget(UnitNum); End; End Else //Turn ship ? If CurrentHeadoHead then Begin CurrentHead:=HeadNear(CurrentHead,Head) ; WaitTimeForMove:=_TurnWait; End Else Begin For Z:=l to _Speed Begin _Heading:=UnitGetBestHeading(UnitNum) ; Pos.X :=Pos.X+Moving[_Heading, 1] ; Pos.Y :=Pos.Y+Moving[_Heading, 2] ; End; If IsFrameToFindTarget then Begin Num:=UnitFindTarget(UnitNum) ; If NumOLow (TUnitCount) then Begin UnitCmd:=NoCmd; UnitSetAttackPatrol(UnitNum,Num); Exit ; End; End; WaitTimeForMove:=_Wait; //Increase unit frame If CurrentFrame< _ShipAni.Move[CurrentHead].NumFrames-1 then Inc(CurrentFrame) Else CurrentFrame:=0; End; End; End; PROCEDURE TGame.ProceedUnitBurning(UnitNum : TUnitCount); Begin //When unit burning, unit nothing else burning ! With GameUnits[UnitNum], UnitsProperty[Typer] Begin If WaitTimeForMove>0 then Begin Dec(WaitTimeForMove) ; Exit ; © CrazyBabe 2003 K-Outertainm ent™ Trang 52 Sim ple ATS GAme Dssign & Ceding End; WaitTimeForMove:=_Wait; //Increase unit frame If CurrentFrame0) and (_DrawLevel=DrawLevel) then Begin RenderUnits(Z); End; End; PROCEDURE TGame.RenderUnits(UnitNum : TUnitCount); Var X,Y,X1,Y1,X2,Y2, SprNum,Effects : Integer; Visible : Boolean; Begin With GameUnits[UnitNum], UnitsProperty[Typer] If HitPoint>0 then Begin //Unit visible ? Visible:=UnitVisible(UnitNum); //Drawing unit X :=Round(Pos.X)-GameWorld.ViewPos.X; Y :=Round(Pos.Y)-GameWorld.ViewPos.Y ; If Visible then Case Typer of FirePlanet : © CrazyBabe 2003 K-Outertainm ent™ Trang 53 Sim ple ATS GAme Dssign & Ceding Begin ImageRenderEffeet(X-GetlmageWidth(GlobelmageNum) ShR 1, Y-GetlmageHeight(GlobelmageNum) ShR 1, GlobelmageNum,EffectSrcAlpha); ImageRenderEffectColor(X-GetlmageWidth(FlarelmageNum) ShR 1, Y-GetlmageHeight(FlarelmageNum) ShR 1, TransparentLevel ShL 16+ TransparentLevel ShR 8+ TransparentLevel, FlarelmageNum,EffectAdd); End; Else Begin //Unit is selection ? If UnitGroup and 128=128 then Begin Rect(X-_Size2,Y-_Size2, X+_Size2,Y+_Size2,Green,EffectNone); TextOut(X-_Size2, Y-_Size2, Format('HP: %d/%d',[HitPoint,_HitPoint]),White); End; Case UnitCmd of NoCmd, CmdFire, CmdMove, CmdAttack, CmdAttackP, CmdAttackT, CmdAttackM, CmdPatrol, CmdBurn : Begin SprNum:=_ShipAni.Move[CurrentHead] Ani[CurrentFrame].FramePos; Case _ShipAni.Move[CurrentHead] Ani[CurrentFrame].FrameStyle of 02 : Effects:=EffectAdd; Else Effects:=EffectSrcAlpha; End; ImageRenderEffeet(X-GetlmageWidth(_Images[SprNum]) ShR 1, Y-GetlmageHeight(_Images[SprNum]) ShR 1, _Images[SprNum],Effects); End; End; End; End; If ShowDebug then Begin If UnitCmd in [CmdMove,CmdAttack,CmdAttackP, CmdAttackT,CmdAttackM,CmdPatrol] then Begin TextOut(X,Y,HeadingName[CurrentHead] , White,EffectNone); XI:=Round(Pos.X)-GameWorld.ViewPos.X; Y1:=Round(Pos.Y)-GameWorld.ViewPos.Y; X2:=Round(Dest.X)-GameWorld.ViewPos.X; Y2:=Round(Dest.Y)-GameWorld.ViewPos.Y; Line(XI,Y1,X2,Y2,White,EffectNone); End; End; RenderBuffer; © CrazyBabe 2003 K-Outertainm ent™ Trang 54 Sim ple ATS GAme Dssign & Ceding End; End; PROCEDURE TGame.Renderlnfos; Var Tick : LongWord; Begin Case MouseCommand of MouseSelection : Begin Rect(SelectStart.X,SelectStart.Y, SelectEnd.X,SelectEnd.Y, White,EffectNone) ; End; End; If ShowFPS then Begin Tick:=MMSystem.TimeGetTime-GameStart; If TickoO then Begin TextOut(0,4 0,Format('UFPS : %0.2f',[GameFrame/Tick*1000]),White) TextOut(0,60,Format('SFPS %0.2f', [GameScreenFrame/Tick*1000] ,White) ; ) TextOut(0,80,Format('Unit used : %d', [UnitCounting]),White); End; End; //Show mini map ? If MiniMapVisible then Begin Bar(MiniMapPosX-1,MiniMapPosY-1, MiniMapPosX+MiniMapSizeX+1, MiniMapPosY+MiniMapSizeY+1, Gray,EffectAdd); ImageRenderEffect(MiniMapPosX,MiniMapPosY, MiniMapImage,EffectAdd); End; //Show command panel ? If CommandPanelVisible then Begin Bar(PanelPosX-1,PanelPosY-1, PanelPosX+PanelSizeX+1, PanelPosY+PanelSizeY+1, BlueGray,EffectAdd) ; If FirstUnitSelectOLow (TUnitCount) then Begin With GameUnits[FirstUnitSelect] , UnitsProperty[Typer] Begin TextOut(PanelPosX,PanelPosY, ShipName[Typer] ,White) ; TextOut(PanelPosX,PanelPosY+20, Format('HP: %d/%d', [HitPoint,_HitPoint]),White); TextOut(PanelPosX,PanelPosY+40, Format('Damage: %d Speed: %d', [_Damage,_Speed]),White) ; TextOut(PanelPosX,PanelPosY+60, Format('Range: %d Gun: %s', [_AttackRange,GunName[_Gun]]),White); If _ShipCanCreateLow(TSpaceShip) then Begin If CreationCounting=0 then Begin TextOut(PanelPosX+400,PanelPosY, Format('Press C to create %s', [ShipName[_ShipCanCreate]] ,White) ; ) © CrazyBabe 2003 K-Outertainm ent™ Trang 55 Sim ple ATS GAme Dssign & Ceding End Else Begin TextOut(PanelPosX+400,PanelPosY, Format('Create %s: %d/%d', [ShipName[_ShipCanCreate] , CréâtionCounting, UnitsProperty[_ShipCanCreate] _BuildTime]),White); End; End; End; End; End; //Show player's money and units counting TextOut(0,0,Format('Money: %d Units: %d', [GamePlayers[HumanControl].Money, GamePlayers[HumanControl].CountUnit]),White); End; PROCEDURE TGame.RenderScene; Begin If GameTime-LastGameScreenTime>ScreenUpdate then Begin LastGameScreenTime:=GameTime ; Inc(GameScreenFrame); BeginRender; RenderWorld; RenderUnits; Renderlnfos; EndRender; End; End; FUNCTION TGame.GetShipTyper(Name : String) Var Z : TSpaceShip; Begin For Z:=Low(TSpaceShip) to High(TSpaceShip) If ShipName[Z]=Name then Begin Result :=Z; Exit ; End; Result :=Low(TSpaceShip); End; FUNCTION TGame.GetPlayer(Name : String) Var Z : TPlayer; Begin For Z:=Low(TPlayer) to High(TPlayer) If PlayerName[Z]=Name then Begin Result :=Z; Exit ; End; Result :=Low(TPlayer); End; FUNCTION TGame.GetHeading(Name : String) Var Z : THeading; Begin For Z:=Low(THeading) to : TSpaceShip; : TPlayer; : THeading; © CrazyBabe 2003 K-Outertainm ent™ Trang 56 Sim ple ATS GAme Design & Ceding High(THeading) If HeadingName[Z]=Name then Begin Result:=Z; Exit; End; Result:=Low(THeading) ; End; FUNCTION TGame.GetGun(Name : String) Var Z : TGun; Begin For Z:=Low(TGun) to High(TGun) If GunName[Z]=Name then Begin Result:=Z; Exit; End; Result:=Low(TGun); End; END : TGun; © CrazyBabe 2003 K-Outertainm ent™ Trang 57 Sim ple ATS GAme DESign & Ceding Chapter IV: Sumary Final ? Như có gam e RTS (xạo) khơng hoàn chỉnh Với game mà tung "thị trường" cầm chít thảm , he he Nhưng hi vọng với code cắc bạn hiếu sơ sơ việc viết mã cho gam e phân rã th ế Với game chưa gọi game RTS, thời gian phát triến q nên chứa đầy lỗi Như công việc bạn sửa lỗi nâng cấp khung Với chương trình nay, tơi chưa com m ent mọt cách đầy đủ thiếu thời gian, tơi nghĩ bạn hiểu cách viết dễ hiểu Nếukhông hiểu rõ lắm, mail cho tôi, dành thời gian thích rõ ràng Upgrade Mặc dù khơng test nhiều tui chắn chương trình chứa số lỗi sau: • Có lúc kéo chuột đế chọn qn lại khơng (Kì chưa ?) • Có lúc đặt lệnh (khơng nhớ lệnh gì) cắc unit lại chạy chỗ khắc (Kì ?) • Chắc cịn nhíu lỗi tui chưa tìm Cơng việc bạn sửa lỗi tối ưu hố chương trình Cạnh đótơi nghĩ chương trình cịn cần nâng cấp số tính sau: • Mặc dù đặt lệnh cho nhóm quân (Move, Patrol ) tơi cố tình đặt cho vị trí đích lệnh lệch chút, chắn có trường hợp unit nằm đè rít rịt lên (hic) Bạn cần thêm tính tự "dãn" cho đơn vị GỢi ý: Hix, kiếm soát số lượng unit bị coi "chồng nhau" ? Có cách thực thi chậm • Toẩn cắc đơn vị đồ bị nhìn thấy (?) tức chương trình chưa tính đến "fog of war" GỢi ý: cập nhật theo thời gian MiniMap, unit © CrazyBabe 2003 K-Outertainm ent™ Trang 58 Sim ple ATS Game Design & Ceding • • • • • tầm nhìn đơn vị thuộc phe người chơi đánh dấu lại Vấn đề phải viết hàm cho nhanh (hix) Các đơn vị gam e giới hạn sinh loại qn khơng, tính có the nâng cap thẩnh cho phép chọn loại qũân sinh Bạn cần thêm list loại quân cổ thể sinh vào liệu đặc tính unit game, sau xây dựng hệ thống menu cho game để người chơi lựa chọn tính sinh quân Các tính di chuyển, công cần hiển thị ro ràng thông qua hệ thống menu Trong game chưa có khai thác tài ngun, thêm cơng việc khiến gam e có tính cạnh tranh hơn, khó tính tốn AI cho máy nhiều gam e thường giểm nhẹ qũán tâm đến vấn đề (?) Nâng cấp tính nầng AI: Hiện gam e hồn tồn chưa có AI, đớn vị quân máy đơn giản sinh quân ầm "am rùi chạy toán loạn quanh đồ 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ùí "lùng giết" quân người chơi hiệu qua Hoàn thiện tính âm game Gam e cần xây dựng modun quản lý âm riêng, thực thi âm gọi nên có thơng số vị trí, kiểu âm nhằm xác định độ to nhỏ loại bỏ bớt âm loại gọi liên tục, v í dụ đám tàu bắn tên lửa chẳng hạn, modun phát 2/3 âm bắn mà cũnp đạt hiệu tường đứơng Tiếp tục tùy ý bạn Hix, công việc van cịn nhíu phía trước hix hix Dưới screen shot từ ga me RTS phát triển: Menu Pause I[DipiowQcyjGold; 4500 Tree: XKXP: Unit: 02/10 Time: 14:31 © CrazyBabe 2003 K-Outertainm ent™ Trang 59 Sim ple ATS GAme DESign & Ceding Reference AvenusHelper • Định nghĩa kiểu: o TBitDepth: Kiểu độ sâu màu hình ■BD16Bit: Độ sâu màu 16bit ■BD32Bit: Đọ sâu màu 32bit o TIm ageForm at: Kiểu form at ảnh ■Form atR3G3B2: Ảnh 8bit (Red 3bit, Green 3bit, Blue 2bit) ■Form atX4R4G4B4: Ảnh 16bit (M ask 4bit, Red 4bit, Green 4bit, Blue 4bit) ■Form atA4R4G4B4: Ảnh 16bit (Alpha 4bit, Red 4bit, Green 4bit, Blue 4bit) ■Form atA8R3G3B2: Ảnh 16bit (Alpha 8bit, Red 3bit, Green 3bit, Blue 2bit) ■Form atR5G6B5: Ảnh 16bit (Red 5bit, Green 6bit, Blue 5bit) ■Form atX lR 5G B : Ảnh 16bit (M ask lb it, Red 5bit, Green 5bit, Blue 5bit) ■Form atA lR 5G 5B 5:Ả n h lõ b it (Alpha lb it , Red 5bit, Green 5bit, Blue 5bit) ■Form atX8R8G8B8: Ảnh 32bit (M ask 8bit, Red 8bit, Green 8bit, Blue 8bit) ■Form atA8R8G8B8:Ảnh 32bit (Alpha 8bit, Red 8bit, Green 8bit, Blue 8bit) • Định nghĩa hằng: o EffectNone: Vẽ không hiệu ứng o EffectAdd: Vẽ kiểu cọng o EffectSrcAlpha: Vẽ theo kênh alpha ảnh, áp dụng với ảnh có kênh alpha o EffectSrcAlphaAdd: Vẽ kiểu cộng theo kênh alpha ảnh, áp dụng với ảnh có kênh alpha, o EffectMul: Vẽ theo kiểu nhân o EffectSrcColor: Vẽ sử dụng màu source kênh alpha, o EffectSrcColorAdd: Vẽ kiếu cộng, sử dụng màu source kênh alpha, o EffectlnvSrcColor: Vẽ với giá trị màu nguồn đảo ngược, o EffectlnvSrcAlpha: Vẽ với giá trị kênh alpha đảo ngược © CrazyBabe 2003 K-Outertainm ent™ Trang 60 Sim ple ATS GAme DESign & Ceding o o o o o o o o EffectlnvSrcM ask: Vẽ với giá tri m ask đảo ngược E ffectB len d l, EffectBlend2, EffectBlend3, EffẽctBlend4: Các kiểu hiệu ứng blend ảnh thử nghiệm, EffectShadow: Vẽ bóng, EffectBlendColor: Vẽ blend với màu nguồn, EffectBlendColorAlphaChannel: Vẽ blend sử dụng kênh alpha, EffectAddDiffuse, EffectDiffuseAlpha: Vẽ khuếch tán với kênh alpha, EffectMirror, EffectFlip: Vẽ lật hình, hiệu ứng kết hợp với hiệu ứng Cắc số Key_# cắc số định nghĩa số hiệu phím, bạn dễ dàng đốn đại diện cho phím nào, tơi khơng thích dài Các hàm, lệnh: o Hàm CreateW indow (W idth,Height : Integer;Title : PChar) : Boolean ■ Tạo cửa sổ kích thước Width X Height có caption Title ■ Hàm trả true tạo thành công, trả false không tạo cửa sổ o Hàm CreateFullScreen(W idth,Height : Integer;ScreenDepth : TBitDepth;Title : PChar) : Boolean ■ Khởi tạo chế đ ộ hình Width X Height đ ộ sâu màu ScreenDepth có caption Title ■ Hàm trả true khởi tạo thành công, trả false không khởi tạo chế độ o Lệnh DestroyScreen ■ Huỷ cửa sổ/chế độ tạo trước đó, sau gọi lệnh tất hàm vẽ, lấy phím sinh lỗi chương trình huỷ handle quản lý tất dịch vụ o Hàm EventMessage : Boolean ■ Kiếm tra events, trả false xuất event Quit, o Lệnh LoadFont(FileNam e : string ;SizeX ,Size Y, Width, Height,TransColor : LongWord) ■ Đọc font chữ từ file ảnh FileName o Lệnh TextO ut(X,Y : Integer;Text : String;Color : LongWord) ■ Viết xâu Text hình, toạ độ [X,Y], màu Color o Lệnh TextO ut(X,Y : Integer;Text : String;Color : LongW ord;Effect : Integer) ■ Viết xâu Text hình, toạ độ [X,Y], màu Color Hiệu ứng Effect o Hàm CreateIm age(SizeX,SizeY : Integer;Form at : TIm ageForm at) : Integer ■ Tạo ảnh có kích thước SizeX X SizeY với form at Format ■ Số trả số hiệu ảnh tạo o Hàm LoadIm age(FileNam e : String;Form at : TIm ageForm at) : Integer ■ Đọc ảnh từ FileName, ảnh đọc vào với form at Format ■ Hố trợ định dạng ảnh JPEG, PNG, BMP ■ Số trả số hiệu ảnh đọc o Hàm SetAlphaM ask(Im ageNum ,TransparentColor : Integer) : Integer ■ Đ ặt kênh Alpha cho tất điếm ảnh có màu Transparent ■ Chỉ hỗ trợ form at ảnh Form atA lR 5G 5B o Hàm GetIm ageW idth(Im ageNum : Integer) : Integer ■ Lấy độ rộng ảnh số hiệu ImageNum o Hàm GetIm ageHeight(Im ageNum : Integer) : Integer ■ Lấy độ cao ảnh số hiệu ImageNum o Hàm Im ageLock(Im ageNum : Integer) : Integer © CrazyBabe 2003 K-Outertainm ent™ Trang 61 Sim ple ATS GAine Dssign & Ceding ■ Lock ảnh số hiệu ImageNum Hàm Im ageUnLock(Im ageNum : Integer) : Integer ■ UnLock ảnh số hiệu ImageNum o Lệnh Im ageClear(Im ageNum : Integer;Color : Cardinal) ■ Xoa ảnh ImageNum màu Color o Lệnh Im agePutPixel(Im ageNum ,X,Y : Integer;Color : Cardinal) ■ Vẽ điểm ảnh màu Color toạ độ [X,Y] ảnh ImageNum o Hàm Im ageGetPixel(Im ageNum ,X,Y : Integer) : Cardinal ■ Lấy màu điểm ảnh Color toạ độ [X,Y] ảnh ImageNum o Lệnh Im ageU ne(Im ag el\lu m ,X l,Y l,X 2,Y : Integer;Color : Cardinal) ■ Ve đường thẳng màu Color từ [ x i/ Y l] đến [X2,Y2] ảnh ImageNum o Lệnh Im ag eR ect(Im ag eN u m ,X l,Y l,X ,Y : Integer;Color : Cardinal) ■ Vẽ hình chữ nhật màu Color từ [X I,Y1] đến [X2,Y2] ảnh ImageNum o Lệnh Im ageFM IRect(Im ageN um ,Xl,Yl,X2,Y2 : Integer;Color : Cardinal) ■ Tơ hình chữ nhật mau Color từ [X I,Y1] đến [X2,Y2] ảnh ImageNum o Lệnh BeginRender ■ Bắt đầu vẽ scene (xoá buffer, xoá render buffer), o Lệnh EndRender ■ Kết thúc vẽ scene o Lệnh ClearScreen(Color : Cardinal) ■ Xố hình màu Color, o Hàm RenderBuffer : Integer ■ Dựng tồn hình render buffer, o Lệnh SetCIipRect(X ,Y1 ,X2jY2 : Integer) ■ Đ ặt clip rect o Lệnh R e c t(X l,Y Ĩ,X ,Y : Integer;Color : Cardinal;Effect : Integer) ■ Vẽ hình chữ nhật o Lệnh B a r(X l,Y l,X ,Y : Integer;Color : Card in al;Effect : Integer) ■ To hình chữ nhật o Lệnh L in e (X l,Y l,X ,Y : Integer;Color : C ardinal;Effect : Integer) ■ Ve đường thẳng o Lệnh S m o o th U n e (X l,Y l,X ,Y : Integer;Color : Cardinal) ■ Vẽ đường thẳng smooth (mịn) o Hàm Im ageRenderEffect(XPos,YPos,Pattern,Effect : Integer) : Boolean ■ Dựng ảnh Pattern vị trí [XPos, YPos] với hiệu ứng Effect, o Hàm Im a g e R e n d e rE ffe ct(X l,Y l,X ,Y ,Pattern,Effect : Integer) : Boolean ■ Dựng ảnh Pattern thành hình chữ nhật [X1,Y1,X2,Y2] với hiệu ứng Effect o Hàm Im ageRenderEffect(XPos,YPos,Scale,Pattern,Effect : Integer) : Boolean ■ Dựng ảnh Pattern vị trí [XPos, YPos] với hiệu ứng Effect Tỉ lệ zoom Scale/256 o Hàm Im ageRenderEffectColor(XPos,YPos : Integer;Color : Cardinal;Pattern,Effect : Integer) : Boolean Dựng ảnh Pattern vị trí [XPos, YPos] với hiệu ứng Effect Màu ắp Color o Hàm Im ageR en d erE ffectC o lor(X l,Y l,X 2,Y : Integer;Color : Cardinal;Pattern,Effect : Integer) : Boolean ■ Dựng ảnh Pattern thành hình chữ nhật [X1,Y1,X2,Y2] với hiệu ứng Effect Màu áp Color o © CrazyBabe 2003 K-Outertainm ent™ Trang 62 Sim ple ATS GAme DESign & Ceding o Hàm Im ageRenderEffectColor(XPos,YPos : In te g e r;C l,C ,C ,C : Long Word; Pattern,Effect : Integer) : Boolean ■ Dựng ảnh Pattern vị trí [XPos, YPos] với hiệu ứng Effect Màu áp bốn góc C1, C2, C3, C4 o Hàm Im ageRenderEffectColor(XPos,YPos,Scale : Integer;Color : Cardinal;Pattern,Effect : Integer) : Boolean ■ Dựng ảnh Pattern vị trí [XPos, YPos] với hiệu ứng Effect Tỉ lệ zoom Scale/256 Màu áp Color o Lệnh G etln p u tstatu s ■ Cập nhật input (Trạng thái mouse, keyboard ) o Hàm KeyDow n(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 M ouseFirstClickL : Boolean ■ Click chuột trái ? o Hàm M ouseFirstClickR : Boolean ■ Click chuột phải ? o Hàm MouseFirstClickM : Boolean ■ Click chuột ? 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 ? 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 ? o Hàm MouseX : Integer ■ Toạ độ X chuột, o Hàm MouseY : Integer ■ Toạ độ Y chuột o Hàm CreateSound(FileNam e : String;Loop : Boolean) : Integer ■ Tạo handle cho sound FileName ■ Trả handle quản lý sound o Lệnh SoundPlay(Slot : Integer) ■ Chơi sound số hiệu Slot, o Lệnh SoundPause(Slot : Integer) ■ Tạm dừng sound số hiệu Slot, o Lệnh SoundStop(Slot : Integer) ■ Dừng sound số hiệu Slot o Lệnh SoundSetVolum e(Slot : Integer;Value : Byte) ■ Đ ặt cường độ âm cho Slot, o Hàm SoundGetVolum e(Slot : Integer) : Byte ■ Lấy cường độ âm Slot © CrazyBabe 2003 K-Outertainm ent™ Trang 63 ... TPoint; Đối tượng chính: GamePlay TYPE TGame = Class Đánh dấu game kết thúc EndGame :Boolean; Đánh dấu game chế độ tạm dừng PauseGame :Boolean; Dữ liệu người chơi game GamePlayers :Array[TPlayer]... GamePlayers[Player].Money:=DefaultMoney; End; PROCEDURE TGame.RestartCount; Begin GameStart:=MMSystem.TimeGetTime; LastGameScreenTime:=GameStart; LastGameUnitTime:=GameStart; LastGamelnputTime:=GameStart; © CrazyBabe 2003... TGame.ProcessEvents; Begin //Update mini map If GameTime-LastGameMiniMapTime>MiniMapUpdate then Begin LastGameMiniMapTime:=GameTime; WorldMiniMapUpdate; End; //Update money If GameTime-LastGameMoneyTime>MoneyTime