I have been working on this code off and on for a bit over a month, the math gave me many head aches. Its very unpolished and has a lot of optimization that I need to do, along with unused code. Been pretty busy as of late so have not got around to cleaning it up. I did use someones base loop for the tween(not used ATM) and separation of logic and display update, cant remember the name. As soon as I get to a stable connection I will upload the project if anyone wants it. I have my projects Explicit declarations unchecked currently. If you use this posted code before I post a download you will need two images.. the stick 256x256 and back 512x512. Of course you can change this, though not sure how this will work on an idevice.. altered or not.
This will place up to 2 virtual joy sticks on the screen at once any where you touch, both with a background and locked origin to the initial touch reset upon release. Both constrain in a circle. At this point there is nothing defining left vs right joystick. Currently the first touch is stick 0, second is stick 1. Possibly replacing the for loop with if/case statements checking for screen position and running a specific joystick will work, not sure if that's the most efficient. The type is set up to use an array so that it can have up to as many joy sticks as the max touches your device can support. I intend on implementing: Optional snap back, locked origin, velocity %, speed %. Currently the only real usable return is angle 0-359, 0 being up, 180 down, 90 right, 270 left.
I hope some of you can find this useful, and would love any suggestions you may have.
Main Code:
// ===================== \\
// Project: Alpha                  
// Start: Monday, July 16, 2012			  
// =====================\\
GLOBAL UPDATE_FREQUENCY% = 20 // times per second
GLOBAL update_time# = 1000 / UPDATE_FREQUENCY%
GLOBAL t% , dt% , execution_time% = 0
GLOBAL Main, Second
SETCURRENTDIR("Media") // Set current dir
AUTOPAUSE FALSE
SMOOTHSHADING TRUE
ALPHATESTING 0.5
LOADSPRITE "JoyStick.png", 0
LOADSPRITE "JoyBack.png", 1
SYSTEMPOINTER TRUE
t = GETTIMERALL()
SetDisplay()
// Set up and initialise 2 Joystics
GLOBAL JoySticks[] AS tJoyStick
DIM JoySticks[2]
JoySticks[0].Initialise(0, 0, 2, 2, 0.08, 2, 2, 2, 2)
JoySticks[1].Initialise(1, 0, 2, 2, 0.08, 2, 2, 2, 2)
// =======\\
// Main loop                     
// =======\\
WHILE NOT KEY(1)
	dt = GETTIMERALL() - t
	t = GETTIMERALL()
	execution_time = execution_time + dt
	// fixed interval update loop
    WHILE execution_time >= update_time
		UpdateLogic()
		execution_time = execution_time - update_time
	WEND
	// calculate the remainder FOR motion interpolation
	LOCAL et# = execution_time
	LOCAL ut# = update_time
	LOCAL tween# = et / ut
	Render(tween)
WEND
// ======= \\
// Functions                     
// ======= \\
// ================== Update Logic ================== \\
FUNCTION UpdateLogic:
	// Update Logic
ENDFUNCTION
// ================= Render Display ================= \\
FUNCTION Render: tween#
	CLEARSCREEN
	ALPHAMODE -1
	ShowGUI()
	SHOWSCREEN
ENDFUNCTION
FUNCTION ShowGUI:
	FOR j = 0 TO 1
		JoySticks[j].Display()
	NEXT
ENDFUNCTION
// =========== Set UP Display based on OS =========== \\
FUNCTION SetDisplay:
	LOCAL info$ = PLATFORMINFO$("") // What device is this
	LOCAL w%, h%
	GETDESKTOPSIZE w,h
	SELECT info$
		CASE "ANDROID"
			SETSCREEN w, h, 1
			SETORIENTATION 0
		CASE "WIN32"
			SETORIENTATION 0
			SETSCREEN w, h, 1
		CASE "MACOSX"
			SETORIENTATION 0
		CASE "LINUX"
			SETORIENTATION 0
	ENDSELECT
ENDFUNCTION
Joy Stick Type and Functions:
// ====================== \\
// Project: Alpha - GUI Functions          
// Start: Monday, July 16, 2012			  
// ====================== \\
TYPE tJoyStyle
ENDTYPE
TYPE tJoyStick
	mIndex		// The # of the mouse
	mX		// Current mouse x
	mY		// Current mouse y
	mB1		// Current mouse button1 state
	mB2		// Current mouse button1 state
	mOriginX	// X possision of mouse on first press
	mOriginY	// Y possision of mouse on first press
	FirstPress	// Track first press
	Distance	// Distance between 2 x, y coordinates
	Delay		// Prevents first frame from rendering JoyStick to avoid bounce/flicker
	jRadius		// Raidius of the Stick
	jStick		// Stick image
	jBase		// Base image
	jStickAlpha	// Transparancy of Stick
	jBaseAlpha	// Transparancy of Base
	jBoundry	// How far from origin the stick can move
	sLimit		// How far from origin can mouse(finger) more before snaping back to center
	jLimitX		// Limit x of Stick based on boundry
	jLimitY		// Limit y of Stick based on boundry
	jStaticX	// Static x possision of JoyStick, if greater then 0 this will take effect.
	jStaticY	// Static y possision of JoyStick
	bRadius		// Base radius
	FUNCTION Initialise%: mIndex, sLimit, jStaticX, jStaticY, jSize, jStick, jBase, jStickAlpha, jBaseAlpha
		LOCAL w, h
		GETDESKTOPSIZE w,h
		// Mouse State Variables
		self.mIndex = mIndex
		self.FirstPress = FALSE
		// Joystick Visuals
		self.jRadius		= jSize * h
		self.jStick			= jStick
		self.jBase			= jBase
		self.jStickAlpha	= jStickAlpha
		self.jBaseAlpha		= jBaseAlpha
		self.jBoundry		= jRadius
		self.sLimit	 		= sLimit
		self.jStaticX		= jStaticX
		self.jStaticY		= jStaticY
		self.bRadius		= jRadius * 2
	ENDFUNCTION
	FUNCTION GetAngle:
		DistanceX = mOriginX - mX
		DistanceY = mOriginY - mY
		res% = ATAN( DistanceX, DistanceY)
		// Change from -/+ 180 to 0 - 359 ( 360 Degrees)
		IF res = 0
			res = 0
		ELSEIF res > 0
			res = ABS(res - 360)
		ELSEIF res < 0
			res = ABS(res)
		ENDIF
		RETURN res
	ENDFUNCTION
	FUNCTION GetVelocity:
		// To be done - % based
	ENDFUNCTION
	FUNCTION GetSpeed:
		// To be done - % based
	ENDFUNCTION
	FUNCTION GetDistance:
		Distance = SQR(POW((mX-mOriginX),2) + POW((mY-mOriginY),2))
		RETURN Distance
	ENDFUNCTION
	FUNCTION Limit:
		vx# = mOriginX - mX;
		vy# = mOriginY - mY;
		// Length
		mag# = SQR(vx*vx + vy*vy);
		// Normalize
		vx = vx / mag;
		vy = vy / mag;
		//calculate the new vector
		jLimitX = (mX + vx * (mag + (-jBoundry)));
		jLimitY = (mY + vy * (mag + (-jBoundry)));
	ENDFUNCTION
	FUNCTION Display:
		Distance = GetDistance()
		SETACTIVEMOUSE mIndex
		MOUSESTATE mX, mY, mB1, mB2
		IF mB1
			IF FirstPress = FALSE
				FirstPress = TRUE
				Delay = TRUE // Prevents first frame from rendering JoyStick to avoid bounce/flicker
				mOriginX = mX
				mOriginY = mY
			ENDIF
			//Draw base here
			IF Distance > jBoundry AND Delay = FALSE
				STARTPOLY 1 // Bitmap = No.0
					POLYVECTOR   mOriginX - bRadius,   mOriginY - bRadius,    0,    0, RGB(255, 255, 255)
					POLYVECTOR   mOriginX - bRadius,   mOriginY + bRadius,    0,  512, RGB(255, 255, 255)
					POLYVECTOR   mOriginX + bRadius,   mOriginY + bRadius,  512,  512, RGB(255, 255, 255)
					POLYVECTOR 	 mOriginX + bRadius,   mOriginY - bRadius,  512,    0, RGB(255, 255, 255)
				ENDPOLY
				// Display Joystick at limited possision
				STARTPOLY 0 // Bitmap = No.0
					POLYVECTOR   jLimitX - jRadius,   jLimitY - jRadius,    0,    0, RGB(255, 255, 255)
					POLYVECTOR   jLimitX - jRadius,   jLimitY + jRadius,    0,  256, RGB(255, 255, 255)
					POLYVECTOR   jLimitX + jRadius,   jLimitY + jRadius,  256,  256, RGB(255, 255, 255)
					POLYVECTOR 	 jLimitX + jRadius,   jLimitY - jRadius,  256,    0, RGB(255, 255, 255)
				ENDPOLY
			ELSEIF Distance < jBoundry AND Delay = FALSE
				STARTPOLY 1 // Bitmap = No.0
					POLYVECTOR   mOriginX - bRadius,   mOriginY - bRadius,    0,    0, RGB(255, 255, 255)
					POLYVECTOR   mOriginX - bRadius,   mOriginY + bRadius,    0,  512, RGB(255, 255, 255)
					POLYVECTOR   mOriginX + bRadius,   mOriginY + bRadius,  512,  512, RGB(255, 255, 255)
					POLYVECTOR 	 mOriginX + bRadius,   mOriginY - bRadius,  512,    0, RGB(255, 255, 255)
				ENDPOLY
				// Display Joystick at mouse possision
				STARTPOLY 0 // Bitmap = No.0
					POLYVECTOR   mX - jRadius,   mY - jRadius,    0,    0, RGB(255, 255, 255)
					POLYVECTOR   mX - jRadius,   mY + jRadius,    0,  256, RGB(255, 255, 255)
					POLYVECTOR   mX + jRadius,   mY + jRadius,  256,  256, RGB(255, 255, 255)
					POLYVECTOR 	 mX + jRadius,   mY - jRadius,  256,    0, RGB(255, 255, 255)
				ENDPOLY
			ENDIF
			Delay = FALSE // After first pass through allow rendering
			Limit()
		ELSEIF mB1 = FALSE
			FirstPress = FALSE
		ENDIF
	ENDFUNCTION
	FUNCTION CleanUp:
		// REDIM - Remove Images
	ENDFUNCTION
ENDTYPE
I don't remember all the modifications I made to the AndroidManifest.xml so:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.yourcompany.alpha"
      android:installLocation="preferExternal"
      android:versionCode="1"
      android:versionName="0.001">
    <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="14" />
	<uses-permission android:name="android.permission.INTERNET" />
	<uses-permission android:name="android.permission.VIBRATE" />
	<uses-permission android:name="android.permission.BATTERY_STATS" />
	<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
	<supports-screens android:resizeable="false"
					  android:smallScreens="true"
					  android:normalScreens="true"
					  android:largeScreens="true"
					  android:anyDensity="true" /> 
    <application android:label="@string/app_name" android:icon="@drawable/icon" android:debuggable="false">
        <activity	android:name="org.libsdl.app.SDLActivity"
					android:label="@string/app_name"
					android:screenOrientation="landscape"
					 >
				<!-- android:configChanges="orientation|keyboardHidden" -->
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest> 
			
			
				MrTaToad did something like this last year. Could be very useful to some. 
			
			
			
				Very true, and its a great piece of code. I have read over the code quite a few times. Unfortunately it constrains the stick to a square and as is only returns values for left right up and down, it just wasnt quite what i was looking for. 
I needed/wanted:
up down left right 
Velocity/Acceleration - how fast the player is moving the joystick
Speed - percentage return, based on min distance from origin to max limit, to allow for speed control
Angle - Allowing for easier orientation of objects and sprites
More Joysticks - Currently tested up to 8 on screen - large tablet + 4 kids great potential
Not all of these features are currently implemented, slowly chipping away at it when i have some time to code. Would love any suggestions.
~Grim S.
			
			
			
				Is there some .PNGs for your code?
			
			
			
				Yes, here is the entire project - Slightly updated to display up to 8 joysticks. Windows/Linux/Mac will only display 1.
http://www.mediafire.com/?34p6xyehd6kdgcn (http://www.mediafire.com/?34p6xyehd6kdgcn)
~Grim S.
P.S. Not sure about iDevices, but works on my HTC EVO LTE
			
			
			
				I had a quick look on windows and I was impressed, it looks really nice, very much like the virtual joysticks you see in most games, well done! :good:
			
			
			
				Indeed (I tried it on Windows too). 
:)