Supersnail
Terugkerende gebruiker
- Lid geworden
- 25 jul 2001
- Berichten
- 1.804
Hallo,
Voor een open-source spel dat ik gemaakt heb gebruik ik SDL. Bij het aanpassen van mijn code merkte ik dat de waarden in de gebruikte SDL_Rects veranderden zonder dat ik ze zelf aanpas. Het gaat om de volgende code (teruggebracht tot het hoogst nodige):
sprite.h
[cpp]#ifndef SPRITE_H
#define SPRITE_H
#include "SDL.h"
class sprite
{
protected:
SDL_Surface *image;
SDL_Rect dst, black;
public:
sprite(const char file[])
{
image = SDL_LoadBMP(file);
SDL_SetColorKey(image, SDL_SRCCOLORKEY, SDL_MapRGB(image->format, 255, 255, 0));
}
~sprite()
{
}
SDL_Rect getDstRect() {return dst;};
SDL_Surface *getSurface() {return image;};
SDL_Rect getBlack() {return black;};
};
#endif[/cpp]
Dit is de sprite-klasse. Het gaat om de SDL_Rects in deze klasse. "dst" is de SDL_Rect die bepaalt waar het plaatje getoond wordt. "black" is de SDL_Rect om bij het verplaatsen van het plaatje, het oude plaatje te bedekken met zwart.
Deze sprite-klasse heeft een subklasse:
chopper.h:
[cpp]#ifndef CHOPPER_H
#define CHOPPER_H
#include <iostream>
#include "SDL.h"
#include "sprite.h"
class chopper: public sprite
{
public:
chopper(int x);
void move(SDL_Surface *screen);
};
#endif[/cpp]
en chopper.cpp:
[cpp]#include "SDL.h"
#include "chopper.h"
chopper::chopper(int x) : sprite("heli1.bmp")
{
dst.x = x;
dst.y = 5;
dst.w = image->w;
dst.h = image->h;
black.w = image->w + 2*3;
black.h = image->h + 3;
black.x = dst.x - 3;
black.y = dst.y - 3;
std::cout << "Created new chopper!\n";
std::cout << "dst.x: " << dst.x << std::endl;
std::cout << "dst.y: " << dst.y << std::endl;
std::cout << "dst.w: " << dst.w << std::endl;
std::cout << "dst.h: " << dst.h << std::endl;
std::cout << "black.x: " << black.x << std::endl;
std::cout << "black.y: " << black.y << std::endl;
std::cout << "black.w: " << black.w << std::endl;
std::cout << "black.h: " << black.h << std::endl;
}
void chopper::move(SDL_Surface *screen)
{
std::cout << "Moved chopper!\n";
std::cout << "dst.x: " << dst.x << std::endl;
std::cout << "dst.y: " << dst.y << std::endl;
std::cout << "dst.w: " << dst.w << std::endl;
std::cout << "dst.h: " << dst.h << std::endl;
std::cout << "black.x: " << black.x << std::endl;
std::cout << "black.y: " << black.y << std::endl;
std::cout << "black.w: " << black.w << std::endl;
std::cout << "black.h: " << black.h << std::endl;
std::cout << "image->w: " << image->w << std::endl;
SDL_FillRect(screen, &black, SDL_MapRGB(screen->format, 0, 0, 0));
SDL_BlitSurface(this->getSurface(), NULL, screen, &dst);
if (dst.x < 0-image->w)
{
dst.x = 800+image->w;
}
dst.x-=3;
black.x = dst.x - 3;
}
void move_choppers(SDL_Surface *screen, chopper *chop)
{
chop->move(screen);
}[/cpp]
Deze subklasse bestaat uit een constructor die de SDL_Rects initeel waardes geeft en een move-functie om het plaatje te verplaatsen. Er is ook een "gewone" move functie die de move-functie van de klasse aanroept.
Verder is er nog een main.cpp:
[cpp]#include "SDL.h"
#include "sprite.h"
#include "chopper.h"
using namespace std;
void move_choppers(SDL_Surface *screen, chopper *chop);
int main(int argc, char *argv[])
{
SDL_Init(SDL_INIT_VIDEO|SDL_INIT_NOPARACHUTE);
SDL_Surface *screen = SDL_SetVideoMode(800, 600, 16, SDL_DOUBLEBUF);
chopper *chop;
chop = new chopper(800);
SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0, 0));
bool end = false;
while (!end)
{
move_choppers(screen, chop);
SDL_Flip(screen);
}
return 0;
}[/cpp]
Dit maakt een chopper aan en roept continue de move-functie aan.
Als ik dit uitvoer krijg ik dit als uitvoer:
Als ik in chopper.cpp de regels
[cpp]SDL_FillRect(screen, &black, SDL_MapRGB(screen->format, 0, 0, 0));
SDL_BlitSurface(this->getSurface(), NULL, screen, &dst);[/cpp]
verander in
[cpp]SDL_Rect chopperltemp = dst;
SDL_Rect chopperblack = black;
SDL_FillRect(screen, &chopperblack, SDL_MapRGB(screen->format, 0, 0, 0));
SDL_BlitSurface(this->getSurface(), NULL, screen, &chopperltemp);[/cpp]
Dus door twee nieuwe SDL_Rects aan te maken en deze dezelfde waardes te geven als dst en black en deze nieuwe SDL_Rects te gebruiken werkt het wel en klopt de uitvoer ook.
Ik kan het spel zo wel werkend krijgen, maar ik snap niet waarom het zo wel werkt en met de originele SDL_Rects niet. Is er iemand die dit wel snapt?
Bij voorbaat dank.
[edit]Het plaatje dat ik gebruik is hier te vinden. De broncode, het plaatje en een Makefile (Linux) is hier te vinden.[/edit]
Voor een open-source spel dat ik gemaakt heb gebruik ik SDL. Bij het aanpassen van mijn code merkte ik dat de waarden in de gebruikte SDL_Rects veranderden zonder dat ik ze zelf aanpas. Het gaat om de volgende code (teruggebracht tot het hoogst nodige):
sprite.h
[cpp]#ifndef SPRITE_H
#define SPRITE_H
#include "SDL.h"
class sprite
{
protected:
SDL_Surface *image;
SDL_Rect dst, black;
public:
sprite(const char file[])
{
image = SDL_LoadBMP(file);
SDL_SetColorKey(image, SDL_SRCCOLORKEY, SDL_MapRGB(image->format, 255, 255, 0));
}
~sprite()
{
}
SDL_Rect getDstRect() {return dst;};
SDL_Surface *getSurface() {return image;};
SDL_Rect getBlack() {return black;};
};
#endif[/cpp]
Dit is de sprite-klasse. Het gaat om de SDL_Rects in deze klasse. "dst" is de SDL_Rect die bepaalt waar het plaatje getoond wordt. "black" is de SDL_Rect om bij het verplaatsen van het plaatje, het oude plaatje te bedekken met zwart.
Deze sprite-klasse heeft een subklasse:
chopper.h:
[cpp]#ifndef CHOPPER_H
#define CHOPPER_H
#include <iostream>
#include "SDL.h"
#include "sprite.h"
class chopper: public sprite
{
public:
chopper(int x);
void move(SDL_Surface *screen);
};
#endif[/cpp]
en chopper.cpp:
[cpp]#include "SDL.h"
#include "chopper.h"
chopper::chopper(int x) : sprite("heli1.bmp")
{
dst.x = x;
dst.y = 5;
dst.w = image->w;
dst.h = image->h;
black.w = image->w + 2*3;
black.h = image->h + 3;
black.x = dst.x - 3;
black.y = dst.y - 3;
std::cout << "Created new chopper!\n";
std::cout << "dst.x: " << dst.x << std::endl;
std::cout << "dst.y: " << dst.y << std::endl;
std::cout << "dst.w: " << dst.w << std::endl;
std::cout << "dst.h: " << dst.h << std::endl;
std::cout << "black.x: " << black.x << std::endl;
std::cout << "black.y: " << black.y << std::endl;
std::cout << "black.w: " << black.w << std::endl;
std::cout << "black.h: " << black.h << std::endl;
}
void chopper::move(SDL_Surface *screen)
{
std::cout << "Moved chopper!\n";
std::cout << "dst.x: " << dst.x << std::endl;
std::cout << "dst.y: " << dst.y << std::endl;
std::cout << "dst.w: " << dst.w << std::endl;
std::cout << "dst.h: " << dst.h << std::endl;
std::cout << "black.x: " << black.x << std::endl;
std::cout << "black.y: " << black.y << std::endl;
std::cout << "black.w: " << black.w << std::endl;
std::cout << "black.h: " << black.h << std::endl;
std::cout << "image->w: " << image->w << std::endl;
SDL_FillRect(screen, &black, SDL_MapRGB(screen->format, 0, 0, 0));
SDL_BlitSurface(this->getSurface(), NULL, screen, &dst);
if (dst.x < 0-image->w)
{
dst.x = 800+image->w;
}
dst.x-=3;
black.x = dst.x - 3;
}
void move_choppers(SDL_Surface *screen, chopper *chop)
{
chop->move(screen);
}[/cpp]
Deze subklasse bestaat uit een constructor die de SDL_Rects initeel waardes geeft en een move-functie om het plaatje te verplaatsen. Er is ook een "gewone" move functie die de move-functie van de klasse aanroept.
Verder is er nog een main.cpp:
[cpp]#include "SDL.h"
#include "sprite.h"
#include "chopper.h"
using namespace std;
void move_choppers(SDL_Surface *screen, chopper *chop);
int main(int argc, char *argv[])
{
SDL_Init(SDL_INIT_VIDEO|SDL_INIT_NOPARACHUTE);
SDL_Surface *screen = SDL_SetVideoMode(800, 600, 16, SDL_DOUBLEBUF);
chopper *chop;
chop = new chopper(800);
SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0, 0));
bool end = false;
while (!end)
{
move_choppers(screen, chop);
SDL_Flip(screen);
}
return 0;
}[/cpp]
Dit maakt een chopper aan en roept continue de move-functie aan.
Als ik dit uitvoer krijg ik dit als uitvoer:
Bij het maken van de chopper en na de eerste verplaatsing kloppen de waardes nog. Echter bij de tweede verplaatsing veranderen de waardes van dst.w, dst.h, black.w en black.h.Created new chopper!
dst.x: 800
dst.y: 5
dst.w: 137
dst.h: 44
black.x: 797
black.y: 2
black.w: 143
black.h: 47
Moved chopper!
dst.x: 800
dst.y: 5
dst.w: 137
dst.h: 44
black.x: 797
black.y: 2
black.w: 143
black.h: 47
image->w: 137
Moved chopper!
dst.x: 797
dst.y: 5
dst.w: 0
dst.h: 0
black.x: 794
black.y: 2
black.w: 3
black.h: 47
image->w: 137
Moved chopper!
dst.x: 794
dst.y: 5
dst.w: 3
dst.h: 44
black.x: 791
black.y: 2
black.w: 3
black.h: 47
image->w: 137
...
Als ik in chopper.cpp de regels
[cpp]SDL_FillRect(screen, &black, SDL_MapRGB(screen->format, 0, 0, 0));
SDL_BlitSurface(this->getSurface(), NULL, screen, &dst);[/cpp]
verander in
[cpp]SDL_Rect chopperltemp = dst;
SDL_Rect chopperblack = black;
SDL_FillRect(screen, &chopperblack, SDL_MapRGB(screen->format, 0, 0, 0));
SDL_BlitSurface(this->getSurface(), NULL, screen, &chopperltemp);[/cpp]
Dus door twee nieuwe SDL_Rects aan te maken en deze dezelfde waardes te geven als dst en black en deze nieuwe SDL_Rects te gebruiken werkt het wel en klopt de uitvoer ook.
Created new chopper!
dst.x: 800
dst.y: 5
dst.w: 137
dst.h: 44
black.x: 797
black.y: 2
black.w: 143
black.h: 47
Moved chopper!
dst.x: 800
dst.y: 5
dst.w: 137
dst.h: 44
black.x: 797
black.y: 2
black.w: 143
black.h: 47
image->w: 137
Moved chopper!
dst.x: 797
dst.y: 5
dst.w: 137
dst.h: 44
black.x: 794
black.y: 2
black.w: 143
black.h: 47
image->w: 137
Ik kan het spel zo wel werkend krijgen, maar ik snap niet waarom het zo wel werkt en met de originele SDL_Rects niet. Is er iemand die dit wel snapt?
Bij voorbaat dank.
[edit]Het plaatje dat ik gebruik is hier te vinden. De broncode, het plaatje en een Makefile (Linux) is hier te vinden.[/edit]
Laatst bewerkt: