Autor Beitrag
Sledge_Hammer
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 32

Win 98 SE, Win XP
D7 Prof
BeitragVerfasst: Fr 01.08.03 15:19 
Moin
Vor einigen Tagen habe ich mein erstes Projekt in DelphiX gestartet (mit Delphi arbeite ich schon 3 Jahre). Dabei soll ein Spiel entstehen, das von den Grundzügen her Super-Mario aus Nintendo ähneln soll.
Nun habe ich als Hintergrund einen Himmel, den ich mittels DXDraw1.Surface.Fill() blau male. Dann habe ich als Landschaft eine Bitmap, die teilweise grün ist, damit also den Boden bildet auf dem der Spieler läuft, und teilweise "fuchsia" ist, was dann transparent ist, sodass man den blauen Himmel im Hintergrund hat.
Die Bitmap ist in einer DXImageList, die Spielerfigut ebenso. Beide steuere ich mit der DXSpriteEngine (Pixelcheck=True), sodass ich feststellen kann wenn sich die beiden Sprites berühren.

Und jetzt, nach der langen Erklärung, meine eigentliche Frage: Wie sorge ich dafür, dass...
1. wenn der Spieler hochspringt er nur so weit runterfällt, bis er den Boden berührt?
2. wenn der Spieler an eine diagonale Rampe kommt, die z.B. 45° Steigung hat, dass er die Rampe entlang hochgeht, aber z.B. wenn er an eine senkrechte Wand kommt oder eine sehr steile Rampe, dass er hier stehenbleibt?

Danke schonmal
Sledge Hammer
Marlno
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 75



BeitragVerfasst: Fr 01.08.03 23:09 
hmmm ich habe da jetzt nicht wirklich viel erfahrung aber logisch wäre doch wenigstens etwas und zwar wenn du mit (Pixelcheck=True) arbeitest kannst du die sachen doch so lösen oder??

für das springen (da das ein simples aufgebautes spiel ist müsste es nicht viel resourcen fressen) du machst einfach eine schleife mit (Pixelcheck=True) nach folgendem ablauf: du checkst jedesmal mit (Pixelcheck=True) und ist kein sprite im weg dann setzt du die figur um ein pixel nach unten solange bis (Pixelcheck=True) ist und du die schleife abbrichst

zu punkt zwei musst du n array benutzen und zwar folgender massen du checks nach dem dreicks prinzip... oder eher gesagt das viereck prinzip
also machst du (Pixelcheck=True) 4 mal dann vergleichst du an einer art tabelle...

beispiel....
ausblenden Quelltext
1:
2:
3:
   o              /~~~~~
  \|/           /            |
  / \           <________|

naja doofe idee sieht man nicht ganz egal...... wenn du also viermal (Pixelcheck=True) benutzt und so ein quadrat prüfst. kanns du doch feststellen wie steil es ist und wenn es nach deinem prinzip entspricht läuft er hoch oder wenns nach deinem prinzip entspricht läuft er hoch und wenns dann zu steil wird läuft er nicht weiter oder du schiebst ihn dann um einige pixel zurück so als runterrutsch effekt....


hier schau..
false = kein zusammenstoß
true = zusammenstoß mit sprite
___ ___
| 1 | | 2 |
---- -----
___ ___
| 3 | | 4 |
---- -----

feld 1 false
feld 2 false
feld 3 false
feld 4 true

dann darf er laufen aber wenn

feld 1 false
feld 2 true
feld 3 false
feld 4 true

dann nicht steigung zu hoch

ich hoffe man konnte es verstehen wenn nicht dann mach ich nen bild

viel glück

MFG Marlno

Moderiert von user profile iconTino: Überflüssige Absätze entfernt & Code-Tags hinzugefügt.
maximus
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 896

Win XP, Suse 8.1
Delphi 4/7/8 alles prof
BeitragVerfasst: Sa 02.08.03 11:02 
Also ich würde garnicht mit pixel-kollision arbeiten (die hat übrigens einen bug bei animierten sprites -> fix hier im forum) , sondern alles mathematisch lösen:

Am besten den untergrung rastern, dann bestimmte geraden/steigungen/gefälle/wände definieren und daten über deren steigung etc. aufnehmen.

Du weist dann ja in welcher raster-spalte er sich befindet und lässt seine position am boden immer mitlaufen, auch wenn er springt. Wenn er fällt dann lässt du ihn nur bis 'boden.y' fallen und gehst wieder in den runMode.

Raster:

|_|_|.:|-|-|-|:.|_|_|/|¯|¯|¯|¯

zB:
Du läufst vorne los (steigung 0.0, höhe 0), nach zwei kacheln kommst du zu steigung 0.4; dann wieter auf steigung 0.0 höhe 10; dann steigung -0.4 höhe 10; jetz bist du wieder höhe 0 steigung 0.0 etc.....wand *pock*

player.y := player.y + moveX*gradient*direction; // gradient = steigung; direction = +1 für vorne -1 für rückwärts!

du kannst auch noch bei jeder raster-grenze die y-pos resetten, damit sich die ungenauigkeiten nicht addieren (mit der zeit). Wie gesagt, wenn du sprigst scannst du den boden trotzdem weiter, damit du weist, wann du landest.

:D ich hoffe der ansatz hilft dir weiter

_________________
mfg.
mâximôv
Sledge_Hammer Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 32

Win 98 SE, Win XP
D7 Prof
BeitragVerfasst: Sa 02.08.03 12:18 
@ Marlno: Was meinst du mit "...wenn du also viermal (Pixelcheck=True) benutzt ..."? Komm ich nicht ganz hinter.
Naja und das mit dem Fallen, die idee mit der schleife hatte ich auch schon und hatte es auch schon eingebaut, das problem ist nur das es erst dann eine Kollision zwischen den Sprites ist , wenn diese sozusagen ineinanderstecken. Dann ist es ja zu spät, die bewegung muss schon aufhören wenn der spieler direkt auf dem untergrund angekommen ist.

@ maximus: hab auch schon dran gedacht in einer Ini-Datei die x- und y-Werte reinzuschreiben, z.B. für die karte von links nach rechts und nur die x-werte reinschreiben, wo sich der y-wert ändert. das problem an der sache war für mich was ich machen soll wenn du etwa einen Tunnel hast, bei dem man entweder durchgehen oder oben rübergehen kann. sowas kriegt man mit dem system wohl kaum realisiert.
Marlno
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 75



BeitragVerfasst: Sa 02.08.03 14:13 
Zitat:
Was meinst du mit "...wenn du also viermal (Pixelcheck=True) benutzt ..."? Komm ich nicht ganz hinter.
Naja und das mit dem Fallen, die idee mit der schleife hatte ich auch schon und hatte es auch schon eingebaut, das problem ist nur das es erst dann eine Kollision zwischen den Sprites ist , wenn diese sozusagen ineinanderstecken. Dann ist es ja zu spät, die bewegung muss schon aufhören wenn der spieler direkt auf dem untergrund angekommen ist.


naja hab doch n beispiel gemacht eben sowas
pixel 0 0
pixel 0 1
pixel 1 0
pixel 1 1

die ergeben doch ein großes pixel bestehend aus vier kleinen......
und das mit der schleife geht
du checkst ja erst und wenn nix im weg dann runter
irgendwann ist er ja auf dem boden das heißt in der letzten abfrage siehts so aus
sprite im weg?
ja
schleife abbrechen spielfigur keine reihe nach unten setzen
end;



Zitat:
hab auch schon dran gedacht in einer Ini-Datei die x- und y-Werte reinzuschreiben, z.B. für die karte von links nach rechts und nur die x-werte reinschreiben, wo sich der y-wert ändert. das problem an der sache war für mich was ich machen soll wenn du etwa einen Tunnel hast, bei dem man entweder durchgehen oder oben rübergehen kann. sowas kriegt man mit dem system wohl kaum realisiert.


doch das funktioniert

denn du kannst ja ein 3 reihen raster nehmen und so prüfen

oberstes ist was im weg
mitte ist nichts
unterstes ist was im weg
dann lässt du die figur langlaufen und du machst sie aber nicht anzeigbar das heißt dein rohr tunnel od sonst was liegt vor der figur

das hat doch dann den tunnel effekt....


MFG
Marlno
maximus
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 896

Win XP, Suse 8.1
Delphi 4/7/8 alles prof
BeitragVerfasst: Sa 02.08.03 19:30 
Das mit der pixel-kollision ist ja schön und gut, aber leider zu langsam :wink:


Sledge_Hammer hat folgendes geschrieben:
@maximus: hab auch schon dran gedacht in einer Ini-Datei die x- und y-Werte reinzuschreiben, z.B. für die karte von links nach rechts und nur die x-werte reinschreiben, wo sich der y-wert ändert. das problem an der sache war für mich was ich machen soll wenn du etwa einen Tunnel hast, bei dem man entweder durchgehen oder oben rübergehen kann. sowas kriegt man mit dem system wohl kaum realisiert.


Ich würde auf keinen eine Ini-datei dafür nehmen! Erstell dir eine level-datei (meinetwegen eine text-datei)...in welcher du das raster definiert.

2D wohlgemerkt (das oben war 1D und sollte nur das prinzip verdeutlichen) :wink:
zunächst würde ich die verschiedenen kachel typen definieren. in etwa so:

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:
27:
28:
29:
 
const 
  tileWidth = 48;
  tileHeight = 32

type
  TTileFlag = (tfAir, tfGround, tfRoof, tfWall, tfPain); // flag für verschiedenes verhalten der kacheln -> zB. tfWall block alles

  TTile = record
    flag : TTileFlags;
    imageName: string[64];
    image: TPictureItem..;
    leftGround, rightGround : byte; // da deine kecheln wohl nicht länger als 255 pixel werden.     
    gradient: single;    
  end;
    
var
  tileDef : Array[0..3] TTile = (
    (flag: tfAirM; image : 'air_image'),
    (flag: tfGTround; leftGround: 2; rightGround : 2, imageName:'air_normal'),
    (flag: tfGTround; leftGround: 2; rightGround : 20, imageName:'air_up1'),    
    (flag: tfGTround; leftGround: 20; rightGround : 2, imageName:'air_down1'));

  // .image vorher aus iamgeName auflösen -> für schnellen zugriff 

  // .gradeient auflösen
  ...
  tileDef[i].gradient := (tileDef[i].rightGround -  tileDef[i].leftGround) / tileWidth;
  ...


in dem level dann nur für jedes raster die nummer eintragen, mit der du auf das tileDef array zugreifst und die dortigen daten verwendest. Du prüfst am besten für alle vier ecken des spielers in welcher sie sich befindet! Bewegt siche eine ecke in eine 'tfWall' kachel so setzt du die speed var zb. auf 0.00 !

kannst du mit dem prinzip was anfangen :?:

_________________
mfg.
mâximôv
Frase
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 17

Win 98 SE, SuSE 8.2 Prof
D5 Prof, D6 Ente, Kylix
BeitragVerfasst: Mo 04.08.03 11:22 
Jump&Run

Schön!
Ich mach auch grad eins im Comander Keen Stil. Soll am Ende Keen Revenge heißen.

Um das Clipping abzufragen, werde ich Vektoren benutzen.
Ich werde dies mal etwas erläutern:

Angenommen, die Figur steht im Moment auf einer Mauer. Nehmen wir eine Sandsteinmauer. Die sehen immer so schön aus ;-)
Ok. Nun haben wir den Spieler auf einer Sandsteinmauer. Wie er da drauf gekommen ist und wie er es anstellt, dass er nicht durch den Sandstein durchfällt (Nanu? Seit wann kann man durch Stein durchfallen? Nehmen wir lieber Bimmstein. Bimmstein ist leichter und Poröser. Da kann man sich leichter vorstellen, dass da jemand durchfällt.)
Ok. Nun haben wir eine Figur auf einem Bimmstein.
Nun zum Vektor:

Lassen wir die Figur springen.
Da muss erstmal geschaut werden, ob über der Figur (Figur ist mir zu blöd. Ich nenne die Figur jetzt Colami (Frei nach meinem alten 486er)) Sandsteine sind.
Mit pixelcheck würde ich nicht arbeiten, denn es ist zu langsam und ungenau. Das ist ja in etwa so, wie wenn du mit Canvas.pixels [x,y] nachschauen würdest, ob der Pixel die Farbe hat.

Zurück zum Springen:
Sobald du auf die Springen-Taste (In unserem Beispiel die Leertaste "Blank") drückst, wird ein Vektor gesetzt. z.B.: auf 10.
Das heißt, Colami soll 10 Irgendwas (Sagen wir mal Bratwürste) in die Luft springen. Während er aber nach oben springt, nimmt der Vektor immer mehr ab.

Für das Clipping würde ich ganz einfach vorschlagen, vor dem Sprung die Sachen innerhalb dieses Vektors zu prüfen, ob da nicht vielleicht Sandstein ist.

_________________
LINUX 4 EVER!