Click&Drag to show image larger than the display

Monkey Forums/Monkey Programming/Click&Drag to show image larger than the display

Arabia(Posted 2013) [#1]
I'm only starting out and haven't probably read enough to be attempting this, my attempts to do this are not going well and I thought that this is probably a simple thing and I'm just missing something.

Here is what I've got - (the image "backImage.PNG" is a 1024x768 image).

Strict

Import mojo

Class myGame Extends App

Global backImage:Image
Global x:Int = 0
Global y:Int = 0


Method OnCreate:Int()

	SetUpdateRate 60
	backImage = LoadImage("backImage.png")
	Return True

End Method

Method OnUpdate:Int()

	If MouseDown()
		x = MouseX()
		y = MouseY()
	End If
	Return True

End Method

Method OnRender:Int()

	Cls
	DrawImage backImage, x, y
	Return True

End Method


End Class

Function Main:Int()

	New myGame
	Return True

End Function


So this works, except the it draws the image where the mouse is currently at, so if I click at 100,100, then the top if the image is at 100,100.

What I'm trying to do is draw the image at the offset from which I first click - so that if I click at 100,100 and then move the mouse around (or your finger on a tablet) then it will redraw the picture at an offset of -100, -100 until you release the mouse.

I know how to write this code in BlitzMax, but as far as I can ascertain, I can't do it the way I'm trying (saving the values of the initial MouseDown() ) in the OnUpdate Method because this method is called for each click of the Update Timer and it clobbers my previously stored values for where the initial click was.

I did search the forums, but didn't turn anything up.

Hope this makes sense.


Midimaster(Posted 2013) [#2]
you should store the mouse in the moment, when it is pressed first. As long as these value is not zero, you should not store it again. If the Mouse is not longer pressed, set this values to zero again:


Strict
Import mojo

Class Game Extends App

	Field StartX%, StartY%, TransX%, TransY%
	
	Method OnCreate%()
		SetUpdateRate 15
		Return 0
	End	

	Method OnUpdate%()
		If KeyHit(KEY_ESCAPE) Then Error ""
		If TouchDown()
			If StartX=0
				StartX=MouseX()-TransX
				StartY=MouseY()-TransY
			Else
				TransX=MouseX()-StartX
				TransY=MouseY()-StartY
			Endif
		Else
			StartX=0
			StartY=0
		Endif
		Return 0
	End	

	Method OnRender%()
		Cls
		Translate TransX,TransY
		Seed= 1
		For Local i%=0 To 100
			SetColor Rnd(255),Rnd(255),Rnd(255)
			DrawRect Rnd(255),Rnd(255),50,50
		Next
		Print Millisecs()
		Return 0
	End	
	
End

Function Main%()
	New Game
	Return 0
End



Arabia(Posted 2013) [#3]
That is exactly what I was trying to achieve, thanks very much.


Arabia(Posted 2013) [#4]
I've successfully modified Midimaster's code so that it only scrolls as far as the size of the image - i.e. you can click/drag to see all of the image, but can't drag it off the screen - which is what I want.

Now what I'm trying to add is an info panel at the bottom of the screen which does not scroll (i.e. it stays in the same position regardless of click & drag)

So what I've done is create a PNG for the information to be drawn on and added this code to the OnRender()

	Method OnRender%()
		Cls
		Translate TransX,TransY
		DrawImage backGround, 0, 0
		Translate 0, 0
		DrawImage infoPanel, 0, 0
		DrawImage infoPanel, 0, DeviceHeight() -infoPanel.Height()
		Return 0
	End	


I would have thought that setting Translate to 0,0 prior to DrawImage infoPanel should mean that these two InfoPanels both get draw and stay at the top and bottom of the display respectively. I'm obviously missing something in the use of Translate?

The manual definition for Translate (Multiplies the current matrix by a matrix representing the specified translation.) doesn't mean much to me, but my understanding is that it is an effectively an offset for when an image is draw.

Any ideas what I'm missing?


Arabia(Posted 2013) [#5]
EDIT:

Fix the problem with :

		DrawImage infoPanel, Abs(TransX), Abs(TransY)
		DrawImage infoPanel, Abs(TransX), Abs(TransY) + DeviceHeight() -infoPanel.Height()


This works, but I still don't understand why setting Translate to 0,0 does not achieve the same thing?


Midimaster(Posted 2013) [#6]
The Translate() command moves the drawing origin "relative" not "absolute"!

So after a first Translate(10,20) the origin is at 10/20. And after a second Translate(7,5) the new origin is at 17,25.

There is a command to "restore" these movements: PushMatrix() and PopMatrix(). Pushmatrix() saves the current state. After this you can change origin, scale and direction. When using PopMatrix() you recall the old state.

So my sample would look like this:

Method OnRender%()
	Cls
	PushMatrix()
		Translate TransX,TransY
		Seed= 1
		For Local i%=0 To 100
			SetColor Rnd(255),Rnd(255),Rnd(255)
			DrawRect Rnd(255),Rnd(255),50,50
		Next
	PopMatrix()
	SetColor 255,255,255
	DrawCircle 100,100,50,50
	Print Millisecs()
	Return 0
End



Arabia(Posted 2013) [#7]
Thanks.

I'd seem examples (using scaling) where PushMatrix & PopMatrix were used and didn't fully understand it, that clears everything up.

Thanks again.