Entwickler-Ecke

Algorithmen, Optimierung und Assembler - kollision im sprung


BusterX - Di 08.09.09 15:40
Titel: kollision im sprung
hallo zusammen,

ich lerne gerade in einer Vorausbildung das Programmieren in Delphi (benutzt wird Delphi 7).
Ich bekomme von meinem Ausbilder, welcher immer nur Freitags in der Firma ist, eine Aufgabe, die ich in einer Woche lösen soll.

Bisher habe ich auch immer alles gut hinbekommen, aber nun verzweifel ich gerade an einer Stelle, weswegen ich mich hier melde.


Nun zu meinem Problem:

Gefordert wird, das ich ein kleines Jump n Run - Game schreibe (like Super Mario) ohne eine externe Engine zu verwenden.
Bisher habe ich es geschaft, dass ein kleines Männchen per Pfeiltasten zu bewegen ist und auch springen kann.

Jetzt soll ich noch einen "Block" einbauen, wo das Männchen drauf-, drunter- und dranspringen kann.
Dran- und draufspringen klappt soweit ganz gut, nur das drunterspringen will nicht so wie ich es will.

Sobald das Männchen meinen Block berührt, wird die Grafik sofort auf den Boden gesetzt oder bei einem anderen versuch bleibt er an dem Block hängen und fällt erst dann wieder, wenn er (ohne den Block gesehen) die oberste Sprunggrenze erreicht hat und wieder auf höhe des Blockes gefallen ist.

Was muss ich tun, damit das Männchen sofort bei Berührung des Blockes in den Fall übergeht und nicht erst am Block "Klebt" ???


Mein Sprung beruht auf der Physikalischen Formel zur Berechnung eines Sprungs, damit dieser nicht Linear dargestellt wird.

Wenn meine Frage in irgendeiner Art unverständlich ist, dann muss ich es etwas anders formulieren.


Falls dieses das falsche Unterforum für diese Frage ist, bitte ich darum ihn zu verschieben.

MfG


platzwart - Di 08.09.09 16:51

Vlt könntest du das mit ein wenig Quelltext verdeutlichen?


BusterX - Di 08.09.09 17:07

Teil meines Quelltextes:


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:
procedure TForm1.GameTimerTimer(Sender: TObject);
var
  gameActive: Boolean;
  R: TRect;
begin

  GameTimer.Enabled := False;

  // Spiel-Schleife
  gameActive := True;

  Bildani := FormImages.stand1;

  While (gameActive) do
  begin
    // Hintergrund auf den Puffer kopieren
    buffer.Canvas.Draw(bg_breite, bg_hoehe, imgBackground.Picture.Graphic);

    // Kaktus an die richtige Stelle kopieren
    buffer.Canvas.Draw(k_breite, k_hoehe, bildani.Picture.Graphic);

    // Block an die richtige Stelle kopieren
    buffer.Canvas.Draw(bl_breite, bl_hoehe, FormImages.imgBlock.Picture.Graphic);

    // Puffer auf den Bildschirm zeichnen
    R.Left := 0;
    R.Top := 0;
    R.Bottom := buffer.Height;
    R.Right := buffer.Width;
    pb1.Canvas.CopyRect(R, buffer.Canvas, R);


    // Tastatur verarbeiten
    Application.ProcessMessages;
    if KeyPressed(27then
      gameActive := False;

    // 1. Springen?
    if (Keypressed(38)) or (t > 0then
    begin



      // 1.1 nach links springen?
      if KeyPressed(37then
      begin
        if Ani >= length(FormImages.img_sl) then
          Ani := 0;
        bildani := FormImages.img_sl[Ani];

        k_breite := k_breite - 2;

        if k_breite <= R.Left + 150 then
          k_breite := R.Left + 150;

        if k_breite = R.Left + 150 then
        begin
          bg_breite := bg_breite + 2;
          bl_breite := bl_breite + 2;
        end;
      end
      // 1.2 nach rechts springen?
      else if KeyPressed(39then
      begin
        if Ani >= length(FormImages.img_sr) then
          Ani := 0;
        bildani := FormImages.img_sr[Ani];

      k_breite := k_breite + 2;

      if k_breite >= R.Right - 150 then
        k_breite := R.Right - 150;

      if k_breite = R.Right - 150 then
      begin
        bg_breite := bg_breite - 2;
        bl_breite := bl_breite - 2;
      end;
      end
      // 1.3 im Stehen springen!
      else
      begin
        if Ani >= length(FormImages.img_spring) then
          Ani := 0;
        bildani := FormImages.img_spring[Ani];
      end;

        y := - 0.5 * g * t * t + v * t;
        k_hoehe := R.Bottom - bildani.Height - Round(y);
        t := t + 0.3;

      if k_hoehe > R.Bottom - bildani.Height then
      begin
        k_hoehe := R.Bottom  - bildani.Height;
        t := 0;
      end;
    end
    ...



Das ist jetzt nur der Auszug vom Sprung, wo wahrscheinlich die bestimmte Abbruchbedingung hineingeschrieben werden muss, wenn das Männchen von unten an den Block springt.


Ich hoffe das hilft etwas weiter.


BenBE - Mo 21.09.09 09:54

Durch einen Timer wiederholst Du eh bereits alles in einem bestimmten Interval. Da brauchst Du die Schleife in dem Sinne nicht.

Zu deinem Sprung-Problem: Rechne das Diskret und merk dir dabei Beschleunigung, Geschwindigkeit usw. und rechne dir daraus abgeleitet die nächste "Bildposition" aus. Wenn dabei die Kante deines Blocks verletzt\durchschritten wird, rechnest du die Bewegung auf diese Kante zurück und beendest die Bewegung.