View previous topic :: View next topic |
Author |
Message |
Inf3rnal
Joined: 15 Jun 2006 Posts: 118 Location: Neverland
|
Posted: Sun Mar 02, 2008 12:31 pm Post subject: Spēles galvenais cikls |
|
Game loop
Iepriekš visos manos projektos spēle darbojās pēc event based principa.
Tagad gribēju pamēģināt uztaisīt tā lai manā spēlē viss notiktu ar game loop laīdzību...
Mana problēma ir tajā, ka mans cikls nokar visu programmu. Droši vien, ka vajag uztaisīt kaut kādu FPS limiteri, taču kā? Būtu labi ja to varētu panākt bez API un citām external funkcijām.
Gūglēšana vēlamo rezultātu nedeva, daudzos piemēros cikls izpildās cik vien ātri velk dators... |
|
Back to top |
|
|
bubu Indago Uzvarētājs
Joined: 23 Mar 2004 Posts: 3223 Location: Riga
|
Posted: Sun Mar 02, 2008 12:35 pm Post subject: |
|
Kā izpaužas "nokar visu programmu"?
Galvenais jau tajā "game loop'ā" ir apstrādāt Operētājsistēmas eventus. WinAPI tas nozīmē regulāri izsaukt GetMessage/PeekMessage/TranslateMessage/DispatchMessage funkcijas, SDL'am tas ir izsaukt kādu no SDL_PumpEvents/SDL_PollEvent/SDL_WaitEvent/.. funkcijām, utt...
Ar kaut kādiem FPS limiteriem tam ir maz sakara. |
|
Back to top |
|
|
Inf3rnal
Joined: 15 Jun 2006 Posts: 118 Location: Neverland
|
Posted: Sun Mar 02, 2008 12:38 pm Post subject: |
|
Paņemsim pavisam primitīvi:
Code: |
Do
'mans kods
Loop While (Running = True)
|
Lūk šis te nokar, tb cikls izpildās visu laiku... |
|
Back to top |
|
|
bubu Indago Uzvarētājs
Joined: 23 Mar 2004 Posts: 3223 Location: Riga
|
Posted: Sun Mar 02, 2008 12:45 pm Post subject: |
|
Nav jau nekāds brīnums - droši vien Running mainīgais nekad nepieņem False vērtību, heh :) |
|
Back to top |
|
|
Inf3rnal
Joined: 15 Jun 2006 Posts: 118 Location: Neverland
|
Posted: Sun Mar 02, 2008 12:50 pm Post subject: |
|
Jā nepieņem To es saprotu, bet es nesaprotu to kā panākt lai game loops izpildītos tā kā tam vajadzētu (deimžēt es īsti neizprotu tā koncepciju)... |
|
Back to top |
|
|
Kamazs Guru
Joined: 17 Jan 2003 Posts: 829 Location: The glorious ancient city of Loja
|
Posted: Sun Mar 02, 2008 12:50 pm Post subject: |
|
Ja tu neko šī lūpa laikā nezīmē uz ekrāna (SDL/DirectX, OpenGL), tad, protams, ka uzkārsies. Lai gan to it kā nemaz nevar saukt par uzkāršanos.
Vari nerakstīt kodu, bet pasaki, ko tu dari ieksh taa Do.. Loop ? Vai tu vispār spēli taisi ar kādu ekrānzīmētājapi (DirectX, OpenGL etc?) vai izmantojot vizuālo vidi (tjipa buttoni, labelji, formas). Ja pēdējais, tad luups tev nav vajadziigs. _________________ ...un es uzskatu, ka Fallout ir etalons |
|
Back to top |
|
|
Inf3rnal
Joined: 15 Jun 2006 Posts: 118 Location: Neverland
|
Posted: Sun Mar 02, 2008 1:01 pm Post subject: |
|
Pašlaik loopā nekā nav vienk es testēju kā un kas...
Bildīte tiek zīmēta ar GDI palīdzību, pogu un labeļu nav, bet grafika tiek zīmēta logā (formā, windowed mode).
Vēlāk gribēju ielikt loopā: invalidate funkciju kas atjauno bildīti ko zīmē form_onpaint funkcija (laikam tā)... Agrāk man tas tika darīts, kad lietotājs nospiež kādu pogu... |
|
Back to top |
|
|
bubu Indago Uzvarētājs
Joined: 23 Mar 2004 Posts: 3223 Location: Riga
|
Posted: Sun Mar 02, 2008 1:23 pm Post subject: |
|
Inf3rnal wrote: | form_onpaint |
No šī teksta pieņemu, ka tu programmē Borland C++ Builderī vai Borland Delphi. Tādā gadījumā tev jāpaskatās uz Application objekta OnIdle eventu.
Tas events tiek izsaukts tad, kad tavai programmai nav ko darīt. T.i. no Windows'a nepienāk nekādi ziņojumi, ka, piemēram, lietotājs kustina peli, vai spiež klaviatūras pogas un tml. Sīkāk vari izlasīt helpā.
Šinī eventā tad arī raksti sava do/loop cikla ķermeni (BET nevis pašu ciklu!!).
Katru reizi izsaucoties šim OnIdle eventam tavas geimloops izpildīs vienu iterāciju. Tajā tu dari, ko gribi, piemēram, izskaitļo spraitu/bildīšu jaunās koordinātes ekrānā un updeito to koordinātes attiecīgajiem elementiem savā formā/canvasā.
Viena lieta, ko uzreiz pamanīsi, šis OnIdle events izsaucās ļoti atkarībā no sistēmas ātrdarbības un noslogojamības. Tāpēc nāksies izmanto vienu no diviem veidiem kā panākt kustības ātruma neatkarību no sistēmas ātruma.
Viens veids ir izpildīt savas darbības tikai, kad ir pagājis noteikts laiks, kopš iepriekšējās reizes (lūk šis ir FPS limiteris). T.i apmēram šādi:
Code: |
void OnIdle(....)
{
float LaiksTagad = ...; /// dabū tekošo laiku sekundēs
if (LaiksTagad - LaiksIepriekš >= 1.0/60.0) // 60 FPS
{
// Te raksti savu game loopa ķermeni
// ...
LaiksIepriekš = LaiksTagad;
}
else
{
Sleep(0); // ļaujam operētājsistēmai drusku "atpūsties"
}
} |
Šo variantu var arī realizēt nevis ar OnIdle, bet ar Timer klases palīdzību.
Otrs variants, ar lielākām iespējām, ir ņemt vērā pagājušo laiku un attiecīgi to izmantot kustības updeitošanā. Vienkāršākajā gadījumā tas izskatās šādi
Code: |
void OnIdle(....)
{
float LaiksTagad = ...; /// dabū tekošo laiku sekundēs
float Delta = LaiksIepriekš - LaiksTagad;
// Te raksti savu game loopa ķermeni
// ...
LaiksIepriekš = LaiksTagad;
} |
Un visur, kur tev vajag izmantot koordināšu updeitošanu (piemēram BildeX = BildeX + 10) tur izmanto to Delta mainīgo: BildeX = BildeX + 10 * Delta; Tas nozīmēs, ka BildeX vērtība mainīsies par 10 vienībām sekundē.
Par šo otro veidu sīkāk lasi te: http://www.gaffer.org/game-physics/fix-your-timestep |
|
Back to top |
|
|
Inf3rnal
Joined: 15 Jun 2006 Posts: 118 Location: Neverland
|
Posted: Sun Mar 02, 2008 1:31 pm Post subject: |
|
Pirmais veids man laikam nederēs, jo lietoju Visual Studio - VB, C++
Otrais izskatās interesanti, tūlīt pastudēšu tuvāk... |
|
Back to top |
|
|
bubu Indago Uzvarētājs
Joined: 23 Mar 2004 Posts: 3223 Location: Riga
|
Posted: Sun Mar 02, 2008 1:43 pm Post subject: |
|
Tad pasaki beidzot, ko tu īsti lieto. Kādu API vai Freimworku. Citādi maldīšanās mežā te visiem sanāk.
Par VB gan neko nezināšu, bet, ja tas ir VB.NET, tad paskaties šo te lapu: http://blogs.msdn.com/tmiller/archive/2005/05/05/415008.aspx Tajā ir parādīts kā to OnIdle eventu panākt c#'ā, bet VB.NET'ā tas darās gandrīz tāpatās. |
|
Back to top |
|
|
Inf3rnal
Joined: 15 Jun 2006 Posts: 118 Location: Neverland
|
Posted: Sun Mar 02, 2008 1:48 pm Post subject: |
|
Es lietoju Visual Basic 2005
Un:
Namespace System.Drawing.Drawing2D
Member of: System.Drawing
Summary:
The System.Drawing.Drawing2D namespace provide advanced two-dimensional and vector graphics functionality.
Vairāk neko nezinu. |
|
Back to top |
|
|
bubu Indago Uzvarētājs
Joined: 23 Mar 2004 Posts: 3223 Location: Riga
|
|
Back to top |
|
|
|