Delphi Wie Snake in einer konsolenanwendung proggen?

computerfreaky

Lt. Commander
Registriert
Juni 2008
Beiträge
1.589
Hallo

also da ist was was mich zimlich interessieren würde, und zwar das Spiel Snake in einer Konsolenapplikation zu proggen. Hab aber nicht wirklich nen Plan wie das gehen sollte, zum bsp um schon mal die Steurung der pfeiltasten abzufangen etc...
Hab gegooglet und da hat jmd das Spiel in C geschrieben und auch den Code veröffentlicht,versteh aber nicht wirklich viel von dem Code...und nen C to pascal Konverter hab ich auch nicht wirklich gefunden^^
Könnte mir jmd bitte erklären wie ich da vorangehen sollte?
wäre zimlich nett:)


danke
 
Wie wärs, wenn du dich selber damit beschäftigst und dann konkrete Fragen stellst...? Und immer daran denken: http://www.gidf.de
 
jap, lern erstmal programmieren. nim dir nen buch und fang mit nem hallo world programm an. was willste jetzt von uns hier haben? nen feritigen quellcode zum abtippen um dann hinterher zu sagen, so das hab ich programmiert, das kanns doch nicht sein oder?
 
nix da mit Hello World ich bin kein blutiger anfänger mehr!
und wollte auch keinen fertigen quellcode zum abtippen, sondern eher mehr nen kleinen 'start' wie ich damit anfangen soll. isz ja auch nicht ohne sowas zu proggen
hab jetz auch schon meine kleine idee wie ich das realisieren könnte
zbsp das futter würde dann mit einer zufallszahl positioniert werden..
bei fragen meld ich mich

danke
 
Zuletzt bearbeitet:
Wenn du nicht weisst, wie du die Pfeiltasten abfangen kannst... dann nutz doch einfach WASD. :)
 
@Bunsen: Wow:) nice idee. Denn delphi kennt die unit CRT nicht...
Danke jetzt komme ich immer näher an mein ziel:)

EDIT:hey
also ich komm nicht wirklich weiter. hab irgendwie 0 ahnung wie sich das realisieren lässt.. ich würde das mal alles in einer repeat-until schleife reinpacken die solang durchläuft bis die Schlange sich selbst frisst
kann mir das jmd erklären bitte?

danke
 
Zuletzt bearbeitet:
Am Anfang schuf Gott Himmel und Erde. Und die Erde war wüst und leer, und es war finster auf der Tiefe; und der Geist Gottes schwebte auf dem Wasser. Und Gott sprach: Es werde Licht! Und es ward Licht...

Ganz im Ernst: Was erwartest du? Du konfrontierst uns hier mit einem ärmlichen Hilferuf einer kargen "Beschreibung" des Problems und erwartest, dass sich irgendwer die Zeit nimmt dir die grundlegensten Grundlagen der Programmierung zu erklären? Das ist unverschämt!

Ich wiederhole meinen Vorschlag: Beschäftige dich *intensiv* mit dem Thema. Wenn du Fragen hast, die Google dir tatsächlich nicht beantworten kann, dann wirst du hier mit Sicherheit auf offene Ohren treffen.
 
ja ich hab fragen die google nicht beantworten kann:
das einzige was ich bis jetzt kenne um etwas reinzulesen ist readln(VARIABLE); aber damit kann ich ja nicht mein snake steuern da ich ansonsten immer eingabe drücken muss nachdem ich zbsp W für geh nach vorne gedrückt habe.
 
Guck dir mal die Funktion Readkey an. Die sollte es in den meisten Sprachen geben.
 
Ich helf dir Delphitechnisch mal auf die Sprünge und gebe dir den Quelltext, der deine Schlange laufen lässt.

Um Kollisionsabfragen und Spiellogik musst du dich aber selber kümmern.

Code:
program Snake;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  Windows;

type
  TDirection = (diUp,diRight,diDown,diLeft);

  TSnake = class
  private
    fDirection: TDirection;
    fBody     : Array of TSmallPoint;
    fBodyChar: Char;
    procedure SetBodyChar(const Value: Char);
    procedure SetDirection(const Value: TDirection);
    function getBodyLength: Integer;
    procedure SetBodyLength(const Value: Integer);
    function getBodyElement(index: integer): TSmallPoint;
  protected
    procedure Clear(Point:TSmallPoint);
    procedure Paint(Point:TSmallPoint);overload;
    procedure Paint;overload;
  public
    property BodyChar:Char read fBodyChar write SetBodyChar;
    property Direction: TDirection read fDirection write SetDirection;
    property BodyElementPos[index:integer]:TSmallPoint read getBodyElement;
    property BodyLength: Integer read getBodyLength write SetBodyLength;
    constructor Create;
    destructor  Destroy;reintroduce;
    procedure   Move;
    function Position:TSmallPoint;
    procedure Grow(Amount:Integer);
  end;

const
  EMPTY_CHAR          : Char     = ' ';
  MAX_X               : SmallInt = 79;
  MAX_Y               : SmallInt = 24;
  SNAKE_DEFAULT_LENGTH: Integer  = 3;
  SLEEP_TIME          : Integer  = 200;

var
  hConsoleInput: THandle;
  hConsoleOutput: THandle;
  ConsoleScreenRect: TSmallRect;
  Snake1: TSnake;

procedure GotoXY(X,Y:Integer);
var
  Coord: TCoord;
begin
  Coord.X := X - 1 + ConsoleScreenRect.Left;
  Coord.Y := Y - 1 + ConsoleScreenRect.Top;
  if not SetConsoleCursorPosition(hConsoleOutput, Coord) then
  begin
    GotoXY(1, 1);
  end;
end;

procedure WriteXY(X,Y:Integer;Text:String);
begin
  GotoXY(X,Y);
  write(Text);
end;

procedure init;
const
  ExtInpConsoleMode = ENABLE_WINDOW_INPUT or ENABLE_PROCESSED_INPUT;
var
  cMode: DWORD;
begin
  Reset(Input);
  hConsoleInput := TTextRec(Input).Handle;
  ReWrite(Output);
  hConsoleOutput := TTextRec(Output).Handle;
  GetConsoleMode(hConsoleInput, cMode);
  if (cMode and ExtInpConsoleMode) <> ExtInpConsoleMode then
  begin
    cMode := cMode or ExtInpConsoleMode;
    SetConsoleMode(hConsoleInput, cMode);
  end;
  Snake1:=TSnake.Create;
end;

procedure SnakeRun;
var
  Key:Integer;
  NumRead: DWORD;
  NumberOfEvents: DWORD;
  InputRec: TInputRecord;
  Runde:Int64;
  Position:TSmallPoint;
  KeyPressed:Boolean;
begin
  Runde:=0;
  Key:=VK_RETURN;
  Snake1.Paint;
  while Key <> VK_Escape do
  begin
    inc(Runde);
    Position:=Snake1.Position;
    WriteXY(2,1,Format('Runde: %5d [Position: %2d/%2d] Taste: %2d',[Runde,Position.x,Position.y,key]));
    Windows.SleepEx(SLEEP_TIME,false);
    KeyPressed:=false;
    GetNumberOfConsoleInputEvents(hConsoleInput, NumberOfEvents);
    if NumberOfEvents > 0 then
    begin
      if PeekConsoleInput(hConsoleInput, InputRec, 1,NumRead) then
      begin
        if (InputRec.EventType = KEY_EVENT)
           AND
           (InputRec.Event.KeyEvent.bKeyDown)
        then
        begin
          KeyPressed := True;
        end
        else
        begin
          ReadConsoleInput(hConsoleInput, InputRec, 1,NumRead);
        end;
      end;
    end;
    if Keypressed then
    begin
      repeat
        ReadConsoleInput(hConsoleInput, InputRec, 1,NumRead);
      until InputRec.Event.KeyEvent.wVirtualKeyCode > 0;
      Key:=Integer(InputRec.Event.KeyEvent.wVirtualKeyCode);
      case Key of
        VK_UP    : Snake1.Direction:=diUp;
        VK_RIGHT : Snake1.Direction:=diRight;
        VK_DOWN  : Snake1.Direction:=diDown;
        VK_LEFT  : Snake1.Direction:=diLeft;
        VK_SPACE : Snake1.Grow(1);
      end;
    end;
    Snake1.Move;
  end;
end;

{ TSnake }

procedure TSnake.Clear(Point: TSmallPoint);
begin
  writeXY(Point.x,Point.y,EMPTY_CHAR);
end;

constructor TSnake.Create;
var
  I: Integer;
begin
  SetLength(fBody,SNAKE_DEFAULT_LENGTH);
  fBody[0].x:=MAX_X DIV 2;
  fBody[0].y:=MAX_Y DIV 2;
  for I := 0 to Length(fBody) - 1 do
  begin
    fBody[i].x:=fBody[0].x-i;
    fBody[i].y:=fBody[0].y;
  end;
  fBodyChar:='#';
  fDirection:=diUp;
end;

destructor TSnake.Destroy;
begin
  SetLength(fBody,0);
end;

function TSnake.getBodyElement(index: integer): TSmallPoint;
begin
  result.x:=0;
  result.y:=0;
  if (index > 0) AND (index < Length(fBody)) then
  begin
    result.x:=fBody[index].x;
    result.y:=fBody[index].y;
  end;
end;

function TSnake.getBodyLength: Integer;
begin
  result:=Length(fBody);
end;

procedure TSnake.Grow(Amount: Integer);
begin
  SetBodyLength(getBodyLength+Amount);
end;

procedure TSnake.Move;
var
  I: Integer;
begin
  Clear(fBody[length(fBody)-1]);
  if Length(fBody)>1 then
  begin
    for I := Length(fBody) - 1 DownTo 1 do
    begin
      fBody[i]:=fBody[i-1];
      Paint(fBody[i]);
    end;
  end;
    case fDirection of
    diUp   : begin
               dec(fBody[0].y);
             end;
    diRight: begin
               inc(fBody[0].x);
             end;
    diDown : begin
               inc(fBody[0].y);
             end;
    diLeft : begin
               dec(fBody[0].x);
             end;
  end;
  Paint(fBody[0]);
end;

procedure TSnake.Paint(Point: TSmallPoint);
begin
  writeXY(Point.x,Point.y,fBodyChar);
end;

procedure TSnake.Paint;
var
  I: Integer;
begin
  for I := 0 to Length(fBody) - 1 do
  begin
    writeXY(fBody[i].x,fBody[i].y,fBodyChar);
  end;
end;

function TSnake.Position: TSmallPoint;
begin
  result := fBody[0];
end;

procedure TSnake.SetBodyChar(const Value: Char);
begin
  if Value <> fBodyChar then
  begin
    fBodyChar := Value;
    self.Paint;
  end;
end;

procedure TSnake.SetBodyLength(const Value: Integer);
var
  OldLength:Integer;
  I: Integer;
begin
  if Value<>Length(fBody) then
  begin
    OldLength:=Length(fBody);
    SetLength(fBody,Value);
    if Value>OldLength then
    begin
      for I := OldLength to Value - 1 do
      begin
        fBody[i].x:=fBody[OldLength-1].x;
        fBody[i].y:=fBody[OldLength-1].y;
      end;
    end;
  end;
end;

procedure TSnake.SetDirection(const Value: TDirection);
begin
  if Value <> fDirection then
  begin
    fDirection := Value;
  end;
end;

begin
  try
  { TODO -oEntwickler -cKonsole Main : Hier Code einfügen }
    init;
    SnakeRun;
  except
    on E:Exception do
      Writeln(E.Classname, ': ', E.Message);
  end;
end.
 
Zurück
Oben