Got an issue with the graph unit in my Pascal program - pascal
I'm new to this forum. I'm here to ask you guys your help.
I have an assignment where I have to code a game in Pascal, which is a brick breaker in my case. Though I stumbled upon a problem that I don't quite manage to solve and it's probably related to the graph unit.
It's supposed to display a wall of bricks of various colours in the graphic interface (generated by the graph unit) but nothing appears. The window stays all black. And I know it's not due to having wrtiten a wrong path to the BGI graphic file in the initialisation of the graph unit as I used the same initalisation in an other program where I managed to draw things in the graphic interface.
Finally, my game is in french, so just a few words that you'll need to know: Niveau means level, Jouer means play and Règles means rules. You'll see by choosing a level in the menu that the application will compile but nothing will be displayed in the graph window.
I'd be very glad if you help me out (please).
Here is the main program:
program principal;
uses
Crt, Keyboard, sysutils, jeu, graph;
var
t : TKeyEvent;
c : char;
x, y, mur : Integer;
F , F2 : Text;
V: r;
GraphicsDriver, GraphicsMode, ErrCode : Smallint;
s : String;
begin
x := 62;
y := 12;
GoToXY(47, 4);
writeln('CASSE BRIQUE STPI EDITION');
GoToXY(55, y);
writeln('Niveaux');
GoToXY(55, y + 2);
writeln('Regles');
GoToXY(x, y);
InitKeyBoard();
repeat //boucle pour déplacer le curseur de haut en bas dans la première fenêtre du menu
t := GetKeyEvent();
t := TranslateKeyEvent(t);
c := GetKeyEventChar(t);
if c = 's' then
begin
GoToXY(x - 1, y + 2);
x := 61;
end;
if c = 'z' then
begin
GoToXY(x, y);
x := 62;
end;
until c = 'm';
ClrScr();
case x of
62: begin
GoToXY(47, 4);
writeln('CASSE BRIQUE STPI EDITION');
GoToXY(55, y);
writeln('Niveau 1');
GoToXY(55, y + 2);
writeln('Niveau 2');
GoToXY(55, y + 4);
writeln('Niveau 3');
GoToXY(63, 14);
end;
61: begin //affichage des règles
DoneKeyBoard();
assign(F2, 'Regles.txt');
reset(F2);
while not eof(F2) do
begin
readln(F2, S);
writeln(S);
end;
RetourArriereMenu(X, Y, mur, T, C, f, f2, V, GraphicsDriver, GraphicsMode, ErrCode, s);
end;
end;
x := 63;
repeat //boucle pour déplacer le curseur de ahut en bas dans la fenêtre de la séléction des niveau
t := GetKeyEvent();
t := TranslateKeyEvent(t);
c := GetKeyEventChar(t);
if c = 's' then
begin
if y < 16 then
begin
GoToXY(x, y + 2);
y := y + 2;
end;
end;
if c = 'z' then
begin
if y > 12 then
begin
GoToXY(x, y - 2);
y := y - 2;
end;
end;
until (c = 'm') or (c = 'w');
if c = 'm' then
begin
DoneKeyboard();
case y of //pour chaque niveau séléctionné, une valeur est assignée à mur (ça serivira au déroulement des procédures ci-dessous)
12: mur := 1;
14: mur := 2;
16: mur := 3;
end;
ClrScr();
GraphicsDriver := Detect; //initialisation de l'unité graph
InitGraph(GraphicsDriver, GraphicsMode,'C:\PP\BGI');
ErrCode := GraphResult;
If GraphResult <> grOK Then //affichage d'un message d'erreur si ça n'arrive pas à trouver le fichier graphique dans le répertoire indiqué ci-dessus
Begin
Writeln('Une erreur graphique s est produite: ', GraphErrorMsg(ErrCode));
Writeln('Le fichier graphique (.BGI) n a pas ete trouve, donc veuillez changer le chemin dans InitGraph');
Readln;
Halt(1);
End
Else
begin
remplissageDoc(mur,F);
MiseEnPlaceMur(mur,F,V);
end;
readln;
closegraph;
end;
if c= 'w' then
RetourArriereMenu(X,Y,mur,T,C,f,f2,V, GraphicsDriver, GraphicsMode, ErrCode,s);
end.
Here is the unit in which is stored all the procedures needed to run the main program
unit jeu;
interface
uses
sysutils, Crt, Keyboard, graph;
const
MAXtabX = 100;
MAXtabY = 50;
Type r = array [1..MAXtabX,1..MAXtabY] of Integer;
procedure remplissageDoc(m: Integer; var f: Text); //remplir les documents aléatoirement à chaque lancement de niveau. m correspond au niveau que le joueur a choisi
procedure MiseEnPlaceMur(m: Integer; var f: Text; res: r); //affichage du mur avec pour chaque bloque des vies (soit 1 soit 2 soit 3)
procedure RetourArriereMenu(X,Y: Integer; var m: Integer; var T: TkeyEvent; var C: char; var f,f2: Text; var res: r; var GraphicsDriver, GraphicsMode, ErrCode : Smallint; s: String); //pour retourner en arrière dans n'importe quel endroit du menu
procedure DessinerBrique(i,j: Integer; res: r; x1,y1,x2,y2: Integer); //dessine une brique
implementation
procedure DessinerBrique(i, j : Integer; res : r; x1, y1, x2, y2 : Integer);
begin
writeln(x1, ',', y1, ' ', x2, ',', y2, '-', res[i][j]);
setcolor(15);
rectangle(x1, y1, x2, y2);
if res[i][j]= 1 then
begin
setfillstyle(1,1);
floodfill((x1+x2)div 2,(y1+y2)div 2,15);
end;
if res[i][j] = 2 then
begin
setfillstyle(1, 2);
floodfill((x1 + x2) div 2, (y1 + y2) div 2, 15);
end;
if res[i][j]= 3 then
begin
setfillstyle(1,4);
floodfill((x1 + x2) div 2, (y1 + y2) div 2, 15);
end;
end;
procedure remplissageDoc(m : Integer; var f : Text);
var
a : Integer;
begin
if m = 1 then
begin
assign(f, 'Niveau 1.txt');
rewrite(f);
for a := 1 to 30 do //30 chiffres vont êtres saisis dans le fichier
begin
write(f, 1);
writeln;
end;
close(f);
end;
if m = 2 then
begin
assign(f, 'Niveau 2.txt');
rewrite(f);
randomize();
for a := 1 to 30 do
begin
write(f, random(2) + 1);
writeln;
end;
close(f);
end;
if m = 3 then
begin
assign(f, 'Niveau 3.txt');
rewrite(f);
randomize();
for a := 1 to 30 do
begin
write(f, random(3) + 1);
writeln;
end;
close(f);
end;
end;
procedure MiseEnPlaceMur(m : Integer; var f : Text; res : r);
var
i, j : Integer;
x1, y1, x2, y2 : Integer;
s : String;
begin
i := 1;
x1 := 200;
x2 := 245;
y1 := 0;
y2 := 25;
reset(f);
read(f, s);
while not eof do
begin
for j:= 1 to length(s) do
begin
res[i][j] := StrToInt(s[j]); //remplissage du tableau des vies
DessinerBrique(i, j, res, x1, y1, x2, y2);
x1 := x2;
x2 := x2 + 10;
if (j = 5) or (j = 10) or (j = 15) or (j = 20) or (j = 25) then //pour avoir des 6 lignes de 5 briques
begin
x1 := 200;
x2 := 245;
y1 := y2;
y2 := y1 + 25
end;
end;
end;
i := i + 1;
close(f);
end;
procedure RetourArriereMenu(X, Y : Integer; var m : Integer; var T : TkeyEvent; var C : char; var f, f2 : Text; var res : r; var GraphicsDriver, GraphicsMode, ErrCode : Smallint; s : String); //retourner en arrière à n'importe quel moment dans le menu
begin
InitKeyBoard();
T := GetKeyEvent();
T := TranslateKeyEvent(T);
C := GetKeyEventChar(T);
if C = 'w' then
begin
X := 62;
Y := 12;
ClrScr();
GoToXY(47, 4);
writeln('CASSE BRIQUE STPI EDITION');
GoToXY(55, Y);
writeln('Niveaux');
GoToXY(55, Y + 2);
writeln('Regles');
GoToXY(X,Y);
repeat
T := GetKeyEvent();
T := TranslateKeyEvent(t);
C := GetKeyEventChar(t);
if C = 's' then
begin
GoToXY(X - 1, Y + 2);
X := 61;
end;
if C = 'z' then
begin
GoToXY(X, Y);
X := 62;
end;
until C = 'm';
ClrScr();
case X of
62: begin
GoToXY(47, 4);
writeln('CASSE BRIQUE STPI EDITION');
GoToXY(55, Y);
writeln('Niveau 1');
GoToXY(55,Y + 2);
writeln('Niveau 2');
GoToXY(55,Y + 4);
writeln('Niveau 3');
GoToXY(63, 14);
x := 63;
end;
61: begin
DoneKeyBoard();
assign(F2, 'Regles.txt');
reset(F2);
while not eof(F2) do
begin
readln(F2, S);
writeln(S);
end;
RetourArriereMenu(X, Y, m, T, C, f, f2, res, GraphicsDriver, GraphicsMode, ErrCode, s);
end;
end;
x:=63;
repeat
t := GetKeyEvent();
t := TranslateKeyEvent(t);
c := GetKeyEventChar(t);
if c = 's' then
begin
if y < 16 then
begin
GoToXY(x, y + 2);
y := y + 2;
end;
end;
if c = 'z' then
begin
if y > 12 then
begin
GoToXY(x, y - 2);
y := y - 2;
end;
end;
until (c = 'm') or (c = 'w');
if c = 'm' then
begin
DoneKeyboard();
case y of
12: m := 1;
14: m := 2;
16: m := 3;
end;
ClrScr();
GraphicsDriver := Detect;
InitGraph(GraphicsDriver, GraphicsMode, 'C:\PP\BGI');
ErrCode := GraphResult;
If GraphResult <> grOK Then
Begin
Writeln('Une erreur graphique s est produite: ', GraphErrorMsg(ErrCode));
Writeln('Le fichier graphique (.BGI) n a pas ete trouve, donc veuillez changer le chemin dans InitGraph');
Readln;
Halt(1);
End
Else
begin
remplissageDoc(m, f);
MiseEnPlaceMur(m, f, res);
end;
readln;
closegraph;
end;
if c = 'w' then
RetourArriereMenu(X, Y, m, T, C, f, f2, res, GraphicsDriver, GraphicsMode, ErrCode, s);
end;
end;
end.
Graphics mode is failing to initialize but you are ignoring the result. Read GraphResult exactly once, and act on that.
Edit: put the BGI fonts in your .exe directory and use '' for the BGI path.
Code Organization
Your code is very disorganized and uses a lot of meaningless variable names — making it very hard to understand what you are trying to do. That and you keep trying to switch back and forth between graphics mode and text mode (and not quite getting it right).
This “answer” is designed to help you better organize your code.
Since this is a graphical game, forget WriteLn and everything else that is not graphical. The very first thing you should do is initialize graphics mode. Put that in a procedure if you wish:
procedure Initialiser;
var
gd, gm : integer;
begin
gd := Detect;
InitGraph( gd, gm, '' );
if GraphResult <> grOK then
begin
WriteLn( 'Impossible de démarrer le mode graphique.' );
Halt( 1 )
end;
ClearDevice
end;
begin
Initialiser;
end.
Next you want to do a menu. Make that a function:
type
ActionDeMenu = (Niveau1, Niveau2, Niveau3, Aider, Quitter);
function Menu : ActionDeMenu;
begin
// dessinez votre menu ici
// obtenir l'entrée de l'utilisateur
// retourner le choix de l'utilisateur
end;
You can then update your main program. You might as well put it in a loop; Break to quit.
begin
Initialiser;
repeat
case Menu of
Niveau1: Jouer( 1 );
Niveau2: Jouer( 2 );
Niveau3: Jouer( 3 );
Aider: Aider;
Quitter: Break
end
until false;
CloseGraph
end.
After that you need to write procedures to show help and to play the game at a specified level of difficulty:
procedure Aider;
begin
// afficher l'aide
// l'utilisateur doit appuyer sur Entrée (ou quelque chose) pour continuer
end;
procedure Jouer( niveau : integer );
begin
// initialiser le niveau de jeu
// jouer le jeu
// affichage gagné/perdu
end;
As you can see, we keep breaking tasks down into simpler tasks that:
do not need to be repeated
keep tasks separate
are simple
With just this organic sense of organization you can make the game much more understandable and easier to implement.
Related
What's wrong with max values of GotoXY function?
My code is doing strange thing when MoveMessage procedure takes max values(ScreenWidth and ScreenHeight). So the "Hello, world" string moves to the right down corner and doing strange thing, but the max and min values are set correctly. Can someone tell me where is my mistake. program HelloCrt; uses crt; const Message = 'Hello, world!'; procedure GetKey(var code: integer); var c: char; begin c := Readkey; if c = #0 then begin c := Readkey; code := -ord(c); end else code := ord(c); end; procedure ShowMessage(x, y: integer; msg: string); begin GotoXY(x, y); write(msg); GotoXY(1, 1); end; procedure HideMessage(x, y: integer; msg: string); var len, i: integer; begin len := Length(msg); GotoXY(x, y); for i := 1 to len do write(' '); GotoXY(1, 1); end; procedure MoveMessage(var x, y: integer; msg: string; dx, dy: integer); begin HideMessage(x, y, msg); x := x + dx; y := y + dy; if x > (ScreenWidth - length(msg)) then x := (ScreenWidth - length(msg) + 1); if x < 1 then x := 1; if y > ScreenHeight then y := ScreenHeight; if y < 1 then y := 1; ShowMessage(x, y, msg); end; var CurX, CurY: integer; c: integer; begin clrscr; CurX := (ScreenWidth - length(Message)) div 2; CurY := ScreenHeight div 2; ShowMessage(CurX, CurY, Message); while true do begin Getkey(c); if c > 0 then break; case c of -75: MoveMessage(CurX, CurY, Message, -1, 0); -77: MoveMessage(CurX, CurY, Message, 1, 0); -72: MoveMessage(CurX, CurY, Message, 0, -1); -80: MoveMessage(CurX, CurY, Message, 0, 1); end end; clrscr; end.
Programming PascalABC. Why is "output" without any text?
Even just in the middle of the program I inserted "write (OutPut, '2');" and even at the very end it is, but the "output" file is still created empty. program HelloFromRussia; var s, y, h, n, x: Integer; InPut, OutPut: Text; begin assign(InPut,'c:\input.txt'); assign(OutPut,'c:\output.txt'); reset(InPut); rewrite(OutPut); read(InPut, y); write(OutPut, '1'); for var i:=1 to y do begin read(InPut, s); if s mod 2 = 0 then write(OutPut, s, ' '); end; writeln(OutPut); reset(InPut); read(InPut, y); for var i:=1 to y do begin read(InPut, s); if s mod 2 <> 0 then writeln(OutPut); write(OutPut, s, ' '); end; for h:=1 to y do begin if s mod 2=0 then n:=n+1; if s mod 2<>0 then x:=x+1; end; if (n>x) then writeln(OutPut, 'YES') else writeln(OutPut, 'NO'); write(OutPut, '2'); close(InPut); close(OutPut); end.
Clearing a single space from the console
I don't know how to word the title correctly but I was wondering if there is any way for me to be able to clear a single space from the console instead of clearing the entire thing just to re-write it again? for example, say I was to draw out a 3 by 3 square with the numbers counting from 1-9 all the way down, is there a way for me to change the final 9 without clearing all the prior numbers. when I clear the entire console it creates a flicker effect which is very annoying. if you want to see an example of this in code here is the thing I plan to use it on: program randomPath; uses crt, sysutils; type StrMultiArray = array of array of String; var finishedBoard : StrMultiArray; size, i, j : integer; regenerate : boolean; function generateMap(size : integer) : StrMultiArray; var posx, posy, choice, counter : integer; ongoing : boolean; board : StrMultiArray; begin setLength(board, size, size); for i := 0 to (size-1) do begin for j := 0 to (size-1) do begin board[i,j] := '#'; end; end; posx := (size div 2); posy := (size div 2); board[posx,posy] := ' '; ongoing := true; counter := 0; while ongoing = true do begin choice := random(2); if (choice = 0) then begin choice := random(2); if (choice = 0) then begin if (posx > 0) then begin posx := posx - 1; end; end else begin if (posx < size-1) then begin posx := posx + 1; end; end; end else begin choice := random(2); if (choice = 0) then begin if (posy > 0) then begin posy := posy - 1; end; end else begin if (posy < size-1) then begin posy := posy + 1; end; end; end; counter := counter + 1; board[posx,posy] := ' '; if counter = (size * 12) then begin ongoing := false; end; end; generateMap := board; end; procedure printBoard(board : StrMultiArray; size : integer); begin textColor(Cyan); write('+'); for i := 0 to (size-1) do begin write('-'); end; writeLn('+'); for i := 0 to (size-1) do begin textColor(Cyan); write('|'); textColor(White); for j := 0 to (size-1) do begin if (board[i,j] = '#') then begin textBackground(White); end; if (board[i,j] = '#') then begin textBackground(Red); end; //write(board[i,j]); write(' '); textBackground(Black); end; textColor(Cyan); writeLn('|'); end; textColor(Cyan); write('+'); for i := 0 to (size-1) do begin write('-'); end; writeLn('+'); textColor(White); end; procedure movePlayer(board : StrMultiArray; size : integer); var ongoing : boolean; posx, posy, prevx, prevy : integer; input : char; begin ongoing := true; posx := (size div 2); posy := (size div 2); while (ongoing = true) do begin board[posx,posy] := '#'; prevx := posx; prevy := posy; printBoard(board, size); input := readKey(); clrScr(); case input of 'w' : if (posx > 0) then begin if (board[posx-1,posy] = ' ') then posx := posx - 1; end; 'a' : if (posy > 0) then begin if (board[posx,posy-1] = ' ') then posy := posy - 1; end; 's' : if (posx < (size-1)) then begin if (board[posx+1,posy] = ' ') then posx := posx + 1; end; 'd' : if (posy < (size-1)) then begin if (board[posx,posy+1] = ' ') then posy := posy + 1; end; 'x' : begin regenerate := false; ongoing := false; end; else ongoing := false; end; board[prevx,prevy] := ' '; end; end; begin size := 10; regenerate := true; randomize; while (regenerate = true) do begin finishedBoard := generateMap(size); movePlayer(finishedBoard, size); end; end.
I found a useful function in Pascal that allow you to select a position in the console to move the "cursor" to from which point you can write in that location. the function is called GoToXY(). documentation can be found here: https://www.freepascal.org/docs-html/rtl/crt/gotoxy.html.
How to make a water effect on TImage or anything?
OK, I just installed a Tortoise git in my PC. And I'm quiet amuse about the water effect from its about page. try to move your mouse cursor on the turtle picture from tortoise GIT - About its more like we are playing out finger on a water. Does anyone know how to do make that kind of water effect in Delphi ?
See Leonel Togniolli's "Water Effects" at efg's lab. The ripple effect is based on 2D Water Effects in December 1999 Game Developer Magazine Article . The algorithm is described in here 2D Water, as mentioned by François and as a reference in the source code. Leonel's implementation is partly based on the gamedev article the-water-effect-explained by Roy Willemse. Here is also pascal code. There is one more Delphi example at efg's called "Ripple Project", a screen shot is shown below.
Please do the following : 01. Create a Delphi Unit named "WaterEffect.pas" and paste the following codes: unit WaterEffect; interface uses Winapi.Windows, System.SysUtils, Vcl.Graphics, Math; const DampingConstant = 15; type PIntArray = ^TIntArray; TIntArray = array[0..16777215] of Integer; PPIntArray = ^TPIntArray; TPIntArray = array[0..16777215] of PIntArray; PRGBArray = ^TRGBArray; TRGBArray = array[0..16777215] of TRGBTriple; PPRGBArray = ^TPRGBArray; TPRGBArray = array[0..16777215] of PRGBArray; TWaterDamping = 1..99; TWaterEffect = class(TObject) private { Private declarations } FrameWidth: Integer; FrameHeight: Integer; FrameBuffer01: Pointer; FrameBuffer02: Pointer; FrameLightModifier: Integer; FrameScanLine01: PPIntArray; FrameScanLine02: PPIntArray; FrameScanLineScreen: PPRGBArray; FrameDamping: TWaterDamping; procedure SetDamping(Value: TWaterDamping); protected { Protected declarations } procedure CalculateWater; procedure DrawWater(ALightModifier: Integer; Screen, Distance: TBitmap); public { Public declarations } constructor Create; destructor Destroy; override; procedure ClearWater; procedure SetSize(EffectBackgroundWidth, EffectBackgroundHeight: Integer); procedure Render(Screen, Distance: TBitmap); procedure Bubble(X, Y: Integer; BubbleRadius, EffectBackgroundHeight: Integer); property Damping: TWaterDamping read FrameDamping write SetDamping; end; implementation { TWaterEffect } const RandomConstant = $7FFF; procedure TWaterEffect.Bubble(X, Y: Integer; BubbleRadius, EffectBackgroundHeight: Integer); var Rquad: Integer; CX, CY, CYQ: Integer; Left, Top, Right, Bottom: Integer; begin if (X < 0) or (X > FrameWidth - 1) then X := 1 + BubbleRadius + Random(RandomConstant) mod (FrameWidth - 2 * BubbleRadius - 1); if (Y < 0) or (Y > FrameHeight - 1) then Y := 1 + BubbleRadius + Random(RandomConstant) mod (FrameHeight - 2 * BubbleRadius - 1); Left := -Min(X, BubbleRadius); Right := Min(FrameWidth - 1 - X, BubbleRadius); Top := -Min(Y, BubbleRadius); Bottom := Min(FrameHeight - 1 - Y, BubbleRadius); Rquad := BubbleRadius * BubbleRadius; for CY := Top to Bottom do begin CYQ := CY * CY; for CX := Left to Right do begin if (CX * CX + CYQ <= Rquad) then begin Inc(FrameScanLine01[CY + Y][CX + X], EffectBackgroundHeight); end; end; end; end; procedure TWaterEffect.CalculateWater; var X, Y, XL, XR: Integer; NewH: Integer; P1, P2, P3, P4: PIntArray; PT: Pointer; Rate: Integer; begin Rate := (100 - FrameDamping) * 256 div 100; for Y := 0 to FrameHeight - 1 do begin P1 := FrameScanLine02[Y]; P2 := FrameScanLine01[Max(Y - 1, 0)]; P3 := FrameScanLine01[Y]; P4 := FrameScanLine01[Min(Y + 1, FrameHeight - 1)]; for X := 0 to FrameWidth - 1 do begin XL := Max(X - 1, 0); XR := Min(X + 1, FrameWidth - 1); NewH := (P2[XL] + P2[X] + P2[XR] + P3[XL] + P3[XR] + P4[XL] + P4[X] + P4[XR]) div 4 - P1[X]; P1[X] := NewH * Rate div 256; end; end; PT := FrameBuffer01; FrameBuffer01 := FrameBuffer02; FrameBuffer02 := PT; PT := FrameScanLine01; FrameScanLine01 := FrameScanLine02; FrameScanLine02 := PT; end; procedure TWaterEffect.ClearWater; begin if FrameBuffer01 <> nil then ZeroMemory(FrameBuffer01, (FrameWidth * FrameHeight) * SizeOf(Integer)); if FrameBuffer02 <> nil then ZeroMemory(FrameBuffer02, (FrameWidth * FrameHeight) * SizeOf(Integer)); end; constructor TWaterEffect.Create; begin inherited; FrameLightModifier := 10; FrameDamping := DampingConstant; end; destructor TWaterEffect.Destroy; begin if FrameBuffer01 <> nil then FreeMem(FrameBuffer01); if FrameBuffer02 <> nil then FreeMem(FrameBuffer02); if FrameScanLine01 <> nil then FreeMem(FrameScanLine01); if FrameScanLine02 <> nil then FreeMem(FrameScanLine02); if FrameScanLineScreen <> nil then FreeMem(FrameScanLineScreen); inherited; end; procedure TWaterEffect.DrawWater(ALightModifier: Integer; Screen, Distance: TBitmap); var DX, DY: Integer; I, C, X, Y: Integer; P1, P2, P3: PIntArray; PScreen, PDistance: PRGBArray; PScreenDot, PDistanceDot: PRGBTriple; BytesPerLine1, BytesPerLine2: Integer; begin Screen.PixelFormat := pf24bit; Distance.PixelFormat := pf24bit; FrameScanLineScreen[0] := Screen.ScanLine[0]; BytesPerLine1 := Integer(Screen.ScanLine[1]) - Integer(FrameScanLineScreen[0]); for I := 1 to FrameHeight - 1 do FrameScanLineScreen[i] := PRGBArray(Integer(FrameScanLineScreen[i - 1]) + BytesPerLine1); begin PDistance := Distance.ScanLine[0]; BytesPerLine2 := Integer(Distance.ScanLine[1]) - Integer(PDistance); for Y := 0 to FrameHeight - 1 do begin PScreen := FrameScanLineScreen[Y]; P1 := FrameScanLine01[Max(Y - 1, 0)]; P2 := FrameScanLine01[Y]; P3 := FrameScanLine01[Min(Y + 1, FrameHeight - 1)]; for X := 0 to FrameWidth - 1 do begin DX := P2[Max(X - 1, 0)] - P2[Min(X + 1, FrameWidth - 1)]; DY := P1[X] - P3[X]; if (X + DX >= 0) and (X + DX < FrameWidth) and (Y + DY >= 0) and (Y + DY < FrameHeight) then begin PScreenDot := #FrameScanLineScreen[Y + DY][X + DX]; PDistanceDot := #PDistance[X]; C := PScreenDot.rgbtBlue - DX; if C < 0 then PDistanceDot.rgbtBlue := 0 else if C > 255 then PDistanceDot.rgbtBlue := 255 else begin PDistanceDot.rgbtBlue := C; C := PScreenDot.rgbtGreen - DX; end; if C < 0 then PDistanceDot.rgbtGreen := 0 else if C > 255 then PDistanceDot.rgbtGreen := 255 else begin PDistanceDot.rgbtGreen := C; C := PScreenDot.rgbtRed - DX; end; if C < 0 then PDistanceDot.rgbtRed := 0 else if C > 255 then PDistanceDot.rgbtRed := 255 else begin PDistanceDot.rgbtRed := C; end; end else begin PDistance[X] := PScreen[X]; end; end; PDistance := PRGBArray(Integer(PDistance) + BytesPerLine2); end; end; end; procedure TWaterEffect.Render(Screen, Distance: TBitmap); begin CalculateWater; DrawWater(FrameLightModifier, Screen, Distance); end; procedure TWaterEffect.SetDamping(Value: TWaterDamping); begin if (Value >= Low(TWaterDamping)) and (Value <= High(TWaterDamping)) then FrameDamping := Value; end; procedure TWaterEffect.SetSize(EffectBackgroundWidth, EffectBackgroundHeight: Integer); var I: Integer; begin if (EffectBackgroundWidth <= 0) or (EffectBackgroundHeight <= 0) then begin EffectBackgroundWidth := 0; EffectBackgroundHeight := 0; end; FrameWidth := EffectBackgroundWidth; FrameHeight := EffectBackgroundHeight; ReallocMem(FrameBuffer01, FrameWidth * FrameHeight * SizeOf(Integer)); ReallocMem(FrameBuffer02, FrameWidth * FrameHeight * SizeOf(Integer)); ReallocMem(FrameScanLine01, FrameHeight * SizeOf(PIntArray)); ReallocMem(FrameScanLine02, FrameHeight * SizeOf(PIntArray)); ReallocMem(FrameScanLineScreen, FrameHeight * SizeOf(PRGBArray)); ClearWater; if FrameHeight > 0 then begin FrameScanLine01[0] := FrameBuffer01; FrameScanLine02[0] := FrameBuffer02; for I := 1 to FrameHeight - 1 do begin FrameScanLine01[I] := #FrameScanLine01[I - 1][FrameWidth]; FrameScanLine02[I] := #FrameScanLine02[I - 1][FrameWidth]; end; end; end; end. In "uses" add "WaterEffect". Add a "Timer" with "Enable" property and "Interval=25". In "Private Declaration" add "Water: TWaterEffect;" and "FrameBackground: TBitmap;". Define "var X:Integer;" Define the following procedure TMainForm.FormCreate(Sender: TObject); begin Timer01.Enabled := true; FrameBackground := TBitmap.Create; FrameBackground.Assign(Image01.Picture.Graphic); Image01.Picture.Graphic := nil; Image01.Picture.Bitmap.Height := FrameBackground.Height; Image01.Picture.Bitmap.Width := FrameBackground.Width; Water := TWaterEffect.Create; Water.SetSize(FrameBackground.Width,FrameBackground.Height); X:=Image01.Height; end; procedure TMainForm.FormDestroy(Sender: TObject); begin FrameBackground.Free; Water.Free; end; procedure TMainForm.Image01MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin Water.Bubble(X,Y,1,100); end; procedure TMainForm.Image01MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); begin Water.Bubble(X,Y,1,100); end; procedure TMainForm.Timer01Timer(Sender: TObject); begin if Random(8)= 1 then Water.Bubble(-1,-1,Random(1)+1,Random(500)+50); Water.Render(FrameBackground,Image01.Picture.Bitmap); with Image01.Canvas do begin Brush.Style:=bsClear; font.size:=12; Font.Style:=[]; Font.Name := 'Comic Sans MS'; font.color:=$e4e4e4; Textout(190, 30, DateTimeToStr(Now)); end; end; Now Compile. I think you will get the required effect.
That effect is generated by applying certain numerical transformations to the image. They're defined in the CWaterEffect class, which you can inspect for yourself in the WaterEffect.cpp source file.
Draw Pascal's triangle in PASCAL Programming like a diamond
How I can draw a Pascal's triangle in PASCAL Programming like a diamond from n number which we get that from input? Edit: This program I tried: program Pascal_triangle; var i,j,n : integer; A : Array[1..6,1..6] of Integer; begin n := 6; for i:=1 to n do begin for j:=1 to i do begin if (j=1) or (i=j) then begin A[i,j]:=1; end else begin A[i,j] := A[i-1,j] + A[i-1,j-1]; end; end; end; for i:=1 to n do begin Gotoxy(41-i,i); for j:=1 to i do write(A[i,j]) end; readln; end. but I got an error on gotoxy line and I need it to be diamond.
Dec 31 '11 at 21:22: Thanks, I wrote this and works program Pascal_triangle; var d,c,y,x,n : integer; begin readln(n); writeln; for y:=0 to n do begin c:=1; for d:=0 to n - y do begin write(' '); end; for x:=0 to y do begin write(c); write(' '); c := c * (y - x) DIV (x + 1); end; writeln; end; for y:=n-1 downto 0 do begin c:=1; for d:=0 to n - y do begin write(' '); end; for x:=0 to y do begin write(c); write(' '); c := c * (y - x) DIV (x + 1); end; writeln; end; readln; end.