Jsou zobrazeny jen nové odpovědi. Zobrazit všechny
Předmět Autor Datum
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls; t…
Delmos 08.05.2013 20:46
Delmos
procedure DrawSnake; var i : integer; Begin if direction = dnone then exit; Form1.Canvas.Brush.Color…
Delmos 08.05.2013 20:47
Delmos
Chtěl bych se zeptat ohledně toho vykreslení hracího pole (DrawPlayfield) Jestli jsem vlastně pochop…
Delmos 09.05.2013 23:07
Delmos
tpoint len uchovava dve celociselne hodnoty, nemusi to byt bod. Zmysel tych hodnot moze byt cokolvek… nový
MM.. 10.05.2013 00:34
MM..
Musím to mít v delphi... A trochu blbě si mě pochopil... nový
Delmos 10.05.2013 00:47
Delmos
.. resp. tym ze do FormPaint (co je asi OnPaint event to musis si pozret ty v tvojom projekte) nasta… nový
MM.. 10.05.2013 00:49
MM..
FormPaint je udalost, ktera se vola pri potrebe o prekresleni formulare (pohnes s nim, prekreje jej… poslední
Jan Fiala 10.05.2013 12:51
Jan Fiala
uses
    Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
    Dialogs, ExtCtrls;

type
    TForm1 = class(TForm)
        snaketimer: TTimer; // Updates the old
// direction and
// draws the snake
        procedure snaketimerTimer(Sender: TObject);
        procedure FormKeyPress(Sender: TObject; var Key: Char); // Handles key input
        procedure FormPaint(Sender: TObject); // Draws the form
// and resets the
// game
    PRIVATE
    PUBLIC
    end;

var
    Form1: TForm1;
    score : Integer;

procedure ResetGame; // Resets the snake and score
function HitWall : Boolean; // returns true if snake hits the wall
function HitFood : Boolean; // Returns true if snake hits food
procedure DrawSnake; // Draws the snake, increase points if
// snake hit food,
procedure PlaceFood;
procedure DrawPlayfield; // Draws the playfield
// (the area which the snake navigates on)
procedure EndGame; // Stops the snake timer and free memory
// allocated by the snake array
implementation

{$R *.dfm}

const
    snakewidth = 10; // specify how wide the snake is
    snakegrow : Integer = 2; // specify how fast snake grows
    snakecolor : tcolor = clBlack;
    foodcolor : tcolor = clRed;
    pfcolor : tcolor = clWhite; // playfield color
    pfdimention : tpoint = (x:200; y:200); // playfield width and hight
    pfposition : tpoint = (x:5; y:5); // playfield position on form
    dup = 0;
    ddown = 1;
    dleft = 2;
    dright = 3;
    dnone = 4;
    speed : Integer = 100; // snake speed higher value
// equals slower snake
var
    snake : array of tpoint; // dynamic array holding snake
// coordinates
    snakelength : Integer; // length of snake
    food : tpoint; // food position
    direction : dup..dnone;
    olddirection : dup..dnone;
// HitWall: returns true if snake hits the wall
function HitWall : Boolean;
var
    i : Integer;
begin
    for i := 0 to snakelength - 1 do
    begin
        if (snake[i].x < pfposition.X) Or
            (snake[i].x + snakewidth > pfposition.X + pfdimention.X) Or
            (snake[i].y < pfposition.y) Or
            (snake[i].y + snakewidth > pfposition.y + pfdimention.y) then
        begin
            hitwall := True;
            exit;
        end;
    end;
    hitwall := False;
end;
// HitFood: Returns true if snake hits food
function HitFood : Boolean;
var
    i : Integer;
begin
    for i := 0 to snakelength - 1 do
    begin
        if (snake[i].x = food.x) And (snake[i].y = food.y) then
        begin
            hitfood := True;
            exit;
        end;
    end;
    hitfood := False;
end;
// PlaceFood: Draws the food on the playfield on a random location
procedure PlaceFood;
begin
    food.x := random(pfdimention.x - snakewidth - pfposition.x) + pfposition.x;
    food.y := random(pfdimention.y - snakewidth - pfposition.y) + pfposition.y;
    while (pfdimention.x - (food.x - pfposition.x)) Mod snakewidth <> 0 do
    begin
        inc(food.x)
    end;
    while (pfdimention.y - (food.y - pfposition.y)) Mod snakewidth <> 0 do
    begin
        inc(food.y)
    end;
    if HitFood then
    begin
        PlaceFood
    end;
    Form1.Canvas.Brush.Color := foodcolor;
    Form1.Canvas.Pen.Color := snakecolor;
    Form1.Canvas.Ellipse(food.x + 1, food.y + 1,
        food.x + snakewidth - 2, food.y + snakewidth - 2);
end;
procedure DrawSnake;
var
i : integer;
Begin
if direction = dnone then
exit;
Form1.Canvas.Brush.Color := pfcolor;
Form1.Canvas.Pen.Color := pfcolor;
Form1.Canvas.Rectangle(snake[snakelength - 1].X, snake[snakelength - 1].Y,
snake[snakelength - 1].X + snakewidth, snake[snakelength - 1].Y + snakewidth);
For i := snakelength - 1 downto 1 do
snake[i] := snake[i-1];
snake[0]:= snake[1];
case direction of
dup : dec(snake[0].y, snakewidth);
ddown : inc(snake[0].y, snakewidth);
dleft : dec(snake[0].x, snakewidth);
dright : inc(snake[0].x, snakewidth);
end;
if HitFood then
begin
inc(score, 5);
inc(snakelength, snakegrow);
setlength(snake, snakelength);
for i := 1 to snakegrow do
snake[snakelength-i] := snake[(snakelength-snakegrow)-1];
PlaceFood;
end;
if HitWall then
begin
EndGame;
ResetGame;
end;
Form1.Canvas.Brush.Color := snakecolor;
Form1.Canvas.Pen.Color := snakecolor;
case direction of
dup : Form1.Canvas.Rectangle(snake[0].X+1, snake[0].Y+1,
snake[0].X + snakewidth-1, snake[0].Y + snakewidth+1);
ddown : Form1.Canvas.Rectangle(snake[0].X+1, snake[0].Y-1,
snake[0].X + snakewidth-1, snake[0].Y + snakewidth-1);
dleft : Form1.Canvas.Rectangle(snake[0].X+1, snake[0].Y+1,
snake[0].X + snakewidth+1, snake[0].Y + snakewidth-1);
dright : Form1.Canvas.Rectangle(snake[0].X-1, snake[0].Y+1,
snake[0].X + snakewidth-1, snake[0].Y + snakewidth-1);
end;
End;
// DrawPlayField: Draws the playfield (the area where the snake navigates on)
procedure DrawPlayfield;
begin
Form1.Canvas.Brush.Color := pfcolor;
Form1.Canvas.Pen.Color := pfcolor;
Form1.Canvas.Rectangle(pfposition.x, pfposition.y, pfdimention.x + pfposition.x, pfdimention.y + pfposition.y);
end;
// ResetGame: Resets the game; resets the snake and score
Procedure ResetGame;
var
i : integer;
Begin
form1.snaketimer.enabled := false;
randomize;
snake := nil;
snakelength := 10;
setlength(snake, snakelength);
snake[0].x := pfposition.x + (pfdimention.x div 2) - (snakewidth div 2);
snake[0].y := pfposition.y + (pfdimention.y div 2) - (snakewidth div 2);
while ((pfdimention.x-(snake[0].x-pfposition.x)) mod snakewidth <> 0) do
inc(snake[0].x);
while ((pfdimention.y-(snake[0].y-pfposition.y)) mod snakewidth <> 0) do
inc(snake[0].y);
for i := 1 to snakelength - 1 do
snake[i] := snake[0];
score := 0;
food.x := 0;
food.y := 0;
direction := dright;
olddirection := direction;
DrawPlayfield;
DrawSnake;
PlaceFood;
form1.snaketimer.Interval := speed;
form1.snaketimer.enabled := true;
End;
// EndGame: Stops the snake timer and free memory allocated by the snake array
Procedure EndGame;
Begin
form1.snaketimer.enabled := false;
snake := nil;
End;
// snaketimerTimer: Updates the old direction and draws the snake
procedure TForm1.snaketimerTimer(Sender: TObject);
begin
olddirection := direction;
DrawSnake;
end;
// FormKeyPress: Handles the key input (#32 = space, stops the snake movement)
procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char);
begin
case key of
'w', 'W': if olddirection <> ddown then direction := dup;
's', 'S': if olddirection <> dup then direction := ddown;
'a', 'A': if olddirection <> dright then direction := dleft;
'd', 'D': if olddirection <> dleft then direction := dright;
#32: direction := dnone;
end;
end;
// FormPaint: Draws the form and resets the game
procedure TForm1.FormPaint(Sender: TObject);
begin
form1.ClientWidth := pfdimention.x + (pfposition.x * 2);
form1.ClientHeight := pfdimention.y + (pfposition.y * 2);
form1.Color := clBlack;
ResetGame;
end;
end.

Chtěl bych se zeptat ohledně toho vykreslení hracího pole (DrawPlayfield)
Jestli jsem vlastně pochopil co se děje v proceduře.

var
pfdimention : tpoint = (x:200; y:200);\\ hrací plocha je jakýsi bod o výšce a šířce 200 pixelů
pfposition : tpoint = (x:5; y:5)\\ umístění na formuláři (jakási pomyslná zeď) je bod o výše a šířce 5 pixelů
pfcolor : tcolor = clWhite; \\ barva hrací plochy nastavena na bílou

procedure DrawPlayfield;
begin
Form1.Canvas.Brush.Color := pfcolor; \\ barva plátna nastavena na bílou
Form1.Canvas.Pen.Color := pfcolor; \\ barva pera natavena na bílou
Form1.Canvas.Rectangle(pfposition.x, pfposition.y, pfdimention.x + pfposition.x, pfdimention.y + pfposition.y);
end
\\ na form1 se vykreslí čtvercový bod který bude mít odsazení od formuláře Left/Top 5 pixelů a bude mít výšku/šířku nastavenou na 200 pixelů.

procedure TForm1.FormPaint(Sender: TObject);
begin
form1.ClientWidth := pfdimention.x + (pfposition.x * 2);
form1.ClientHeight := pfdimention.y + (pfposition.y * 2);
form1.Color := clBlack;
end

\\ Na výšku/šířku formuláře se nastaví naše hrací pole a barva formuláře je černá.
Takže tím pádem, ta naše pomyslná zeď dostane barvu černou protože to je ten formulář. ??
Kdyby Vám něco nesedělo nebo to chápu špatně byl bych moc rád kdyby jste mě opravili a dovysvětlily.

tpoint len uchovava dve celociselne hodnoty, nemusi to byt bod. Zmysel tych hodnot moze byt cokolvek. Trebars v tom pripade vyska a sirka nejakej plochy.

Brush neni platno ale stetec (= Brush po anglicky), t.j. farba vyplne ak kreslim nejaky vyplnitelny objekt, napr. obdlznik.

Na form1 sa nenakresli bod, ale obdlznik (= Rectangle po anglicky).

procedura FormPaint je tam pouzita dost dementne, nastavuje to len parametre objektu form1, ta procedura je ale volana systemom (kniznicou) z uplne inych dovodov. Niekde tu sirku platna autor nastavit musel, tak to robi tam lebo ine ho nenapadlo.

Vseobecne ak sa pouziva nejaky kniznicny objekt napr. ten Form.Canvas tak si nastuduj ze jake to ma parametre a co vsetko musis tomu objektu nastavit, a jake procedury ti system bude volat a kedy. Snad k tomu delphi bol pribaleny aj nejaky help, referencna prirucka, apod. Ak nemas tak google Form.Canvas reference, apod. Alebo si googli rovno slova programovani v delphi pro zacatecniky a citaj si nejaky tutorial od zaciatku. Aby si aspon chapal jak sa strukturuje Windows program a co to je riadenie eventami apod.

P.S> a nechapem preco to nutne chces v Delphi, imho mrtva platforma.

.. resp. tym ze do FormPaint (co je asi OnPaint event to musis si pozret ty v tvojom projekte) nastavuje clientwidth a height co je asi sirka a vyska okna na pevnu hodnotu, a OnPaint je volany pri kazdom prekresleni okna, by mal tym padom dosiahnut ze sa okno neda zvacsit/zmensit. Nie som si isty ptz delhi nerobim a neda sa k tomu najst poriadna referencia googlom, je to mrtve.

FormPaint je udalost, ktera se vola pri potrebe o prekresleni formulare (pohnes s nim, prekreje jej jiny formular apod.).
V teto procedure by melo probehnout veskere kresleni na Canvas formulare.
Jak psal MM, nastaveni ClientWidth a ClientHeight staci pouze jednou v OnCreate formulare. Je to oblast, na ktere muzes umistovat komponenty apod.
To same plati o nastaveni cerne barvy formulare.

V podstate to melo probehnout nasledovne:
inicializace hry - vygenerujes si pole (2 rozmerna hraci plocha) s hadem, jidlem, prekazkami, ...
V OnPaint formulare budes mit pouze vykresleni pole na plochu formulare, nic jineho - obycejne 2 cykly v sobe, ktere vykresli mrizku a hada.
Po stisku klavesy nebo v udalosti Timeru budes aktualizovat pouze pole, zadne kresleni a na konci obsluhy zavolas Form.Refresh, Form.Invalidate pripadne jinou metodu, ktera vynuti prekresleni formulare

Zpět do poradny Odpovědět na původní otázku Nahoru