Numeric Ramp
BlitzMax Forums/BlitzMax Programming/Numeric Ramp
| ||
I recently acclimated myself to the usage of pointers in BlitzMax, and I made a few PureData-inspired functions that I thought I'd share :)'ramp function.bmx '============================= Function Ramp(f:Float Var, value:Float, milliseconds:Int, override:Int=True) Local target:Float Ptr = Varptr(f) Local r:TRamp = TRamp.Create(target, value, milliseconds, override) End Function '============================= Function ReverseRamp(f:Float Var, milliseconds:Int=0) Local target:Float Ptr = Varptr(f) Local ramp1:TRamp = TRamp.FindRamp(target) If ramp1=Null Then Return If milliseconds = 0 Local time_passed:Int = MilliSecs()-ramp1.start_time milliseconds = time_passed EndIf Local ramp2:TRamp = TRamp.Create(target, ramp1.start_value, milliseconds, True) End Function '============================= Function HaltRamp(f:Float Var) Local target:Float Ptr = Varptr(f) Local ramp:TRamp = TRamp.FindRamp(target) If ramp<>Null ramp.Destroy() Return EndIf End Function '============================= '============================= Type TRamp Global global_list:TList = New TList '============================= Field global_link:TLink '============================= Method New() global_link = global_list.AddLast(Self) End Method '============================= Field target:Float Ptr Field start_value:Float Field start_time:Int Field end_value:Float Field end_time:Int Field duration:Int Field previous_value:Float Field difference:Float '============================= Function FindRamp:TRamp(target:Float Ptr) Local ramp:TRamp For ramp=EachIn global_list If ramp.target=target Return ramp EndIf Next Return Null End Function '============================= Function Create:TRamp(target:Float Ptr, value:Float, duration:Int, override:Int=True) Local ramp:TRamp=FindRamp(target) If ramp<>Null Select override Case True ramp.Destroy() 'new ramps override old ones Case False Return Null 'old ramps override new ones Default End Select EndIf '============================= ramp:TRamp = New TRamp ramp.target = target ramp.start_value = target[0] ramp.start_time = MilliSecs() ramp.end_value = value ramp.end_time = ramp.start_time+duration ramp.duration = duration ramp.difference = ramp.end_value-ramp.start_value ramp.previous_value=target[0] Return ramp End Function '============================= Function Update_All() Local ramp:TRamp For ramp=EachIn global_list ramp.Update() Next End Function '============================= Function Print_All() Local ramp:TRamp For ramp=EachIn global_list Print ramp.ToString() Next End Function '============================= Method Update() If target[0]<>previous_value Destroy() 'ramp is interrupted (doesn't respond if the variable is set to it's current value) Return EndIf Local current_time:Int = MilliSecs() If current_time >= end_time target[0]=end_value Destroy() Return EndIf Local time_passed:Float=current_time-start_time target[0] = start_value + time_passed*difference/duration previous_value = target[0] End Method '============================= Method Destroy() global_link.Remove() End Method '============================= Method ToString:String() Return "start_value: "+start_value+" end_value: "+end_value+" duration: "+duration End Method End Type '============================= here's a usage example. controls: -spacebar ramps myfloat to a random value over a random interval -backspace reverses an in-progress ramp to return myfloat to it's previous value -left click anywhere to set myfoat's value (this interrupts an in-progress ramp) -right click anywhere to halt an in-progress ramp 'ramp example.bmx '============================= SuperStrict Include "ramp function.bmx" Graphics 400, 300 '============================= '============================= Global myfloat:Float=150 '============================= '============================= While Not KeyHit(KEY_ESCAPE) '============================= If KeyHit(KEY_SPACE) Ramp(myfloat, Rnd(0, 300), Rnd(500, 2000)) EndIf '============================= If KeyHit(KEY_BACKSPACE) ReverseRamp(myfloat) EndIf '============================= If MouseHit(1) myfloat=MouseY() EndIf '============================= If MouseHit(2) HaltRamp(myfloat) EndIf '============================= TRamp.Update_All() '============================= Local ramp:TRamp For ramp=EachIn TRamp.global_list SetColor 255, 255, 0 DrawOval 190, ramp.end_value-10, 20, 20 SetColor 0, 0, 255 DrawOval 190, ramp.start_value-10, 20, 20 Next '============================= SetColor 255, 255, 255 DrawOval 190, myfloat-10, 20, 20 '============================= Flip Cls Wend End '============================= Pretty self-explanatory, tell me what you think :) Comments, suggestions, and let me know if something like this already exists. |