Entwickler-Ecke

Algorithmen, Optimierung und Assembler - Raumschiffe bewegen sich nicht per zufall?


mimi - So 27.03.05 23:22
Titel: Raumschiffe bewegen sich nicht per zufall?
Hallo,
ich habe eine funktion geschriebn die die richtung der raumschiffe verändern sobalt eine collision kommt, wird die richtung geänderd. Das Problem ist:
Die Raumschiffe fliegen immer die gleiche bahn, sie fliegen immer von Oben nach unten Rechts und von Unten Rchts nach obenLings und das in einer endloschleife warum ???
hier ist der code:

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:
// Hier die Const die ich verwende:
const
  LingsOben   = 0;
  RechtsUnten = 1;
  LingsUnten  = 2;
  RechtsOben  = 3;

// Diese Funktion sucht sich zufällig eine zhal aus der angeben liste aus
function RandomZahl(Zahlen:array of Integer; zu:Integer):Integer;
var
  r,m:Integer;
begin
  r:=-1;
  Randomize;
  M:=High(Zahlen)+1;

  repeat
    r:=random(m);
  until (r <> zu);
  result:=Zahlen[r];
end;

// Diese funktion soll die raumschiffe bewegen
procedure TShipGame.Move_Ship(index:Integer);
begin
  with Ships[index] do begin
    if r = 0 then begin // lings Oben
      if (x-1 > 0and (y-1 > 0then begin
        x:=x-1;
        y:=y-1;
      end
      else begin
        if s = False then begin
          s:=True;
          r:=RandomZahl([RechtsOben,RechtsUnten],0);
        end;
      end;
    end
    else begin
      if r = 2 then begin // lings Unten
        if (x-1 > 0and (y+1 <=280then begin
          x:=x-1;
          y:=y+1;
        end
        else begin
          if s = False then begin
            s:=True;
            r:=RandomZahl([RechtsOben,RechtsUnten],2);
          end;
        end;
      end
      else begin
        if r = 1 then begin // rechts  Unten
          if (x+1 <= 640-Ships[index].w) and (y+1 <=280then begin
            x:=x+1;
            y:=y+1;
          end
          else begin
            if s = False then begin
              s:=True;
              r:=RandomZahl([LingsOben,LingsUnten],1);
            end;
          end;
        end
        else begin
          if r = 3 then begin // Rechts Oben
            if (x-1 > 0and (y-1 > 0then begin
              x:=x+1;
              y:=y-1;
            end
            else begin
              if s = False then begin
                s:=True;
                r:=RandomZahl([LingsUnten,LingsOben],3);
              end;
            end;
          end;
        end;
      end;
    end;
    s:=False;
  end;
end;


Moderiert von user profile iconGausi: Code- durch Delphi-Tags ersetzt.


mimi - Mo 28.03.05 10:57

habe ich jetzt hinbekommen, doch leider hauen sie auf der rechten seit ab und zu immer ab(also so das man sie nicht mehr sehen kann):

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:
function RandomZahl(Zahlen:array of Integer):Integer;
var
  r,m:Integer;
begin
  r:=-1;
  Randomize;
  M:=High(Zahlen)+1;
  r:=random(m);
  result:=Zahlen[r];
end;


procedure TShipGame.Move_Ship(index:Integer);
begin
  with Ships[index] do begin
    if r = 0 then begin // lings Oben
      if (x-1 > 0and (y-1 > 0and (GetCollision(x-1,y-1,w,h) = False ) then begin
        x:=x-1;
        y:=y-1;
      end
      else begin
        if s = False then begin
          s:=True;
          r:=RandomZahl([RechtsOben,RechtsUnten]);
        end;
      end;
    end
    else begin
      if r = 2 then begin // lings Unten
        if (x-1 > 0and (y+1 <=280and (GetCollision(x-1,y+1,w,h) = False) then begin
          x:=x-1;
          y:=y+1;
        end
        else begin
          if s = False then begin
            s:=True;
            r:=RandomZahl([RechtsOben,RechtsUnten]);
          end;
        end;
      end
      else begin
        if r = 1 then begin // rechts  Unten
          if (x+1 <= 640-Ships[index].w) and (y+1 <=280and (GetCollision((x+w)+1,y+1,w,h) = False) then begin
            x:=x+1;
            y:=y+1;
          end
          else begin
            if s = False then begin
              s:=True;
              r:=RandomZahl([LingsOben,LingsUnten]);
            end;
          end;
        end
        else begin
          if r = 3 then begin // Rechts Oben
            if (x-1 > 0and (y-1 > 0and (GetCollision((x+w)+1,y-1,w,h) = False)then begin
              x:=x+1;
              y:=y-1;
            end
            else begin
              if s = False then begin
                s:=True;
                r:=RandomZahl([LingsUnten,LingsOben]);
              end;
            end;
          end;
        end;
      end;
    end;
    s:=False;
  end;
end;


MathiasH - Mo 28.03.05 11:19

hallo mimi
ich hab jetzt leider nicht die Zeit deinen code durchzudenken(kommt mir irgendwie etwas kunfus vor :wink: ) , wie sollen sich die schiffe überhaupt bewegen, weil wenn ein schiff diagonal in ein eck fliegt, ist es klar, dass es im selben Wikel wieder herauskommen muss, andernfalls müsste es ja vom Spielfeld fliegen. Wird nämlich eine Richtung berechtnet, die nicht genau entgegen der anflugrichtung ist wird ja sofort eine neue berechnet. Das ganze widerholt sich nunmal bis das schiff wieder aus dem eck herauskommt.


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
var
vec, pos: TPoint;
begin
//initialisierung
//vec.x := 1;
//vec.y := 1;
//pos.x := 100;
//pos.y := -100;


// das ist die ganze Bewegung:
pos.x := pos.x + vec.x;
pos.y := pos.y + vec.y;

//Kollision x:
while (pos.x+vec.x>maxX) or (pos.x+vec.x<minX)do vec.x := Random(3)-1;

//Kollision y:
while (pos.y+vec.y>maxY) or (pos.y+vec.y<minY)do vec.y := Random(3)-1;


end;

Allerdings wird dieser code bei einem quadratischen Feld zu exakt dem selben Ergebnis führen. Bei einem Rechteckigen Feld sieht das allerdings anders aus, weil kollisionx und y da nicht (immer) zusammenfallen.
Alternativ könnte man auch die bewegungsvektoren und die positionen als float wert machen, dann bewegt sich die sache schöner.

naja ich hoffe ich konnte dir helfen.

Mathias Helinger


mimi - Mo 28.03.05 13:45

verstehe ich nicht ganz:
es gibt nur den rand und die Raumschiffe als collison punkte sonst nichts und ich dachte mir jetzt folgendes:
sobalt eine collision stand finden z.b. Rechts Unten dann kann er doch noch Lings Oben und Nach Lings Unten wobei wenn es zu weit Rechts Unten ist geht das mit den Lings nach Unten auch nicht aber das sollte meine funtkion doch merken ?
dafür ist sie doch ausgelegt: um bei den oben genatten beispiel zu bleiben: es wird ja aus zwei richtungen eine ausgesucht wenn es eine ist die nicht geht z.b. Lings Unten dann merkt das doch die entsprechne IF anweisung und sucht sich eine neue aus....
warscheinlich währe es besser die richtung zu ermittelen die Frei sind, dann währe das problem evlt. nicht mehr da....


MathiasH - Mo 28.03.05 15:24

ich glaub ich kapier net ganz, was das ding tun soll.

Prinzipell, wenn du eine Kollision feststellst kannst du ja ausrechnen, in welcher Richtung diese gewesen ist vom Schiff aus gesehen (x>y/-x>y usw.) dann musst du einfachdiese kombination aus x und y ausschließen beim zufallsgenerator


äh zwischenfrage, ist "Lings" absichtlich überall so geschrieben?


mimi - Mo 28.03.05 16:49

user profile iconMathiasH hat folgendes geschrieben:
äh zwischenfrage, ist "Lings" absichtlich überall so geschrieben?

ich habe meine schächen mit der Rechtschreibung, schreibe gerne was falsche ganze sätzt und so auch einzel Wörter...

ich habe jetzt aber eine idee wie ich es machen werde:
ich schriebe mir eine funktion die gibt mir zurück welche seiten frei ist denn die richtung ist in r geseichert was alle Raumschiffe haben. dann dürfte das problem behoben sein oder ?

Moderiert von user profile iconTino: Quote-Tags hinzugefügt.


MathiasH - Mo 28.03.05 16:50

dann sollte es klappen, ja


mimi - So 03.04.05 08:47

so habes es hinbekommen.
Und Rechts oben


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
     if r = 3 then begin // Rechts Oben
            if (x-1 > 0and (y-1 > 0then begin
              x:=x+1;
              y:=y-1;
            end
            else begin
              if s = False then begin
                s:=True;
                r:=RandomZahl([LingsUnten,LingsOben],3);
              end;
            end;
          end;

dieser code ist etwas falsch:

Delphi-Quelltext
1:
if (x-1 > 0and (y-1 > 0then begin                    

die erste bedingung ist komplet falsch:

Delphi-Quelltext
1:
if (x+1 <= 640and (y-1 > 0then begin                    


das kommt davon wenn man seinen eigenen code kopiert und was übersieht bei der anpasung *G*