Autor Beitrag
F34r0fTh3D4rk
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 5284
Erhaltene Danke: 27

Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
BeitragVerfasst: Di 01.03.05 21:10 
hallo, ich wollte mal anfangen ein non-dx snake zu programmieren.

habe grad alle zeichenprozeduren geschrieben funktonieren auch wunderbar,
jetzt gehts an die bewegung und da scheitere ich mal wieder,
die schlange wird komischerweise immer länger, und nach links und rechts geht nicht,
hier mal der code (bis gerade eben ist es auch immer abgestürzt, jetzt müsste es soweit gehen, bis auch die bewegungen)

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
const
  up = -1;
  down = 1;
  left = -1;
  right = 1;  

var
  Game: TGame;
  map: array[1..80of array[1..80of integer;
  snake: array of TPoint;
  snakelength, XDirection, YDirection: integer;

implementation

{$R *.dfm}

procedure FillField(x,y: integer; color: Tcolor);
begin
  with game.field.canvas do
    begin
      pen.color:= color;
      brush.color:= color;
      rectangle(x*5-4, y*5-4, x*5, y*5);
   end;   
end;

procedure DrawWalls;
var
  x, y, i: integer;
begin
  for i:= 1 to 80 do
    begin
      x:= 1;
      y:= i;
      FillField(x, y, clblack);
      x:= 80;
      FillField(x, y, clblack);
      x:= i;
      y:= 1;
      FillField(x, y, clblack);
      y:= 80;
      FillField(x, y, clblack);
    end;
end;

procedure DrawMap;
var
  x, y, i: integer;
begin
  x:= 0;
  y:= 0;
  for i:= 0 to 80 do
    begin
      with game.field.canvas do
        begin
          pen.Color:= clgray;
          moveto(x, 0);
          lineto(x, 401);
          moveto(0, y);
          lineto(401, y);
        end;
      x:= x + 5;
      y:= y + 5;
    end;
  DrawWalls;
end;

procedure DrawSnake;
var
  i: integer;
begin
  for i:= 0 to SnakeLength - 1 do
    FillField(Snake[i].X, Snake[i].Y, clgreen);
end;

procedure TGame.FormCreate(Sender: TObject);
var
  i: integer;
begin
  randomize;
  Game.DoubleBuffered:= true;
  XDirection:= 0;
  YDirection:= up;
  snakelength:= 4;
  setlength(snake, snakelength + 1);
  snake[0].x:= random(30) + 20;
  snake[0].y:= random(30) + 20;
  for i:= 1 to snakelength do
    begin
      snake[i].x:= snake[0].x;
      snake[i].Y:= snake[0].Y + i;
    end;
  DrawMap;
  DrawSnake;
end;

procedure TGame.SnakeTimerTimer(Sender: TObject);
var
  i: integer;
begin
  snake[0].x:= snake[0].X + XDirection;
  snake[0].y:= snake[0].Y + YDirection;
  for i:= 1 to snakelength do
    begin
      snake[i].x:= snake[0].x - XDirection;
      snake[i].Y:= snake[0].Y - YDirection;
    end;
  DrawMap;
  DrawSnake;
end;

procedure TGame.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  if key = vk_up then YDirection:= Up;
  if key = vk_down then YDirection:= Down;
  if key = vk_left then XDirection:= left;
  if key = vk_right then XDirection:= right;
  if YDirection <> 0 then XDirection:= 0;
  if XDirection <> 0 then YDirection:= 0;
end;


Wo liegt der Fehler ? Ist der Ansatz komplett falsch ?

hier ne entschärfte version vom timer:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
procedure TGame.SnakeTimerTimer(Sender: TObject);
var
  i: integer;
begin
  snake[0].x:= snake[0].X + XDirection;
  snake[0].y:= snake[0].Y + YDirection;
  //memo1.lines[0]:= inttostr(snake[0].X)+'/'+inttostr(snake[0].Y);
  for i:= 1  to snakelength do
    begin
      if XDirection = 0 then
        if XDirection < 0 then
          snake[i].Y:= snake[0].Y - YDirection - i else
            snake[i].Y:= snake[0].Y - YDirection + i
      else
        if YDirection <0 then
          snake[i].X:= snake[0].X - XDirection - i else
            snake[i].X:= snake[0].X - XDirection + i;
  //    memo1.Lines[i]:= inttostr(snake[i].X)+'/'+inttostr(snake[i].Y);
    end;
  DrawMap;
  DrawSnake;
end;

Der Ansatz ist aber komplett falsch, ich arbeite gerade an einem neuen :)

Der Ansatz hier ist besser:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
procedure TGame.SnakeTimerTimer(Sender: TObject);
var
  i: integer;
begin
  if Direction = Up then
    begin
      snake[0].Y:= snake[0].Y - 1;
      for i:= 1 to snakelength do
        snake[i].y:= snake[i-1].Y;
    end;
  DrawMap;
  DrawSnake;    
end;

Aber die Schlange wird trotzdem immer länger, liegt das an der SnakeDraw Procedure ?

Ich finde den Fehler nicht !!!


Zuletzt bearbeitet von F34r0fTh3D4rk am Do 03.03.05 17:58, insgesamt 1-mal bearbeitet
HolgerB
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 91

Win XP
D6 Pers
BeitragVerfasst: Mi 02.03.05 17:28 
Hallo,

ich gehe mal davon aus, das die Schlange sich bewegen soll, wie bei Tron. (Mein Gott habe ich es geliebt!)

Zu dem Ansatz in deinem zweiten Post.

Sollte die Schleife nicht rückwärts durch die Schlange laufen? Dadurch wird das vorletzte Kästchen zum letzten und vorne entsteht ein Leerfeld für die neue Position.

ausblenden Delphi-Quelltext
1:
2:
3:
for i:= snakelength  downto 1 do  
  snake[i].y:= snake[i-1].Y;  
snake[0].Y:= snake[0].Y - 1;


Das gleiche brauchst du dann auch noch mal für X, aber das ist glaube ich sowieso klar.
Gruß
Holger

Moderiert von user profile iconraziel: Code- durch Delphi-Tags ersetzt.
F34r0fTh3D4rk Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 5284
Erhaltene Danke: 27

Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
BeitragVerfasst: Mi 02.03.05 20:26 
funktioniert jetzt soweit, die schlange "wächst" zwar immer noch aus sich selbst heraus, das ist beim original glaube ich auch so.
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197:
198:
199:
200:
201:
202:
203:
204:
205:
206:
207:
208:
209:
210:
211:
212:
213:
214:
215:
216:
217:
unit UMain;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls, Menus;

type
  TGame = class(TForm)
    Field: TImage;
    SnakeTimer: TTimer;
    PointDisplay: TLabel;
    Label1: TLabel; //Hier demnächst HighScore
    procedure FormCreate(Sender: TObject);
    procedure FormKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure SnakeTimerTimer(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

const
  up = 1;
  down = 2;
  left = 3;
  right = 4;
  Wall = 5;
  Food = 6;

var
  Game: TGame;
  map: array[1..40of array[1..40of integer;
  snake: array of TPoint;
  FoodPos: Tpoint;
  snakelength, Direction, Points, HighScore: integer;

implementation

{$R *.dfm}

procedure FillField(x,y: integer; color: Tcolor);
begin
  with game.field.canvas do
    begin
      pen.color:= color;
      brush.color:= color;
      rectangle(x*5-4, y*5-4, x*5, y*5);
   end;   
end;

procedure DrawWalls;
var
  x, y, i: integer;
begin
  for i:= 1 to 40 do
    begin
      x:= 1;
      y:= i;
      FillField(x, y, clblack);
      Map[x, y]:=  wall;
      x:= 40;
      FillField(x, y, clblack);
      Map[x, y]:=  wall;
      x:= i;
      y:= 1;
      FillField(x, y, clblack);
      Map[x, y]:=  wall;
      y:= 40;
      FillField(x, y, clblack);
      Map[x, y]:=  wall;
    end;
end;

procedure DrawMap;
var
  x, y, i: integer;
begin
  with game.Field.Canvas do
    begin
      brush.color:= clwhite;
      rectangle(00201201);
    end;  
  x:= 0;
  y:= 0;
  for i:= 0 to 40 do
    begin
      with game.field.canvas do
        begin
          pen.Color:= clgray;
          moveto(x, 0);
          lineto(x, 201);
          moveto(0, y);
          lineto(201, y);
        end;
      x:= x + 5;
      y:= y + 5;
    end;
  DrawWalls;
end;

procedure DrawSnake;
var
  i: integer;
begin
  FillField(Snake[0].X, Snake[0].Y, clred);
  for i:= 1 to SnakeLength do
    FillField(Snake[i].X, Snake[i].Y, clgreen);
end;

procedure DrawFood;
begin
  FillField(foodpos.x, foodpos.y, clblack);
end;

procedure MakeFood;
begin
  FoodPos.X:= random(39) + 2;
  FoodPos.Y:= random(39) + 2;
  map[FoodPos.x, FoodPos.y]:= food;
end;

procedure StartGame;
var
  i, x, y: integer;
begin
  Game.SnakeTimer.Enabled:= true;
    Points:= 0;
  for x:= 1 to 40 do
    for y:= 1 to 40 do
      map[x, y]:= 0;
  direction:= random(4)+1;
  snakelength:= 8;
  setlength(snake, snakelength + 1);
  snake[0].x:= random(20) + 10;
  snake[0].y:= random(20) + 10;
  for i:= 1 to snakelength do
    snake[i].Y:= snake[0].Y + i;
  MakeFood;  
  DrawMap;
  DrawFood;
  DrawSnake;
end;

procedure GameOver;
begin
  Game.SnakeTimer.Enabled:= false;
  showmessage('Game Over!');
  StartGame;
end;


procedure TGame.FormCreate(Sender: TObject);
begin
  randomize;
  Game.DoubleBuffered:= true;
  StartGame;
end;

procedure TGame.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  if (key = vk_up) and (Direction <> Down) then
    Direction:= Up;
  if (key = vk_down) and (Direction <> Up) then
    Direction:= Down;
  if (key = vk_left) and (Direction <> Right) then
    Direction:= left;
  if (key = vk_right) and (Direction <> Left) then
    Direction:= right;
end;

procedure TGame.SnakeTimerTimer(Sender: TObject);
var
  i, c: integer;
begin
  for i:= snakelength downto 1 do
    begin
      snake[i].y:= snake[i-1].Y;
      snake[i].X:= snake[i-1].X;
    end;
  if Direction = Up then
    snake[0].Y:= snake[0].Y - 1;
  if Direction = Down then
    snake[0].Y:= snake[0].Y + 1;
  if Direction = Left then
    snake[0].X:= snake[0].X - 1;
  if Direction = Right then
    snake[0].X:= snake[0].X + 1;
  if Map[snake[0].X, snake[0].y] = wall then
    begin
      GameOver;
      exit;
    end;
  if Map[snake[0].X, snake[0].Y] = food then
    begin
      Points:= points + 50;
      PointDisplay.Caption:= 'Points: ' + inttostr(points);
      snakelength:= snakelength + 1;
      setlength(snake, snakelength + 1);
      map[FoodPos.x, FoodPos.y]:= 0;
      MakeFood;
    end;
  for c:= 1 to snakelength do
    if (snake[0].X = snake[c].X) and (snake[0].Y = snake[c].Y) then
      begin
        GameOver;
        exit;
      end;  
  DrawMap;
  DrawFood;
  DrawSnake;
end;

end.

Testen mit einem 201*201 pixel großem image,

imagename: field,
formname: game,
timername: snaketimer,
labelname: pointdisplay

highscore noch nicht implementiert

Warum muss ich Direction auf 300 setzen wenn ich nach links will ?

das ist doch völliger schwachsinn, wer findet den fehler, bitte, ich finde nichts... :(

wenn am start links als richtung gesetzt ist, kommt game over !

nach einiger zeit kommt kein essen mehr !

wer noch andere fehler findet, bitte bescheid sagen !
Larus
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 431



BeitragVerfasst: Do 03.03.05 20:22 
Also... du must direction nicht auf 300 setzen... du muss nur ein wenig Code ändern!
Problem: Left ist eine Positionsangabe... Right up und down nicht (in der programmiersprache)
Ändere das mal so ab!
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197:
198:
199:
200:
201:
202:
203:
204:
205:
206:
unit UMain;

 
interface  

 
uses  
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,  
  Dialogs, ExtCtrls, StdCtrls;  

 
type  
  TGame = class(TForm)  
    Field: TImage;
    SnakeTimer: TTimer;
    b_retry: TButton;
    l_fps: TLabel;
    fps: TTimer;
    l_thatundsoll: TLabel;
    procedure FormCreate(Sender: TObject);  
    procedure FormKeyDown(Sender: TObject; var Key: Word;  
      Shift: TShiftState);  
    procedure SnakeTimerTimer(Sender: TObject);
    procedure b_retryClick(Sender: TObject);
    procedure fpsTimer(Sender: TObject);
  private  
    { Private-Deklarationen }  
  public  
    { Public-Deklarationen }  
  end;  

 
const  
  goup = 1;
  godown = 2;
  goleft = 3;
  goright = 4;

 
var  
  Game: TGame;  
  map: array[1..80of array[1..80of integer;  
  snake: array of TPoint;  
  snakelength, Snakeshouldbe, Direction: integer;


implementation  

 
{$R *.dfm}  

 
procedure FillField(x,y: integer; color: Tcolor);  
begin  
  with game.field.canvas do  
    begin  
      pen.color:= color;  
      brush.color:= color;  
      rectangle(x*5-4, y*5-4, x*5, y*5);  
   end;     
end;  

 
procedure DrawWalls;  
var  
  x, y, i: integer;  
begin  
  for i:= 1 to 80 do  
    begin  
      x:= 1;  
      y:= i;
      FillField(x, y, clblack);
      x:= 80;
      FillField(x, y, clblack);
      x:= i;  
      y:= 1;  
      FillField(x, y, clblack);  
      y:= 80;  
      FillField(x, y, clblack);  
    end;  
end;  

 
procedure DrawMap;  
var  
  x, y, i: integer;  
begin  
  with game.Field.Canvas do
    begin  
      brush.color:= clwhite;  
      rectangle(00401401);  
    end;    
  x:= 0;  
  y:= 0;  
  for i:= 0 to 80 do  
    begin
      with game.field.canvas do  
        begin  
          pen.Color:= clgray;  
          moveto(x, 0);  
          lineto(x, 401);
          moveto(0, y);
          lineto(401, y);  
        end;  
      x:= x + 5;  
      y:= y + 5;  
    end;  
  DrawWalls;  
end;  

 
procedure DrawSnake;  
var  
  i: integer;  
begin
  FillField(Snake[0].X, Snake[0].Y, clred);
  for i:= 1 to SnakeLength do  
    FillField(Snake[i].X, Snake[i].Y, clgreen);  
end;  

procedure Lost;
Var
  i: Integer;
Begin
  GAme.SnakeTimer.Enabled:=False;
  Game.b_retry.Enabled:=True;
  Game.b_retry.SetFocus;
End;
 
procedure TGame.FormCreate(Sender: TObject);  
var
  i: integer;
begin
  randomize;
  Game.DoubleBuffered:= true;
  Direction:=random(4)+1;
  Snakeshouldbe:=10;
  snakelength:= 0;
  setlength(snake, snakelength + 1);
  snake[0].x:= random(30) + 20;
  snake[0].y:= random(30) + 20;
  for i:= 1 to snakelength do
    snake[i].Y:= snake[0].Y + i;
  DrawMap;
  DrawSnake;
end;  

 
procedure TGame.FormKeyDown(Sender: TObject; var Key: Word;  
  Shift: TShiftState);  
begin  
  if (key = vk_up) And (Direction<>goDown) then Direction:= goUp;
  if (key = vk_down) And (Direction<>goUp) then Direction:= goDown;
  if (key = vk_Left) And (Direction<>goright) then Direction:= goleft;
  if (key = vk_right) And (Direction<>goleft) then Direction:= goright;
end;  

 
procedure TGame.SnakeTimerTimer(Sender: TObject);  
var  
  i: integer;  
begin  
  for i:= snakelength downto 1 do
    begin
      snake[i].y:= snake[i-1].Y;
      snake[i].X:= snake[i-1].X;
    end;
  if Direction = goUp then
    snake[0].Y:= snake[0].Y - 1;
  if Direction = goDown then
    snake[0].Y:= snake[0].Y + 1;
  if Direction = goLeft then
    snake[0].X:= snake[0].X - 1;
  if Direction = goRight then
    snake[0].X:= snake[0].X + 1;
  DrawMap;
  DrawSnake;
  If (snake[0].Y=1Or (snake[0].Y=80Or (snake[0].X=1Or (snake[0].X=80Then
    Lost;
  If Snakelength<Snakeshouldbe Then
    SnakeLength:=Snakelength+1;
end;


procedure TGame.b_retryClick(Sender: TObject);
var
  i: integer;
begin
  randomize;
  Game.DoubleBuffered:= true;
  Direction:=random(4)+1;
  Snakeshouldbe:=10
  snakelength:= 0;
  setlength(snake, snakelength + 1);
  snake[0].x:= random(30) + 20;
  snake[0].y:= random(30) + 20;
  for i:= 1 to snakelength do
    snake[i].Y:= snake[0].Y + i;
  DrawMap;
  DrawSnake;
  SnakeTimer.Interval:=100;
  SnakeTimer.Enabled:=True;
  b_retry.Enabled:=False;
end;

end.


P.S. Ich hatte noch was weiter gecodet damit die Schlange immer nur um 90° drehen kann etc.

Allerdings tauchte nun ein Neues Prob auf.. das Programm stürzt mit Zich fehlern ab.. Ob das an dem zusätzlichen FPS Counter liegt den ich zu Testzwecken eingebundne hab???

//Edit: Ich hatte ebenfalls zu testzecken einen Retrybutton eingesetzt und hab dann festgestellt das beim neustart die Punkte der schlange verteilt waren und musste deshalb den Wert snakeshoulbe hinzufügen....
F34r0fTh3D4rk Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 5284
Erhaltene Danke: 27

Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
BeitragVerfasst: Do 03.03.05 20:25 
ist retry n button, beimir registriert er dann die tastenanschläge nimmer :(

kannst du die wesentlichen änderungen mal markieren, so bekomme ich ziemlich viele fehler :(

was hast du geändert, um den 300 fehler zu beheben ?
Larus
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 431



BeitragVerfasst: Do 03.03.05 20:30 
ja b_retry is ein Button und die Anwendung startet mit dem disabled und während des Games ist der weiterhin disabled... Nur wenne verlierst wird er aktiviert... hasse meinen direction hinweis ma ausprobiert?



Um den 300 Fehler zu beheben hab ich statt left goleft in const etc gesetzt. Left is ja schließlich eine Positionsangabe für Formen und Buttons und das hat mich stutzig gemacht weswegen ich das so ausprobiert hab.
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
const    
  goup = 1;  
  godown = 2;  
  goleft = 3;  
  goright = 4;  

 
...

  if (key = vk_up) And (Direction<>goDown) then Direction:= goUp;  
  if (key = vk_down) And (Direction<>goUp) then Direction:= goDown;  
  if (key = vk_Left) And (Direction<>goright) then Direction:= goleft;  
  if (key = vk_right) And (Direction<>goleft) then Direction:= goright;  

...

  if Direction = goUp then  
    snake[0].Y:= snake[0].Y - 1;  
  if Direction = goDown then  
    snake[0].Y:= snake[0].Y + 1;  
  if Direction = goLeft then  
    snake[0].X:= snake[0].X - 1;  
  if Direction = goRight then  
    snake[0].X:= snake[0].X + 1;  

...
F34r0fTh3D4rk Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 5284
Erhaltene Danke: 27

Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
BeitragVerfasst: Fr 04.03.05 10:51 
na klar, danke !!! das muss die ursache sein, aber warum kommt nach einiger zeit kein futter mehr ?

DANKE :D
Larus
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 431



BeitragVerfasst: Fr 04.03.05 11:09 
Weil das Futter in die Wand gelegt wird??? Ich habs bei mir mal blau gefärbt und gesehen das es auf die wand gelegt wird!
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
procedure MakeFood;  
begin  
  FoodPos.X:= random(38) + 2;  
  FoodPos.Y:= random(38) + 2;  
  map[FoodPos.x, FoodPos.y]:= food;  
end;

müsste es glaub ich lauten probier ich heute mittag aus.. hab im moment INFO unterricht!

Moderiert von user profile iconraziel: Code- durch Delphi-Tags ersetzt.
F34r0fTh3D4rk Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 5284
Erhaltene Danke: 27

Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
BeitragVerfasst: Fr 04.03.05 14:43 
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
procedure MakeFood;    
begin    
  FoodPos.X:= random(37) + 2;    
  FoodPos.Y:= random(37) + 2;    
  map[FoodPos.x, FoodPos.y]:= food;    
end;

du hast recht, aber es muss 37 sein, weil wenn beim random 37 rauskommt, +2 macht das 39 :D

so funktionierts jetzt:
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197:
198:
199:
200:
201:
202:
203:
204:
205:
206:
207:
208:
209:
210:
211:
212:
213:
214:
215:
216:
unit UMain;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls, Menus;

type
  TGame = class(TForm)
    Field: TImage;
    SnakeTimer: TTimer;
    PointDisplay: TLabel;
    Label1: TLabel;
    procedure FormCreate(Sender: TObject);
    procedure FormKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure SnakeTimerTimer(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

const
  sup = 1;
  sdown = 2;
  sleft = 3;
  sright = 4;
  Wall = 5;
  Food = 6;

var
  Game: TGame;
  map: array[1..40of array[1..40of integer;
  snake: array of TPoint;
  FoodPos: Tpoint;
  snakelength, Direction, Points, HighScore: integer;

implementation

{$R *.dfm}

procedure FillField(x,y: integer; color: Tcolor);
begin
  with game.field.canvas do
    begin
      pen.color:= color;
      brush.color:= color;
      rectangle(x*5-4, y*5-4, x*5, y*5);
   end;   
end;

procedure DrawWalls;
var
  x, y, i: integer;
begin
  for i:= 1 to 40 do
    begin
      x:= 1;
      y:= i;
      FillField(x, y, clblack);
      Map[x, y]:=  wall;
      x:= 40;
      FillField(x, y, clblack);
      Map[x, y]:=  wall;
      x:= i;
      y:= 1;
      FillField(x, y, clblack);
      Map[x, y]:=  wall;
      y:= 40;
      FillField(x, y, clblack);
      Map[x, y]:=  wall;
    end;
end;

procedure DrawMap;
var
  x, y, i: integer;
begin
  with game.Field.Canvas do
    begin
      brush.color:= clwhite;
      rectangle(00201201);
    end;  
  x:= 0;
  y:= 0;
  for i:= 0 to 40 do
    begin
      with game.field.canvas do
        begin
          pen.Color:= clgray;
          moveto(x, 0);
          lineto(x, 201);
          moveto(0, y);
          lineto(201, y);
        end;
      x:= x + 5;
      y:= y + 5;
    end;
  DrawWalls;
end;

procedure DrawSnake;
var
  i: integer;
begin
  FillField(Snake[0].X, Snake[0].Y, clred);
  for i:= 1 to SnakeLength do
    FillField(Snake[i].X, Snake[i].Y, clgreen);
end;

procedure DrawFood;
begin
  FillField(foodpos.x, foodpos.y, clblue);
end;

procedure MakeFood;
begin
  FoodPos.X:= random(37) + 2;
  FoodPos.Y:= random(37) + 2;
  map[FoodPos.x, FoodPos.y]:= food;
end;

procedure StartGame;
var
  i, x, y: integer;
begin
  Game.SnakeTimer.Enabled:= true;
    Points:= 0;
  for x:= 1 to 40 do
    for y:= 1 to 40 do
      map[x, y]:= 0;
  direction:= random(4)+1;
  snakelength:= 8;
  setlength(snake, snakelength + 1);
  snake[0].x:= random(20) + 10;
  snake[0].y:= random(20) + 10;
  for i:= 1 to snakelength do
    snake[i].Y:= snake[0].Y + i;
  MakeFood;  
  DrawMap;
  DrawFood;
  DrawSnake;
end;

procedure GameOver;
begin
  Game.SnakeTimer.Enabled:= false;
  showmessage('Game Over!');
  StartGame;
end;    

procedure TGame.FormCreate(Sender: TObject);
begin
  randomize;
  Game.DoubleBuffered:= true;
  StartGame;
end;

procedure TGame.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  if (key = vk_up) and (Direction <> sDown) then
    Direction:= sUp;
  if (key = vk_down) and (Direction <> sUp) then
    Direction:= sDown;
  if (key = vk_left) and (Direction <> sRight) then
    Direction:= sleft;
  if (key = vk_right) and (Direction <> sLeft) then
    Direction:= sright;
end;

procedure TGame.SnakeTimerTimer(Sender: TObject);
var
  i, c: integer;
begin
  for i:= snakelength downto 1 do
    begin
      snake[i].y:= snake[i-1].Y;
      snake[i].X:= snake[i-1].X;
    end;
  if Direction = sUp then
    snake[0].Y:= snake[0].Y - 1;
  if Direction = sDown then
    snake[0].Y:= snake[0].Y + 1;
  if Direction = sLeft then
    snake[0].X:= snake[0].X - 1;
  if Direction = sRight then
    snake[0].X:= snake[0].X + 1;
  if Map[snake[0].X, snake[0].y] = wall then
    begin
      GameOver;
      exit;
    end;
  if Map[snake[0].X, snake[0].Y] = food then
    begin
      Points:= points + 50;
      PointDisplay.Caption:= 'Points: ' + inttostr(points);
      snakelength:= snakelength + 1;
      setlength(snake, snakelength + 1);
      map[FoodPos.x, FoodPos.y]:= 0;
      MakeFood;
    end;
  for c:= 1 to snakelength do
    if (snake[0].X = snake[c].X) and (snake[0].Y = snake[c].Y) then
      begin
        GameOver;
        exit;
      end;  
  DrawMap;
  DrawFood;
  DrawSnake;
end;

end.

nur bekomme ich ab und zu ein game over, obwohl ich mich noch nicht selbst gebissen habe, ein feld dazwischen ist noch frei ?!

ach ja: und um den fehler zu beheben, das beim neustart die alte schlange noch so fehlerhaft zu sehen ist, muss ein stück bei startgame durch das hier ersetzt werden:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
  for i:= 1 to snakelength do
    begin
      snake[i].Y:= snake[0].Y;
      snake[i].X:= snake[0].X;
    end;


aber das manchmal einfach so game over kommt, finde ich komisch ....
Larus
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 431



BeitragVerfasst: Sa 05.03.05 10:47 
Folgende Bugs gefunden:
1.Futter landet in Wand
2.Unbegründeter GAMEOVER bei restart (selten)
3.Bei restart sind noch Schlangenreste im Spielfeld verteilt (jedes mal)
4.Futter wird unter der Schlange erstellt
5.Start: links... oben und sofort rechts = Tot weil die schlange sich selbst frisst (in sich hinein...)

zu 1. gelöst
zu 2. Vermute das der Kopf der Schlange sich auf einem Teil der kaputten Schlange befindet...
zu 3. scheint gelöst werd ich aber noch testen
zu 4. man muss versuchen das das Futter nicht da produziert werden kann wo sich im Moment die Schlange befindet
auch hier werd ich mich mal ransetzen
zu 5. Man muss irgentwie festlegen das man während der 100ms nicht zwei richtungstasten drücken kann sonst wie
gesagt... Auch hier bin ich bereits an einem Lösungsansatz
F34r0fTh3D4rk Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 5284
Erhaltene Danke: 27

Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
BeitragVerfasst: Sa 05.03.05 14:35 
ja 1-4 sind gelöst 5 habe ich auch gerade die ursache gefunden, aber das futter kann ruhig unter der schlange laden, das ist nicht alzu wild, hier mal mein neuer code, mit highscore

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197:
198:
199:
200:
201:
202:
203:
204:
205:
206:
207:
208:
209:
210:
211:
212:
213:
214:
215:
216:
217:
218:
219:
220:
221:
222:
223:
224:
225:
226:
227:
228:
229:
230:
231:
232:
233:
234:
235:
unit UMain;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls, Menus, inifiles;

type
  TGame = class(TForm)
    Field: TImage;
    SnakeTimer: TTimer;
    PointDisplay: TLabel;
    HSDisplay: TLabel;
    procedure FormCreate(Sender: TObject);
    procedure FormKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure SnakeTimerTimer(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

const
  sup = 1;
  sdown = 2;
  sleft = 3;
  sright = 4;
  Wall = 5;
  Food = 6;

var
  Game: TGame;
  map: array[1..40of array[1..40of integer;
  snake: array of TPoint;
  FoodPos: Tpoint;
  snakelength, Direction, Points, HighScore: integer;
  HSFile: TIniFile;

implementation

{$R *.dfm}

procedure FillField(x,y: integer; color: Tcolor);
begin
  with game.field.canvas do
    begin
      pen.color:= color;
      brush.color:= color;
      rectangle(x*5-4, y*5-4, x*5, y*5);
   end;   
end;

procedure DrawWalls;
var
  x, y, i: integer;
begin
  for i:= 1 to 40 do
    begin
      x:= 1;
      y:= i;
      FillField(x, y, clblack);
      Map[x, y]:=  wall;
      x:= 40;
      FillField(x, y, clblack);
      Map[x, y]:=  wall;
      x:= i;
      y:= 1;
      FillField(x, y, clblack);
      Map[x, y]:=  wall;
      y:= 40;
      FillField(x, y, clblack);
      Map[x, y]:=  wall;
    end;
end;

procedure DrawMap;
var
  x, y, i: integer;
begin
  with game.Field.Canvas do
    begin
      brush.color:= clwhite;
      rectangle(00201201);
    end;  
  x:= 0;
  y:= 0;
  for i:= 0 to 40 do
    begin
      with game.field.canvas do
        begin
          pen.Color:= clgray;
          moveto(x, 0);
          lineto(x, 201);
          moveto(0, y);
          lineto(201, y);
        end;
      x:= x + 5;
      y:= y + 5;
    end;
  DrawWalls;
end;

procedure DrawSnake;
var
  i: integer;
begin
  FillField(Snake[0].X, Snake[0].Y, clred);
  for i:= 1 to SnakeLength do
    FillField(Snake[i].X, Snake[i].Y, clgreen);
end;

procedure DrawFood;
begin
  FillField(foodpos.x, foodpos.y, clblue);
end;

procedure MakeFood;
begin
  FoodPos.X:= random(37) + 2;
  FoodPos.Y:= random(37) + 2;
  map[FoodPos.x, FoodPos.y]:= food;
end;

procedure StartGame;
var
  i, x, y: integer;
begin
  try
    HSFile:=TIniFile.Create('Highscore.ini');
    HighScore:= HSFile.Readinteger('Score''HighScore'0);
  finally
    HSFile.Free;
  end;
  Game.HSDisplay.caption:= 'HighScore: ' + inttostr(HighScore);
  Game.SnakeTimer.Enabled:= true;
  Points:= 0;
  Game.PointDisplay.Caption:= 'Points: ' + inttostr(points);
  for x:= 1 to 40 do
    for y:= 1 to 40 do
      map[x, y]:= 0;
  direction:= random(4)+1;
  snakelength:= 8;
  setlength(snake, snakelength + 1);
  snake[0].x:= random(20) + 10;
  snake[0].y:= random(20) + 10;
  for i:= 1 to snakelength do
    begin
      snake[i].Y:= snake[0].Y;
      snake[i].X:= snake[0].X;
    end;  
  MakeFood;  
  DrawMap;
  DrawFood;
  DrawSnake;
end;

procedure GameOver;
begin
  Game.SnakeTimer.Enabled:= false;
  try
    HSFile:=TIniFile.Create('Highscore.ini');
    if HSFile.Readinteger('Score''HighScore'0) < Points
      then HSFile.Writeinteger('Score''Highscore', Points);
  finally
    HSFile.Free;
  end;
  showmessage('Game Over!');
  StartGame;
end;    

procedure TGame.FormCreate(Sender: TObject);
begin
  randomize;
  Game.DoubleBuffered:= true;
  StartGame;
end;

procedure TGame.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  if (key = vk_up) and (Direction <> sDown) then
    Direction:= sUp;
  if (key = vk_down) and (Direction <> sUp) then
    Direction:= sDown;
  if (key = vk_left) and (Direction <> sRight) then
    Direction:= sleft;
  if (key = vk_right) and (Direction <> sLeft) then
    Direction:= sright;
end;

procedure TGame.SnakeTimerTimer(Sender: TObject);
var
  i, c: integer;
begin
  for i:= snakelength downto 1 do
    begin
      snake[i].y:= snake[i-1].Y;
      snake[i].X:= snake[i-1].X;
    end;
  if Direction = sUp then
    snake[0].Y:= snake[0].Y - 1;
  if Direction = sDown then
    snake[0].Y:= snake[0].Y + 1;
  if Direction = sLeft then
    snake[0].X:= snake[0].X - 1;
  if Direction = sRight then
    snake[0].X:= snake[0].X + 1;
  if Map[snake[0].X, snake[0].y] = wall then
    begin
      GameOver;
      exit;
    end;
  if Map[snake[0].X, snake[0].Y] = food then
    begin
      Points:= points + 50;
      PointDisplay.Caption:= 'Points: ' + inttostr(points);
      snakelength:= snakelength + 1;
      setlength(snake, snakelength + 1);
      map[FoodPos.x, FoodPos.y]:= 0;
      MakeFood;
    end;
  for c:= 1 to snakelength do
    if (snake[0].X = snake[c].X) and (snake[0].Y = snake[c].Y) then
      begin
        GameOver;
        exit;
      end;  
  DrawMap;
  DrawFood;
  DrawSnake;
end;

end.


Problem 5 habe ich mit einer Art Relais gelöst:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
procedure TGame.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  if (key = vk_up) and (Direction <> sDown) then
    KeyDirection:= sUp;
  if (key = vk_down) and (Direction <> sUp) then
    KeyDirection:= sDown;
  if (key = vk_left) and (Direction <> sRight) then
    KeyDirection:= sleft;
  if (key = vk_right) and (Direction <> sLeft) then
    KeyDirection:= sright;
end;

procedure TGame.SnakeTimerTimer(Sender: TObject);
var
  i, c: integer;
begin
  if KeyDirection <> 0 then
    Direction:= KeyDirection;
...
Larus
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 431



BeitragVerfasst: So 06.03.05 17:40 
Wenn ich den Code so lese hasse mich schon auf einen gedanken gebracht.. weil bei deinem der Bug noch funzen würde (wenn mich nicht alles täuscht nach x Stunden Lan durchzoggen und *verzweifeltaugenoffenhalt* Dabei noch saufen.... Wieso gripiert man eigentlich manchmal noch beim Sart und das absolut unbegründet?
F34r0fTh3D4rk Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 5284
Erhaltene Danke: 27

Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
BeitragVerfasst: So 06.03.05 17:43 
tut man doch net oder, hier mal die exe:

leider kein direct link möglich :(:

teamelectronix.te.fu...mp;um=show&fid=1
Larus
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 431



BeitragVerfasst: So 06.03.05 18:20 
Was meintest du mit "tut man doch net oder, ..."???

Achso ich geb zu ich hab mich vertan nur ist jetzt die Steuerung leicht verbugt!


Zuletzt bearbeitet von Larus am So 06.03.05 18:21, insgesamt 1-mal bearbeitet
F34r0fTh3D4rk Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 5284
Erhaltene Danke: 27

Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
BeitragVerfasst: So 06.03.05 18:21 
Larus hat folgendes geschrieben:
Wieso gripiert man eigentlich manchmal noch beim Sart und das absolut unbegründet?


der fehler tritt nicht mehr auf, lade es dir runter und schau ^^
Larus
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 431



BeitragVerfasst: So 06.03.05 21:00 
Ich hab gedacht.. wenn wir schon Snake proggen, dann aber richtig... es fehlte noch das Bonusteil... in diesem Fall Lila

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197:
198:
199:
200:
201:
202:
203:
204:
205:
206:
207:
208:
209:
210:
211:
212:
213:
214:
215:
216:
217:
218:
219:
220:
221:
222:
223:
224:
225:
226:
227:
228:
229:
230:
231:
232:
233:
234:
235:
236:
237:
238:
239:
240:
241:
242:
243:
244:
245:
246:
247:
248:
249:
250:
251:
252:
253:
254:
255:
256:
257:
258:
259:
260:
261:
262:
263:
264:
265:
266:
267:
268:
269:
270:
271:
272:
273:
274:
275:
unit UMain;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls, Menus, inifiles;

type
  TGame = class(TForm)
    Field: TImage;
    SnakeTimer: TTimer;
    PointDisplay: TLabel;
    HSDisplay: TLabel;
    procedure FormCreate(Sender: TObject);
    procedure FormKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure SnakeTimerTimer(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

const
  sup = 1;
  sdown = 2;
  sleft = 3;
  sright = 4;
  Wall = 5;
  Food = 6;
  Bonus = 7;

var
  Game: TGame;
  map: array[1..40of array[1..40of integer;
  snake: array of TPoint;
  FoodPos, BonusPos: Tpoint;
  snakelength, KeyDirection, Direction, Points, HighScore, BonusStay: integer;
  HSFile: TIniFile;

implementation

{$R *.dfm}

procedure FillField(x,y: integer; color: Tcolor);
begin
  with game.field.canvas do
    begin
      pen.color:= color;
      brush.color:= color;
      rectangle(x*5-4, y*5-4, x*5, y*5);
   end;   
end;

procedure DrawWalls;
var
  x, y, i: integer;
begin
  for i:= 1 to 40 do
    begin
      x:= 1;
      y:= i;
      FillField(x, y, clblack);
      Map[x, y]:=  wall;
      x:= 40;
      FillField(x, y, clblack);
      Map[x, y]:=  wall;
      x:= i;
      y:= 1;
      FillField(x, y, clblack);
      Map[x, y]:=  wall;
      y:= 40;
      FillField(x, y, clblack);
      Map[x, y]:=  wall;
    end;
end;

procedure DrawMap;
var
  x, y, i: integer;
begin
  with game.Field.Canvas do
    begin
      brush.color:= clwhite;
      rectangle(00201201);
    end;  
  x:= 0;
  y:= 0;
  for i:= 0 to 40 do
    begin
      with game.field.canvas do
        begin
          pen.Color:= clgray;
          moveto(x, 0);
          lineto(x, 201);
          moveto(0, y);
          lineto(201, y);
        end;
      x:= x + 5;
      y:= y + 5;
    end;
  DrawWalls;
end;

procedure DrawSnake;
var
  i: integer;
begin
  FillField(Snake[0].X, Snake[0].Y, clred);
  for i:= 1 to SnakeLength do
    FillField(Snake[i].X, Snake[i].Y, clgreen);
end;

procedure DrawFood;
begin
  FillField(foodpos.x, foodpos.y, clblue);
end;

procedure MakeFood;
begin
  FoodPos.X:= random(37) + 2;
  FoodPos.Y:= random(37) + 2;
  map[FoodPos.x, FoodPos.y]:= food;
end;

procedure DrawBonus;
begin
  If (BonusStay>=5And (BonusStay<35Then
    FillField(BonusPos.x, BonusPos.y, clPurple)
  Else If BonusStay=35 Then
    BonusStay:=0;
end;

procedure MakeBonus;
begin
  BonusPos.X:= random(37) + 2;
  BonusPos.Y:= random(37) + 2;
  While map[BonusPos.X, BonusPos.Y]= food Do
  Begin
    BonusPos.X:= random(37) + 2;
    BonusPos.Y:= random(37) + 2;
  End;
  map[BonusPos.x, BonusPos.y]:= bonus;
end;

procedure StartGame;
var
  i, x, y: integer;
begin
  try
    HSFile:=TIniFile.Create('Highscore.ini');
    HighScore:= HSFile.Readinteger('Score''HighScore'0);
  finally
    HSFile.Free;
  end;
  Game.HSDisplay.caption:= 'HighScore: ' + inttostr(HighScore);
  Game.SnakeTimer.Enabled:= true;
  Points:= 0;
  Game.PointDisplay.Caption:= 'Points: ' + inttostr(points);
  for x:= 1 to 40 do
    for y:= 1 to 40 do
      map[x, y]:= 0;
  direction:= random(4)+1;
  snakelength:= 8;
  setlength(snake, snakelength + 1);
  snake[0].x:= random(20) + 10;
  snake[0].y:= random(20) + 10;
  for i:= 1 to snakelength do
    begin
      snake[i].Y:= snake[0].Y;
      snake[i].X:= snake[0].X;
    end;  
  BonusStay:=0;
  MakeFood;
  MakeBOnus;
  DrawMap;
  DrawFood;
  DrawSnake;
end;

procedure GameOver;
begin
  Game.SnakeTimer.Enabled:= false;
  try
    HSFile:=TIniFile.Create('Highscore.ini');
    if HSFile.Readinteger('Score''HighScore'0) < Points
      then HSFile.Writeinteger('Score''Highscore', Points);
  finally
    HSFile.Free;
  end;
  showmessage('Game Over!');
  StartGame;
end;    

procedure TGame.FormCreate(Sender: TObject);
begin
  randomize;
  Game.DoubleBuffered:= true;
  StartGame;
end;

procedure TGame.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  if (key = vk_up) and (Direction <> sDown) then
    KeyDirection:= sUp;
  if (key = vk_down) and (Direction <> sUp) then
    KeyDirection:= sDown;
  if (key = vk_left) and (Direction <> sRight) then
    KeyDirection:= sleft;
  if (key = vk_right) and (Direction <> sLeft) then
    KeyDirection:= sright;
end;

procedure TGame.SnakeTimerTimer(Sender: TObject);
var
  i, c: integer;
begin
  if KeyDirection <> 0 then
    Direction:= KeyDirection;
  for i:= snakelength downto 1 do
    begin
      snake[i].y:= snake[i-1].Y;
      snake[i].X:= snake[i-1].X;
    end;
  if Direction = sUp then
    snake[0].Y:= snake[0].Y - 1;
  if Direction = sDown then
    snake[0].Y:= snake[0].Y + 1;
  if Direction = sLeft then
    snake[0].X:= snake[0].X - 1;
  if Direction = sRight then
    snake[0].X:= snake[0].X + 1;
  If BonusStay>=5 Then
    BonusStay:=BonusStay+1;
  if Map[snake[0].X, snake[0].y] = wall then
    begin
      GameOver;
      exit;
    end;
  if Map[snake[0].X, snake[0].Y] = food then
    begin
      Points:= points + 50;
      PointDisplay.Caption:= 'Points: ' + inttostr(points);
      snakelength:= snakelength + 1;
      setlength(snake, snakelength + 1);
      map[FoodPos.x, FoodPos.y]:= 0;
      If BonusStay<5 Then
        BonusStay:=BonusStay+1;
      MakeFood;
    end;
  if Map[snake[0].X, snake[0].Y] = bonus then
    begin
      Points:= points + 250;
      PointDisplay.Caption:= 'Points: ' + inttostr(points);
      snakelength:= snakelength + 5;
      setlength(snake, snakelength + 5);
      map[BonusPos.x, BonusPos.y]:= 0;
      MakeBonus;
      BonusStay:=0;
    end;
  for c:= 1 to snakelength do
    if (snake[0].X = snake[c].X) and (snake[0].Y = snake[c].Y) then
      begin
        GameOver;
        exit;
      end;
  DrawMap;
  DrawBonus;
  DrawFood;
  DrawSnake;
end;

end.


Wenn man fünf Futterteile gefressen hat taucht das Bonusteil für 3 Sekunden auf wenn der Timer auf 100ms Intervall steht.
F34r0fTh3D4rk Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 5284
Erhaltene Danke: 27

Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
BeitragVerfasst: So 06.03.05 21:04 
schonmal geil, müsste etwas länger da sein, weil die map größer ist als beim original und es sollte nicht gleichzeitig mit dem normalen kommen, vielleicht, pro 5 normale 1 extra aber dann eine beliebe zeit danach so zwischen 2 und 5 sekunden
Larus
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 431



BeitragVerfasst: So 06.03.05 21:08 
Das mit der beliebig langen Zeit kann ich ,achen nur sag ich ma so... 3 Sekunden reichen im Normalfall voll aus.. soll ja auch net zu schwierig sein oda ;)
F34r0fTh3D4rk Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 5284
Erhaltene Danke: 27

Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
BeitragVerfasst: Mo 07.03.05 16:24 
nein ich meine, es soll nach einer zufälligen zeit kommen und dann so 5 sekunden liegen bleiben.

Ich habe hier aber die Antwort auf ein weiteres Problem, das essen kann nun nicht mehr unter der schlange entstehen:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
procedure MakeFood;
var
  i: integer;
begin
  FoodPos.X:= random(37) + 2;
  FoodPos.Y:= random(37) + 2;
  for i:= 0 to snakelength do
    if (Snake[i].X = FoodPos.X) and (Snake[i].Y = FoodPos.Y) then
      MakeFood else
        map[FoodPos.x, FoodPos.y]:= food;
end;
Larus
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 431



BeitragVerfasst: Mo 07.03.05 19:33 
UNd es geht weiter.... ;) Im Moment proggen wir gerade nen Leveledito.. schätz ma die erste Editor Beta stell ich gleich rein mit der passenden Snake version :lol:

Aber bevor ich das mache noch mal die aktuelle Snake version!
Einloggen, um Attachments anzusehen!