Entwickler-Ecke

Multimedia / Grafik - Pacman Barrieren


Killuminati91 - So 07.06.09 21:46
Titel: Pacman Barrieren
Moin Leute,

ich hab nen kleines Pacman-Spiel gebastelt... Das ganze is so aufgebaut, dass das Programm eine Datei mit bestimmten Buchstaben läd. Diesen Buchstaben sind dann bestimmte Bilder zugeordnet, sodass sich daraus das Level bildet.

Dem Buchstaben "d" habe ich das Bild einer Barriere zugeordnet, wie kriege ich jetzt pacman dazu von der Barriere abzuprallen, anstatt über sie zu laufen und sie zu fressen?

Danke schonmal für die Antworten, ich weis nich genau was ihr benötigt aber ich hab mal den ganzen Quelltext eingefügt.

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:
unit Unit1;

interface

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

type
  TSpielfeld = array[0..19of string[20];

  TForm1 = class(TForm)
    ImageList1: TImageList;
    Timer1: TTimer;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    Label5: TLabel;
    Label6: TLabel;
    Label7: TLabel;
    Label8: TLabel;
    MainMenu1: TMainMenu;
    Start1: TMenuItem;
    Stop1: TMenuItem;
    Info1: TMenuItem;
    Ende1: TMenuItem;
    Neustart1: TMenuItem;
    procedure FormCreate(Sender: TObject);
    procedure FormKeyPress(Sender: TObject; var Key: Char);
    procedure Timer1Timer(Sender: TObject);
    procedure FormKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure FormPaint(Sender: TObject);
    procedure Start1Click(Sender: TObject);
    procedure Stop1Click(Sender: TObject);
    procedure Info1Click(Sender: TObject);
    procedure Ende1Click(Sender: TObject);
    procedure Neustart1Click(Sender: TObject);
  private
     Richtung:integer; //0-> rechts; 1-> links; 2-> runter; 3-> hoch
     Posx, PosY: integer; //aktuelle Position der Figur
     Animationsphase: integer;
     LevelNr: integer;
     SF: TSpielfeld;

      Punkte: integer;
      Zeit: real;
      Leben: integer;
      d: Textfile;
      s: string;

      procedure levelladen (Nr: integer);
      procedure start(Level: integer);
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.Levelladen(Nr: integer);
var
   Datei: Textfile;
   i: integer;

begin
   assignfile(Datei, 'level' + inttostr(Nr) + '.dum');
   reset(Datei);
   for i:=0 to 19 do
     readln(Datei, SF[i]);
   closefile(Datei);
end;

procedure TForm1.start(Level: integer);
begin
  PosX:=8;
  PosY:=8;
  Richtung:=0;
  Zeit:=60;
  Animationsphase:=0;
  levelladen(LevelNr);
  paint;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  LevelNR:=0;
  Start(LevelNr);
  
  Leben:=5;

  assignfile(d,'level0.dum');
  reset(d);
  readln(d,s);

  while not EoF(d) do
       begin readln(d,s);
      end;
    closefile(d);
end;

procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char);
begin
  if key = 's'
  then Timer1.enabled:=true;



  if key = 'p' then Timer1.enabled:=false;


  end;


procedure TForm1.Timer1Timer(Sender: TObject);
begin
   Zeit:= Zeit - timer1.interval/ 1000;
   label4.caption:= inttostr(round(Zeit)) + 's';
   if round(Zeit) < 1 then begin
     timer1.enabled := false;
     showmessage('Spiel Vorbei! Versuch es erneut.');
   end;
  //löschen
   {canvas.brush.color:=clBtnFace;
   canvas.Pen.color:=clBtnFace;
   canvas.Rectangle(PosX*32, PosY*32, PosX*32 + 32, PosY*32 + 32);  }

  Imagelist1.Draw(Form1.canvas, PosX * 32, PosY * 328) ;

  //neue Position berechnen
  case Richtung of   //stößt er gegen den rand, läuft er in die andre richtung
  0 : if posX < 19 then PosX:=PosX + 1
      else Richtung:=1;
  1 : if posX > 0 then posX:=posX - 1    //PosX:=PosX - 1;
      else Richtung:=0;
  2 : if posY < 19 then PosY:=PosY + 1  // PosY:=PosY + 1;
      else Richtung:=3;
  3 : if posY > 0 then posY:=posY - 1   //PosY:=PosY - 1;
      else Richtung:=2;
  end;

   if SF[PosY , PosX + 1] = 'p' then begin
    label8.caption:= inttostr(strtoint(Label8.caption) + 1);
    SF[PosY , PosX + 1] := 'X';
   end;

   if SF[PosY , PosX + 1] = 'P' then begin
      label5.caption:= inttostr(strtoint(label5.caption) - 1);
      SF[PosY , PosX + 1] := 'X';
      end;

   if label5.caption < '1' then begin
   timer1.enabled:=false;
   showmessage('Spiel Vorbei')
   end;


Animationsphase:= (Animationsphase + 1mod 2;  //bei mehr Bildern, dann mod und die Zahl von Bildern
 if Animationsphase = 0 then
    Imagelist1.Draw(Form1.canvas, PosX*32, PosY*32, Richtung * 2);
 if Animationsphase = 1 then
    Imagelist1.Draw(Form1.canvas, PosX*32, PosY*32, Richtung * 2 + 1);

{if Animationsphase = 2 then  Imagelist1.Draw(Form1.canvas, PosX*32, PosY*32, 2);
 if Animationsphase = 3 then  Imagelist1.Draw(Form1.canvas, PosX*32, PosY*32, 3);
 if Animationsphase = 4 then  Imagelist1.Draw(Form1.canvas, PosX*32, PosY*32, 4);
 if Animationsphase = 5 then  Imagelist1.Draw(Form1.canvas, PosX*32, PosY*32, 5);
 if Animationsphase = 6 then  Imagelist1.Draw(Form1.canvas, PosX*32, PosY*32, 6);
 if Animationsphase = 7 then  Imagelist1.Draw(Form1.canvas, PosX*32, PosY*32, 7); }


  end;

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
    case key of
     VK_LEFT : richtung:=1;
     VK_UP   : richtung:=3;
     VK_RIGHT: richtung:=0;
     VK_DOWN : richtung:=2;
    end;
end;

procedure TForm1.FormPaint(Sender: TObject);
var
i,j: integer;
begin
  for i:= 0 to 19 do
    for j:= 0 to 19 do

      case SF[i , j + 1of
       'X': Imagelist1.Draw(Form1.canvas, j * 32, i * 328);
       'P': Imagelist1.Draw(Form1.canvas, j * 32, i * 329);
       'p': Imagelist1.Draw(Form1.canvas, j * 32, i * 3210);
       'd': Imagelist1.Draw(Form1.canvas, j * 32, i * 3211);
end;
end;
procedure TForm1.Start1Click(Sender: TObject);
begin
   Timer1.enabled:=true;
end;

procedure TForm1.Stop1Click(Sender: TObject);
begin
  Timer1.enabled:=false;
end;

procedure TForm1.Info1Click(Sender: TObject);
begin
  openfile(application.handle, 'info.html');
end;

procedure TForm1.Ende1Click(Sender: TObject);
begin
  showmessage ('Schade...');
  close
end;

procedure TForm1.Neustart1Click(Sender: TObject);
begin
  timer1.enabled:=false;
  LevelNr:=0;
  Start(LevelNr);
end;

end.


ffgorcky - Mo 08.06.09 08:41

Also ich steige da leider noch nicht so ganz durch, aber normalerweise müsstest Du doch immer nur das in der momentanen Laufrichtung nächste Feld abfragen - und wenn es eine Barriere (also ='d') ist, dann soll er entsprechend reagieren - also umdrehen, oder wie meinst Du das mit dem abprallen?
Dann wäre es doch so in etwa zu lösen:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
case Richtung of   //stößt er gegen den Rand oder gegen eine Barrikade, dreht er um und läuft in die andere Richtung  
0 : if (posX < 19)and not(SF[PosY,PosX + 1]='X'then PosX:=PosX + 1   //PosX:=PosX + 1;   
     else Richtung:=1;  
1 : if (posX > 0)and not(SF[PosY,PosX - 1]='X'then posX:=posX - 1    //PosX:=PosX - 1;      
     else Richtung:=0;  
2 : if (posY < 19)and not(SF[PosY + 1,PosX]='X'then PosY:=PosY + 1  // PosY:=PosY + 1;      
     else Richtung:=3;  
3 : if (posY > 0)and not(SF[PosY - 1,PosX]='X'then posY:=posY - 1   //PosY:=PosY - 1;      
     else Richtung:=2;
end//of case

- oder habe ich Dein Problem gerade total falsch gedeutet?
(Ich hoffe nur, dass ich da jetzt keine Fehler reingebaut habe - ich kann das im Moment leider nicht überprüfen!)


oki - Mo 08.06.09 08:53

Prüfe, ob deine Sprites die Position deiner Barriere erreicht haben. Das kannst du mitttels PtinRect tun. Als Point übergibst du nacheinander die Eckpunkte deines Sprites und als Rect das Rect deiner Barriere.

Gruß oki


DeLphiNoobI^^ - Mo 08.06.09 20:37

huhu
in der Schule muss ich grade Pacman programmieren mittels Delphi..ist wohl logisch :D
ich hänge grade an der sache mit den Wänden und mit der KI fest.
Nun hab ich mir mal deinen Quelltext zu angeschaut und hab mal eins zwei drei kleine Fragen :)
1. hast du "procedure TForm1.Levelladen(Nr: integer);" selber geschrieben weil normalerweise steht doch da dann immer (Object: Sender) oder nicht?
2. für was steht die Abkürzung .dum?...ist mir nicht geläufig :/
3. "EoF" und "readln" sind zwei befehle die mir nichts sagen.

wegen Wänden und KI werd ich nochmal meinen lehrer fragen wenn ich was rauskrieg schreib ich es hier einfach rein :)


BenBE - Di 09.06.09 13:39

user profile iconDeLphiNoobI^^ hat folgendes geschrieben Zum zitierten Posting springen:
1. hast du "procedure TForm1.Levelladen(Nr: integer);" selber geschrieben weil normalerweise steht doch da dann immer (Object: Sender) oder nicht?

Ja, die ist selbstgeschrieben

user profile iconDeLphiNoobI^^ hat folgendes geschrieben Zum zitierten Posting springen:
3. "EoF" und "readln" sind zwei befehle die mir nichts sagen.

EoF = End Of File, ist ein Befehl zum Abfragen, ob man das Dateiende erreicht hat.
ReadLn = Read Line, ist ein Befehl zum Lesen einer Zeile aus einer Textdatei.