How about something like the following? I used the mesh button class provided by @Vega. I suggest you put the Button() class in a separate tab.
Regarding your comment on tutorials, there are some over at http://codeatuts.blogspot.com.au/ I will add this code to the Tutorials with some supplementary explanations.
At the moment the ship only moves when you tap the button. Bonus points if you modify this code so that the ship moves as long as you hold the button down.
--# Main
-- Use this function to perform your initial setup
function setup()
-- This block of code is optional. We just include it in
-- every project so that we have a method of version control.
version = 1.0
saveProjectInfo("Description", "Move Object Demonstration")
saveProjectInfo("Author", "Reefwing Software")
saveProjectInfo("Date", "11th July 2012")
saveProjectInfo("Version", version)
print("MoveShip v"..version.."\
")
-- Initialise the co-ordinates of your "Ship"
-- These will be updated by the action methods
-- associated with each directional button.
shipPosition = vec2(WIDTH/2, HEIGHT/2)
-- This slider parameter will control the ship "speed"
-- The larger the number the further the ship will
-- move with each button tap.
--
-- The format of this function is:
-- parameter("name", min value, max value, init value)
parameter("shipSpeed", 1, 10, 4)
-- Define the four Buttons used to move the ship
-- They wont be visible until you draw() them.
-- Note that 50 pixels is the minimum height for the default
-- button font size.
local mButtonSize = vec2(100, 50)
local mLocX = WIDTH - 250
local mLocY = 100
leftButton = Button("Left", vec2(mLocX, mLocY), mButtonSize.x, mButtonSize.y)
leftButton.action = function() leftButtonTapped() end
mLocX = mLocX + 150
rightButton = Button("Right", vec2(mLocX, mLocY), mButtonSize.x, mButtonSize.y)
rightButton.action = function() rightButtonTapped() end
mLocX = mLocX - 75
mLocY = mLocY + 60
upButton = Button("Up", vec2(mLocX, mLocY), mButtonSize.x, mButtonSize.y)
upButton.action = function() upButtonTapped() end
mLocY = mLocY - 120
downButton = Button("Down", vec2(mLocX, mLocY), mButtonSize.x, mButtonSize.y)
downButton.action = function() downButtonTapped() end
-- Assign the colours that you want to use in your game.
blackColour = color(0,0,0)
end
-- This function gets called once every frame
-- Codea will attempt to call draw() 60 times per second, it
-- can be much less than this if you have a lot going on in your code.
function draw()
-- This sets a black background color
background(blackColour)
-- Do your drawing here
-- Draw your ship at the current co-ordinates stored in shipPosition
sprite("Tyrian Remastered:Boss D", shipPosition.x, shipPosition.y)
-- Draw the four directional buttons
leftButton:draw()
rightButton:draw()
upButton:draw()
downButton:draw()
end
-- Button action methods
function leftButtonTapped()
-- Update ship position as long as the ship isnt off the screen.
-- math.max() returns the maximum value of the arguments, so
-- if shipPosition < 0 it will set it to 0.
shipPosition.x = math.max(shipPosition.x - shipSpeed, 0)
end
function rightButtonTapped()
-- Update ship position as long as the ship isnt off the screen.
-- math.min() returns the minimum value of the arguments, so
-- if shipPosition > WIDTH it will set it to WIDTH.
shipPosition.x = math.min(shipPosition.x + shipSpeed, WIDTH)
end
function upButtonTapped()
shipPosition.y = math.min(shipPosition.y + shipSpeed, HEIGHT)
end
function downButtonTapped()
shipPosition.y = math.max(shipPosition.y - shipSpeed, 0)
end
-- Handle screen touches
-- Note that you need to pass any touches through
-- to your button touch handlers.
function touched(touch)
leftButton:touched(touch)
rightButton:touched(touch)
upButton:touched(touch)
downButton:touched(touch)
end
--# Button
Button = class()
-- Mesh Button Class courtesy of @Vega
-- 26 May 2012
--
-- Modified: Call Back Functionality added
-- pushStyle() & popStyle() added to draw()
--
-- Version 1.1
function Button:init(text,location,width,height)
self.state = "normal"
self.text = text
self.textColor = color(255,255,255,192)
self.location = location
self.width = width
self.height = height
self.visible = true
self.fontSize = 28
self.font = "ArialRoundedMTBold"
self.color1 = color(255, 255, 255, 96)
self.color2 = color(128,128,128,32)
self.presscolor1 = color(192, 224, 224, 128)
self.presscolor2 = color(96, 192, 224, 128)
self.verts = self:createVerts(self.width, self.height)
self.myMesh = mesh()
self.myMesh.vertices = triangulate(self.verts)
self.vertColor = {}
self:recolor()
self.action = nil
end
function Button:setColors(c1,c2,p1,p2)
self.color1 = c1
self.color2 = c2
self.presscolor1 = p1
self.presscolor2 = p2
end
function Button:textOptions(fn, sz, col)
self.font = fn
self.fontSize = sz
self.textColor = col
end
function Button:draw()
pushStyle()
if self.visible == true then
self:recolor()
pushMatrix()
translate(self.location.x,self.location.y)
self.myMesh:draw()
fill(self.textColor)
fontSize(self.fontSize)
font(self.font)
text(self.text, self.width/2,self.height/2)
self:drawLines(self.verts)
popMatrix()
end
popStyle()
end
function Button:touched(touch)
if self.visible then
if touch.x >= self.location.x and touch.x <= self.location.x + self.width and touch.y >= self.location.y and touch.y <= self.location.y + self.height then
if touch.state == BEGAN then
self.state = "pressing"
sound(SOUND_HIT, 14227)
elseif touch.state == ENDED then
if self.state == "pressing" then
self.state = "normal"
end
if self.action then
self.action()
end
end
else
self.state = "normal"
end
end
end
function Button:createVerts(w,h)
local r
local v = {}
if w > 100 or h > 100 then
if w>=h then r = math.round(h/100) else r = math.round(w/100) end
else
r = 1
end
v[1] = vec2(w,6*r)
v[2] = vec2(w-r,4*r)
v[3] = vec2(w-2*r,2*r)
v[4] = vec2(w-4*r,r)
v[5] = vec2(w-6*r,0)
v[6] = vec2(6*r,0)
v[7] = vec2(4*r,r)
v[8] = vec2(2*r,2*r)
v[9] = vec2(r,4*r)
v[10] = vec2(0,6*r)
v[11] = vec2(0,h-6*r)
v[12] = vec2(r,h-4*r)
v[13] = vec2(2*r,h-2*r)
v[14] = vec2(4*r,h-r)
v[15] = vec2(6*r,h)
v[16] = vec2(w-6*r,h)
v[17] = vec2(w-4*r,h-r)
v[18] = vec2(w-2*r,h-2*r)
v[19] = vec2(w-r,h-4*r)
v[20] = vec2(w,h-6*r)
return v
end
function Button:drawLines(v)
noSmooth()
strokeWidth(1)
stroke(0, 0, 0, 192)
for i=1, #v-1 do
line(v[i].x,v[i].y,v[i+1].x,v[i+1].y)
end
line(v[#v].x,v[#v].y,v[1].x,v[1].y)
end
function Button:recolor()
local lt, dk
if self.state == "normal" then
lt = self.color1
dk = self.color2
else
lt = self.presscolor1
dk = self.presscolor2
end
for i=1,3 * #self.verts - 6 do
if self.myMesh.vertices[i].y > self.height/2 then
self.vertColor[i] = lt
else
self.vertColor[i] = dk
end
end
self.myMesh.colors = self.vertColor
end
function math.round(num)
-- math.round function courtesy of @Vega
return math.floor(num + 0.5)
end