PDA

View Full Version : Beginner here! Quick question



much.love
21-11-2013, 06:22 PM
Hey guys.

I've just started with game development (and programming in general). Right now I'm just trying to learn the ropes and by reading some tutorials (most of them are for C or C++, sadly), I came up with this. But why doesn't the sprite move?



program sdltest;

uses
sdl2, SDL2_image;
const
SCREEN_WIDTH: integer = 640;
SCREEN_HEIGHT: integer = 480;
quit: boolean = false;
var
win: pSDL_WINDOW;
ren: pSDL_RENDERER;
background, sprite: pSDL_TEXTURE;
e: pSDL_EVENT;
ret: pSDL_RECT;
rect: pSDL_RECT;
thisTime, lastTime: integer;
dt: single;

begin
win := SDL_CreateWindow('Hello World', 100, 100, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
ren := SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED or SDL_RENDERER_PRESENTVSYNC);
background := IMG_LoadTexture(ren, 'background.png');
sprite := IMG_LoadTexture(ren, 'sprite.png');
new(ret);
ret^.x := 0;
ret^.y := 0;
ret^.w := 64;
ret^.h := 64;
new(rect);
rect^.x := 100;
rect^.y := 100;
rect^.w := 64;
rect^.h := 64;
new(e);

while quit = false do
begin
thisTime := SDL_GetTicks;
dt := (thisTime - lastTime) / 1000;
lastTime := thisTime;
while SDL_POLLEVENT(e) <> 0 do
begin
if e^.type_ = SDL_MOUSEBUTTONDOWN then
quit := TRUE;
if e^.type_ = SDL_KEYDOWN then
begin
case e^.type_ of
SDLK_LEFT: rect^.x := rect^.x - 10;
SDLK_RIGHT: rect^.x := rect^.x + 10;
SDLK_UP: rect^.y := rect^.y - 10;
SDLK_DOWN: rect^.y := rect^.y + 10;
end;
end;
SDL_RenderClear(ren);
SDL_RenderCopy(ren, background, nil, nil);
SDL_RenderCopy(ren, sprite, ret, rect);
SDL_RenderPresent(ren);
end;

end;
SDL_DestroyTexture(background);
SDL_DestroyTexture(sprite);
SDL_DestroyRenderer(ren);
SDL_DestroyWindow(win);

IMG_QUIT;
SDL_QUIT;
end.



Also, if I add

if e^.type_ = SDL_QUIT then
quit := TRUE;
the program won't even compile.

Thanks a lot for your help in advance.

SilverWarior
21-11-2013, 09:08 PM
In pascal you don't need to use pointers everywhere. This means that you can acces object properties/record values simply by:

rect.x := 100;

So your code would look something like this:


program sdltest;

uses
sdl2, SDL2_image;
const
SCREEN_WIDTH: integer = 640;
SCREEN_HEIGHT: integer = 480;
quit: boolean = false;
var
win: pSDL_WINDOW;
ren: pSDL_RENDERER;
background, sprite: pSDL_TEXTURE;
e: pSDL_EVENT;
ret: pSDL_RECT;
rect: pSDL_RECT;
thisTime, lastTime: integer;
dt: single;

begin
win := SDL_CreateWindow('Hello World', 100, 100, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
ren := SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED or SDL_RENDERER_PRESENTVSYNC);
background := IMG_LoadTexture(ren, 'background.png');
sprite := IMG_LoadTexture(ren, 'sprite.png');
new(ret);
ret.x := 0;
ret.y := 0;
ret.w := 64;
ret.h := 64;
new(rect);
rect.x := 100;
rect.y := 100;
rect.w := 64;
rect.h := 64;
new(e);

while quit = false do
begin
thisTime := SDL_GetTicks;
dt := (thisTime - lastTime) / 1000;
lastTime := thisTime;
while SDL_POLLEVENT(e) <> 0 do
begin
if e.type_ = SDL_MOUSEBUTTONDOWN then
quit := TRUE;
if e.type_ = SDL_KEYDOWN then
begin
case e.type_ of
SDLK_LEFT: rect.x := rect.x - 10;
SDLK_RIGHT: rect.x := rect.x + 10;
SDLK_UP: rect.y := rect.y - 10;
SDLK_DOWN: rect.y := rect.y + 10;
end;
end;
SDL_RenderClear(ren);
SDL_RenderCopy(ren, background, nil, nil);
SDL_RenderCopy(ren, sprite, ret, rect);
SDL_RenderPresent(ren);
end;

end;
SDL_DestroyTexture(background);
SDL_DestroyTexture(sprite);
SDL_DestroyRenderer(ren);
SDL_DestroyWindow(win);

IMG_QUIT;
SDL_QUIT;
end.


Not I haven't tested this out as I myself am not using SDL.

Now for learning about using SDL with pascal I recomend you visit page below. It contains sveral tutorials about using SDL with Free Pascal but they should work with other Pascal dialects also.
http://www.freepascal-meets-sdl.net/

Cybermonkey
21-11-2013, 09:27 PM
The above recommended site is for SDL 1.x only for now. First question is: Which SDL2 headers are you using? Since there are several "under offer" it's hard to help because they differ in some things. I use the headers from github here: https://github.com/ev1313/Pascal-SDL-2-Headers
I saw a difference in how I use events, I don't use pSDL_event but TSDL_Event. My function getkey which returns the SDL_SCANCODE of a pressed key looks like this:

Function GetKey : integer;
var ch: integer;
event:TSDL_event;
Begin
while (SDL_PollEvent( @event ) <> 0) do
begin
if (event.type_ = SDL_QUITEV) then
begin
SDL_Quit();
halt;
end;
if (event.key.type_ = SDL_KEYDOWN) then
begin

ch := Event.key.keysym.scancode;
//key := char (ch);
result := ch;
end;
end;
end ;

And another thing was pointed out correctly by SilverWarrior: you don't need to use pointers with rects. Maybe my procedure drawsprite can help you:

procedure drawsprite (sprite:PSDL_Texture; x,y:integer;width,height,angle:real;vflip,hflip:bo olean);
var dest:PSDL_Rect;
flip:TSDL_RendererFlip;
w,h:integer;
begin
SDL_QueryTexture(sprite, nil, nil, @w, @h);
new (dest);
dest.x:=x;
dest.y:=y;
dest.w:=round(w*width);
dest.h:=round(h*height);
if vflip then begin
flip:=SDL_FLIP_VERTICAL;
SDL_RenderCopyEx(SDL_GetRenderer (SDL_GetWindowFromID(activewindow)), sprite, nil, dest,angle, nil, PSDL_RendererFlip(flip));
end else
if hflip then begin
flip:=SDL_FLIP_HORIZONTAL;
SDL_RenderCopyEx(SDL_GetRenderer (SDL_GetWindowFromID(activewindow)), sprite, nil, dest,angle, nil, PSDL_RendererFlip(flip));
end else begin
SDL_RenderCopyEx(SDL_GetRenderer (SDL_GetWindowFromID(activewindow)), sprite, nil, dest,angle, nil, nil);
dispose (dest);
end;
end;

My engine can use several windows and renderers so don't be frightened by the construct SDL_GetRenderer (SDL_GetWindowFromID(activewindow)) - just place your renderer here.