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.

 
demos/plasma_in_pascal.txt · Last modified: 2010/06/10 19:31 by steve