Seite 1 von 2

Sprite H/V-Flip on the fly

Verfasst: 15.05.2007 13:55
von TomS
Hallo.
Gibt es eine Möglichkeit Images/Sprites zur Laufzeit zu spiegeln?
Bei einem Spiel werden nämlich Wurfgeschosse je nachdem, wer an der Reihe ist, von links nach rechts oder von rechts nach links bewegt. Und es wäre gut, wenn ich nicht jedes Teil 2 mal malen müsste.

Verfasst: 15.05.2007 14:40
von Kaeru Gaman
nur mit sprite3D...

aber 2x malen müßtest dus ja garnicht.
ob du deine bildchen nun nochmal flipst und ein zweites mal speicherst,
ist doch eigentlich unerheblich, oder?

...wenn es sich um viele viele bildchen handelt:
irfanview hat eine funktion zur batch-konvertierung.
da kannst du ein ganzes verzeichnis voll bildchen in einem rutsch flippen.

Verfasst: 15.05.2007 14:49
von TomS
Naja. Du weißt schon, dann hab ich alles doppelt. Aber ok. Wenns nicht anders geht ohne 3D...

Danke.

Verfasst: 15.05.2007 14:56
von Kaeru Gaman
nuja...
im endeffekt wirst du sowieso alles doppelt im speicher haben,
oder willst, du vor jeden einzelnen display richtigflippen?

was ist, wenn du in einem frame zwei geschosse darstellen willst,
die unterschiedliche ausrichtung haben?
dann müßtest du in jedem frame 2x flippen, das wär doch wahnsinn.

also wirst du sowieso ein einziges mal zubeginn alles flippen,
und dann im speicher belassen, das ist die einzig sinnvolle anwendung.

also kannst du das auch vorab machen.
was in der GraKa platz hat, hat auch platz auf der Platte.

Verfasst: 15.05.2007 16:38
von TomS
Jup. Hast recht.
Geht ja auch sehr schnell mit Irfanview.

Verfasst: 16.05.2007 16:06
von PureLust
Hi Tom, ...

ich hab Dir hier mal eine kleine FlipSprite-Routine samt kleinem DemoCode gebastelt, mit der Du dann Sprites "on the fly" flippen kannst:

Code: Alles auswählen

EnableExplicit
Define n, StartTime, StopTime, Key$, Event

Procedure FlipSprite(SpriteNr, Direction=0)   ; Direction = 0 -> Flip horizontal, Direction <> 0 -> Flip vertical
	Protected Point1.l, Point2.l
	Protected x,y
	If IsSprite(SpriteNr) And StartDrawing(SpriteOutput(SpriteNr))
		Protected Width  = SpriteWidth(SpriteNr)-1
		Protected Height = SpriteHeight(SpriteNr)-1
		If Direction	; vertical Flip
			For x = 0 To Width
				For y = 0 To Int((Height-1)/2)
					Point1 = Point(x,y)
					Point2 = Point(x,Height-y)
					If Point1 <> Point2
						Plot(x,y,Point2)
						Plot(x,Height-y,Point1)
					EndIf
				Next y
			Next x
		Else				; horizontal Flip
			For y = 0 To Height
				For x = 0 To Int((Width-1)/2)
					Point1 = Point(x,y)
					Point2 = Point(Width-x,y)
					If Point1 <> Point2
						Plot(x,y,Point2)
						Plot(Width-x,y,Point1)
					EndIf
				Next x
			Next y
		EndIf
		StopDrawing()
	EndIf
EndProcedure

If InitSprite() And InitKeyboard() And OpenWindow(0,0,0,640,480,"FlipSprite()",#PB_Window_ScreenCentered | #PB_Window_SystemMenu)
	If OpenWindowedScreen(WindowID(0),0,0,640,480,0,0,0)
		CreateSprite(1,100,100)
		If StartDrawing(SpriteOutput(1))
			For n = 1 To 50 : Circle(Random(100), Random(100), Random(20), Random($ffffff)) : Next n
			Debug "OK"
			StopDrawing()
		EndIf
		Key$ = "h"
		Repeat
			Event = WaitWindowEvent(10)
			If Key$ = "h" Or Key$ = "v"
				StartTime = ElapsedMilliseconds()
				If Key$ = "h"
					FlipSprite(1)
				Else
					FlipSprite(1,1)
				EndIf	
				StopTime = ElapsedMilliseconds()
				ClearScreen(0)
				DisplaySprite(1,270,170)
				If StartDrawing(ScreenOutput())
					DrawText(235,190+SpriteHeight(1),"Sprite flipped within "+Str(StopTime - StartTime)+"ms",$ffffff,0)
					StopDrawing()
				EndIf
				FlipBuffers()
			EndIf
			ExamineKeyboard()
			Key$ = KeyboardInkey()
		Until Key$ = #ESC$ Or Event = #PB_Event_CloseWindow
	EndIf
EndIf
Um es plattformübergreifend zu halten, werden ausschließlich reine PureBasic-Befehle verwendet, so dass die Routine auch problemlos unter Linux und Mac laufen sollte.

Horizontal bzw. vertikal flippen kannst Du bei der Demo mit "h" und "v".

Gruß, PureLust.

Verfasst: 16.05.2007 16:45
von Kaeru Gaman
PureLust hat geschrieben:... mit der Du dann Sprites "on the fly" flippen kannst
in diesem fall wohl eher "on the snail"... :lol:

ich glaube kaum, dass TomS ein problem gehabt hätte,
zwei verschachtelte schleifen zu schreiben,
wo mittels Point/Plot die punkte vertauscht werden.

bei der zu erwartenden performance halte ich diese vorgehensweise jedoch für eher sinnfrei.... ;)

Verfasst: 16.05.2007 17:09
von PureLust
@Kaeru:
Da diese Anfrage im Anfängerforum geschrieben wurde, gehe ich nicht davon aus, das TomS das unbedingt selber so einfach hinbekommen hätte.

Aber da das ohnehin nur TomS selber beurteilen kann ob die Routine für ihn brauchbar und schnell genug ist,
war das mal wieder ein für Dich absolut typisches Posting: Zitat : ... eher sinnfrei. :?

Verfasst: 16.05.2007 17:14
von Kaeru Gaman
eine flip-routine mit point/plot hätte ich ihm gestern schon posten können,
aber aufgrund ihrer langsamkeit halte ich das nicht für praktikabel.

im gegensatz zu dir mache ich mir gedanken über die bedürfnisse der fragenden.
deshalb poste ich keine schneckenroutine, sondern führe ihn zu einer praktikablen lösung.

genausowenig wie ich einem anfänger, für den andere kollegen Arrays
für verfrüht halten, keinen thread um die ohren haue.

Verfasst: 16.05.2007 17:20
von AND51
Ich wollte mich gerade an das Erstellen einer FlpH() und FlipV() Prozedur machen, aber ich setze mich erst dran, wenn ich selber was brauche.

Kann mir einer sagen, wie ich mit DrawingBuffer() arbeite? Einfach da raus peeken?


@ Topic:
Ich finde es besser, man erstellt eine Kopie des Sprites und flippt es einmal. Dann kann man die geflippte Version immer wie ein normales Sprite anzeigen. Bevor das Sprite noch ausflippt... :lol:

Idee: Vielleicht kann man ja, wenn man DrawingBuffer() benutzt, mit Pointern arbeiten. Und dann 2 Pointer-Pixel immer mit Swap vertauschen. Wäre das nicht schnell (genug)?