Skip to content

Instantly share code, notes, and snippets.

@alexmaryin
Created May 6, 2022 12:45
Show Gist options
  • Save alexmaryin/abf4cac6f0ee20d87b1eb31e772354e0 to your computer and use it in GitHub Desktop.
Save alexmaryin/abf4cac6f0ee20d87b1eb31e772354e0 to your computer and use it in GitHub Desktop.
Starfield Pascal
program sdl_test;
uses
sdl2, SysUtils, ctypes, Math, SDL_DrawCircles;
const
Width = 1360;
Height = 760;
CENTER = SDL_WINDOWPOS_CENTERED;
STARS_COUNT = 200;
Speed = 0.1;
Radius_delta = 0.001;
type
{ TStar }
TStar = class(TObject)
private
x, y, z, radius, brightness, viewX, viewY: real;
function IsOffScreen: boolean;
procedure NewStar;
public
constructor Create;
procedure ProcessStar;
end;
var
window: PSDL_Window;
windowEvent: PSDL_Event;
i, x, y: integer;
sdlRenderer: PSDL_Renderer;
fpsLastTime, fpsFrames: cint32;
stars: array of TStar;
color: cuint8;
procedure SetFPSTitle(window: PSDL_Window);
var
title: string;
begin
fpsFrames += 1;
if fpsLastTime < SDL_GetTicks() - 1000 then
begin
fpsLastTime := SDL_GetTicks();
title := 'Lazarus SDL app ' + IntToStr(fpsFrames) + ' FPS';
SDL_SetWindowTitle(window, PChar(title));
fpsFrames := 0;
end;
end;
{ Star }
function TStar.IsOffScreen: boolean;
begin
if (self.z <= 0) or (self.viewX <= -Width / 2) or (self.viewY <= -Height / 2) or
(self.viewX >= Width / 2) or (self.viewY >= Height / 2) then
Result := True
else
Result := False;
end;
procedure TStar.NewStar;
begin
self.x := RandomRange(0, Width) - Width / 2;
self.y := RandomRange(0, Height) - Height / 2;
self.z := 256;
self.radius := 1;
self.brightness := 0;
self.viewX := self.x;
self.viewY := self.y;
end;
constructor TStar.Create;
begin
self.NewStar;
end;
procedure TStar.ProcessStar;
begin
self.viewX := self.x * 256 / self.z;
self.viewY := self.y * 256 / self.z;
self.z -= Speed;
self.radius += Radius_delta;
if self.IsOffScreen then self.NewStar;
if self.brightness < 256 then
self.brightness += 0.15;
end;
begin
fpsLastTime := SDL_GetTicks();
fpsFrames := 0;
if SDL_Init(SDL_INIT_EVERYTHING) <> 0 then
begin
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, 'Error Box', SDL_GetError, nil);
Exit;
end;
window := SDL_CreateWindow('Lazarus SDL2 app', CENTER, CENTER,
Width, Height, SDL_WINDOW_ALLOW_HIGHDPI);
sdlRenderer := SDL_CreateRenderer(window, -1, 0);
if (window = nil) or (sdlRenderer = nil) then
begin
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, 'Error Box', SDL_GetError, nil);
Exit;
end;
SetLength(stars, STARS_COUNT);
for i := 0 to STARS_COUNT - 1 do stars[i] := TStar.Create;
new(windowEvent);
while True do
begin
if SDL_PollEvent(windowEvent) <> 0 then
begin
if windowEvent^.type_ = SDL_QUITEV then
break;
end;
SetFPSTitle(window);
SDL_SetRenderDrawColor(sdlRenderer, 0, 0, 0, 255);
SDL_RenderClear(sdlRenderer);
for i := 0 to STARS_COUNT - 1 do
begin
stars[i].ProcessStar;
color := Round(stars[i].brightness);
SDL_SetRenderDrawColor(sdlRenderer, color, color, color, 255);
x := Round(stars[i].viewX + Width / 2);
y := Round(stars[i].viewY + Height / 2);
SDL_RenderFillCircle(sdlRenderer, x, y, Round(stars[i].radius));
end;
SDL_RenderPresent(sdlRenderer);
end;
for i := 0 to STARS_COUNT - 1 do stars[i].Free;
stars := nil;
SDL_DestroyRenderer(sdlRenderer);
SDL_DestroyWindow(window);
SDL_Quit();
end.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment