Ce este o modalitate mai bună de a crea o buclă de jocuri pe iPhone în afară de utilizarea NSTimer?

Am programat un joc pe iPhone. În prezent, folosesc NSTimer pentru a declanșa actualizarea/renunțarea la joc. Problema cu acest lucru este că (după profilare), par să pierd mult timp între actualizări/randamente și acest lucru pare să aibă cel mai mult de a face cu intervalul de timp pe care am conectat la NSTimer.

Deci, întrebarea mea este ce este cea mai bună alternativă la utilizarea NSTimer?

O alternativă pentru fiecare răspuns vă rog.

0
M-am uitat la multe exemple și cercetări alternative pe internet. Așa că știu deja câteva alternative. Ceea ce am cu adevărat după ce este ceea ce alții cred că este cea mai bună alternativă? Lucrez la un proiect extrem de scurt, astfel încât oricând salvat pe investigație va fi un mare ajutor.
adăugat autor Ashley Davis, sursa
Te-ai uitat la exemplele dezvoltatorilor iPhone? Cred că există câteva exemple (Touch Fighter sau CrashLanding, de exemplu) care ar putea fi iluminate.
adăugat autor Mark Bessey, sursa

3 răspunsuri

Puteți obține o performanță mai bună cu firele, încercați ceva de genul:

- (void) gameLoop
{
    while (running)
    {
        NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
        [self renderFrame];
        [pool release];
    }
}

- (void) startLoop
{
    running = YES;
#ifdef THREADED_ANIMATION
    [NSThread detachNewThreadSelector:@selector(gameLoop)
    toTarget:self withObject:nil];
#else
    timer = [NSTimer scheduledTimerWithTimeInterval:1.0f/60
    target:self selector:@selector(renderFrame) userInfo:nil repeats:YES];
#endif
}

- (void) stopLoop
{
    [timer invalidate];
    running = NO;
}

În metoda renderFrame Vă pregătiți framebuffer-ul, trageți cadrul și prezentați framebuffer-ul pe ecran. (P.S. Există un mare articol despre diferite tipuri de bucle de joc și argumentele lor pro și contra.)

0
adăugat
@zoul: alternativa THREADED_ANIMATION funcționează și pentru versiunile anterioare? Am crezut că am citit că nu a fost undeva.
adăugat autor Jonas Byström, sursa
@tc: Ai dreptate, dar posterul nu spune nimic despre stratul grafic pe care îl folosește. Deoarece vorbim de jocuri, am preluat OpenGL, unde o astfel de buclă funcționează fără probleme.
adăugat autor zoul, sursa
Vreți să spuneți versiuni mai vechi pentru iOS? Da, am folosit cod similar folosit în jocuri în jurul valorii de 2.x sau 3.x.
adăugat autor zoul, sursa
-1. UIView nu este sigură în legătură cu firul, deci trebuie să faceți o grămadă de alte lucruri pentru ao face să funcționeze. UIGraphics este sigură numai pentru fir de la 4.0.
adăugat autor tc., sursa

Nu știu în special despre iPhone, dar pot să-i ajut în continuare: În loc să conectați pur și simplu o întârziere fixă ​​la sfârșitul bucla, utilizați următoarele:

  • Stabiliți un interval de reîmprospătare cu care ați fi mulțumit și care este mai mare decât o singură trecere prin buclă principală.
  • La începutul buclă, luați o marcă de timp curentă a rezoluției pe care o aveți și păstrați-o.
  • La sfârșitul buclă, luați un alt timestamp și stabiliți timpul scurs de la ultimul timestamp (inițializați acest lucru înainte de buclă).
  • somn/întârziere pentru diferența dintre timpul ideal al cadrului și timpul deja scurs pentru acest cadru.
  • La următorul cadru, puteți chiar să încercați să compensați inexactitățile din intervalul de întrerupere prin comparație cu marcajul de timp de la începutul buclei anterioare. Stocați diferența și adăugați-o/scădeți-o din intervalul de somn la sfârșitul acestei buclă (somnul/întârzierea poate dura prea mult sau prea scurt).

S-ar putea să doriți să aveți un mecanism de alertă care să vă anunțe dacă sincronizarea este prea strânsă (i, e, dacă timpul de somn după ce compensarea este mai mică de 0, ceea ce ar însemna că aveți mai mult timp să procesați decât viteza cadrului permite). Efectul va fi că jocul dvs. încetinește. Pentru a obține puncte suplimentare, vă recomandăm să simplificați randarea pentru o vreme, dacă descoperiți acest lucru, până când aveți suficientă capacitate de rezervă din nou.

0
adăugat

Utilizați CADisplayLink, puteți găsi modul în care în proiectul OpenGL ES șablon furnizat în XCODE (creați un proiect pornind de la acest șablon și aruncați o privire la clasa EAGLView, acest exemplu se bazează pe GL deschis, dar puteți utiliza CADisplayLink numai pentru alte genul de jocuri

0
adăugat