Seite 1 von 1

[Projekt] Snake

Verfasst: 24.10.2011, 20:28
von Zudomon
Huhu!

Ich habe mir heute mal die Zeit genommen, ein Snake zu schreiben.
Das ganze hat etwa 2 Stunden gedauert. Und dann nochmal etwa 2,5 Stunden, um das ganze vom Code ( nicht von der Laufzeit ) zu optimieren um es kleiner zu bekommen und zu Verunstalten *g*
Snake.png
Und hier der komplette Quellcode in Delphi...

Snake.dpr

Code: Alles auswählen

program Snake;

uses
  Forms,
  uSnake;

{$R *.res}

begin
  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.
uSnake.pas

Code: Alles auswählen

unit uSnake;

interface
  uses
    Windows, SysUtils, Graphics, Forms, Dialogs, Math, AppEvnts,
    StdCtrls, Classes, Controls, ExtCtrls;

type
  TForm1=class(TForm)
    Timer1: TTimer;
    ApplicationEvent1: TApplicationEvents;
    Label1: TLabel;
    Button1: TButton;
    Button2: TButton;
    procedure Click(Sender: TObject);
    procedure FormKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure ApplicationEvent1Activate(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
  end;

var
  Form1: TForm1;
  Fruit, Dir, Dir2: Word;
  Snake: Array of Word;
  Points: Int64;

implementation

{$R *.dfm}

procedure TForm1.ApplicationEvent1Activate(Sender: TObject);
begin
  randomize;
  Canvas.Brush.Color:=clWhite;
  Canvas.FrameRect(Rect(14, 46, 529, 433));
end;

procedure TForm1.Click(Sender:TObject);
var
  i:Integer;
begin
  if Sender=Button1 then begin
    Button1.Hide;
    Button2.Hide;
    Canvas.Brush.Color:=0;
    Canvas.FillRect(Rect(15,47,528,432));
    SetLength(Snake,3);
    for i:=0 to high(Snake) do Snake[i]:=(32+i) shl 8+24;
    Dir:=1;
    Dir2:=Dir;
    Points:=0;
    Fruit:=$FF;
    Timer1.Interval:=150;
    Timer1.Enabled:=true;
  end else Close;
end;

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
  if(Dir<>((Key and 3)+2) mod 4) and (Key>=37) and (Key<=40) then Dir2:=Key and 3;
end;

procedure TForm1.Timer1Timer(Sender: TObject);

  procedure Draw(p: Word; c: TColor=clBlack);
  var
    x, y: Integer;
  begin
    x:=16+p shr 8*8;
    y:=48+p and $FF*8;
    Canvas.Brush.Color:=c;
    Canvas.FillRect(Rect(x, y, 7+x, 7+y));
  end;

  function OnSnake(p:Word):Boolean;
  var
    i:Integer;
  begin
    Result:=false;
    for i:=0 to high(Snake) do if p=Snake[i] then Result:=true;
  end;

var
  i, NewPos, Color: Integer;
begin
  Dir:=Dir2;
  NewPos:=Snake[0]-sign(Dir mod 3-0.5) shl (Dir mod 2*8);
  Label1.Caption:='Punkte: '+inttostr(Points);

  if (NewPos<0) or (NewPos>$3FFF) or (NewPos and $FF>47) or OnSnake(NewPos)then begin
    Timer1.Enabled:=false;
    ShowMessage('Game over!');
    Button1.Show;
    Button2.Show;
    exit;
  end;

  if NewPos=Fruit then begin
    SetLength(Snake, Length(Snake)+1);
    Fruit:=$FF;
    inc(Points,round(2000/(Timer1.Interval+1)));
    Timer1.Interval:=round(Timer1.Interval*0.98);
  end;

  if Fruit=$FF then repeat
    Fruit:=random(64) shl 8+random(48);
  until not OnSnake(Fruit);

  Draw( Fruit, $FFFF );
  Draw( Snake[high(Snake)] );

  for i:= high(Snake) downto 1 do Snake[i]:=Snake[i-1];

  Snake[0]:=NewPos;
  for i:=0 to high(Snake)do begin
    Color:=round((sin(i*2)*0.175+0.625)*50);
    if i=0 then Color:=50;
    Draw(Snake[i], RGB(Color, Color*4, Color));
  end;
end;

end.
Viel Spass beim zocken! :D
Snake.zip
(219.65 KiB) 232-mal heruntergeladen
[/size]

Re: [Projekt] Snake

Verfasst: 24.10.2011, 20:40
von antisteo
Nah

guter Anlass, mal wieder mein Bootsektor-Snake rauszukramern:

http://botwars.tk/snake.img
240 Bytes

Einfach in den Bootsektor einer CD/USB/Diskette schreiben (Dateisystem geht dabei nicht kaputt) und den Rechner damit booten (oder das ganz in die VirtualBox)

Das Ding hat sogar einen Thread Manager :D

Naja und dank des sich-immer-wieder-mal-selbst-löschenden Speichers meines Taschenrechners musste ich Snake immer wieder neu Programmieren und bekomm's inzwischen auch in Rekordzeit hin.

Re: [Projekt] Snake

Verfasst: 24.10.2011, 20:43
von antisteo
- ich hab plötzlich verloren.. prüfst du die Rückwärtsbewegung?
- Nutzt du das KeyUp-Event? Das ließ sich voll komisch steuern und ich hab nicht alle Kurven gekriegt.

Re: [Projekt] Snake

Verfasst: 24.10.2011, 20:58
von Zudomon
Mich würde auch der Code von deinem Snake interessieren.

Rückwärtsprüfung prüfe ich und das ganze ist beim KeyDown Event.
(Hättest doch einfach mal in den Code schauen können... :lol: wobei, ich glaube, da sieht man nicht, dass es KeyDown ist )

Code: Alles auswählen

procedure TF.KD(SN:TObject;var K:W;SH:TShiftState);
begin
  if(D<>((K and 3)+2)mod 4)and(K>=37)and(K<=40)then D2:=K and 3;
end;
Da werden die Pfeiltasten abgefragt. Vor dem zweiten "and" ist die Rückwertprüfung.
antisteo hat geschrieben:Naja und dank des sich-immer-wieder-mal-selbst-löschenden Speichers meines Taschenrechners musste ich Snake immer wieder neu Programmieren und bekomm's inzwischen auch in Rekordzeit hin.
Für mich ist es das erste mal...

Re: [Projekt] Snake

Verfasst: 24.10.2011, 21:28
von LONy
2590 Punkte^^ und schuld ist natürlich nur die minimaler Verzögerung von meiner Funktastatur xD

Re: [Projekt] Snake

Verfasst: 24.10.2011, 22:15
von antisteo
Zudomon hat geschrieben:Mich würde auch der Code von deinem Snake interessieren.
http://botwars.tk/snake

Leute, so muss gut strukturierter, gut dokumentierter Assembler-Code aussehen.

Re: [Projekt] Snake

Verfasst: 25.10.2011, 13:56
von Zudomon
Hab den Quellcode mal in übersichtlicher Form gepostet... (Eingangspost) mit ordentlichen Variablenamen. :D

Wer Fragen hat dazu, möge diese bitte stellen! :D

Re: [Projekt] Snake

Verfasst: 25.10.2011, 22:24
von Specialist
Hier mal eins, dass ich vor ein paar Monaten an einem langweiligen Nachmittag geschrieben habe:

http://bug-soft.net/Snake/test.html