Unlimited Objects Source Code

In my old blog post I gave some idea how to implement “unlimited objects” program. In the original video I used 16 canvases with 16 images + the actual visible canvas. Two canvases only is sufficient.

In the source (Cerberus X) below, no external graphics files are needed:

Import mojo2
Function Main()
	New MyApp
End
Class MyApp Extends App
	
	Field gfxCopy:Image[16]
	Field ccanvas:Canvas
	Field counter:Int
	Field angle:Float	
	Field canvas:Canvas
	
	Field scaleX:Float, scaleY:Float
		
	Field x:Float, y:Float
	Field r:Float
	
	Method OnCreate()
			
		canvas = New Canvas()
		counter = 0
		
		For Local i:Int = 0 To 15
			gfxCopy[i] = New Image(640,480,.0,.0)
		Next
		
		ccanvas = New Canvas(gfxCopy[0])
		
		scaleX = DeviceWidth / 640
		scaleY = DeviceHeight / 480
		
		r = 100
		SetUpdateRate(60)
	End
	
	Method OnUpdate()
	End
	
	Method OnRender()
		
		angle = angle + 2
		x = Cos(angle) * r + 640 / 2
		y = Sin(angle) * r + 480 / 2
		
		r = r + 0.1
		counter = counter + 1
		If counter = 16 Then counter = 0
				
		ccanvas.SetRenderTarget(gfxCopy[counter])
		ccanvas.SetColor(1,1,0)
		ccanvas.DrawCircle(x,y,32)
		ccanvas.SetColor(1,0,1)
		ccanvas.DrawCircle(x,y,30)
		
		ccanvas.Flush()
		
		canvas.PushMatrix()
		canvas.Scale(scaleX,scaleY)
		
		canvas.Clear	
		canvas.DrawImage(gfxCopy[counter],0,0)
		canvas.Flush()
		canvas.PopMatrix()
						
	End
	
End Class

The program gives different output, if the calculations are in OnUpdate() on HTML5 target.

Below is the old video I’ve made previously:

Good Commodore 64 games I’ve previously forgotten and which could be re-made

In my old blog post I discussed my computer gaming history with Vic 20 And Commodore 64. Of course, I forgot some nice games that as re-made could be good games even today.

First, I’d like to mention the game I have discussed before: Stix.

I’ve even started to make a remake of this game to Android. Though, I think this project will take some time to get finished.

One game we played with my friends as youngsters a lot is Artillery Duel.

This could be a nice Android game with possibility to play with others via the internet.

Omega Race has been for example to the Amiga as shareware remake game. It would be nice to make some kind of version of this game to Android, too. Below a video of the Vic 20 version of this game:

I’ve started to make a remake also from this game to Android…

Cataball is also something, that could be interesting to make to Android platform. Video of the Commodore 64 version:

With nice backgrounds with parallax scrolling, the result could be nice.

Also, a version of Gyruss to Android could be nice.

My Contribution to Music Game Jam 2018

I participated in Music Game Jam 2018 on itch.io. My game is quickly made musical memory game. Find match to part of the tune you hear and build a tune…

I have used as in-game music my first PC tracker music module, that is in fact unfinished… To the title screen I made strange music background with ProTrekkr — sounds like old school C64 music! ๐Ÿ™‚

Below is the video of my contribution:

I will probably be left to the bottom positions of the Jam with my game.. At least I participated and tried to to make something nice in retro spirit..

3D Stars As Lines

I must have been really tired when I coded & posted the old 3D stars codes… Anyway, here’s code for 3D stars as lines.

Below the video:

To get the stars drawn as lines is really simple. In the 2D world to draw a line we need x1, y1, x2 and y2. In the projection from 3D space, we simple add for example 4 to the z-coordinate of a point so that, the other point is further away and we get two points to the 2D world.

Below is the main part of the Monkey X source code:

‘ Projection from 3D space to 2D screen For Local i:Int = 0 To STARS – 1 Local x1,x2,y1,y2:Float z[i] = z[i] – 1 If z[i] < 10 Then z[i] = Rnd(50,200) sx = x[i] / z[i] * 200 + 320 sy = y[i] / z[i] * 200 + 240 shade = 1 – z[i] / 200 canvas.SetColor shade,shade,shade x1 = x[i] / z[i] * 200 + 320 x2 = x[i] / (z[i] + 4) * 200 + 320 y1 = y[i] / z[i] * 200 + 240 y2 = y[i] / (z[i] + 4) * 200 + 240 canvas.DrawLine(x1,y1,x2,y2) Next

For the end the source code in full:

Import mojo2 Function Main:Int() New MyApp Return 0 End Class MyApp Extends App Const STARS:Int = 280 Field x:Float[STARS],y:Float[STARS],z:Float[STARS] Field canvas:Canvas Field sx:Float, sy:Float Method OnCreate() For Local i:Int = 0 To STARS – 1 x[i] = Rnd(-50,50) y[i] = Rnd(-50,50) z[i] = Rnd(50,200) Next canvas = New Canvas() SetUpdateRate(60) End Method OnUpdate() End Method OnRender() Local shade:Float canvas.PushMatrix() canvas.Clear() ‘ Projection from 3D space to 2D screen For Local i:Int = 0 To STARS – 1 Local x1,x2,y1,y2:Float z[i] = z[i] – 1 If z[i] < 10 Then z[i] = Rnd(50,200) sx = x[i] / z[i] * 200 + 320 sy = y[i] / z[i] * 200 + 240 shade = 1 – z[i] / 200 canvas.SetColor shade,shade,shade x1 = x[i] / z[i] * 200 + 320 x2 = x[i] / (z[i] + 4) * 200 + 320 y1 = y[i] / z[i] * 200 + 240 y2 = y[i] / (z[i] + 4) * 200 + 240 canvas.DrawLine(x1,y1,x2,y2) Next canvas.Flush() canvas.PopMatrix() End End Class

Feel free to use this code.

Sine Wave Scroller in Monkey2

Today’s little code, sine scroller in Monkey2. In the previous post you can download the code and data files for plain scroller. In this project same data files are used. Let’s take a look at the video:

The scrolling isn’t very smooth in the video, but try the code:

Namespace myapp

#Import "<std>"
#Import "<mojo>"


#Import "gfx/bg.jpg"
#Import "fonts/DoctorJekyllNF.ttf"

Using std..
Using mojo..


Class MyWindow Extends Window

Const SCROLLTEXT:String = "                              Sine scroller programmed in Monkey2 programming language...  One of the traditional sine scrollers seen in Amiga demos...                   "

Field bg:Image
Field scrollString:String
Field scrollX:Int
Field scrollY:Int
Field chrStartOffset:Int
Field firstChrWidth:Int
Field chrEndOffset:Int
Field font:Font

Field angl:Float

	Method New( title:String="Simple sine scroller",width:Int=640,height:Int=480,flags:WindowFlags=Null )

		Super.New( title,width,height,flags )

		bg = Image.Load("asset::bg.jpg")
		font = Font.Load("asset::DoctorJekyllNF.ttf",80)
		
		
		chrStartOffset = 0
		firstChrWidth = font.TextWidth(SCROLLTEXT.Mid(0,1))
		scrollX = 0
		
	End

	Method OnRender( canvas:Canvas ) Override
	
		App.RequestRender()

		canvas.DrawImage(bg,0,0)
		canvas.Font = font
		canvas.Color = Color.Orange
		
					
		If scrollX < -firstChrWidth Then
			
			chrStartOffset = chrStartOffset + 1

			If chrStartOffset > SCROLLTEXT.Length - 1 Then chrStartOffset = 0
			
			firstChrWidth = font.TextWidth(SCROLLTEXT.Mid(chrStartOffset,1))
			chrEndOffset = getTextEndOffset()
			
			If chrEndOffset > SCROLLTEXT.Length - 1 Then chrEndOffset = 0
			
			scrollX = 0
		Endif
				
		
		
				
		Local s:String
		Local position:Int = 0

		For Local c:Int = 0 To scrollString.Length - 1
			s = scrollString.Mid(c,1)
		
			Local angle:Float = ((640.0 / scrollString.Length) / 360.0 * 2) * (Pi / 180) + 8 * (chrStartOffset + c) * (Pi / 180) + angl
			
			scrollY = 200 + Sin(angle) * 80
			canvas.DrawText(s,scrollX+position,scrollY)
			
			position = position + font.TextWidth(scrollString.Mid(c,1))
		Next
		
		scrollX = scrollX - 2
		angl = angl - (Pi / 180) * 4
	End

	
	Method getTextEndOffset:Int()
		Local c:Int = chrStartOffset
		Local textWidth:Int = 0
		
		scrollString = ""
		
		' 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
			
			scrollString = scrollString + SCROLLTEXT.Mid(c,1)
			c = c + 1
						
			If c > SCROLLTEXT.Length - 1 Then c = 0
			
			textWidth = font.TextWidth(scrollString)
		Wend
		
		Return c
		
	End	
		
End

Function Main()

	New AppInstance
	
	New MyWindow
	
	App.Run()
End

The idea is to build a string (“scrollString”) that’s characters are drawn one by one to the screen in order to achieve the sine wave effect.

Feel free to use this code.

Simple text scrollers in Monkey X and Monkey2

I coded today simple text scrollers in Monkey X and Monkey2. When the old school bug had bitten me I coded among other things the following:

This night it’s time to just simple text scrollers code.

Let’s take a look at the result of the Monkey X code:

The source code:

Import mojo2 Import brl.databuffer Import mojo.audio Function Main() New MyApp End Class MyApp Extends App Const FONT_HEIGHT:Int = 153 Const SCROLLTEXT:String = ” Testing plain text scrolling code… Coded in good old Monkey X Pro… The picture is from my home, when I was living in Turku, Finland… ” field canvas:Canvas field fontDat:DataBuffer field gfxFont:Image field gfxBG:Image field chrStartOffset:Int field firstChrWidth:Int field chrEndOffset:Int field x:Float Method OnCreate() canvas = New Canvas gfxBG = Image.Load(“bg.jpg”,.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”) x = 0 chrStartOffset = 0 firstChrWidth = charWidth(0) SetUpdateRate(15) End Method OnUpdate() ‘ Scroll the amount of width of the character in the font If x < -firstChrWidth Then chrStartOffset = chrStartOffset + 1 If chrStartOffset > SCROLLTEXT.Length – 1 Then chrStartOffset = 0 firstChrWidth = charWidth(chrStartOffset) chrEndOffset = getTextEndOffset() If chrEndOffset > SCROLLTEXT.Length – 1 Then chrEndOffset = 0 x = 0 Endif x = x – 2 ‘ scrolling speed End Method OnRender() canvas.PushMatrix() ‘ canvas.Scale(DeviceWidth()/640.0,DeviceHeight()/480.0) canvas.SetBlendMode(BlendMode.Alpha) canvas.DrawImage(gfxBG,0,0) canvas.SetBlendMode(BlendMode.Additive) ‘ draw string to position x drawString(x) canvas.Flush() canvas.PopMatrix() End ‘ This function draws text from indexes ‘ chrStartOffset to chrEndOffset of the scrolltext string Method drawString(x:Int) Local xx:float Local angle:Int Local index:Int Local len = SCROLLTEXT.Length() Local chrs:Int[] chrs = SCROLLTEXT.ToChars() Local prevChrWidth:Int For Local i:Int = chrStartOffset To chrEndOffset canvas.DrawRect(x+prevChrWidth, (480 – FONT_HEIGHT) / 2, fontDat.PeekInt((chrs[i]-32)*4*2 + 4), FONT_HEIGHT, gfxFont, fontDat.PeekInt((chrs[i]-32)*4*2), 0, fontDat.PeekInt((chrs[i]-32)*4*2 + 4), FONT_HEIGHT) prevChrWidth = prevChrWidth + fontDat.PeekInt((chrs[i]-32)*4*2 + 4) Next End ‘ get character’s width in pixels Method charWidth:Int(offset:Int) Local chrs:Int[] chrs = SCROLLTEXT.ToChars() Return fontDat.PeekInt((chrs[offset]-32)*4*2 + 4) End Method getTextEndOffset:Int() Local chrs:Int[] Local c:Int = chrStartOffset Local textWidth:Int = 0 chrs = SCROLLTEXT.ToChars() ‘ Find the endoffset 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

For the font I’ve used my Font 2 PNG and its data file. Notice, that the update rate is only 15, change that to 60.

For the first time I made a text scroller in Monkey2 too. The result is in video below:

As you can see, the code is a little different:

Namespace myapp
#Import ""
#Import ""
#Import "gfx/bg.jpg"
#Import "fonts/DoctorJekyllNF.ttf"
Using std..
Using mojo..
Class MyWindow Extends Window
Const SCROLLTEXT:String = "                              Testing simple text scrolling code written in Monkey2...  Later it's time again for old school sine scrollers...                     "
Field bg:Image
Field scrollString:String
Field scrollX:Int
Field chrStartOffset:Int
Field firstChrWidth:Int
Field chrEndOffset:Int
Field font:Font
	
	Method New( title:String="Simple mojo app",width:Int=640,height:Int=480,flags:WindowFlags=Null )
		Super.New( title,width,height,flags )
		bg = Image.Load("asset::bg.jpg")
		font = Font.Load("asset::DoctorJekyllNF.ttf",80)
		
		scrollX = 0
		chrStartOffset = 0
		firstChrWidth = font.TextWidth(SCROLLTEXT.Mid(0,1))
	End
	Method OnRender( canvas:Canvas ) Override
	
		App.RequestRender()
		canvas.DrawImage(bg,0,0)
		canvas.Font = font
		canvas.Color = Color.Orange
				
		If scrollX < -firstChrWidth Then
			chrStartOffset = chrStartOffset + 1
			
			If chrStartOffset > SCROLLTEXT.Length - 1 Then chrStartOffset = 0
			
			firstChrWidth = font.TextWidth(SCROLLTEXT.Mid(chrStartOffset,1))
			chrEndOffset = getTextEndOffset()
			
			If chrEndOffset > SCROLLTEXT.Length - 1 Then chrEndOffset = 0
			
			scrollX = 0
		Endif
				
		canvas.DrawText(scrollString,scrollX,200)
		scrollX = scrollX - 2
		
	End
	
	Method getTextEndOffset:Int()
		Local c:Int = chrStartOffset
		Local textWidth:Int = 0
		
		scrollString = ""
		
		' 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
			
			scrollString = scrollString + SCROLLTEXT.Mid(c,1)
			textWidth = textWidth + font.TextWidth(SCROLLTEXT.Mid(c,1))
			c = c + 1
						
			If c > SCROLLTEXT.Length - 1 Then c = 0
			
		Wend
		
		Return c
		
	End	
		
End
Function Main()
	New AppInstance
	
	New MyWindow
	
	App.Run()
End

I used to have a download package available for the sources with gfx, but I’m now on free plan at WordPress.com…

Later it’s time to again for sine wave scrollers… ๐Ÿ™‚

Have fun!

Recently published to Android: Calculus

I published recently initial version 1.0 of a calculusย program called Calculus toย Android. I have plans to publish PC version too, when the program is developed further.

The program differentiates and integrates user given polynomial and simplifies all the fractions. The coefficients can be 4 digits long. I haven’t given a limit to amount of terms in the polynomial, the available memory is the only limit.

The coefficients can be fractional too — and of course negative or positive. Next version will be out soon, which will improve some features of the program and add some features too. I’m not aware of any actual bugs in the program at the moment.

See below a demonstration video of the program (in the video Calculus is compiled to PC and used with the mouse):

Calculus is free educational program.

Notice that when integrating the polynomial, Calculus doesn’t give the integral constant.

Memorable Melodies v1.3 available

Memorable Melodies v1.3 is written in Monkey2 programming language. Now it is tested to be working properly on newer Android devices!

Remember there is a cheat in the game: Tap at the upper right corner of the screen and all the mistakes are cleared.

In the code now MusicState() isn’t tested at all, instead the duration of the played music.

Do try it! ๐Ÿ™‚ It’s free witout adds.

 

 

Inside the Julia Set – Voxel Fractals

Today it was fractal day for me… As a result two voxel fractal landscape demonstrations with the Monkey2 programming language. The demonstrations are based on an example program that comes with Monkey2.

The first experiment is below:

I’ve used my Fractals program to generate the 2D fractal and the Monkey2 program renders 3D landscape of it. The fractal is the famous “dragon” shape of the Julia set.

Below the second experiment:

Looks a bit better… The little dot in the 2D fractal shows the location where we’re going inside the Julia set.

Take a trip inside a fractal… ๐Ÿ™‚