A plasma effect in Pascal
Save this code to your computer with an appropriate name (such as plasma.pp) and download the plasma images to go with it. Make sure you've built the Brick unit, and then compile the tree demo thus:
fpc plasma.pp
and enjoy!
Program Plasma;
uses
brick, ctypes;
const
{ Screen dimensions }
SCREEN_W = 256;
SCREEN_H = 180;
{ Loaded image sizes }
IMG_W = 500;
IMG_H = 400;
{ Generated wave sizes }
WAVE_W = 540;
WAVE_H = 440;
{ Movement limits }
DIFF_W = 244;
DIFF_H = 220;
var
{ Some loop counters }
i, j : integer;
{ The layer var }
layer : integer;
{ The sprite variables and setup information }
sprites : array[1..6] of Pbr_sprite;
plasma_srcs : array[1..4] of Pchar = ('p1.png', 'p2.png', 'p3.png', 'p4.png');
{ The displacement sprite containers }
w1, w2 : array[1..WAVE_H, 1..WAVE_W, 1..2] of cshort;
{ The sprite movement offsets }
angles, adders : array[1..6] of real;
{ The input record }
io : Tbr_input;
begin
{ Initialize brick and create the layer }
InitBrick;
layer := LayerAdd;
LayerSetSorting(layer, 1);
LayerSetCamera(layer, DIFF_W div 2, DIFF_H div 2);
{ Load the plasma sprites }
for i := 1 to 4 do
begin
sprites[i] := SpriteCreate;
SpriteAddFrame(sprites[i], FrameConvert(FrameFromDisk(plasma_srcs[i], Nil), FRAME_LT, Nil));
SpriteSetZHint(sprites[i], 10);
ListAdd(LayerGetSpriteList(layer), sprites[i]);
end;
{ Create the wave data for the displacment sprite .. }
for i := 1 to WAVE_H do
for j := 1 to WAVE_W do
begin
w1[i][j][1] := trunc(-20.0 * sin(i*6.28/IMG_H));
w1[i][j][2] := trunc(-20.0 * sin(j*6.28/IMG_W));
w2[i][j][1] := trunc(20.0 * sin(i*6.28/IMG_H));
w2[i][j][2] := trunc(20.0 * sin(j*6.28/IMG_W));
end;
{ And load the wave sprite data. }
sprites[5] := SpriteCreate;
SpriteAddFrameData(sprites[5], FRAME_DISPL, WAVE_W, WAVE_H, @w1, Nil);
SpriteSetZHint(sprites[5], 15);
ListAdd(LayerGetSpriteList(layer), sprites[5]);
sprites[6] := SpriteCreate;
SpriteAddFrameData(sprites[6], FRAME_DISPL, WAVE_W, WAVE_H, @w2, Nil);
SpriteSetZHint(sprites[6], 30);
ListAdd(LayerGetSpriteList(layer), sprites[6]);
{ Now, open the graphics display! }
GraphicsOpen(GRAPHICS_ACCEL, SCREEN_W, SCREEN_H, 0, 2);
RenderSetBgColor(0, 0, 0);
RenderSetOverdraw(40, 40);
{ Initialize the sprite position setters and enter the main loop. }
for i := 1 to 6 do
angles[i] := 0;
adders[1] := 0.01;
adders[2] := 0.03;
adders[3] := 0.02;
adders[4] := 0.02;
adders[5] := 0.04;
adders[6] := 0.04;
while true do
begin
{ Update the all of the sprite movement offsets }
for i := 1 to 6 do
angles[i] := angles[i] + adders[i];
{ Adjust the plasma sprite motion }
for i := 1 to 4 do
SpriteSetPosition(sprites[i], trunc( (DIFF_W/2 - 40) * cos(angles[i])), trunc( (DIFF_H/2 - 40) * sin(angles[i]) ));
{ And update the distorting waves }
SpriteSetPosition(sprites[5], trunc( -40 + (DIFF_W/2 - 40) * cos(angles[5])), trunc( -40 + (DIFF_H/2 - 40) * sin(angles[5]) ));
SpriteSetPosition(sprites[6], trunc( -20 + (DIFF_W/2 - 20) * cos(angles[6])), trunc( -20 + (DIFF_H/2 - 20) * sin(angles[6]) ));
{ Display the frame and run the delay loop }
RenderDisplay;
Delay(50);
{ Read the keyboard/joystick input and quit on escape or application-close }
IoFetch(0, @io);
if (io.esc = 1) or (IoHasQuit = 1) then
break;
end;
end.