Yet another sine wave scroller. Now the wave moves also — just like in the most traditional Amiga demos. 🙂
Below is the video (new version with smoother movement):
The angle for sin function is calculated from the x-coordinate again. 360 is divided by the screen width = 640 pixels, the quotient is 0.5625. The screen position (in pixels) from 0 to 640 – 1 is multiplied by this quotient which makes the sine wave to be positioned to full screen width.
That’s the idea. In the code the starting position can be negative (minus character’s width).
The variable addAngle is added to the screen position for the sin function, which makes the wave move. If the value of addAngle is negative, the wave moves to the other direction.
Below is the code:
Import mojo2 Import brl.databuffer Function Main() New MyApp End Class MyApp Extends App Const FONT_HEIGHT:Int = 135 Const SCROLLTEXT:String = " Old School IV - Yet another sine wave scroller made in Monkey X... Now also the wave moves... " Global canvas:Canvas Global fontDat:DataBuffer Global gfxFont:Image Global gfxBG:Image Global chrStartOffset:Int Global firstChrWidth:Int Global chrEndOffset:Int Global angleAdd:Int Global lightAngle:Float, lightX:Float, lightY:Float Global x:Float Method OnCreate() canvas = New Canvas gfxBG = Image.Load("bg.png",.0,.0) gfxFont = Image.Load("font.png") fontDat = New DataBuffer(95*4*2) ' 95 characters, for each character two 4 byte integers fontDat = DataBuffer.Load("monkey://data/font.dat") canvas.SetAmbientLight .2,.3,.7 x = 0 chrStartOffset = 0 firstChrWidth = charWidth(0) chrEndOffset = getTextEndOffset() angleAdd = 0 SetUpdateRate(60) End Method OnUpdate() lightX = Cos(lightAngle) * 150 + 640 / 2 lightY = Sin(lightAngle) * 150 + 480 / 2 lightAngle = lightAngle + 1 ' If the amount of scrolling is at least the width of the first ' character to be drawn, increase the starting index where the next ' character will be drawn by one and handle the end of the string If x < -firstChrWidth Then x = firstChrWidth + x chrStartOffset = chrStartOffset + 1 If chrStartOffset > SCROLLTEXT.Length - 1 Then chrStartOffset = 0 firstChrWidth = charWidth(chrStartOffset) chrEndOffset = getTextEndOffset() If chrEndOffset > SCROLLTEXT.Length - 1 Then chrEndOffset = 0 Endif x = x - 2 ' scrolling speed End Method OnRender() canvas.PushMatrix() canvas.Scale(DeviceWidth()/640.0,DeviceHeight()/480.0) canvas.Clear canvas.SetLightType 0,1 canvas.SetLightColor 0,.7,.7,.9 canvas.SetLightPosition 0,lightX,lightY,-100 canvas.SetLightRange 0,200 For Local sx:=0 Until DeviceWidth Step 128 For Local sy:=0 Until DeviceHeight Step 128 canvas.DrawImage gfxBG,sx,sy Next Next canvas.SetBlendMode(BlendMode.Additive) ' draw string to position x drawString(x) canvas.Flush() canvas.PopMatrix() End ' This function draws text with sine wave from indexes ' chrStartOffset to chrEndOffset of the scrolltext string Function drawString(x:Int) Local angle:Int Local index:Int Local len = SCROLLTEXT.Length() Local i:Int = 0, xx:Int Local chrs:Int[] chrs = SCROLLTEXT.ToChars() xx = x For i = chrStartOffset To chrEndOffset For Local ii = 0 To fontDat.PeekInt((chrs[i]-32)*4*2 + 4) - 1 canvas.DrawRect(xx, Sin(angle) * 64 + (480 - FONT_HEIGHT) / 2, 1, FONT_HEIGHT, gfxFont, fontDat.PeekInt((chrs[i]-32)*4*2)+ii, 0, 1, FONT_HEIGHT) angle = (xx + angleAdd) * 0.5625 xx = xx + 1 Next angleAdd = angleAdd + 1 ' This moves the wave Next End ' get character's width in pixels Function charWidth:Int(offset:Int) Local chrs:Int[] chrs = SCROLLTEXT.ToChars() Return fontDat.PeekInt((chrs[offset]-32)*4*2 + 4) End Function getTextEndOffset:Int() Local chrs:Int[] Local c:Int = chrStartOffset Local textWidth:Int = 0 chrs = SCROLLTEXT.ToChars() ' Find the end offset for a character to build a string ' that's width in pixels is at least 640 + first character's width While textWidth < 640 + firstChrWidth textWidth = textWidth + charWidth(c) c = c + 1 If c > SCROLLTEXT.Length - 1 Then c = 0 Wend Return c End End Class
Check the other Old School posts for more info and feel free to use this code.