Touching a real time scaled and middle handled image in Monkey X

One of my Android projects is getting further every now and then… I’d like to share here something that is related to that project: Touching a real time scaled middle handled image. This version uses Mojo2 and OpenGL2. OpenGL2 is only needed for storing the pixel information of the image (LoadImageData).

You might want check the video:

The image that the program uses, has transparent pixels. Touching the image is done by checking is the alpha component of image’s pixel <> 0. If it is, the image has been touched. With mojo2 every image is middle handled by default. This is good for real time scaling and rotation.

The program below tests if pre-loaded image has been touched while it is real time scaled.

Import mojo2
Import opengl.gles20

Function Main()
	New MyApp
End


Class MyApp Extends App
	
	Const WIDTH:Float = 80
	Const HEIGHT:Float = 80

	Global canvas:Canvas
	
	Global gfxBG:Image
	Global gfxBall:Image
	Global BallData:DataBuffer
	
	Global scaleX:Float, scaleY:Float
	Global scale:Float
	Global touchX:Float, touchY:Float
	Global angle:Float
	Global x:Int, y:Int
	Global hit:Bool = False
	
	Method OnCreate()
		
		SetDeviceWindow(800,600,0)
		
		canvas = New Canvas
		
		scaleX = DeviceWidth() / 800.0
		scaleY = DeviceHeight() / 600.0

		gfxBG = Image.Load("bg.png",0,0)
	    gfxBall = Image.Load("ball.png")	' By default this image is middle handled ("ball.png",.5,.5)

		' Information of "ball.png" image is loaded here
	    BallData = LoadImageData("monkey://data/ball.png")
		
		SetUpdateRate(60)
		
	End
	
	Method OnUpdate()

		Local coordX:Float, coordY:Float
		
		hit = False
		
		touchX = TouchX() / scaleX
		touchY = TouchY() / scaleY
		
		scale = 2 - Cos(angle) * 1.5
		angle = angle + 2

		coordX = ((800 - WIDTH) / 2 + (WIDTH * (1-scale)) / 2.0)
		coordY = ((600 - HEIGHT) / 2 + (HEIGHT * (1-scale)) / 2.0)

		If touchX - coordX < WIDTH * scale And touchX - coordX > 0 And touchY - coordY < HEIGHT * scale And touchY - coordY > 0 Then
		
			Local pointX:Int
			Local pointY:Int
			Local data:Int

			pointX = Int(touchX - coordX) / scale ' pointX gets values 0..image width - 1
			pointY = Int(touchY - coordY) / scale ' pointY gets values 0..image height - 1

			' BallData holds the original color information of the image
			data = BallData.PeekInt(pointX * 4 + pointY * WIDTH * 4)
			
			' Get the alpha value
			data = (data & $FF000000) Shr 24
			
			' If data <> 0 then there are pixels
			If data <> 0 Then hit = True Else hit = False

		Endif
		
	End

	Method OnRender()

		canvas.PushMatrix()
		canvas.Scale(scaleX,scaleY)
		canvas.Clear
		canvas.SetBlendMode(BlendMode.Alpha)
		canvas.SetAlpha 1
		canvas.DrawImage gfxBG,0,0
		canvas.DrawImage(gfxBall, (800 - WIDTH) / 2 + (WIDTH * (1-scale)) / 2.0 + (WIDTH / 2) * scale, (600 - HEIGHT) / 2 + (HEIGHT * (1-scale)) / 2.0 + (HEIGHT / 2 ) * scale, 0, scale, scale)
	
		If KeyDown(KEY_SPACE) Then	
			canvas.SetBlendMode(BlendMode.Alpha)
			canvas.SetAlpha 0.2
			' First the picture is centered, then x,y coordinates are changed so,
			' that the picture stays at the center of the screen
			canvas.DrawRect((800 - WIDTH) / 2 + WIDTH * (1-scale) / 2.0, (600 - HEIGHT) / 2 + HEIGHT * (1-scale) / 2.0, WIDTH * scale, HEIGHT * scale)
		Endif

		If hit = True Then
			canvas.SetAlpha 0.5
			canvas.DrawRect(0,0,DeviceWidth(),DeviceHeight())
		Endif
		
		canvas.Flush
		canvas.PopMatrix
		
	End

End Class

If you want to see the above code in practice, please check the video above. And as always, feel free to use this code as you wish.

%d bloggers like this: