Repository 32bit  Forum
Repository 64bit  Wiki

Tecniche di scrittura

Forum dedicato alla programmazione.

Moderatore: Staff

Regole del forum
1) Citare in modo preciso il linguaggio di programmazione usato.
2) Se possibile portare un esempio del risultato atteso.
3) Leggere attentamente le risposte ricevute.
4) Scrivere i messaggi con il colore di default, evitare altri colori.
5) Scrivere in Italiano o in Inglese, se possibile grammaticalmente corretto, evitate stili di scrittura poco chiari, quindi nessuna abbreviazione tipo telegramma o scrittura stile SMS o CHAT.
6) Appena registrati è consigliato presentarsi nel forum dedicato.

La non osservanza delle regole porta a provvedimenti di vari tipo da parte dello staff, in particolare la non osservanza della regola 5 porta alla cancellazione del post e alla segnalazione dell'utente. In caso di recidività l'utente rischia il ban temporaneo.

Tecniche di scrittura

Messaggioda nuitari » mer gen 09, 2008 18:30

Ecco questa è una funzione del mio "vecchio" server di gaming che mostra l'uso delle IOCP sul Network:

Codice: Seleziona tutto
//o----------------------------------------------------------------------------------
//|   Function      -   DWORD WINAPI WorkerThread (LPVOID ThreadContext)
//|   Date         -   
//|   Author         -   Nuitari
//|   Modified      -
//o----------------------------------------------------------------------------------
//|   Purpose         -   Thread per i socket connessi
//o----------------------------------------------------------------------------------
DWORD WINAPI cNetwork::WorkerThread (LPVOID ThreadContext)
{
   SEH_BEGIN("DWORD WINAPI WorkerThread (LPVOID ThreadContext)")
    cNetwork      *ContextServer = (cNetwork *)ThreadContext;
   BOOL         bSuccess;
    DWORD         dwIoSize = 0, dwRecvNumBytes = 0, dwFlags = 0, dwSendNumBytes = 0;
    cSocket         *lpSocket = NULL;
    LPOVERLAPPED   lpOverlapped = NULL;
   PIO_CONTEXT      lpIoContext = NULL;
   INT            rc = 0;

   BOOL   bCtxtSect = FALSE, bOutBuffSect = FALSE, bCrSectClient = FALSE;


   __try
   {
      InterlockedExchangeAdd(&ContextServer->lWorkThreads,1);
      while (TRUE)
      {
         if (bOutBuffSect)
         {
            LeaveCriticalSection(&lpSocket->CrSect_OutBuffer);
            bOutBuffSect = FALSE;
         }
         if (bCrSectClient)
         {
            LeaveCriticalSection(&ContextServer->CrSect_Client);
            bCrSectClient = FALSE;
         }

         bSuccess = GetQueuedCompletionStatus(ContextServer->hWorkIOCP, &dwIoSize, (LPDWORD)&lpSocket, &lpOverlapped, INFINITE);
         InterlockedExchangeAdd(&ContextServer->lBusyWorkThreads,1);

         if (ContextServer->lBusyWorkThreads == ContextServer->lWorkThreads && ContextServer->lWorkThreads < ContextServer->lMaxWorkThreads)
         {
            //Gui->MessageLog(L"NETWORK: Spawning New Thread");
            DebugLog("NETWORK: Spawning New Thread");
            HANDLE  hThread;
            DWORD   dwThreadId;
         
            hThread = CreateThread(NULL, 0, WorkerThread, ContextServer, 0, &dwThreadId);
            if (hThread == NULL)
            {
               //Gui->MessageLog(L"NETWORK: ERROR Spawning New Thread");
               DebugLog("NETWORK: ERROR Spawning New Thread");
            }
         }
         
         if (ContextServer->bEndServer)
            break;

         if (!bSuccess || (bSuccess && (0 == dwIoSize)))
         {
            __try
            {
               __try
               {
                  if (lpSocket)
                  {
                     rc = GetLastError();
                     lpSocket->bClose = TRUE;
                     lpIoContext = CONTAINING_RECORD(lpOverlapped, IO_CONTEXT, Overlapped);
                     if (lpIoContext)
                     {
                        if (lpIoContext->IOOperation == ClientIoWrite)
                        {
                           //lpSocket->ClearOut();
                           lpSocket->isSending = FALSE;
                        }
                        lpSocket->CtxtDeAllocate(lpIoContext);
                     }
                     InterlockedExchangeAdd(&lpSocket->IoPending,-1);
                  } else {
                     //Gui->MessageLog(L"NETWORK: Invalid Socket in Worker Thread");
                     DebugLog("NETWORK: Invalid Socket in Worker Thread");
                  }
               }
               __except(EXCEPTION_EXECUTE_HANDLER)
               {
                  //Gui->MessageLog(L"NETWORK: DISCONNECT EXCEPTION");
                  DebugLog("NETWORK: DISCONNECT EXCEPTION");
               }
            }
            __finally
            {
               if (bCrSectClient)
               {
                  LeaveCriticalSection(&ContextServer->CrSect_Client);
                  bCrSectClient = FALSE;
               }
            }
            InterlockedExchangeAdd(&ContextServer->lBusyWorkThreads,-1);
            continue;
         }
         
         lpIoContext = CONTAINING_RECORD(lpOverlapped, IO_CONTEXT, Overlapped);
   
         switch(lpIoContext->IOOperation)
         {
            case ClientIoRead:
               InterlockedExchangeAdd(&lpSocket->IoPending,-1);
               lpIoContext->nRecvBytes += dwIoSize;
               lpSocket->AddIn(lpIoContext);
               lpSocket->isWaitRecv = FALSE;
               GetLocalTime(&lpSocket->LastRecv);
               break;

            case ClientIoWrite:
               // a write operation has completed, determine if all the data intended to be
               // sent actually was sent.
               InterlockedExchangeAdd(&lpSocket->IoPending, -1);
               lpIoContext->nSentBytes  += dwIoSize;
               dwFlags = 0;
               if (lpIoContext->nSentBytes < lpIoContext->nTotalBytes)
               {
                  // the previous write operation didn't send all the data,
                  // post another send to complete the operation
                  //DebugLog("NETWORK: Resending incomplete data");
                  //Gui->MessageLog(L"NETWORK: Resending incomplete data..");
                  lpIoContext->wsabuf.buf = lpIoContext->Buffer + lpIoContext->nSentBytes;
                  lpIoContext->wsabuf.len = lpIoContext->nTotalBytes - lpIoContext->nSentBytes;
                  //lpIoContext->nTotalBytes = lpIoContext->wsabuf.len;
                  InterlockedExchangeAdd(&lpSocket->IoPending, 1);
                  rc = WSASend (
                     lpSocket->sd,
                     &lpIoContext->wsabuf, 1, &dwSendNumBytes,
                     dwFlags,
                     &lpIoContext->Overlapped, NULL);
                  if (SOCKET_ERROR == rc && (ERROR_IO_PENDING != WSAGetLastError()))
                  {
                     rc = WSAGetLastError();
                     DebugLog("NETWROK: RESEND ERROR");
                     //ContextServer->Disconnect(lpSocket);
                     lpSocket->pClient->Disconnect();
                  }
               }
               else
               {
                  // previous write operation completed for this socket, delete context
                  EnterCriticalSection(&lpSocket->CrSect_OutBuffer);
                  bOutBuffSect = TRUE;
                  lpSocket->CtxtDeAllocate(lpIoContext);
                  if (lpSocket->OutBuffer.empty())
                  {
                     lpSocket->isSending = FALSE;
                  } else {
                     InterlockedExchangeAdd(&lpSocket->IoPending, 1);
                     lpIoContext = *lpSocket->OutBuffer.begin();
                     lpSocket->OutBuffer.erase(lpSocket->OutBuffer.begin());
                     rc = WSASend(
                        lpIoContext->pSocket->sd,
                        &lpIoContext->wsabuf, 1, &dwSendNumBytes,
                        dwFlags,
                        &lpIoContext->Overlapped, NULL);
                  }
                  if (SOCKET_ERROR == rc)
                  {
                     rc = WSAGetLastError();
                     if (rc != ERROR_IO_PENDING)
                     {
                        DebugLog("NETWORK: SEND ERROR");
                        //ContextServer->Disconnect(lpSocket);
                     }
                  }
                  LeaveCriticalSection(&lpSocket->CrSect_OutBuffer);
                  bOutBuffSect = FALSE;
               }
               break;
         }
         InterlockedExchangeAdd(&ContextServer->lBusyWorkThreads,-1);
      }
   }
   __finally
   {
      if (bOutBuffSect)
         LeaveCriticalSection(&lpSocket->CrSect_OutBuffer);
      InterlockedExchangeAdd(&ContextServer->lWorkThreads,-1);
   }
   return FALSE;
   SEH_END_FUNC
}


Per inciso, ricordo che non ho potuto usare le features complete delle IOCP ai tempi perchè il client non le supportava, s'inchidava invariabilmente perchè non riusciva a gestire l'invio non sequenziale dei dati... ma d'altronde quello non l'avevo mica programmato io :P
Avatar utente
nuitari
Linux 2.6
Linux 2.6
 
Messaggi: 777
Iscritto il: dom ott 14, 2007 11:51
Località: San Colombano al Lambro
Slackware: 12.0

Re: Tecniche di lettura

Messaggioda Blizzard » gio gen 10, 2008 17:42

ciao,
ho passato il codice alla velocità della rotellina del mouse :P (dopo 2 ore di algoritmi e dati distribuiti ecc... non ho un cervello freschissimo)

A dargli un occhiata meglio comunque spero che ci capirò qualcosa :P (a partire dal fatto che non ho basi di winapi ecc...) in ogni caso mi piace un casino la stilistica e finalmente vedo i blocchi di codice in stile C
Codice: Seleziona tutto
if()
{
}


e non in stile java
Codice: Seleziona tutto
if(){
}

che è uno stile che fondamentalmente odio... perchè comunque avere indentato il blocco insieme alle parentesi di inizio e chiusura aiuta moltissimo.

ciao
Gio
Avatar utente
Blizzard
Master
Master
 
Messaggi: 1509
Iscritto il: mar gen 02, 2007 22:53
Nome Cognome: Giovanni Santostefano
Slackware: 12.2
Kernel: 2.6.27.7-smp
Desktop: Fluxbox

Re: Tecniche di lettura

Messaggioda nuitari » gio gen 10, 2008 17:50

Eheh si lo odio pure io... grazie comunque, anch'io adoro leggere il codice così. L'unico prob è che incollandolo nel forum mi ha sballato i tab . dentro l'ide di M$ è tutto + ordinato .
Avatar utente
nuitari
Linux 2.6
Linux 2.6
 
Messaggi: 777
Iscritto il: dom ott 14, 2007 11:51
Località: San Colombano al Lambro
Slackware: 12.0

Re: Tecniche di lettura

Messaggioda gallows » gio gen 10, 2008 18:26

Quel modo di sistemare i blocchi non è Java, il K&R è scritto in quel modo... quindi se vogliamo lo stile ufficiale è proprio quello
Avatar utente
gallows
Staff
Staff
 
Messaggi: 3466
Iscritto il: dom set 19, 2004 23:00
Località: Palermo
Kernel: FreeBSD 8.0-RELEASE-p3
Desktop: ratpoison

Re: Tecniche di lettura

Messaggioda nuitari » gio gen 10, 2008 18:29

gallows ha scritto:Offtopic: Quel modo di sistemare i blocchi non è Java, il K&R è scritto in quel modo... quindi se vogliamo lo stile ufficiale è proprio quello


Mah, che io sappia quella è la formattazione standard in ANSI C...

Ho provato ad usare la formattazione proposta nei GNU Coding Standards, ma l'ho trovata veramente SCOMODA (ebbene si).

Codice: Seleziona tutto
For the body of the function, we prefer code formatted like this:

if (x < foo (y, z))
  haha = bar[4] + 5;
else
  {
    while (z)
      {
        haha += foo (z, z);
        z--;
      }
    return ++x + bar ();
  }

Avatar utente
nuitari
Linux 2.6
Linux 2.6
 
Messaggi: 777
Iscritto il: dom ott 14, 2007 11:51
Località: San Colombano al Lambro
Slackware: 12.0

Re: Tecniche di lettura

Messaggioda gallows » gio gen 10, 2008 18:35

nuitari ha scritto:Mah, che io sappia quella è la formattazione standard in ANSI C...

Non lo sapevo, non ho mai letto direttamente gli standard.

Ho provato ad usare la formattazione proposta nei GNU Coding Standards, ma l'ho trovata veramente SCOMODA (ebbene si).

Concordo, è orribile. Per citare Linus Torvalds:

First off, I'd suggest printing out a copy of the GNU coding standards,
and NOT read it. Burn them, it's a great symbolic gesture.


Io uso quella di linux, quindi con i blocchi alla K&R. Sebbene da un po' usi l'indentazione a 4 (stile Stroustrup), la cosa buona è che rientri tranquillamente nelle 79 colonne, però l'indentazione a 8 la trovo molto più facile da leggere e infatti credo che tornerò a quella.

Ps. non sopporto la caratteristica del codice BSD di scrivere le funzioni in questa maniera:
Codice: Seleziona tutto
static int
f(char *foo, size_t bar)
{
}


(Ah, io l'asterisco lo applico al tipo, non al nome della variabile.)
Avatar utente
gallows
Staff
Staff
 
Messaggi: 3466
Iscritto il: dom set 19, 2004 23:00
Località: Palermo
Kernel: FreeBSD 8.0-RELEASE-p3
Desktop: ratpoison

Tecniche di scrittura

Messaggioda Blizzard » gio gen 10, 2008 18:56

Codice: Seleziona tutto
For the body of the function, we prefer code formatted like this:

if (x < foo (y, z))
  haha = bar[4] + 5;
else
  {
    while (z)
      {
        haha += foo (z, z);
        z--;
      }
    return ++x + bar ();
  }

Sai che jed utilizza direttamente questo tipo di formattazione? all'inizio non capivo e credevo che sballasse da qualche parte #-o
comunque anche IMHO è brutta forte :P

Io uso quella di linux, quindi con i blocchi alla K&R. Sebbene da un po' usi l'indentazione a 4 (stile Stroustrup), la cosa buona è che rientri tranquillamente nelle 79 colonne, però l'indentazione a 8 la trovo molto più facile da leggere e infatti credo che tornerò a quella.

Io di norma utilizzo quella a 8... anche se aimè a volte se una riga sfora la 79 vado oltre...

(Ah, io l'asterisco lo applico al tipo, non al nome della variabile.)

Io lo facevo nei programmi in C++. Scrivendo per classi definivo gli attributi uno per linea e allora mi sembrava più giusto leggere il puntatore come """tipo"""
Type* ptr;
Poi però mi sono accorto che comunque è una cosa sbagliatissima... perchè comunque in quanto abitudine poteva indurmi all'errore o allorquando avevo più variabili dichiarate sulla stessa riga e soprattutto era poco leggibile da parte di altri. Adesso anche quando scrivo OO nelle classi l'asterisco lo attacco comunque al nome e non al tipo.

ciao
Gio

P.S.
Ho dato un'occhiata al comparto grafico e di input di SDL e ho deciso di sviluppare il gioco interamente mediante queste librerie.
Solo per quanto riguarda il comparto sonoro sono ancora deciso ad affrontarlo... diciamo in maniera più dummy affidandomi a librerie tipo audiere che non devi fare altro che aprire un device caricare un file audio e dirgli di riprodurlo... senza impiccarti tra mixer , sampler e cavoli vari.
Avatar utente
Blizzard
Master
Master
 
Messaggi: 1509
Iscritto il: mar gen 02, 2007 22:53
Nome Cognome: Giovanni Santostefano
Slackware: 12.2
Kernel: 2.6.27.7-smp
Desktop: Fluxbox

Re: Tecniche di lettura

Messaggioda Blizzard » gio gen 10, 2008 19:15

ah! altra cosa che ho poco chiara del GNU coding style...

Codice: Seleziona tutto
foo = (char *) malloc (sizeof *foo);
     if (foo == 0)
       fatal ("virtual memory exhausted");

Qua alla malloc fanno un cast esplicito... e lo fanno praticamente sempre... io lo facevo in c++, una volta mi trovavo su comp.lang.c e scrivo per caso una cosa del genere. Giustamente mi fanno notare che il C non richiede, anzi era addirittura deleterio, il cast esplicito e giustamente trovo su wikipedia questa descrizione:
malloc returns a void pointer (void *), which indicates that it is a pointer to a region of unknown data type. Note that because malloc returns a void pointer, it needn't be explicitly cast to a more specific pointer type: ANSI C defines an implicit coercion between the void pointer type and other pointer types. An explicit cast of malloc's return value is sometimes performed because malloc originally returned a char *, but this cast is unnecessary in modern C code.[2][3] However, omitting the cast creates an incompatibility with C++, which requires it.

Dove opportunamente spiega che in ANSI C la malloc restituisce un void* e pertanto non è necessario fare un cast.
Perchè loro lo fanno?????
In teoria l'avrei fatto anch'io magari solo per chiarezza... però dopo quella discussione è uscito fuori che la cosa poteva creare anche problemi, quindi personalmente in C non utilizzo più quella scrittura.
Avatar utente
Blizzard
Master
Master
 
Messaggi: 1509
Iscritto il: mar gen 02, 2007 22:53
Nome Cognome: Giovanni Santostefano
Slackware: 12.2
Kernel: 2.6.27.7-smp
Desktop: Fluxbox

Re: Tecniche di lettura

Messaggioda gallows » gio gen 10, 2008 19:35

Quella è una cosa che non capirò mai... Peraltro può creare problemi di questo tipo:
Se hai:
Codice: Seleziona tutto
struct Fred* foo =  malloc(sizeof(struct Fred));                                     

E non hai incluso l'header con il prototipo di malloc() il compilatore ti avverte con un warning del casting da un intero al puntatore.
Invece, se scrivi:
Codice: Seleziona tutto
struct Fred* foo = (struct Fred*) malloc(sizeof(struct Fred));

Per lui è tutto normale, perché fai il casting esplicito. Un compilatore non è detto che ti avverta dell'errore!
gcc, con le flag di default, lo fa, perché malloc() è built-in ma non è detto che io voglia compilare con gcc..
Infatti, anche usando gcc, se passi la flag -fno-builtin lui non dice nulla...

ps. Uhm, siamo passati da tecniche di lettura a tecniche di scrittura... mi sa che ciò andrebbe copiato in un thread specifico...
Avatar utente
gallows
Staff
Staff
 
Messaggi: 3466
Iscritto il: dom set 19, 2004 23:00
Località: Palermo
Kernel: FreeBSD 8.0-RELEASE-p3
Desktop: ratpoison

Re: Tecniche di lettura

Messaggioda nuitari » gio gen 10, 2008 20:36

However, omitting the cast creates an incompatibility with C++, which requires it.


Credo stia tutto qui.
Personalmente, trovo errato che non sia richiesto fare un casto esplicito fra (void *) e (char *), in quanto seppur è vero che i pointer sono tutte dword, è concettualmente errato.
Avatar utente
nuitari
Linux 2.6
Linux 2.6
 
Messaggi: 777
Iscritto il: dom ott 14, 2007 11:51
Località: San Colombano al Lambro
Slackware: 12.0

Re: Tecniche di lettura

Messaggioda conraid » gio gen 10, 2008 21:28

Blizzard ha scritto:A dargli un occhiata meglio comunque spero che ci capirò qualcosa :P (a partire dal fatto che non ho basi di winapi ecc...) in ogni caso mi piace un casino la stilistica e finalmente vedo i blocchi di codice in stile C
Codice: Seleziona tutto
if()
{
}


e non in stile java
Codice: Seleziona tutto
if(){
}

che è uno stile che fondamentalmente odio... perchè comunque avere indentato il blocco insieme alle parentesi di inizio e chiusura aiuta moltissimo.


Ognuno ha il suo "stile" :-)
Io odio il primo metodo, sarà che ho imparato dal K&R, sarà che sono tardo a modificare una cosa ormai assimilata, ma odio quel tipo di formattazione.
Io come gallows uso il sistema K&R, ma con l'indentazione a 4
Avatar utente
conraid
Staff
Staff
 
Messaggi: 11986
Iscritto il: mer lug 13, 2005 23:00
Località: Livorno
Nome Cognome: Corrado Franco
Slackware: current

Re: Tecniche di scrittura

Messaggioda Blizzard » gio gen 10, 2008 21:49

Personalmente, trovo errato che non sia richiesto fare un casto esplicito fra (void *) e (char *), in quanto seppur è vero che i pointer sono tutte dword, è concettualmente errato.

Si anch'io penso che in linea logica il cast andrebbe messo... tuttavia:

AnticitizenOne wrote:
> On 29 Lug, 14:39, Richard Heathfield <r...@see.sig.invalid> wrote:
>> AnticitizenOne said:

>> > On 29 Lug, 14:04, santosh <santosh....@gmail.com> wrote:
>> >> AnticitizenOne wrote:

>> <snip>

>> >> > b=(struct Sample*)malloc(sizeof(struct Sample));

>> >> The cast isn't recommended in C.

>> > This is really new for me o_O
>> > I use the cast a lot...

>> Why?

>> > why in C is not recommended?

>> Several reasons, but before we get into those reasons, let's find out
>> your reasons for using the cast.

> I use the cast as referenced in C-Language (Kerningan & Ritchie)

That book was written before the first Standard for C was published. At that
point, there was no void * as a generic pointer type, but instead that
purpose was served by the char * type. Since then it's not necessary in C
to cast between a void * and another pointer type. Any pointer can be
converted to a void * and back again without any loss of information.

Infact casting the return value of malloc can prevent your compiler from
warning you when you fail to include stdlib.h, which declares malloc's
prototype. This can lead to possible undefined behaviour.

The only real reason for casting the return of malloc in C is if you're
forced to compile it under a C++ compiler or in a mixed C and C++
environment. That's pretty rare.

Questo è un estratto della discussione che dicevo
discussione originale
si fanno dei riferimenti anche a probabili comportamenti indefiniti #-o

Ognuno ha il suo "stile" :-)

in effetti come darti torto :-k

ciao
Gio
Avatar utente
Blizzard
Master
Master
 
Messaggi: 1509
Iscritto il: mar gen 02, 2007 22:53
Nome Cognome: Giovanni Santostefano
Slackware: 12.2
Kernel: 2.6.27.7-smp
Desktop: Fluxbox

Re: Tecniche di scrittura

Messaggioda Blizzard » ven gen 11, 2008 0:13

ciao,
sto progettando in C++ l'editor per un tile engine.
Devo scrivere la classe per i tiles... ora, per quello che mi è stato sempre riferito, è buona norma definire gli attributi di classe come private e lasciare a metodi Get/Set il compito di prelevare/settare i valori.
A conti fatti tuttavia avendo parecchi accessi agli attributi di quella classe non mi piace per niente l'idea di invocare una funzione per ogni volta che necessito di quel particolare valore...
che ne dite se lo setto come public????
Avatar utente
Blizzard
Master
Master
 
Messaggi: 1509
Iscritto il: mar gen 02, 2007 22:53
Nome Cognome: Giovanni Santostefano
Slackware: 12.2
Kernel: 2.6.27.7-smp
Desktop: Fluxbox

Re: Tecniche di scrittura

Messaggioda nuitari » ven gen 11, 2008 0:30

Che è comodo ma non giusto.
L'utilizzo di funzioni get/set permette in seguito di cambiare l'implementazione conservando l'interfaccia, tra le altre cose.

Sappi comunque una cosa. Nei giochi non si programma quasi mai con il paradigma ad oggetti puro, per via delle performance. I Videogames sono il ricettacolo di ogni tecnica di programmazione, dalle più sporche alle più sofisticate.
Avatar utente
nuitari
Linux 2.6
Linux 2.6
 
Messaggi: 777
Iscritto il: dom ott 14, 2007 11:51
Località: San Colombano al Lambro
Slackware: 12.0

Re: Tecniche di scrittura

Messaggioda Blizzard » ven gen 11, 2008 9:50

Sappi comunque una cosa. Nei giochi non si programma quasi mai con il paradigma ad oggetti puro, per via delle performance. I Videogames sono il ricettacolo di ogni tecnica di programmazione, dalle più sporche alle più sofisticate.

è questo il punto!
ho una mappa con x tiles... di queste tiles ad una risoluzione di 640x480 ne devo mandare 300 a schermo. Senza contare che ho diversi livelli di tiling!
Le tiles sono in un contenitore statico e a seconda di quali mostrare le prelevo una ad una (e gia qua la vedo brutta) poi devo prelevarne le proprietà associate al tileset :P (se mi metto a chiamare le funzioni non mi spiccio più)
Gia per lo scrolling mi ero cominciato a porre qualche problema... se a livello di prestazioni sto combinando un casino... penso che agirò in questo modo:
Ho 4 livelli di tiles sortate in base all'altezza. Di base le tiles a livello 0 sono il terreno crudo, quelle al livello 1 sono le strade. Quelle al 2 sono gli oggetti sullo stesso piano del player, cui può urtare e il 3 sono tutti gli oggetti (tipo la parte attraversabile di un ponte) cui il player può passare sotto.
Avendo questi 4 livelli se devo disperatamente rinunciare allo scrolling allora quasi quasi li prerenderizzo in 4 surfaces in caricamento e poi li renderizzo come 4 sfondi sovrapposti.
Comunque questa è una questione di poi.
Penso che in virtù di avere un sistema quantopiù veloce rinuncerò se posso ai virtuosismi di una buona programmazione OO (virtualizzazione ecc...).
Spero di non dovermene pentire in fase di scrittura e revisione del codice...

ciao
Gio
Avatar utente
Blizzard
Master
Master
 
Messaggi: 1509
Iscritto il: mar gen 02, 2007 22:53
Nome Cognome: Giovanni Santostefano
Slackware: 12.2
Kernel: 2.6.27.7-smp
Desktop: Fluxbox

Prossimo

Torna a Programmazione

Chi c’è in linea

Visitano il forum: Google [Bot] e 1 ospite

cron