Page 1 of 1

Animated Gradient Text

Posted: Mon Jun 02, 2008 7:18 pm
by veganisafreak
This is my first proper PB program. It isn't really advanced but it's kinda kewl. Hope there are no bugs left. Save the following as "gradient text.pb":

Code: Select all

; Code tested

; Gradient Text Library

; There are procedures to draw animated or still gradient text
; and set its properties like color, speed and direction.
; There are no procedures to retrieve the properties, you
; have to access the global variables directly.

Global GT_SPEED.f = 1.0 ; number of cycles per second, must be > 0.0
Global GT_UPDATE_TIME = 1000 / GT_SPEED ; time taken for one complete cycle
Global GT_PREV_TIME = ElapsedMilliseconds() ; records the last time the text was at phase 0.0
Global GT_DIR = 0 ; scroll direction - 0 means left to right, 1 means right to left

; rgb values of first color in gradient

Global GT_R1 = 30
Global GT_G1 = 30
Global GT_B1 = 238

; rgb values of second color in gradient

Global GT_R2 = 48
Global GT_G2 = 223
Global GT_B2 = 233

; differences in rgb values of the two colors (used to calculate intermediate colors)

Global GT_RDIFF = GT_R2 - GT_R1
Global GT_GDIFF = GT_G2 - GT_G1
Global GT_BDIFF = GT_B2 - GT_B1

; background color

Global GT_BACK_R = 0
Global GT_BACK_G = 0
Global GT_BACK_B = 0

Declare.f Float(i.l)


; Draw gradient text (animated)

Procedure GradientText(x,y,Lit$,cx = 0,cy = 0)
	Protected i,j
	Protected Offset
	Protected Length
	Protected HalfLength.f
	Protected Time
	Protected Elapsed
	Protected Phase.f,Factor.f

  BackColor(RGB(GT_BACK_R,GT_BACK_G,GT_BACK_B))

	Time = ElapsedMilliseconds()
	Elapsed = Time - GT_PREV_TIME

	Phase.f = (Float(Elapsed % GT_UPDATE_TIME) / Float(GT_UPDATE_TIME))
	
	If Elapsed >= GT_UPDATE_TIME
		GT_PREV_TIME = Time - (Elapsed % GT_UPDATE_TIME)
	EndIf

	Length = Len(lit$)

	If cx = 1
		x = x - TextWidth(Lit$) / 2
	EndIf
	
	If cy = 1
		y = y - TextHeight(Lit$) / 2
	EndIf


	HalfLength.f = Float(Length) / 2.0

	For i = 0 To Length - 1
	
		If GT_DIR = 0
      If (i - (Length * Phase.f)) <= 0.0
				j = Length + (i - (Length * Phase.f))
			Else
				j = (i - (Length * Phase.f))
			EndIf
		Else
			j = Int(i + (Length * Phase.f)) % Int(Length)
		EndIf

		If Float(j) / Length >= 0.5
			Factor.f = 1.0 - (j - HalfLength.f) / HalfLength.f		
		Else
			Factor.f = j / HalfLength.f
		EndIf

		FrontColor(RGB(GT_R1 + Factor.f * GT_RDIFF,GT_G1 + Factor.f * GT_GDIFF,GT_B1 + Factor.f * GT_BDIFF))

		DrawText(x + Offset,y,Mid(Lit$,i+1,1))
		Offset = Offset + TextWidth(Mid(Lit$,i+1,1))
	Next
	
	ProcedureReturn 1
EndProcedure


; Old gradient text Procedure, not animated

Procedure GradientTextClassic(x,y,Lit$,cx = 0,cy = 0)
	Protected i
	Protected Offset
	Protected Length
	Protected HalfLength.f
	Protected Factor.f

  BackColor(RGB(GT_BACK_R,GT_BACK_G,GT_BACK_B))

	Length = Len(lit$)

	If cx = 1
		x = x - TextWidth(Lit$) / 2
	EndIf
	
	If cy = 1.
		y = y - TextHeight(Lit$) / 2
	EndIf

	HalfLength.f = Float(Length) / 2

	For i = 0 To Length - 1
		If Float(i) / Length >= 0.5
			Factor.f = 1.0 - (i - HalfLength.f) / HalfLength.f		
		Else
			Factor.f = i / HalfLength.f
		EndIf

		FrontColor(RGB(GT_R1 + Factor.f * GT_RDIFF,GT_G1 + Factor.f * GT_GDIFF,GT_B1 + Factor.f * GT_BDIFF))

		DrawText(x + Offset,y,Mid(Lit$,i+1,1))
		Offset = Offset + TextWidth(Mid(Lit$,i+1,1))
	Next
	
	ProcedureReturn 1
EndProcedure

; Set gradient colors. The first three params make up the first color (red, green blue in that order)
; the last three make up the last color.

Procedure SetGradientTextColor(R1,G1,B1,R2,G2,B2)
	GT_R1 = R1
	GT_G1 = G1
	GT_B1 = B1
	
	GT_R2 = R2
	GT_G2 = G2
	GT_B2 = B2
	
	GT_RDIFF = GT_R2 - GT_R1
	GT_GDIFF = GT_G2 - GT_G1
	GT_BDIFF = GT_B2 - GT_B1
EndProcedure

Procedure SetGradientTextBackColor(R,G,B)
  GT_BACK_R = R
  GT_BACK_G = G
  GT_BACK_B = B
EndProcedure

; Set speed of gradient text (cycles per second, must be > 0.0)

Procedure SetGradientTextSpeed(Speed.f)
	GT_SPEED.f = Speed.f
	GT_UPDATE_TIME = 1000 / GT_SPEED.f
EndProcedure

; Set anim direction - 0 means left to right (default), 1 means right to left

Procedure SetGradientTextDirection(Dir)
	GT_DIR = Dir
EndProcedure

; Synchronises (resets) gradient text to current time

Procedure SyncGradientText()
	GT_PREV_TIME = ElapsedMilliseconds()
EndProcedure

Procedure.f Float(i.l)
  Protected r.f
  !FILD dword [p.v_i]
  !FSTP dword [p.v_r] 
  ProcedureReturn r
EndProcedure
And then save the example in the same folder and run it:

Code: Select all

IncludeFile("gradient text.pb")

#WIDTH = 768
#HEIGHT = 768


window = OpenWindow(0,0,0,#WIDTH,#HEIGHT,"My Window")
InitKeyboard()
If window = 0
  MessageRequester("error","meh",0)
EndIf

If InitSprite() = 0
    MessageRequester("Error", "Can't open screen & sprite enviroment!", 0)
    End
  EndIf

screen = OpenWindowedScreen(window,0,0,#WIDTH,#HEIGHT,0,0,0)

font.l = LoadFont(0,"comic sans ms",40,#PB_Font_Bold)

SetGradientTextBackColor(0,0,0)
SetGradientTextColor(0,0,255,0,255,255)


SetGradientTextSpeed(1.0)
SetGradientTextDirection(0)
SyncGradientText()





Repeat
  ClearScreen(RGB(0,0,0))
  If StartDrawing(ScreenOutput())
    
    DrawingFont(FontID(0))

     GradientText(#WIDTH / 2,#HEIGHT / 2 - TextHeight("[ New Game ]"),"[ New Game ]",1,1)
     GradientText(#WIDTH / 2,#HEIGHT / 2,"[ High Scores ]",1,1)
     GradientText(#WIDTH / 2,#HEIGHT / 2 + TextHeight("[ Quit ]"),"[ Quit ]",1,1)
            
    StopDrawing()
    FlipBuffers()
  EndIf
  event = WindowEvent()
  Select event
    Case #PB_Event_CloseWindow
      End
  EndSelect
  ExamineKeyboard()
Until KeyboardPushed(#PB_Key_All)


End
Apologies if there are any Bad Programming PRactices. It is my first attempt.

Posted: Mon Jun 02, 2008 9:32 pm
by rsts
Cool :) Very nice effect.

cheers

Posted: Tue Jun 03, 2008 4:26 pm
by veganisafreak
Yay someone liked it. BTW you're free to use it in any games or demos or anythign really. I'd love to see my code used in some bigger project.

PS it has my own Float() function because I ported it from BB and it was behaving oddly but I think maybe that func is unnecessary but I'm not sure...

Posted: Thu Jun 05, 2008 9:26 am
by Kwai chang caine
Yeeesss !!! I like it 8)

Posted: Thu Jun 05, 2008 6:42 pm
by Ollivier
Cool effect!

Posted: Fri Jun 06, 2008 8:57 pm
by veganisafreak
Thanks loads guys you're really inspiring me to write more code! Even tho I'm half falling asleep on my keyboard!!!

Posted: Sat Jun 07, 2008 3:05 am
by nicolaus
I can't compile your code because i have all times a asm error :(
ASM is enabled in the compiler options

Posted: Sat Jun 07, 2008 2:31 pm
by Green Snake
Try this:

Code: Select all

Procedure.f Float(i.l) 
  Protected Ar.f 
  !FILD dword [p.v_i] 
  !FSTP dword [p.v_Ar] 
  ProcedureReturn Ar 
EndProcedure

If you use jaPBe: jaPBe replaces r with R.

Posted: Sat Jun 07, 2008 2:37 pm
by nicolaus
Green Snake wrote:Try this:

Code: Select all

Procedure.f Float(i.l) 
  Protected Ar.f 
  !FILD dword [p.v_i] 
  !FSTP dword [p.v_Ar] 
  ProcedureReturn Ar 
EndProcedure

If you use jaPBe: jaPBe replaces r with R.
Thanks, now it works. It shows very nice!