JnR mit Tiles, aber sauberem (Pixel) Scrolling
-
Hmmmm, ja kann man aber das ist nicht die Richtung.
Ich habe mir jetzt überlegt jedem Tile eine Mittelpunkt koordinate zu geben,
diese ja einfach erechnet werden kann und je nach wichtung zum letzten oder
nächsten Tile zu reagieren.
Ich bin sogar am überlegen die Tile-Matrix auf 8x8 zu setzten, so würde für
das Menschliche Auge eine nahezu Pixelgenaue abfrage ergeben, aber ich mach erst
paar Test mit 16x16 und guck wie mein Auge das sieht, da bei 8x8 die Arrays
schon viel Speicher fressen.Das Ausrechnen der pixelgenauen Position eines Tiles zwischen 2 anderen ist
sehr einfach und geht schnell, somit halte ich das für die beste Lösung im
Moment, oder hat jemand anderes eine bessere Idee, so bin ich für jeden
Vorschlag offen.gruß MiC++ha
-
ich versteh zwar immernoch net dein problem, aber vielleicht hilft dir das ja:
http://www.gamedev.net/reference/programming/features/gpgenesis8/
-
Das Problem ist die Abfrage der Tile-Koordinaten,
eine Figur kann und soll am Rand eines Abgrund stehen können (z.B. X-Tile:21)
geht es aber 1-2 Pixel Vorwärts, stürzt es ab, da ab dieser Position Tile:22
gültig ist, mit anderen Worten geht es hier um Kolisionsabfragen bezogen auf
der Laufebene, und dies sollte nahezu Pixelgenau sein.Aber ich habe schon eine gute Lösung mir überlegt, werde das mal überarbeiten
und bissel Ausreifen und hier reinschreiben. Diese Lösung kann man dann auch
für gewisse Game-Events und Effekte etc. Verwenden.gruß MiC++ha
-
sry ich verstehs immernoch net: was fürn abgrund? was hat die kollisionsabgrage mit scrolling zutun? Warum stürzt dein programm ab? Weil die Figur in nen abgrund geht? warum ist dann der abgrund nicht einfach unbegehbar? oO
Erklär mal genau, wie du es bisher machst (wie wird figurpos gespeichert, wie kollision abgefragt, usw.) und wo da ein fehler auftaucht (z.b. bei deinem "abgrund" beispiel).
edit: "Das Problem ist die Abfrage der Tile-Koordinaten" Von der Figur? tileX = Figur.x / 16; tileY = Figur.y / 16
Nun hat deine Figur die x Koordinate 351 --> tileX = 21
Figur soll 1 pixel nach rechts gehn:
--> zug möglich? --> neue koordinate wäre 352 --> tileX = 22 --> tilearray[tileX][tileY].begehbar --> false --> figur fällt net in abgrund
xD
-
Genau das ist das Problem, ja so ist es richtig wie du es beschreibst, und
gemacht habe ich noch gar nichts, es ist erst auf Papier.Nur bei dieser (üblichen?) Methode würde die Figur schon in den Abgrund fallen,
obwohl er noch 8 Pixel Platz hat bei einer 16x16 Matrix und der Boden bis zur
Mitte reicht bei diesem Tile, also muß das prog wissen was anbach ist.
Beispiel:
Alle Tiles mit gewissen Events sind gespeichert.
Spieler steht auf Tile-Nr. 121, normaler Boden, geht nach rechts und nach der
rechnung erscheint als Kol.-Tile der nächste mit z.B. der Nr. 212 und diesem
Tile ist ein Event zugeordnet der Abgefragt wird, der giebt aus das er nach
rechts noch 8 Pixel Platz hat bevor er fällt. und so weiter.
Das ist meine bisherige Überlegung.Aber nochmal zum besseren Verständnis meiner Frage:
Ich möchte Bewegungen und Abfragen nahezu Pixelgenau vollbringen, so das
eine Spielerfigur auch am Rand eines Tiles stehen kann wenn der Rand in der
Mitte des Tiles ist, ohne sofort zu stürtzen.
Eine 1x1 Pixel Map würde Speicher fressen, daher tendiere ich auf 16x16, so in
der Mitte des Üblichen, bei einer Auflösung von 640x480.
Nun kommt die Spielfigur auf das nächste Tile und dies ist für jene Boden/Kolisions-
Abfrage zuständig, aber was ist es und wie stehts mit der Balance zum vorherigem, kann er noch paar Pixel vor, wackelt er da er fast das
Gleichgewicht verliert etc....? Ich denke sowas kann man mit einer Event-verarbeitung
für gewisse Tiles am besten lösen.Darum ging es mir Hauptsächlich, bei Pixelgenauem Übergang von einem Tile zum anderen
richtig und Pixelgenau zu reagieren. Meine Frage war Blöd gestellt.
Denn wenn ich die Figur von Tile zu Tile springen lasse ist eine Abfrage immer
Perfekt, aber nicht Pixelgenau und ruckelig.gruß MiC++ha
-
also dein abgrund ist kleiner als ein tile (daher das abgrundtile beinhaltet auch begehbare fläche)? Naja dann musste die Kollisionsabfrage irgendwie anderes machen. Z.b. könnteste noch ein Teilrechteck für das jeweilige tile definieren, dass festlegt wo ca. der abgrund ist und dann dies bei der kollision abfragen. Oder du machst ein Array, dass so groß ist wie der Bildschirm Pixel hat und vom typ bool ist und beinhaltet, welcher Pixel begehbar ist und welcher nicht
Dann wärs Pixelgenau ~~
-
Siehe FAQ, 2D-Scrolling
Bye, TGGC (Der Held ist zurück!)
-
TGGC schrieb:
Siehe FAQ, 2D-Scrolling
Bye, TGGC (Der Held ist zurück!)
Bitte Thread lesen (nicht nur topic).
-
life schrieb:
also dein abgrund ist kleiner als ein tile (daher das abgrundtile beinhaltet auch begehbare fläche)? Naja dann musste die Kollisionsabfrage irgendwie anderes machen. Z.b. könnteste noch ein Teilrechteck für das jeweilige tile definieren, dass festlegt wo ca. der abgrund ist und dann dies bei der kollision abfragen. Oder du machst ein Array, dass so groß ist wie der Bildschirm Pixel hat und vom typ bool ist und beinhaltet, welcher Pixel begehbar ist und welcher nicht
Dann wärs Pixelgenau ~~
Du könntest auch ne Maske erstellen, für jeden Tiletyp, dann setzt du für deinem Character zwei bis 3 Vertices fest, nun überprüfst du alle Vertices ob einer in der weißen Farbe der Maske ist. Wenn das dann bei 3 Vertices nur der vordere ist oder nur der hintere dann fällt er nicht, aber wenn 2 Vertices: vorne und in der mitte oder hinten und in der mitte frei liegen, schubst du den Chara nen bischen nach vorne so dass das aussieht als würde er kippen und er fällt bei 3 frei-liegenden dann runter....whaaaa....
Wenn du das mit den Tiles so machst:
for(int.....) { for(int....) { BlitTile(x,y); } }
dann musst du einfach scrollen:
for(int.....) { for(int....) { BlitTile(x-Cam.x,y-Cam.y); } }
Normalerweise müssten dann keine übergänge oder sonstwas sein.
Wenn das da oben alles falsch ist, liegt es daran das ich nicht weiß was JnR ist
-
Timm schrieb:
Du könntest auch ne Maske erstellen, für jeden Tiletyp, dann setzt du für deinem Character zwei bis 3 Vertices fest, nun überprüfst du alle Vertices ob einer in der weißen Farbe der Maske ist. Wenn das dann bei 3 Vertices nur der vordere ist oder nur der hintere dann fällt er nicht, aber wenn 2 Vertices: vorne und in der mitte oder hinten und in der mitte frei liegen, schubst du den Chara nen bischen nach vorne so dass das aussieht als würde er kippen und er fällt bei 3 frei-liegenden dann runter....whaaaa....
entspricht ja dem boolarray, nur das bei dir false weiße Farbe ist und true schwarze Farbe
edit: aber am besten für jeden tiletyp nen eigenes 16x16 boolarray (spart memory xD)
-
Eure Ideen klingen nicht schlecht, aber leider nicht Optimiert.
Zu viel Speicher etc.Also ich denke das mit dem Events für einige Tiles ist schon was und
gut Ausbaufähig, da man z.B. dann auf einen Tile ein Schalter setzten kann
der weiter hinten im Spielfeld eine Tür öffnet.Ich denke mir das so, ich habe z.B. 32 Tiles mit Events, von Absturz bis Schalter
über Feuer und Laserwand etc.
Gesamt habe ich 256 Tiles, die Event-Tiles setzte ich am Anfang von 0-31, der
Rest dahinter.
Liegt der Spieler mit ein paar Pixel auf ein Event-Tile wird dieser Verarbeitet
und geprüft ob er z.B. schon am Rand des Abgrunds steht oder die Laserwand berührt.
Wenn ja - Action.
Dazu müßen für jedes Event Routinen aufgerufen werden, diese Stehen in einem
Array[32], folglich also eine einfache Art ziemlich genau zu Handeln.Ich bin gestern hier mal auf ein Thread gestossen wo eine Spielfigur einen
Berg oder Schräge hochlaufen soll, das ist dann auch einfach:
Berg-Tile = Event-Tile, Event->gehe_auch_ein_pix_hoch()Die Sache ist nur die, und das war ja ansich auch meine Grundfrage, das die
Tiles der Spielfigur nicht voll gefüllt sind, seine Füsse sind schmaler als
sein Hip, der äussere Pixel seines Bauches kann als Abfrage bei einer Feuerwand
dienen, aber nicht für einen Abgrund, denn da steht er noch am Rand, also
werde ich mich am Mittelpunkt halten und von da aus die Position der Füsse,
Bauch, Arme, Schädel etc.
Es kann ja nicht sein das er in den Abgrund fällt weil er einen großen Sombreo-
Hut aufhatgruß MiC++ha
PS:
@life
Ein Bool ist oft (oder immer) ein Byte groß, eine Schwarz/Weiß Bitmap kommt da
:8 mal besser, also 1/8 an Speicher als ein Boolarray, gecheckt wird
dann auf Bit-ebene. Wobei 0 = Leerraum wäre, 1 = da ist was (Boden,Wand). Aber
in meinen Fall könnte ich mir das auch ersparen da ich die Farbe Schwarz RGB(0,0,0)
als Leerraum verwende (Tranzparent, bzw. Colorkeying), so brauche ich stehts
nur darauf zu testen, aber das wird komplizierter und Unübersichtlicher als mit
Tiles und halt Events-Tiles.
-
mach wie dus für richtig hälst
btw. bool ist doch ein bit groß?! 0 oder 1 wofür brauch ich da ein byte? oO
Außerdem willste ja deine bitmap auch irgendwie in dein programm laden und dafür brauchste dann mindestens genausoviel speicherIm Prinzip würd ich es so machen, dass ich eine bitmap mit der kollisionsinformation einlade und dann beim entsprechenden tiletyp (z.b. abgrund) als (static) bool array abspeicher. Selbst wenn du 100 unterschiedliche tiletypen gleichzeitig intialisiert haben müsstest, bräuchste dafür grademal 100*16^2 bits = 25600 bits = 3200bytes = 3,2kb. Also das ist lächerlich wenig memory auslastung
-
life schrieb:
mach wie dus für richtig hälst, aber wie willste abfragen wann das event ausgelöst wird?
Wenn die Spielfigur nach rechts läuft so wird geprüft ob sich das rechts-äussere Tile
sich um mind. 1pix auf ein Event-Tile befindet, und wenn ja ob dessen Bedinnungen
erfüllt werden für eine Reaktion, also relativ einfach.life schrieb:
btw. bool ist doch ein bit groß?! 0 oder 1 wofür brauch ich da ein byte? oO
Eine Bool-Variable belegt einen Speicherbereich der Adressierbar sein muß,
Logisch, da man aber nur Bytes Adressiert und nicht einzellne Bit´s, belegt
es einen Byte. Anders gesagt, der kleinste Zugriff ist ein Byte mit seinem Inhalt.
-
Wenn die Spielfigur nach rechts läuft so wird geprüft ob sich das rechts-äussere Tile
sich um mind. 1pix auf ein Event-Tile befindet, und wenn ja ob dessen Bedinnungen
erfüllt werden für eine Reaktion, also relativ einfach.rechts-äussere tile? rechteck um die spielfigur? oO Also wie auch immer, wie willste die informationen abspeichern, wo der abgrund ist? Das muss doch in dein event-tile drinstehen und irgendwie muss die informartion auch gespeichert werden und da du es pixelgenau haben willst, kannste ja nicht einfach ein kollisionsrechteck angeben. Also wie willste das machen?
Anders gesagt, der kleinste Zugriff ist ein Byte mit seinem Inhalt.
und wie willste dann deine bitmap abspeichern? Oder willste jedesmal von festplatte lesen? Also da würd ich schon lieber die paar kb memoryverbrauch in kauf nehmen
-
bool operator[](unsigned int pt) { return m_Array[pt>>3]&(1<<(pt&3)); }
und schon hast du zugriff auf jedes einzelne bit (btw, es gibt auch assembler funktionen die einzelnen bits in die branchflags laden).
rapso->greets();
-
@rapso
Danke für die Antwort, aber wie ich mit Bit´s & Byte´s umzugehen habe weiß ich
schon seit, ähhh, vielen Jahren.
Hier gehts um eine vernünftige Positions-/Kolisionsabfrage die möglichst genau
ist und so gut wie Pixel getreu.Fakt ist, das ich keine Zusätzliche Map brauche, ob Array oder Bitmap. Da die
begehbare Ebene Schwarz RGB(0,0,0) als Freiraum, bzw. frei beweglicher
Raum gildet, somit ist eine Kolisionsbitmap überflüssig.
Und ich brauche keine Submaps für jedes Map sondern nur für die, wo es angebracht
ist, also jene die ich mit Event-Tile beschimpfe. Dazu benötige ich aber auch nicht
wieder eine Map sondern nur Parameter und Routinen.Ich will eine Spielebene von (Screen 640x480) 19.200 x 1.920 Pixel, Tiles sind
16x16, also Tiles-Array[X=1200][Y=120] (~140KB bei 256 Tiles), die Tiles-Bitmap
ist (True-Color) 192KB groß.
Nun bewegt sich die Spielfigur, bestehend aus 3(X) x 5(Y) Tiles nach rechts, das
Tile unten-rechts tritt mitt mind. einem Pixel das nächste Tile des Hintergrunds
und dieses ist ein Event-Tile, nun prüfe ich anhand von gegebenen Parametern
ob das ereignis des Event-tiles statt findet oder nicht.
Durch die Klasse der spielfigur weiß die Event-Routine das das mittlere Tile
der Spielfigur zuständig ist für z.B. den Abgrund, also wird nichts passieren
ausser das mittlere Tile befindet sich auf diesem Event-Tile, wenn das dann so
ist wird geprüft wie viele Pixel spielraum noch sind, bevor er stürtzt, ausser
er springt (Steuerung) etc.Daher:
Wenn Tile != EventTile -> weiter
wenn Tile == EventTile -> Prüfe(Event Verarbeiten())
etc.Also alles sogar einfach und Übersichtlich ohne zusätzliche Map´s oder so.
Erst auf Tile checken und dann ob Event, wenn ja inns Detail gehen.gruß MiC++ha