Gå til innhold

Strukturering av kode i små spill


Anbefalte innlegg

Jeg har laget et par småspill (snake, achtung die kurve osv) i c++/sdl.

Disse spillene har jeg ofte skrevet i en eneste stor fil. Det blir lett litt rotete.

Har sett meg om etter et godt eksempel på nettet eller noe som forklarer hvordan man burde strukturere koden når man lager spill. Veldig få tutorials gir direkte svar på hvordan man burde gjøre det. Du må ofte tygge deg igjennom så mye annet stoff først.

 

Her er det jeg har kommet fram til så langt:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <SDL/SDL.h>
#include <windows.h>

#define SCREENWIDTH 640
#define SCREENHEIGHT 480

/* The screen surface */
SDL_Surface *screen = NULL;

class Cgame
{
  public:
		 bool running;
		 void draw()
		 {
			   SDL_Flip (screen);
		 }
		 void loop()
		 {
			  while(running)
			  {
				   input();
				   draw();
			  }
			  cleanup();
		 }
		 void init()
		 {
			  char *msg;

			  /* Initialize SDL */
			  if (SDL_Init (SDL_INIT_VIDEO) < 0)
			  {
				   sprintf (msg, "Couldn't initialize SDL: %s\n", SDL_GetError ());
				   error(msg); 
				   free (msg);
				   exit (1);
			  }
			  atexit (SDL_Quit);

			  /* Set 640x480 16-bits video mode */
			  screen = SDL_SetVideoMode (SCREENWIDTH, SCREENHEIGHT, 32, SDL_SWSURFACE | SDL_DOUBLEBUF);
			  if (screen == NULL)
			  {
				   sprintf (msg, "Couldn't set video mode: %s\n",
					 SDL_GetError ());
				   error(msg); 
				   free (msg);
				   exit (2);
			  }
			  SDL_WM_SetCaption ("Game", NULL);

			  running=1;
			  loop();
		 }
		 void input()
		 {
			  SDL_Event event;

			  /* Check for events */
			  while (SDL_PollEvent (&event))
			  {
				  switch (event.type)
				  {
				  case SDL_KEYDOWN:
					   break;
				  case SDL_QUIT:
					   running = false;
					   break;
				  default:
					   break;
				  }
			  }
		 }
		 void cleanup()
		 {
			  SDL_FreeSurface(screen);
			  SDL_Quit();
		 }
		 void error(char *msg)
		 {
			  MessageBox (0, msg, "Error", MB_ICONHAND); 
		 }

};
Cgame game;

int
main (int argc, char *argv[])
{
 game.init();

return 0;
}

Jeg burde kanskje lage en Cgame.h fil som jeg putter alle deklarasjonene i, og lage filer som heter noe sånt som:

Cgame_loop.cpp

Cgame_input.cpp

Cgame_draw.cpp

osv.

 

Hva pleier dere som er litt mer erfarne å gjøre?

 

 

Hadde forresten vært fint med et eget underforum for spillprogrammering.

Endret av nahoy
Lenke til kommentar
Videoannonse
Annonse

Jeg ville putta deklarasjonen i en header fil og resten i en source fil.

Jeg ville ikke delt opp kode delen i flere filer.

Hvis du mener du har en så stor fil at du mener det er lurt å splitte koden fra en klasse opp så burde du vurdere om du bør splitte klassen opp i flere klasser.

 

I c++ så heter det ikke <stdio.h>, men <stdio>... dvs bare fjern .h bak i headerene som skal være med i c++ språket.

 

En siste ting er at i klassen din så er alt public og det er veldig fy fy i vanlige klasser (ikke i alle klasser). Slik jeg ser det så er det bare init som blir brukt utenfor klassen så hvorfor er de andre funksjonene public?

Var jeg deg så ville jeg kikket på strukturering av c++ kode først og så kikke på strukturering av spill kode. Det er så å si den sammen struktureringen av koden som blir brukt i spill.

 

Lykke til

Endret av Giddion
Lenke til kommentar

Takk for svar.

Hvorfor er det fyfy å gjøre alt public? Det gjør vel ingenting, bortsett fra at det er unødvendig?

EDIT: Forresten så blir dev-c++ sint når jeg fjerner .h fra headerne. Hva kan jeg gjøre med det?

Endret av nahoy
Lenke til kommentar

Det er kun programmet ditt som skal kontrollere dataene i klassen din, det er veldig viktig at programmer til enhver tid har kontroll på dataene som ligger i klassen. Hvis alle felt er public, er den ikke nødvendigvis det.

 

edit:

Jeg tror ikke stdio ligger i STL, der heter det iostream, og en skal bruke std::cout istedet.

Så det spiller egentlig ingen rolle

Endret av GeirGrusom
Lenke til kommentar

Slik jeg gjør det, er å dele opp spillet i logiske enheter (subsystemer). Et videosubsystem, inputsubsystem, audiosubsystem, osv., også har jeg gjerne en "spill"-klasse. Et snake spill kan derfor f.eks. ha disse klassene:

- Input

Tar imot input og lager/henter instanser av Snake, utfører operasjoner (eks. snake->move(Snake::LEFT))

- Video

Tar seg av å oppdatere skjermen, osv.

- Audio

Lyd...

- Snake

Spill-logikk (move, grow, has_collided, etc.)

- Game

Initialisere spillet, osv.

 

Mulig dette er litt overkill i de enkleste tilfellene, men...

Lenke til kommentar
Det er kun programmet ditt som skal kontrollere dataene i klassen din, det er veldig viktig at programmer til enhver tid har kontroll på dataene som ligger i klassen. Hvis alle felt er public, er den ikke nødvendigvis det.

 

edit:

Jeg tror ikke stdio ligger i STL, der heter det iostream, og en skal bruke std::cout istedet.

Så det spiller egentlig ingen rolle

 

Tror dette kan gi et litt villedende svar da programmet er det eneste som vanligvis noensinne kommer til å kontrollere dataene som ligger i de forskjellige klassene. Utenfor programmet betyr det lite om noe er public, protected eller private.

 

Hele ideen bak objekt-orientert programmering (OOP) er at en deler opp kildekoden i objekter som det ville vært naturlig å dele opp i. Dette betyr ikke at du må lære deg hvordan dele opp <sett inn programtype her> (i dette tilfellet spill), men at du selv lager objekter som har mening oppe i ditt hode.

 

Klasser og datastrukturer beskriver objekter i OOP. I mitt hode ville et spill bestått av flere deler (les: objekter). I hjernen vår kategoriserer vi ting fra vi blir født, det være dyr, elektroniske duppeditter, blomster og ugress. Hvis man i tillegg er religiøs er feks dyr, blomster og ugress: skapninger. Et eksempel på en måte å beskrive en løve på er å først lage en klasse som heter Skapning, deretter Dyr og så videre helt til man kommer til Løve.

 

For at det skal være vits å kategorisere slik må man ha en måte å koble de ulike kategoriene med. Dette gjøres ved å såkalt arve (eng. inherit) egenskaper fra andre kategorier. Et eksempel i C++ er:

 

(selve syntaxen er sikkert kjent for deg, men siden du spør hvordan tar jeg med dette)

 

class Skapning 
{ funksjoner her... };

class Dyr : public Skapning
{funksjoner her... }

 

Ved å skrive "public Skapning" gjør man slik at klassen Dyr inneholder alle de variablene som er definert public og protected i klassen Skapning. Dette var det GeirGrusom prøvde å si tidligere, og dette kalles Encapsulation på engelsk. Hvis en variabel er definert public betyr det at den kan aksesseres utenfor klassen. En protected variabel eksisterer kun inne i klassen den er definert og av de klassene som arver klassen. En private variabel eksisterer kun i klassen den er definert i.

 

Jeg anbefaler at du bare sitter og prøver deg fram og lager forskjellige ting for moro skyld, samt leser om Object-oriented programming (OOP) diverse steder på nettet. OOP er ikke noe som på død og liv må benyttes, men kan være en stor hjelp til deg selv.

Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...