Meine schon beschriebenen Probleme wie 'Zeilenendeerkennung' und 'Läuft auf PC aber nicht auf GP2X' hat Gernot durch ein Update gelöst. Den GLBasic-Fehler einzugrenzen, hat mich aber einiges an Zeit gekostet - von wegen schnell mal mit GLBasic was entwickeln...
Neues Problem:
Aus den Beschreibungen zu BOXCOLL und SPRCOLL wird mir nicht klar, ob eine Sprite-Kollission nun wirklich pixelgenau ausgeführt wird. Genauer: Ein Sprite enthält ja eine Grafik, die durch die Farbe einzelner Pixel bestimmt wird. Beim Anzeigen des Sprites achtet man darauf, dass die die Grafik umgebenden Pixel transparent sind, so dass man den Hintergrund erkennen kann. Ich möchte nun gerne erreichen, dass die transparenten Pixel bei einer Kollissionsabfrage nicht einbezogen werden. Es scheint mir so, als ob dies mit GLBasic nicht möglich ist. Stimmt dass?
Wenn ich mich recht erinnere, machte dies z.B. beim C-64 die Hardware und ich erwartete eigentlich, dass GLBasic dies per Software nachbildet, dies scheint aber nicht so zu sein. Schade!
Wenn es aber tatsächlich nicht geht, dann möchte ich Euch fragen, wie Ihr dieses Problem lösen würdet?
Oder macht tastsächlich niemand eine pixelgenaue Kollissionsabfrage?
Liebe Grüße
Luckeie
BOXCOLL ist Boxkollision und SPRCOLL ist Pixelkollision. Geht 100%. Mach doch nen Test.:D
Bei schnellen Shootern brauchst du keine Pixelkollision. Das sieht eh keine Sau.:D
Cheers
Quote from: BumbleBeeBOXCOLL ist Boxkollision und SPRCOLL ist Pixelkollision. Geht 100%. Mach doch nen Test.:D
Bei schnellen Shootern brauchst du keine Pixelkollision. Das sieht eh keine Sau.:D
Cheers
Es ist aber kein Shooter, es ist ein kleines Fahrzeug, welches in Geschwindigkeit und Winkel nahezu stufenlos bewegt werden kann und in einer Umgebung nicht an die Wand fahren darf...
Ich glaube, ich weiß jetzt warum es nicht geht: Ein gedrehtes Sprite wird trotz der Darstellung mit den ursprünglich gladenen Pixeln verglichen und nicht mit den durch die Drehung enstandenen. Trotzdem Danke für die Infos. Für mein Spiel ist das allerdings tödlich.
Liebe Grüße
Luckeie
Gut zu wissen.
Ein Ausweg aus deiner Misere wäre vielleicht noch, für jede Drehrichtung eine eigene Grafik zu erstellen, sodaß aus allen Grafiken quasi eine Animation entsteht. Weiß ja nicht, wieviele Grafiken du dafür bräuchtest. Könntest dann aber mit SPRITE statt ROTOSPRITE arbeiten und hättest deine gewünschte pixelgenaue Kollisionsabfrage.
ROTOSPRITE _zeichnet_ nur eine gedrehte Grafik - das Sprite ist dann nicht irgendwie an der Stelle. Hach - ich muss das dringend in BLIT umbenennen. Das verwirrt so...
Heisst also, dass es nicht sinnig ist ... z.b. Die "Hauptfigur" mit rotosprite zu drehen??
Dann bietet sich das Rotosprite hauptsächlich für bewegte Objekt an, die nichts mit Kollision zu tun haben???
Ich frage, da ich auch gerade meine ersten Versuche Starte?!
Sprite/RotoSprite usw. "kleben" nur eine Grafik auf den Backbuffer. Nichts weiter.
Wo wir grad bei Collisionen sind, Gernot, gibts es eine Möglichkeit ein Sprite das peer Vector "gestreckt" wurde, auf Collision zu prüfen?
EDIT:
Dann könnte man einen GEILEN "Vector -Map-Editor" Basteln :D
Quote from: GernotFrischROTOSPRITE _zeichnet_ nur eine gedrehte Grafik - das Sprite ist dann nicht irgendwie an der Stelle. Hach - ich muss das dringend in BLIT umbenennen. Das verwirrt so...
Könntest Du nicht einen neuen Befehl einbauen, der die durch die Rotation zur Ausgabe berechneten Pixel in das für die Rotation benutzte Sprite hinein schreibt? ... Ah, wahrscheinlich wird es dann immer unansehnlicher ... aber vielleicht eine Kombination aus zwei Spriteplätzen? In einem Sprite hat man ein Original-Muster welches durch Rotation in einen zweiten Spriteplatz geschrieben wird, welchen man wiederum anzeigt und zur Kollisionserkennung benutzt? Das könntest Du doch machen, oder (Könnte ROTOCOPY oder so heißen)? ;-)
Liebe Grüße
Luckeie
ich denke, das kann man mit den vorhandenen Befehlen ja schon erreichen. Ich denke ich probier das heute abend mal aus.
Vorgehen wäre folgendes:
- Sprite rotiert und/oder gezoomt darstellen
- dieses Sprite mit GRABSPRITE einfangen
- und damit die Kollisionsabfrage machen
kommt mir grad so, kanns im Moment aber nicht austesten.
Mach doch vor der Hautpschleife Rotosprite, und speicher jede Drehung in ein neues Sprite(GRABSPRITE).
Hintergrund mit Fillrect und RGB (255,0,128) machen !!!!
Dann die "Animation" in der Hauptschleife machen, und schon hat man eine Pixelgenaue Collision.
Achja man muss ja nicht jedes Grad ein neues Sprite machen! ( ich sag nur STEP) :)
EDIT:
Scheisse Quentin war schneller ...
Aber: Das Sprite wird um Faktor 1.41 (Wurzel 2) größer. Diesen Unterschied muss man dann wieder von der Sprite-Position bei SPRCOLL abziehen. Ausser, man zeichnet ein Sprite so groß, dass Platz für das gedrehte Sprite ist, dann geht's auch so.
Ich glaube übrigens, dass keine Sprache gedrehte Pixel-Kolllision unterstützt. Da geht der Rechner ganz schön in die Knie mit sowas.
Quote from: GernotFrischAber: Das Sprite wird um Faktor 1.41 (Wurzel 2) größer. Diesen Unterschied muss man dann wieder von der Sprite-Position bei SPRCOLL abziehen. Ausser, man zeichnet ein Sprite so groß, dass Platz für das gedrehte Sprite ist, dann geht's auch so.
Ich glaube übrigens, dass keine Sprache gedrehte Pixel-Kolllision unterstützt. Da geht der Rechner ganz schön in die Knie mit sowas.
Mag sein, aber in meinem Programm wird ja zur Darstellung eh schon gedreht und ich denke, dass da die Hauptzeit verbraten wird. Man muß ja nur die für die Ausgabe eh schon gedrehten Pixel in den Spritebuffer schreiben - sonst nichts. Und wegen der Speed: Mein Programm läuft ja soweit schnell genug. Also so ein ROTOCOPY wäre eine recht elegante Sache und um Größenprobleme auszugleichen, muß man halt den die Grafik umschließenden rechteckigen Bereich des Sprites etwas größer als die Ausgangsgrafik wählen. Aber das ist dem Entwickler des Spiels sein Problem.
Es wäre dann so einfach:
Beim Start:
LOADSPRITE "originalsprite.bmp", 1
LOADSPRITE "dummy.bmp", 2
In der Schleife immer wieder:
ROTOCOPY Sprite1, Sprite2, Grad
SPRCOLL 2, XCoordSpr2, YCoordSpr2, TestSpriteID, XCoordTSpr, YCoordTSpr
SPRITE Sprite2, XCoord, YCoord
oder ähnlich.
Bitte, bitte!
Liebe Grüße
Luckeie
Quote from: Schranz0rMach doch vor der Hautpschleife Rotosprite, und speicher jede Drehung in ein neues Sprite(GRABSPRITE).
Hintergrund mit Fillrect und RGB (255,0,128) machen !!!!
Dann die "Animation" in der Hauptschleife machen, und schon hat man eine Pixelgenaue Collision.
Achja man muss ja nicht jedes Grad ein neues Sprite machen! ( ich sag nur STEP) :)
EDIT:
Scheisse Quentin war schneller ...
Da muß ich viel mehr programmieren und testen... ;-) Aber Du hast schon recht - performanter wäre das auch. Aber nicht elegant: Erst alles in den Bildshcirmbuffer schreiben, dann wieder herausgrabben und dann doch auch noch den Bereich löschen, oder?
Luckeie
hmm Doppelpost.... Naja
ROTOCOPY ist eine schlechte Idee, da es, wie Gernot schon sagt, massig an Speicher frisst.
Ich Schreib mal schnell ne Function, die dein Problem lösen kann( Hoffe ich).
Dann hat Gernot seine ruhe , und kann sich auf die wichtigeren Dinge konzentrieren.
Quote from: Schranz0rhmm Doppelpost.... Naja
ROTOCOPY ist eine schlechte Idee, da es, wie Gernot schon sagt, massig an Speicher frisst.
Ich Schreib mal schnell ne Function, die dein Problem lösen kann( Hoffe ich).
Dann hat Gernot seine ruhe , und kann sich auf die wichtigeren Dinge konzentrieren.
Du musst für mich nichts programmieren. Ich habe schon verstanden wie Du es meinst und kann das selbst lösen. Trotzdem vielen Dank für Dein Angebot.
Liebe Grüße
Luckeie
dabe fällt mir gerade ein, wenn man so eine allgemein nutzbare Funktion basteln will, hat man ja nicht nur das von Gernot beschriebene problem der unterschiedlichen Größen, sondern auch das von sich überlagernden Sprites. Wenn ich das richtig sehe, müsste man vor dieser Aktion erst mal den kompletten Bildschirminhalt im Backbuffer sichern, das rotierte Sprite zeichen, grabben, Backbuffer restoren, Sprite zeichen ... ich glaub jetzt hab ich alles *grübel*
Quote from: Schranz0rhmm Doppelpost.... Naja
ROTOCOPY ist eine schlechte Idee, da es, wie Gernot schon sagt, massig an Speicher frisst.
Ich Schreib mal schnell ne Function, die dein Problem lösen kann( Hoffe ich).
Dann hat Gernot seine ruhe , und kann sich auf die wichtigeren Dinge konzentrieren.
Es frißt keinen Speicher. Deine Lösung würde viel mehr Speicher verbrauchen.
Luckeie
Quote from: Quentindabe fällt mir gerade ein, wenn man so eine allgemein nutzbare Funktion basteln will, hat man ja nicht nur das von Gernot beschriebene problem der unterschiedlichen Größen, sondern auch das von sich überlagernden Sprites. Wenn ich das richtig sehe, müsste man vor dieser Aktion erst mal den kompletten Bildschirminhalt im Backbuffer sichern, das rotierte Sprite zeichen, grabben, Backbuffer restoren, Sprite zeichen ... ich glaub jetzt hab ich alles *grübel*
Gernot muß doch nur die Funktion die er schon hat (ROTOSPRITE) kopieren und das von dieser Funktion erzeugte Ergebnis - also die gedrehten Pixel - anstatt auf den Bildschirm (bzw. Buffer) in den Speicherbereich mit dem zweiten Sprite schreiben - sonst nichts, oder?
Liebe Grüße
Luckeie
@luckeie
ich glaube so einfach ist das nicht. Bei Sprites mit quadratischer Grundfläche ginge das wohl recht einfach, aber davon kann man ja nicht ausgehen. Stell dir vor, dein Sprite in ein Balken, 20 Pixel breit und 100 Pixel hoch. Nun drehst du das Teil. Um jetzt die Grafik im Sprite zu speichern benötigst du schon einen größeren Bereich. Ich denke schon, daß der interne Rechenaufwand für diese Verwaltungsaktionen recht aufwändig werden können.
also etwa so
|
| Original
\
\ gedreht
ähh, hoffe es ist verständlich ;)
Oh weia! ROTOSPRITE verwendet die OpenGL funktionen und zeichnet ein gedrehtes Rechteck, das eine Textur hat. Damit macht das die Grafikkarte und es ist superschnell.
Wenn ich das für die Kollision drehen müsste, dann (wie auch bei PocketPC und GP2X) muss ich das PixelXPixel machen -> das kostet Zeit.
Also, wenn wirklich akkurate Prüfung nötig ist, dann lieber ein paar Grafiken mehr zeichnen/erstellen (GRABSPRITE - nur einmal beim Programmstart), und damit arbeiten, statt wirklich in Echtzeit das Ding drehen+testen.
Ich bau' euch gerne einen ROTOCOPY ein, aber das ist einfach schlechter Programmierstil. Ich kenne kein Spiel, das seine Kollisionen so abfragt, weil's einfach uneffektiv^3 ist.
Das soll jetzt keine Kritik, sondern ein guter Rat sein, OK?
[edit]
Schilder mal Deine Spielidee, dann sag' ich Dir wie's effektiv geht.
Quote from: Quentin@luckeie
ich glaube so einfach ist das nicht. Bei Sprites mit quadratischer Grundfläche ginge das wohl recht einfach, aber davon kann man ja nicht ausgehen. Stell dir vor, dein Sprite in ein Balken, 20 Pixel breit und 100 Pixel hoch. Nun drehst du das Teil. Um jetzt die Grafik im Sprite zu speichern benötigst du schon einen größeren Bereich. Ich denke schon, daß der interne Rechenaufwand für diese Verwaltungsaktionen recht aufwändig werden können.
also etwa so
|
| Original
\
\ gedreht
ähh, hoffe es ist verständlich ;)
Hat Gernot und ich doch schon erklärt: Man muß halt den Spritebuffer etwas größer wählen und die Grafik mittig plazieren...
Luckeie
Quote from: GernotFrischOh weia! ROTOSPRITE verwendet die OpenGL funktionen und zeichnet ein gedrehtes Rechteck, das eine Textur hat. Damit macht das die Grafikkarte und es ist superschnell.
Wenn ich das für die Kollision drehen müsste, dann (wie auch bei PocketPC und GP2X) muss ich das PixelXPixel machen -> das kostet Zeit.
Also, wenn wirklich akkurate Prüfung nötig ist, dann lieber ein paar Grafiken mehr zeichnen/erstellen (GRABSPRITE - nur einmal beim Programmstart), und damit arbeiten, statt wirklich in Echtzeit das Ding drehen+testen.
Ich bau' euch gerne einen ROTOCOPY ein, aber das ist einfach schlechter Programmierstil. Ich kenne kein Spiel, das seine Kollisionen so abfragt, weil's einfach uneffektiv^3 ist.
Das soll jetzt keine Kritik, sondern ein guter Rat sein, OK?
[edit]
Schilder mal Deine Spielidee, dann sag' ich Dir wie's effektiv geht.
Ok, dann verstehe ich das Problem, dann geht es halt nicht. Und für meine Spielidee ist dann der Vorschlag von Schranz0r ganz gut geeignet.
Aber so ähnlich wie Basic nicht unbedingt die effektivste Sprache für Spiele ist, es aber trotzdem nimmt, weil man beim Entwickeln schnell vorwärts kommt, wäre halt für mich der Einsatz von ROTOCOPY gewesen: Ich wäre schnell einen ganzen Schritt weiter gewesen.
Liebe Grüße
Luckeie
num = Spritenummer
drehungs_step = fortschritt der Drehung pro Durchlauf
start_num = Mit welchen Sprite die Drehung anfängt
FUNCTION ROTOCOPY: num, drehungs_step, start_num
GLOBAL Winkel
LOCAL XX, YY, Spitzenmass
GETSPRITESIZE num, XX, YY
Spitzenmass = SQR( POW(XX,2) + POW(YY,2) )
FOR Winkel = 0 TO 359 STEP drehungs_step
FILLRECT 0,0,Spitzenmass,Spitzenmass, RGB(0xff, 0x00, 0x80)
ROTOSPRITE num,(Spitzenmass-XX)/2, (Spitzenmass-YY)/2, Winkel
GRABSPRITE start_num + Winkel / drehungs_step, 0, 0, Spitzenmass, Spitzenmass
BLACKSCREEN
NEXT
ENDFUNCTION
Würde gehen, wenn Grabsprite auch Transparenz setzen würde, und nicht nur schwarz....
EDIT:
soll ichs unter Codeschnipsel auch reinmachen?
Hoi! BASIC nicht effektiv? Mach mal ein Benchmark gegen andere BASICs, dann bekommst Du große Augen.
Problem bei ROTOCOPY: Du musst das Ding noch verschieben:
FUNCTION ROTOCOPY: number, numberout, angle, BYREF dx, BYREF dy
LOCAL sx, sy, newx, newy
GETSPRITESIZE number, sx, sy
newx = sx*1.42
newy = sy*1.42
dx = (newx-sx)/2
dy = (newy-sy)/2
ROTOSPRITE number, dx,dy, angle
GRABSPRITE number2, 0,0,newx,newy
ENDFUNCTION
und dann:
SPRCOLL numberout, x-dx, y-dy, anderes_sprite,x,y
@ Gernot
Meins war ja für vor die Hauptschleife!
Quasi die Sprites in den Speicher laden...
und wenn man dann immer noch das Sprite Middeln will, auf x und y ,dann kann man ja ganz einfach:
GETSPRITESIZE (eins der drehbilder), nehmen und die Position -1/2 Spritesize setzen!
Stimmt. Klasse Idee.
Dann noch ein SPRCOLL_Center() machen, und feddig.
Uff.. da muss man dann auch die Spritepositionen um jeweils die halbe Sprite breite und höhe versetzen ?
Hier noch ein MidHandle für die ROTOSPRITE
FUNCTION Sprite_Mid: num, X, Y
LOCAL XX, YY
GETSPRITESIZE num , XX, YY
SPRITE num, X-XX/2, Y-YY/2
ENDFUNCTION
Quote from: GernotFrischHoi! BASIC nicht effektiv? Mach mal ein Benchmark gegen andere BASICs, dann bekommst Du große Augen.
Entschuldige, ich wollte Dir nicht zu nahe treten. Klar kommt es letztlich auf die Implementierung an! Ich bin auch kein Basic-Experte, ich komme von Turbo-Pascal, Delphi und Java und notfalls halt Assembler.
Bis auf die Dinge, die ich hier auch schon moniert habe, gefällt mir GLBasic ganz gut!
Liebe Grüße
Luckeie
Quotesoll ichs unter Codeschnipsel auch reinmachen?
Ja bitte!! :)
Quote from: GernotFrischSchilder mal Deine Spielidee, dann sag' ich Dir wie's effektiv geht.
Für alle Neugierigen, die wissen wollen was ich mit GLBasic versuche: Hier mein bisheriger Spielcode:
Ist aber längst nicht fertig und ich habe auch nicht den Anspruch ein Superspiel zu machen. Ich probiere so herum, schaue was machbar ist und knüpfe nahtlos an meine Träume aus C-64 Zeiten an: Ein großer Programmierer zu werden - hat leider nicht geklappt! ;-)
Das MP3 ist von Achim Tober!
http://www.steinlaus.de/GLBasic/TankGame.zip
Luckeie
Prüft ein "ROTOCOPY-Sprite" auf Collision!
mid_num ist dabei das Sprite aus der Rotation!
FUNCTION Sprcoll_mid: num1, x1, y1, mid_num2, x2, y2
LOCAL XX, YY
GETSPRITESIZE mid_num2, XX, YY
IF SPRCOLL(num1, x1, y1, mid_num2, x2-XX/2, y2-XX/2)
RETURN 1
ENDIF
ENDFUNCTION
;) cooles Teil, erfordert Fingerspitzengefühl. Bleibe aufgrund meiner Ungeduld immer an den Rändern hängen
Quote from: LuckeieHier mein bisheriger Spielcode:
http://www.steinlaus.de/GLBasic/TankGame.zip
Luckeie
Jetzt läufts auch auf dem GP2X (mit 'A' gehts weiter, auch auf dem PC)!
Liebe Grüße
Luckeie