Seite 1 von 2

LifeBar

Verfasst: 26.05.2005 23:11
von Rubiko
nehmen wir (wieder) ein RPG als beispiel:

bei vielen gibt es eine lifebar,
grün gefüllt wenn sie voll ist, etwas helleres grün wenn er angeschlagen ist,
bei fast den halben hp gelb, immer dunkleres bis es in den orangen ton kommt und letzendlich rot ist...

also:
voll = grün ; fast voll = helleres grün ; irgendwann gelb, gelb wird immer dumkler; bei 20 % z.B rot... das rot wird immer dunkler

hm, sorry das ich mich nicht so klar ausdrücke...
aufjedenfall:
ich will auch so ne lifebar machen, nur hab ich keine idee wie ich das anstellen soll, ich kann ja kaum für jeden millimeter eine neue bar machen

Verfasst: 26.05.2005 23:14
von MVXA
Natürlich kannst du das. Das wurde bei uralten Spielen auch so gemacht. Wenn du eine Lifebar dynamisch erstellen willst, wird das ne schwierige Sache, wenn du auch mit Sprite3D arbeiten willst.

Verfasst: 26.05.2005 23:17
von Rubiko
hm... hätte gedacht das is ein bisschen speicherfressend und es gäbe eine andre möglichkeit...
naja danke :p

Re: LifeBar

Verfasst: 27.05.2005 00:25
von Danilo
Rubiko hat geschrieben:also:
voll = grün ; fast voll = helleres grün ; irgendwann gelb, gelb wird immer dumkler; bei 20 % z.B rot... das rot wird immer dunkler
Sollen diese Farben alle in der 'Lifebar' sein, oder soll sich
der ganze Balken so färben?

Code: Alles auswählen

Dim lifebar_colors(100)

f.f = 255/25
For i = 0 To 25 : lifebar_colors(100-i)=RGB($00,$80+f*i/2,00) : Next
For i = 0 To 25 : lifebar_colors( 75-i)=RGB(i*f,$FF      ,00) : Next
For i = 0 To 25 : lifebar_colors( 50-i)=RGB($FF,$FF-f*i  ,00) : Next
For i = 0 To 25 : lifebar_colors( 25-i)=RGB($FF-f*i/2,$00,00) : Next



Procedure DrawBar(Index)
  If Index<=100 And Index>=1 And StartDrawing(ImageOutput())
    Box(0,0,50,400,lifebar_colors(Index))
    StopDrawing()
    SetGadgetState(0,ImageID())
  EndIf
EndProcedure

Procedure DrawColors(y_start,width,height,color1,color2)
  red   = Red(color1)
  green = Green(color1)
  blue  = Blue(color1)
  
  r.f = (Red(color2)   -red   )/ height
  g.f = (Green(color2) -green )/ height
  b.f = (Blue(color2)  -blue  )/ height

  For a = 0 To height
    Line(0,a+y_start,width,0,RGB(red+a*r,green+a*g,blue+a*b))
  Next a
EndProcedure


power = 100

CreateImage(0,50,400)
If StartDrawing(ImageOutput())
  DrawColors(  0,50,100,RGB($00,$80,$00),RGB($00,$FF,$00))
  DrawColors(100,50,100,RGB($00,$FF,$00),RGB($FF,$FF,$00))
  DrawColors(200,50,100,RGB($FF,$FF,$00),RGB($FF,$00,$00))
  DrawColors(300,50,100,RGB($FF,$00,$00),RGB($80,$00,$00))
  StopDrawing()
EndIf

OpenWindow(0,0,0,160,420,#PB_Window_SystemMenu|#PB_Window_ScreenCentered,"Lifebar")
  CreateGadgetList(WindowID())
  ImageGadget(2,100,10,50,400,ImageID())
  ImageGadget(0,10,10,50,400,CreateImage(1,50,400))
  TrackBarGadget(1,70,10,20,400,1,100,#PB_TrackBar_Vertical)
  SetGadgetState(1,power)
  DrawBar(power)


Repeat
  Select WaitWindowEvent()
    Case #PB_Event_Closewindow
      Break
    Case #PB_Event_Gadget
      Select EventGadgetID()
        Case 1
          power=GetGadgetState(1)
          DrawBar(power)
      EndSelect
  EndSelect
ForEver
Mit 2 Farbverläufen zwischen 3 Farben müßte es aber
auch ausreichen:

Code: Alles auswählen

Dim lifebar_colors(100)

f.f = 255/50
; For i = 0 To 25 : lifebar_colors(100-i)=RGB($00,$80+f*i/2,00) : Next
; For i = 0 To 25 : lifebar_colors( 75-i)=RGB(i*f,$FF      ,00) : Next
; For i = 0 To 25 : lifebar_colors( 50-i)=RGB($FF,$FF-f*i  ,00) : Next
; For i = 0 To 25 : lifebar_colors( 25-i)=RGB($FF-f*i/2,$00,00) : Next
For i = 0 To 50 : lifebar_colors(100-i)=RGB($00+f*i,$80+f*i/2  ,00) : Next
For i = 0 To 50 : lifebar_colors( 50-i)=RGB($FF-f*i/2,$FF-f*i,00) : Next


Procedure DrawBar(Index)
  If Index<=100 And Index>=1 And StartDrawing(ImageOutput())
    Box(0,0,50,400,lifebar_colors(Index))
    StopDrawing()
    SetGadgetState(0,ImageID())
  EndIf
EndProcedure

Procedure DrawColors(y_start,width,height,color1,color2)
  red   = Red(color1)
  green = Green(color1)
  blue  = Blue(color1)
  
  r.f = (Red(color2)   -red   )/ height
  g.f = (Green(color2) -green )/ height
  b.f = (Blue(color2)  -blue  )/ height

  For a = 0 To height
    Line(0,a+y_start,width,0,RGB(red+a*r,green+a*g,blue+a*b))
  Next a
EndProcedure


power = 100

CreateImage(0,50,400)
If StartDrawing(ImageOutput())
;   DrawColors(  0,50,100,RGB($00,$80,$00),RGB($00,$FF,$00))
;   DrawColors(100,50,100,RGB($00,$FF,$00),RGB($FF,$FF,$00))
;   DrawColors(200,50,100,RGB($FF,$FF,$00),RGB($FF,$00,$00))
;   DrawColors(300,50,100,RGB($FF,$00,$00),RGB($80,$00,$00))
  DrawColors(  0,50,200,RGB($00,$80,$00),RGB($FF,$FF,$00))
  DrawColors(200,50,200,RGB($FF,$FF,$00),RGB($80,$00,$00))
  StopDrawing()
EndIf

OpenWindow(0,0,0,160,420,#PB_Window_SystemMenu|#PB_Window_ScreenCentered,"Lifebar")
  CreateGadgetList(WindowID())
  ImageGadget(2,100,10,50,400,ImageID())
  ImageGadget(0,10,10,50,400,CreateImage(1,50,400))
  TrackBarGadget(1,70,10,20,400,1,100,#PB_TrackBar_Vertical)
  SetGadgetState(1,power)
  DrawBar(power)


Repeat
  Select WaitWindowEvent()
    Case #PB_Event_Closewindow
      Break
    Case #PB_Event_Gadget
      Select EventGadgetID()
        Case 1
          power=GetGadgetState(1)
          DrawBar(power)
      EndSelect
  EndSelect
ForEver

Verfasst: 27.05.2005 01:58
von zigapeda
Ich glaube er hat gemeint das der ganze balken eine farbe hat und je nach dem wie voll er ist färbt er sich dem entsprechend oder?

Verfasst: 27.05.2005 02:10
von Ynnus
Das Problem dürfte wohl weniger das Einfärben eines immer gleichgroßen Balkens sein, als mehr diesen Balken größentechnisch zu ändern UND einzufärben. Denn dann würde man 3D-Sprites verwenden, auf die man afaik nicht als buffer zeichnen kann. (Allerdings auf die 2D-Sprites, die als Textur verwendet werden. Dann könnte man die Textur einfärben und daraus ein neues 3D-Sprite erstellen).

Verfasst: 27.05.2005 10:57
von Danilo
Sunny hat geschrieben:Das Problem dürfte wohl weniger das Einfärben eines immer
gleichgroßen Balkens sein, als mehr diesen Balken größentechnisch
zu ändern UND einzufärben.
Da sehe ich kein Problem.
Sunny hat geschrieben:Denn dann würde man 3D-Sprites verwenden,
Kann man genauso auch mit normalen Sprites machen.
Für die Größenänderung hilft ClipSprite().

Hier das ganze für einen Screen. Gleiche Prozeduren, nur
SpriteOutput() statt ImageOutput().

Code: Alles auswählen

Dim lifebar_colors(100)

f.f = 255/50
; For i = 0 To 25 : lifebar_colors(100-i)=RGB($00,$80+f*i/2,00) : Next
; For i = 0 To 25 : lifebar_colors( 75-i)=RGB(i*f,$FF      ,00) : Next
; For i = 0 To 25 : lifebar_colors( 50-i)=RGB($FF,$FF-f*i  ,00) : Next
; For i = 0 To 25 : lifebar_colors( 25-i)=RGB($FF-f*i/2,$00,00) : Next
For i = 0 To 50 : lifebar_colors(100-i)=RGB($00+f*i,$80+f*i/2  ,00) : Next
For i = 0 To 50 : lifebar_colors( 50-i)=RGB($FF-f*i/2,$FF-f*i,00) : Next


Procedure DrawBar(Index)
  If Index<=100 And Index>=1 And StartDrawing(SpriteOutput(0))
    Box(0,0,50,400,lifebar_colors(Index))
    StopDrawing()
  EndIf
EndProcedure


Procedure DrawColors(y_start,width,height,color1,color2)
  red   = Red(color1)
  green = Green(color1)
  blue  = Blue(color1)
  
  r.f = (Red(color2)   -red   )/ height
  g.f = (Green(color2) -green )/ height
  b.f = (Blue(color2)  -blue  )/ height

  For a = 0 To height
    Line(0,a+y_start,width,0,RGB(red+a*r,green+a*g,blue+a*b))
  Next a
EndProcedure


Procedure ClipBars(power)
  length = power*4
  y      = 100*4-length
  ClipSprite(0,0,y,50,length)
  ClipSprite(1,0,y,50,length)
  ProcedureReturn y
EndProcedure


#w = 800
#h = 600
#n = "lifebar"


If InitSprite()=0 Or InitKeyboard()=0
  MessageRequester("ERROR","Cant create sprite !"):End
EndIf

If OpenScreen(#w,#h,32,#n)=0
  If OpenScreen(#w,#h,32,#n)=0
    If OpenScreen(#w,#h,32,#n)=0
      If OpenScreen(#w,#h,32,#n)=0
        MessageRequester("ERROR","Cant open screen !"):End
EndIf:EndIf:EndIf:EndIf

If CreateSprite(0,50,400)=0 Or CreateSprite(1,50,400)=0
  CloseScreen()
  MessageRequester("ERROR","Cant create sprite !"):End
EndIf

If StartDrawing(SpriteOutput(1))
;   DrawColors(  0,50,100,RGB($00,$80,$00),RGB($00,$FF,$00))
;   DrawColors(100,50,100,RGB($00,$FF,$00),RGB($FF,$FF,$00))
;   DrawColors(200,50,100,RGB($FF,$FF,$00),RGB($FF,$00,$00))
;   DrawColors(300,50,100,RGB($FF,$00,$00),RGB($80,$00,$00))
  DrawColors(  0,50,200,RGB($00,$80,$00),RGB($FF,$FF,$00))
  DrawColors(200,50,200,RGB($FF,$FF,$00),RGB($80,$00,$00))
  StopDrawing()
EndIf

power = 100

DrawBar(power)


Repeat
  ExamineKeyboard()
  FlipBuffers()
  If IsScreenActive()
    ClearScreen(0,0,0)
    If KeyboardPushed(#PB_Key_Up)
      If power<100
         power +1
         DrawBar(power)
         offset_y = ClipBars(power)
      EndIf
    EndIf
    If KeyboardPushed(#PB_Key_Down)
      If power>1
         power -1
         DrawBar(power)
         offset_y = ClipBars(power)
      EndIf
    EndIf

    DisplaySprite(0,    50,50+offset_y)
    DisplaySprite(1,#w-100,50+offset_y)

    If StartDrawing(ScreenOutput())
      DrawingMode(1)
      FrontColor($FF,$FF,$FF)
      Locate(30,20)
      DrawText("Cursor up/down to change the bars")
      StopDrawing()
    EndIf

  EndIf
Until KeyboardPushed(#PB_Key_Escape)

Verfasst: 27.05.2005 12:06
von Ynnus
Wenn man eine feste Größe für die Lifebar hat, sollte es mit 2D-Sprites auch kein Problem sein, da hast du Recht. Allerdings, bei mehreren Lifebars mit unerschiedlichster Größen, mal kleiner, mal größer und breiter oder länger, muss das Geclippte Sprite jeweils immmer so groß sein, dass es für das größte passt. Das macht das Handling mit 2D-Sprites wesentlich schwieriger als das 3D-Sprite mal eben zu stretchen.

Wer sich mit OpenGL auskennt, der weiß, dass man dort ganz easy die Größe der Sprites ändern kann (Sind da ja Vertex-Modelle mit Textur drauf) und auch per glColor4f-Function die Farbwerte festlegen kann. Damit lässt sich die Textur ganz leicht in die gewünschten Farbe einfärben, ohne großes Neuzeichnen der Farben auf die Textur oder so. Wer also komfortables Handling damit haben will, sollte OpenGL einbinden. :)
(Das Einbinden selbst ist wieder nicht so komfortabel, dafür aber später eine Lifebar wie hier umso mehr).

Verfasst: 27.05.2005 12:22
von Danilo
Sunny hat geschrieben:Wenn man eine feste Größe für die Lifebar hat, sollte es mit 2D-Sprites auch kein Problem sein, da hast du Recht. Allerdings, bei mehreren Lifebars mit unerschiedlichster Größen, mal kleiner, mal größer und breiter oder länger, muss das Geclippte Sprite jeweils immmer so groß sein, dass es für das größte passt. Das macht das Handling mit 2D-Sprites wesentlich schwieriger als das 3D-Sprite mal eben zu stretchen.
Auch wenn Du in Deinem Spiel 100 unterschiedlich große 'Lifebars'
gleichzeitig auf dem Screen ausgeben mußt, sollte das eig. kein
Problem sein.

Ich habe "power" extra von 1 bis 100 gewählt, da es dadurch
gleichzeitig eine Prozentangabe ist. In Prozent kann man gut
rechnen, egal wie groß der Balken ist.

Für Rubiko ist es IMHO das Einfachste: Leicht zu benutzen und
läuft einfach mit Standard-PB überall wo die Sprite- und Drawing-
Funktionen verfügbar sind. Habe es ja hier auf Linux getestet.

Sprite3D ist im Moment nur auf Windows verfügbar und bei
OpenGL mußt Du alle Funktionen erstmal selbst schreiben.
Angefangen vom Screen öffnen über Sprites bis hin zu
Zeichenfunktionen. Natürlich platformunabhängig.

Aber hast schon Recht: Warum die einfachste Lösung nehmen
wenn es auch kompliziert geht? ;)

BTW: Hast Du zufällig ein PB-OpenGL-Beispiel rumliegen was
so etwas zeigt und auf Windows und Linux läuft?
Damit könnte Rubiko vielleicht mehr anfangen als mit der Theorie.

Verfasst: 27.05.2005 14:18
von Ynnus
Ich hab OpenGL bisher leider nur in Verbindung mit C/WinAPI verwendet, mit PB noch überhaupt nicht. Und dann eben durch WinAPI auch nicht Plattformabhängig.

Zum Thema kompliziert machen: Da ich meine Grafiken sowieso nur noch mit OpenGL mache, macht es da auch keinen Umstand. Mit PB erst einmal OpenGL einrichten könnte komplexer werden, da hab ich keine Erfahung, aber wenn der RenderContext erstmal da ist, ist es recht einfach, Texturen beliebig groß und beliebig gefärbt darzustellen.

EDIT: Spätestens wenn du > 100 Objekte mit Lifebar auf dem Monitor hast, wird es umständlich, immer das ganze Sprite neu mit der gewünschen Farbe zu übermalen.
Dann wird PB auch Probleme bekommen, mit 100 Draw-Operationen pro Frame. Da ist Hardwarebeschleunigt wie OpenGL doch besser, dort sind mehrere millionen Farbwechsel pro Frame drinne. (Hab ich zumindest neulich in einem Benchmark mal gelesen, selbst noch nicht getestet).