Autor Beitrag
Borlox
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 191

Win XP
Delphi 6 Enterprise
BeitragVerfasst: Sa 13.12.03 21:25 
Hi Leute,

ich möchte ein 2D-Rollenspiel programmieren (machen hier ja auch ziemlich viele,stimmts?), aber ich weiß einfach nicht wie ich es am beste mit den Leveln mache, wie ich sie in einer Datei speichere! Ich weiß zwar wie ich eine Datei erstelle und so, aber ich weiß nicht wie ich es anstellen soll, dass dort ja z.B. auch bestimmte If-Befehle drinstehen müssten! Außerdem würde ich es gerne irgendwie schaffen, dass man als User nicht merkt, dass es viele kleine Level sind, sondern, dass man einfach durch die Welt läuft und die Level sozusagen schon vorgeladen werden! Habt ihr ein paar Anregungen für mich? Bestimmt, oder?

Man sollte so ein Level natürlich auch nicht so leicht verändern können!

Vielen Dank schon mal

Borlox
Gandalfus
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 129



BeitragVerfasst: Sa 13.12.03 23:50 
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:
type
 TFeld = class
    passierbar: boolean;
    top    : integer;
    left   : integer;
    width  : integer;
    height : integer;
    oberflaeche: integer;
  end;

var
  Spielfelder  : array [0..100,0..100] of TFeld;
  backpuffer: TBitmap;
  Landschaften: Array[1..15] of TBitmap;


function TF_main.RectinRect(rect1,rect2: Trect): boolean;
begin //für BB
  result := true;
  if (rect1.Left > rect2.BottomRight.x) then result:=false;
  if (rect1.top > rect2.BottomRight.y) then result:=false;
  if (rect2.Left > rect1.BottomRight.x) then result:=false;
  if (rect2.top > rect1.BottomRight.y) then result:=false;
end;


oncreate:
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:
  For i := 1 to 15 do
  begin
    Landschaften[i] := TBitmap.Create;
  end;
  Landschaften[1].LoadFromFile(ExtractFilePath(ParamStr(0)) + 'Bilder\Landschaftenunpassierbar\L1 beach.bmp');
  Landschaften[2].LoadFromFile(ExtractFilePath(ParamStr(0)) + 'Bilder\Landschaftenunpassierbar\L2 beach.bmp');
  Landschaften[3].LoadFromFile(ExtractFilePath(ParamStr(0)) + 'Bilder\Landschaftenunpassierbar\L3 beach.bmp');
  Landschaften[4].LoadFromFile(ExtractFilePath(ParamStr(0)) + 'Bilder\Landschaftenunpassierbar\L4 beach.bmp');
  Landschaften[5].LoadFromFile(ExtractFilePath(ParamStr(0)) + 'Bilder\Landschaftenunpassierbar\L5 beach.bmp');
  Landschaften[6].LoadFromFile(ExtractFilePath(ParamStr(0)) + 'Bilder\Landschaftenunpassierbar\L6 beach.bmp');
  Landschaften[7].LoadFromFile(ExtractFilePath(ParamStr(0)) + 'Bilder\Landschaftenunpassierbar\L7 beach.bmp');
  Landschaften[8].LoadFromFile(ExtractFilePath(ParamStr(0)) + 'Bilder\Landschaftenunpassierbar\L8 beach.bmp');
  Landschaften[9].LoadFromFile(ExtractFilePath(ParamStr(0)) + 'Bilder\Landschaftenunpassierbar\L9 beach.bmp');
  Landschaften[10].LoadFromFile(ExtractFilePath(ParamStr(0)) + 'Bilder\Landschaftenunpassierbar\L10 beach.bmp');
  Landschaften[11].LoadFromFile(ExtractFilePath(ParamStr(0)) + 'Bilder\Landschaftenunpassierbar\L11 beach.bmp');
  Landschaften[12].LoadFromFile(ExtractFilePath(ParamStr(0)) + 'Bilder\Landschaftenunpassierbar\L12 beach.bmp');
  Landschaften[13].LoadFromFile(ExtractFilePath(ParamStr(0)) + 'Bilder\Landschaftenunpassierbar\L13 Felsen.bmp');
  Landschaften[14].LoadFromFile(ExtractFilePath(ParamStr(0)) + 'Bilder\Landschaftenpassierbar\L1 gras.bmp');
  Landschaften[15].LoadFromFile(ExtractFilePath(ParamStr(0)) + 'Bilder\Landschaftenpassierbar\L2 wasser.bmp');


Application.OnIdle := F_main.GameLoop;
  for x := 0 to heigh() do
  begin
    for y := 0 to heigh() do
    begin
      Spielfelder[x,y] := TFeld.create;
      Spielfelder[x,y].width := 25;
      Spielfelder[x,y].height := 25;
      Spielfelder[x,y].top := y;
      Spielfelder[x,y].left := x;
      Spielfelder[x,y].passierbar := true;
      Spielfelder[x,y].oberflaeche := 15;
    end;
  end;

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:
//onidel = Ereigniss das ausgelöst wird wenn das programm gerade nichts macht
//also ein guter zeitpunkt um zu zeichne
Procedure TF_main.GameLoop(Sender: TObject; var Done: Boolean); 
Begin
  Done := False;

  for x := 0 to heigh(Spielfelder) do
  begin
    IF ((Spielfelder[x,1].left) >= 0) and (Spielfelder[x,1].left <= (backpuffer.Width div 25)) then {nur der sichtbare bereich wird getzeichnet}
    begin
      for y := 0 to heigh(Spielfelder) do
      begin
       IF (Spielfelder[x,y].top >= 0) and (Spielfelder[x,y].top <= (backpuffer.height div 25)-5) then {nur der sichtbare bereich wird getzeichnet}
       begin //25 ist die breite der Felder
            BitBlt(backpuffer.canvas.handle, karte.Spielfelder[x,y].left*25, Spielfelder[x,y].top*25, Spielfelder[x,y].width, Spielfelder[x,y].height, Landschaften[Spielfelder[x,y].oberflaeche].Canvas.Handle, 0, 0, srccopy);
          
        end;
      end;
    end;
  end;

  BitBlt(F_main.canvas.handle, 0, 0, backpuffer.Width, backpuffer.Height, backpuffer.canvas.handle, 0, 0, srccopy);

End;


karte kannst du jetzt so erstellen:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
   karte.Spielfelder[10,10].passierbar := false;
  karte.Spielfelder[10,10].oberflaeche := 1;
  karte.Spielfelder[9,10].passierbar := false;
  karte.Spielfelder[9,10].oberflaeche := 2;
  karte.Spielfelder[9,9].passierbar := false;
  karte.Spielfelder[9,9].oberflaeche := 3;
  karte.Spielfelder[9,8].passierbar := false;
  karte.Spielfelder[9,8].oberflaeche := 4;
  karte.Spielfelder[10,8].passierbar := false;
  karte.Spielfelder[10,8].oberflaeche := 5;
  karte.Spielfelder[10,8].passierbar := false;
  karte.Spielfelder[11,8].oberflaeche := 6;
  karte.Spielfelder[11,8].passierbar := false;
  karte.Spielfelder[11,9].oberflaeche := 7;
  karte.Spielfelder[11,9].passierbar := false;
  karte.Spielfelder[11,10].oberflaeche := 8; 
  ......


Speichern und laden von Karten geht jetzt auch leicht über typerisierte Dateine[/delphi]

_________________
Wennn man feststellt, dass es drei Moeglichkeiten gibt, die einen Vorgang schiefgehen lassen koennen und man diese ausschaltet, entstehen automatisch drei neue Moeglichkeiten.
Borlox Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 191

Win XP
Delphi 6 Enterprise
BeitragVerfasst: Do 18.12.03 23:26 
Titel: Gut
Das is ja schon mal nicht schlecht, aber wie mache ich es denn, das ich die Level nicht mehr alle Laden brauch, wenn ich ins nächste gehe, sondern sozusagen ein flüssiger Übergang vorhanden ist! Das man nicht merkt, dass es viele Lavel sind? Hat da nicht jemand eine Idee??
MathiasH
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 699

WinXP, Win98SE, Debian, Win95
D5 Stand, D6 Prof
BeitragVerfasst: Fr 19.12.03 18:31 
die theorie ist einfach, du lädst, die level die der spieler in kürze brauchen könnte in einen backbuffer, der dann sehr schnell verfügbar ist.
In der Praxis ist das nicht immer ganz leicht, sollte aber bei nem 2d spiel schaffbar sein, man muss sich nur irgendwas überlgen, wie man flexibel an die Welt "anstückeln" kann, ohne dass du riesen datenmengen quer durch ein aray schieben muss, man könnte eine 3x3 matrix anlegen, von spielfeldbereichen(z.B. 3x3x100x100 Tiles). Kommt der spieler aus dem mittleren bereich heraus werden die Felder(3) die hinter ihm waren vor ihm angelegt und aus der entsprechneden map datei geladen.

MathiasH

_________________
"Viel von sich reden, kann auch ein Mittel sein, sich zu verbergen."
Friedrich Nietzsche
umpani
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 389



BeitragVerfasst: Fr 19.12.03 19:50 
Es gibt für deine Frage keine Ideallösung.

Du mußt dir zunöchst die Frage stellen, welche merkmale hat jedes Feld meiner Karte (sagen wir mal eine Kartenfläche von 30*30).

(Achtung Ähnlich zu Gandalfus Lösung, also nicht PLAGIAT rufen :wink: )

Jedes Feld müste z.B. EIne Landschaft haben, für jedes Feld müßte eingestellt sein, ob es begehbar ist oder nicht.



Du hast also eine Datenstruktur, Nenne wir sie mal TFeld

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
Type TDaten = Record
                           begehbar:boolean;
                           untergrund:byte;
                       end; 

        TFeld  = array[1..30;1..30] of TDaten;


Du mußt dir klar machen, wieviele änderungsmöglichkeiten ein Wert hast. Wenn du z.B. nur 10 verschiedene Untergründe hast, lohnt es sich nicht dür die Untergrundvariable den Typ INTEGER zu nehmen. Das wäre unnötige Speicherplatzverschwendung.

Jetzt gibt es aber auch Objekte (z.B. Monster), die nicht auf jedem Feld zu finden sind. Hier wäre also ein Array von 30*30 sinnlos, denn du mu0t nur die einzelnen Monster und die Gesamtanzahl der Monster speichern.

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
Type TDaten = Record
                           begehbar:boolean;
                           untergrund:byte;
                       end; 

         TMonster = Record
                              Position:tpoint;
                               monsterart:byte;
                           end;

        TFeld  = record
                        feld:array[1..30;1..30] of TDaten;  
                        monsterliste:array of TMonster;
                        max_monster:integer;
                     end;



usw. usw.....

Das mit dem Flüssigen Übergang verstehe ich nicht. Willst du eine Freie Fläche (Außenareal) aus mehreren Datenstrukturen (Leveln) gestalten? Wenn ja, dann rate ich Dir davon ab. Vergrößere lieber die Anzahl der Felder (z.B. 100*100) Das ist schon dehr groß. Wenn dein Charakter dann in ein Haus geht, weir einfach ein neues Level geladen. Wo ist das Problem?

Gruß Umpani

Moderiert von user profile iconPeter Lustig: Code- durch Delphi-Tags ersetzt

_________________
Lernen, ohne zu denken, ist eitel; denken, ohne zu lernen, ist gefährlich. Konfuzius
mimi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3458

Ubuntu, Win XP
Lazarus
BeitragVerfasst: Fr 19.12.03 20:25 
ich schreibe gerade in einem Team ein 3D spiel, wo wir uns auch diese ziel gesetzt haben: es soll niemals die Meldung:
Bitte warten, es wird geladen
auf den bildschrim erscheinen.

ich habe mir nun folgende möglichkten überleg:
Man setzt ins level, makierungen, sobalt sie ereich werden, werden andre level teile geladen und zwar in einem Thread(oder wie das geschrieben wird) und fertig !
dann mekr der user das laden nicht

_________________
MFG
Michael Springwald, "kann kein englisch...."
Raphael O.
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 1596


VS 2013
BeitragVerfasst: Fr 19.12.03 21:11 
das machen kommerzielle Spiele wie z.B. Gothic II auch so...
ist also realisierbar mit etwas aufwand...
mimi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3458

Ubuntu, Win XP
Lazarus
BeitragVerfasst: Sa 20.12.03 16:22 
naja, unseres soll os werden, aber das ist egal, ist dir jetzt ne idee eingefallen, wie du das machen kannst ?
achja:
wir willst du das mit der Musik/Grafik/Sound tuen , das ist noch viel schwere, da bin ich gerade am überlegen !

_________________
MFG
Michael Springwald, "kann kein englisch...."
MathiasH
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 699

WinXP, Win98SE, Debian, Win95
D5 Stand, D6 Prof
BeitragVerfasst: Sa 20.12.03 18:29 
sagte ich doch bereits(guckst du ein paar posts aufwärst), mach ne 3x3 matrix, die z.B. je 50x50 tiels groß sind. wenn der speiler das mittlere der 9 Felder verlässt werden die hinteren 3 Felder vorne wieder angestückeöt und geladen, hat den vorteil, dass der sichtbare teil des spiels nie geladen werden muss, das geschiet im vorraus mit den Felder, wo der speiler bald sein könnte

_________________
"Viel von sich reden, kann auch ein Mittel sein, sich zu verbergen."
Friedrich Nietzsche
mimi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3458

Ubuntu, Win XP
Lazarus
BeitragVerfasst: Sa 20.12.03 23:52 
Zitat:

wo der speiler bald sein könnte

das ist nicht gut, es muss heißen: sein muss, aber nicht könnte, sonst sieht du nacher ein vollkommen andres bild als vohrer und das soll ja nicht passieren !

_________________
MFG
Michael Springwald, "kann kein englisch...."
MathiasH
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 699

WinXP, Win98SE, Debian, Win95
D5 Stand, D6 Prof
BeitragVerfasst: So 21.12.03 00:01 
nö , diese dinger werden ja in 8 backbuffer geladen, betritt der spieler einen dieser 8 wird er zum frontbuffer, und die umliegenden werden neu geladen/umsortiert

_________________
"Viel von sich reden, kann auch ein Mittel sein, sich zu verbergen."
Friedrich Nietzsche
mimi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3458

Ubuntu, Win XP
Lazarus
BeitragVerfasst: So 21.12.03 11:36 
das braucht aber speicher wenn man alle möglichkeiten die der spiele hat abspeichert und die dann herrausholt die gerade gebraucht wird !

_________________
MFG
Michael Springwald, "kann kein englisch...."
MathiasH
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 699

WinXP, Win98SE, Debian, Win95
D5 Stand, D6 Prof
BeitragVerfasst: So 21.12.03 11:38 
so viel is das net, so ne map braucht in nem 2d spiel nur ein paar kb, glaub mir ich hab das selber mal so gebaut, das funzt wunderbar

_________________
"Viel von sich reden, kann auch ein Mittel sein, sich zu verbergen."
Friedrich Nietzsche
mimi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3458

Ubuntu, Win XP
Lazarus
BeitragVerfasst: So 21.12.03 15:50 
naja ich meinte den arbeitsspeicher.
bei mir sind es im bytebereich *G*

_________________
MFG
Michael Springwald, "kann kein englisch...."
Borlox Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 191

Win XP
Delphi 6 Enterprise
BeitragVerfasst: Mo 22.12.03 21:19 
Titel: Hilfe
Hi,

also, dass ganze ist schon mal ziemlich hilfreich!

Aber wie mache ich es denn am Besten, wenn in den Level auch noch so Sachen reinkommen sollen, wie, wenn der Spieler eine Figure anspricht und dann etwas anderes tut, usw. ! Wie mache ich das mit diesen Befehlen am Besten! Auch mit dem Speichern???

THX
Borlox
mimi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3458

Ubuntu, Win XP
Lazarus
BeitragVerfasst: Di 23.12.03 18:09 
nimmt dir z.b. erstmal eine TSTringlist und packe dort alle daten rein.
diese TStringlist gehst du beim zeichnen jedes ms durch und mals die objekte und wen die position verändert wird, sieht das so aus, als ob sie sich bewegen würden z.b. beim player

_________________
MFG
Michael Springwald, "kann kein englisch...."
Borlox Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 191

Win XP
Delphi 6 Enterprise
BeitragVerfasst: Do 25.12.03 21:37 
Titel: Beispiel
Hast du vielleicht irgendwo ein Beispiel???

Weiß nämlich trotzdem noch nicht so genau, was ich machen soll!

Wenn das so etwas in der Datei mit drin steht, wie:

if Player1.x==Player2.x then Begin showmessage(Hallo); Geh zu x=10; End.!

Wie kann man denn so etwas am einfachsten Implementieren????

Keine Ahnung wie ich damit anfangen müsste!

THX
Borlox
mimi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3458

Ubuntu, Win XP
Lazarus
BeitragVerfasst: Fr 26.12.03 00:58 
es hängt vom spiel ab was du schreiben möchtes.
wenn du z.b. ein Snake, Sokubahn, Pacman, so in der art jetzt schreiben möchtes, schau dir mal die level dateien aus meinen spielen an(z.b. das von Sokubhan)

es kommt wirklich auf dein spiel an. was du schreiben möchtes, dann könnte ich dir ein einfaches beispiel mit z.b. DelphiX schreiben.

damit meine ich: möchtes du ein game schreiben, wo alle objekte gleichgroß sind ?
wenn ja: dann nim ein 2D array und packt dort daten die du aus einer datei läfs rein. wenn nein, ist das ganze schon etwas aufwendiger aber auch noch einfach(habe ich aber noch nie so richtig gemacht)

_________________
MFG
Michael Springwald, "kann kein englisch...."
Borlox Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 191

Win XP
Delphi 6 Enterprise
BeitragVerfasst: Fr 26.12.03 16:16 
Titel: Rollenspiel
Es soll ein 2D Rollenspiel werden! Also man läuft mit Personden durch Welten und trifft in den Level auf Leute und muss Rätsel lösen!

Kennst du Graal?? www.graalonline.com
So in die Richtung sollte es gehen!

THX