Last active
August 29, 2015 13:57
-
-
Save dermotbalson/9542640 to your computer and use it in GitHub Desktop.
Dave
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--# Main | |
--Main | |
--This program contains over 20 mini-projects created by dave1707 to answer questions asked in the forum | |
--** How to run the projects ** | |
--When you run the program, you can select any of these projects by number using the slider at upper left | |
--(Underneath the slider you will see a textbox with descriptions of what each numbered project does) | |
--When you've selected a project, press the button "Run selected project" to run it | |
--** Viewing the code ** | |
--The code tabs to the right are in the same order as the numbered projects, and each one contains all | |
--the code you need to run the project. | |
--** Copying the code to your own project ** | |
--To copy one of the projects to your own separate project, just copy all the code in that tab and paste it | |
--into your project. You can delete the first line starting "if localise then..." if you want. | |
--** What is all the code below, in this tab? | |
--You can ignore the code below. It manages the selection of projects and is quite technical. It has nothing to do with what dave wrote. | |
--** DON'T TOUCH THE CODE BELOW ***** | |
--This code manages which Code tab is run | |
--it remembers your last choice, and if you select a different one, it runs that instead | |
local tabs = {} | |
local fnames = {"setup","draw","touched","collide","orientationChanged","close","restart","keyboard","cleanup"} | |
local fns = {} | |
local tabDesc={} | |
local LastCode,PrevCode,projectList | |
PN=0 | |
function setup() | |
for k,v in ipairs(fnames) do --store addresses of key event functions | |
fns[v] = _G[v] | |
end | |
projectList="" | |
for i=1,#tabs,2 do | |
if projectList~="" then projectList=projectList.."\n" end | |
local txt1=GetString(i) | |
if i<#tabs then | |
local txt2=tostring(i+1)..": "..tabDesc[i+1] | |
projectList=projectList..txt1 .. txt2 | |
else | |
projectList=projectList..txt1 | |
end | |
end | |
RunCode() | |
end | |
function GetString(i) | |
pushStyle() | |
font("SourceSansPro-Regular") | |
fontSize(12) | |
local txt=i..": "..tabDesc[i] | |
local n=textSize(txt) | |
local s=textSize(" ")/20 | |
popStyle() | |
local m=(80-n)/s if m<0 then m=1 end | |
return txt..string.rep(" ",m) | |
end | |
--these two functions do all the tab switching magic (thanks to Andrew_Stacey) | |
function localise(n,d) | |
if d then tabDesc[n]=d end | |
local t= {} | |
setmetatable(t,{__index = _G}) | |
setfenv(2,t) | |
tabs[n] = t | |
end | |
--change tabs | |
function RunCode() | |
if Choose_a_tab then | |
if LastCode then PrevCode=LastCode end | |
saveProjectData("DaveTuts",Choose_a_tab) | |
end | |
cleanup() | |
cleanup2() | |
local t = tabs[Choose_a_tab] | |
for k,v in ipairs(fnames) do | |
if t[v] then _G[v] = t[v] else _G[v] = fns[v] end -- overwrite with the new code | |
end | |
setup() | |
end | |
--default empty function to avoid errors for tabs that don't have it | |
function cleanup() | |
end | |
--additional cleanup | |
function cleanup2() | |
resetStyle() | |
collectgarbage() | |
output.clear() | |
parameter.clear() | |
LastCode=readProjectData("DaveTuts") or 1 --load stored tab number | |
print(string.upper(tabDesc[LastCode])) | |
parameter.integer("Choose_a_tab",1,#tabs,LastCode) --tab selector | |
parameter.text("Projects",projectList) | |
parameter.action("Run selected project", RunCode) | |
end | |
--# Snake | |
--snake example | |
--delete the next line if you copy this to your own project | |
if localise then PN=PN+1 localise(PN,"Snake") end | |
--KNOWLEDGE = basic tables, pairs looping | |
function setup() | |
tab={} --define an empty table (array) called tab, to hold the parts of the "snake" | |
x=WIDTH/2 --set x,y position to centre of screen initially | |
y=HEIGHT/2 | |
sx=0 --sx and sy will hold the change in direction based on your fi ger movement | |
sy=0 | |
length=150 --set maximum length of snake | |
end | |
--when you touch the screen, figure out the direction | |
function touched(t) | |
getDirection() | |
end | |
function getDirection() | |
--CurrentTouch holds the location of the last touch | |
--calculate distance to the current x,y position | |
dx=CurrentTouch.x-x | |
dy=CurrentTouch.y-y | |
--we will move towards the touch point by 1/25 of the current distance | |
sx=dx/25 | |
sy=dy/25 | |
end | |
function draw() | |
background(40,40,50) | |
fill(255,0,0) | |
text("Drag your finger around the screen",WIDTH/2,HEIGHT-50) | |
--move toward the current touch position | |
x = x + sx | |
y = y + sy | |
--insert a new point at the beginning of our table at x,y | |
--we store the point as a "vec2", which is just a pair of numbers | |
table.insert(tab,1,vec2(x,y)) | |
--if our snake is too long, remove the last item to make room | |
--(#tab gives us the number of items in table tab) | |
if #tab>length then | |
table.remove(tab,#tab) | |
end | |
--this is a way of looping through all the items in the table | |
--and drawing a circle at eahc position we have stored | |
--for each item, we will be given an a and b value | |
--the a value will be a sequence 1, 2, 3, etc (ie the 5th item will have a=5) | |
--the b value will be the contents of that item in the table, which is a vec2 | |
--containing an x,y value | |
for a,b in pairs(tab) do | |
if a==1 then --the first item gets drawn bigger, as the head | |
ellipse(b.x,b.y,20,20) | |
else | |
ellipse(b.x,b.y,10,10) | |
end | |
end | |
end | |
--# Touch | |
-- touch detection | |
--delete the next line if you copy this to your own project | |
if localise then PN=PN+1 localise(PN,"Touch") end | |
--KNOWLEDGE = nil | |
function setup() | |
--nothing needed, we could omit the function completely | |
end | |
--note all the variables in draw are defined with "local" in front of them | |
--this is not only faster, but because they aren't needed outside this function | |
--this means we can safely use the same variable names elsewhere without them | |
--getting confused with each other | |
--(We don't have other functions in this example, but I'm trying to set you a good example!) | |
function draw() | |
background(40, 40, 50) | |
fill(255) | |
text("Slide finger across ellipse or circle",WIDTH/2,HEIGHT-100) | |
--ellipse | |
fill(220) | |
local ex,ey=250,200 | |
local xr,yr=150,100 | |
ellipse(ex,ey,xr*2,yr*2) -- first two items are x,y position, then width, height | |
--circle | |
fill(139, 187, 209, 255) | |
local cx,cy,cr=450,450,100 | |
--a circle uses the ellipse command but only provides width, then height is assumed to be the same | |
ellipse(cx,cy,cr*2) | |
--store current touch position | |
local x=CurrentTouch.x -- touched x value | |
local y=CurrentTouch.y -- touched y value | |
-- determine if touched value is inside ellipse | |
fill(255,0,0) | |
if (y-ey)^2/xr^2+(x-ex)^2/yr^2 <= 1 then --standard math formula | |
text("inside",ex,ey) | |
end | |
--same for circle | |
--we could use the same method as above, but because it is a circle, we can try something else | |
--given two points, Codea can calculate the distance between them for you | |
--as long as they are in vec2 format, like so | |
if vec2(cx,cy):dist(vec2(x,y))<cr then --check if dostance is less than radius | |
text("inside",cx,cy) | |
end | |
end | |
--# Select | |
--selecting a square | |
--delete the next line if you copy this to your own project | |
if localise then PN=PN+1 localise(PN,"Select") end | |
--KNOWLEDGE = nil | |
function setup() | |
size=100 -- size of the squares | |
squares=5 -- number of squares wide and high | |
startX,startY=130,100 --bottom left position of table | |
end | |
function draw() | |
background(40,40,50) | |
fill(255) | |
text("tap a square",WIDTH/2,HEIGHT-100) | |
strokeWidth(2) --width of table border | |
stroke(255) | |
noFill() --draw empty rectangles | |
--draw table | |
for x=1,squares do --loop through from left to right | |
--the rect command draws a square with the lower left corner at the x,y position we provide | |
local px=startX+x*size-size --calculate bottom left x value for this square | |
for y=1,squares do --and loop from bottom to top (remember y=0 at bottom and increases upwards) | |
local py=startY+y*size-size --calculate y position of the bottom left of the square | |
rect(px,py,size,size) --draw the square | |
end | |
end | |
if zone then -- square touched, fill with color | |
fill(255, 0, 0) | |
local px=startX+tx*size-size --as above | |
local py=startY+ty*size-size | |
rect(px,py,size,size) -- draw squares | |
end | |
end | |
function touched(touch) | |
--touch has three "states" to tell you what is happening | |
--BEGAN means the touch has just started | |
--MOVING means the touch is moving across the screen | |
--ENDED means the touch has just ended | |
--we could use BEGAN or ENDED for this | |
if touch.state == ENDED then | |
--calculate which square was touched, x value first | |
tx=math.floor((touch.x-startX)/size)+1 | |
--if invalid, exit, set zone to nil | |
if tx<1 or tx>squares then | |
zone=nil | |
return | |
end | |
--same for y | |
ty=math.floor((touch.y-startY)/size)+1 | |
if ty<1 or ty>squares then | |
zone=nil | |
return | |
end | |
--if we got this far, we have a valid touch, set zone=true | |
zone=true | |
end | |
end | |
--# Drag | |
-- drag grid example | |
--delete the next line if you copy this to your own project | |
if localise then PN=PN+1 localise(PN,"Drag") end | |
function setup() | |
dx=WIDTH/2 --initial centre of grid | |
dy=HEIGHT/2 | |
end | |
function draw() | |
background(40, 40, 50) | |
pushStyle() --remember current style settings so we can put them back | |
fontSize(30) | |
fill(255) | |
text("Drag grid around",WIDTH/2,HEIGHT-50) | |
translate(dx,dy) --centre the grid on the current touch position | |
--draw white circle | |
fill(255) | |
ellipse(0,0,100,100) | |
--set line width, colour | |
stroke(255) | |
strokeWidth(4) | |
--draw the grid, x lines first | |
for x=-3000,3000,100 do | |
line(x,-3000,x,3000) | |
fill(255) | |
text(x,x,0) | |
end --y lines | |
for y=-3000,3000,100 do | |
line(-3000,y,3000,y) | |
text(y,0,y) | |
end | |
popStyle() --put original style settings back | |
end | |
--the "touched" function will tell you when a touch happens | |
--the parameter t (or whatever else you want to call it) has all the info you need | |
function touched(t) | |
--there are 3 situations, you can find out which from the "state" property | |
--state=BEGAN means the touch just started | |
--state=MOVING means the user is moving their finger around | |
--state==ENDED means the user stopped touching | |
if t.state==BEGAN then --store x,y values when touch starts | |
x1=t.x | |
y1=t.y | |
elseif t.state==MOVING then | |
dx=dx+t.x-x1 --set dx, dy equal to distance we moved from original start of touch | |
dy=dy+t.y-y1 --these are used in the draw function to position the grid | |
x1=t.x | |
y1=t.y | |
end | |
end | |
--# Drag2 | |
-- faster drag grid example | |
-- drawing the grid only once, when we start | |
--delete the next line if you copy this to your own project | |
if localise then PN=PN+1 localise(PN,"Faster Drag") end | |
function setup() | |
dx=WIDTH/2 --initial centre of grid | |
dy=HEIGHT/2 | |
grid=DrawGrid(6000,6000,100) --draw grid 2000x2000, with square size 100, store in image | |
end | |
--function to draw grid | |
--we put this in its own function to keep things neat | |
--it also allows us to easily to change the size if we need to | |
function DrawGrid(w,h,s) | |
img=image(w,h) --create blank image to hold grid | |
--we can draw onto this blank image instead of the screen, like this | |
setContext(img) | |
pushStyle() --remember current style settings so we can put them back | |
fontSize(30) | |
fill(255) | |
--draw white circle | |
fill(255) | |
ellipse(0,0,100,100) | |
--set line width, colour | |
stroke(255) | |
strokeWidth(4) | |
--draw the grid, x lines first | |
for x=0,w,s do | |
line(x,0,x,h) | |
fill(255) | |
text(x,x,0) | |
end --y lines | |
for y=0,h,s do | |
line(0,y,w,y) | |
text(y,0,y) | |
end | |
popStyle() --put original style settings back | |
setContext() --stop drawing on image | |
return img | |
end | |
function draw() | |
background(40, 40, 50) | |
text("Drag grid around",WIDTH/2,HEIGHT-50) | |
sprite(grid,dx,dy) --centre the grid on the current touch position | |
end | |
--the "touched" function will tell you when a touch happens | |
--the parameter t (or whatever else you want to call it) has all the info you need | |
function touched(t) | |
--there are 3 situations, you can find out which from the "state" property | |
--state=BEGAN means the touch just started | |
--state=MOVING means the user is moving their finger around | |
--state==ENDED means the user stopped touching | |
if t.state==BEGAN then --store x,y values when touch starts | |
x1=t.x | |
y1=t.y | |
elseif t.state==MOVING then | |
dx=dx+t.x-x1 --set dx, dy equal to distance we moved from original start of touch | |
dy=dy+t.y-y1 --these are used in the draw function to position the grid | |
x1=t.x | |
y1=t.y | |
end | |
end | |
--# Button | |
--button example | |
--delete the next line if you copy this to your own project | |
if localise then PN=PN+1 localise(PN,"Button") end | |
--we don't need to setup anything | |
function setup() | |
end | |
function draw() | |
background(40, 40, 50) | |
pushStyle() --remember current style settings so we can put them back | |
--draw button (see Drag2 tab for how to draw it just once for greater speed) | |
rectMode(CENTER) --we'll use a rectangle. Set it so it is centred on the position where it is drawn | |
fill(255) --button colour | |
rect(150,600,200,100) --draw button | |
fill(255,0,0) --text colour | |
text("Change to theme 2",150,620) | |
fill(0,255,0) | |
text("Cancel OK",150,580) | |
popStyle() --put original style settings back | |
end | |
--see comments on Touch example for how touch works | |
function touched(t) | |
--if touch has just started, check if it is within the button area | |
if t.state==BEGAN then | |
if t.x>50 and t.x<150 and t.y>550 and t.y<600 then | |
print("Cancel pressed") | |
end | |
if t.x>150 and t.x<2000 and t.y>550 and t.y<600 then | |
print("OK pressed") | |
end | |
end | |
end | |
--# Game | |
--simple game | |
--you try to touch buttons which appear randomly and shrink to nothing | |
--delete the next line if you copy this to your own project | |
if localise then PN=PN+1 localise(PN,"Game") end | |
function setup() | |
--initialise | |
hit=0 | |
missed=0 | |
createCircle() --create first circle to touch | |
end | |
function draw() | |
background(40, 40, 50) | |
fontSize(40) | |
pushStyle() --store style settings | |
if rad>1 then --if we have a circle (radius>0) then draw it | |
fill(c) | |
ellipse(x,y,rad) --draw circle | |
rad=rad-1 --decrease radius | |
else --no circle, draw a new one | |
createCircle() | |
missed = missed + 1 --we missed, so add to total | |
end | |
fill(255) | |
str=string.format("Hit %d Missed %d",hit,missed) | |
text(str,WIDTH/2,HEIGHT-50) | |
text("Try to touch the circle",WIDTH/2,HEIGHT-100) | |
popStyle() --restore style settings | |
end | |
function createCircle() | |
rad=70+math.random(1,100) --size of circle | |
x=math.random(25,WIDTH-25) | |
y=math.random(25,HEIGHT-100) | |
c=color(math.random(0,255),math.random(0,255),math.random(0,255)) | |
end | |
function touched(t) | |
if t.state==BEGAN then | |
if vec2(x,y):dist(vec2(t.x,t.y))<=rad then | |
--if (t.y-y)^2/rad^2+(t.x-x)^2/rad^2 <= 1 then -- circle tapped | |
createCircle() | |
hit = hit + 1 | |
end | |
end | |
end | |
--# Keyboard | |
--keyboard example | |
--delete the next line if you copy this to your own project | |
if localise then PN=PN+1 localise(PN,"Keyboard") end | |
function setup() | |
showKeyboard() --shows on screen keyboard | |
str="" --initialise text on screen | |
end | |
function draw() | |
background(40,40,50) | |
fill(255) | |
text("Enter your name",WIDTH/2,HEIGHT/2+50) | |
str=keyboardBuffer() --capture typed text | |
if rtn then --if return was pressed, hide then re-show keyboard | |
rtn=false | |
hideKeyboard() | |
showKeyboard() | |
end | |
text(str,WIDTH/2,HEIGHT/2) | |
end | |
--this function captures keystrokes | |
function keyboard(k) | |
if k==RETURN then --if return pressed, display text | |
rtn=true --create indicator for the draw function | |
print(str) | |
end | |
end | |
--# Keyboard2 | |
--keyboard example 2 | |
--this one stores keyboard input in a table so multiple lines can be displayed | |
--delete the next line if you copy this to your own project | |
if localise then PN=PN+1 localise(PN,"Keyboard2") end | |
function setup() | |
strTab={} --table for typed text | |
buffer="" --typed keyboard text | |
showKeyboard() | |
textMode(CORNER) | |
end | |
function draw() | |
background(30,30,0,255) | |
fill(255) | |
text("Keyboard example",100,HEIGHT-100) | |
text("Type something and press return",100,HEIGHT-150) | |
--draw text that has already been typed | |
if buffer~="" then | |
text(buffer,10,400) | |
end | |
--draw previously typed lines of text | |
for z=1,#strTab do | |
text(strTab[z],10,420+(#strTab-z)*20) | |
end | |
end | |
function touched() | |
showKeyboard() | |
end | |
function keyboard(key) | |
if key == RETURN then | |
--as each line is completed, add it to the table | |
table.insert(strTab,buffer) | |
buffer="" | |
elseif key==BACKSPACE then | |
buffer=string.sub(buffer,1,string.len(buffer)-1) | |
else --new key has been pressed, add to current text string | |
buffer=buffer..key | |
end | |
end | |
--# TextInput | |
--text input box | |
--see comments for previous keyboard and touch examples | |
--delete the next line if you copy this to your own project | |
if localise then PN=PN+1 localise(PN,"Text input") end | |
function setup() | |
hideKeyboard() | |
showKeyboard() | |
str="" | |
nbr=0 | |
end | |
function draw() | |
background(40,40,50) | |
rectMode(CENTER) --set textbox to be centred on the position we give it | |
fill(255) | |
if keyboardBuffer() ~= nil then | |
str=keyboardBuffer() | |
end | |
text("number "..nbr,300,730) | |
text("Enter number then press return",300,640) | |
rect(300,600,200,50) | |
fill(255,0,0) | |
text(str,300,600) | |
end | |
function keyboard(k) | |
if k==RETURN then | |
hideKeyboard() | |
nbr=str | |
if nbr=="" or nbr==nil then | |
nbr=0 | |
end | |
end | |
end | |
function touched(t) | |
if t.state==BEGAN then | |
showKeyboard() | |
end | |
end | |
--# TextInput2 | |
--text input example 2 | |
--delete the next line if you copy this to your own project | |
if localise then PN=PN+1 localise(PN,"Text input 2") end | |
function setup() | |
str = "" | |
bcolor= 0 | |
x=300 | |
y=500 | |
w=200 | |
h=50 | |
l=x-w/2 --button left | |
r=x+w/2 --right | |
b=y-h/2 --bottom | |
t=y+h/2 --top | |
end | |
function draw() | |
background(30,30,0,255) | |
strokeWidth(6) --width of border | |
rectMode(CENTER) --set button and text to be centred | |
textMode(CENTER) | |
fill(255) | |
text("Tap button then input data",x,700) | |
text("Press RETURN to show input",x,650) | |
text("Enter value",x,550) | |
if bcolor == 0 then | |
fill(255, 0, 0, 255) | |
else | |
fill(128,0,0,255) | |
end | |
rect(x,y,w,h) -- input area | |
fill(255) | |
if keyboardBuffer() ~= nil then | |
text(keyboardBuffer(),x,500) -- show data as it is keyed | |
else | |
text(str,x,500) -- show data in input area | |
end | |
text(str,x,450) -- show data below input area | |
end | |
--see comments in Touch example | |
function touched() -- check if input area was touched | |
if CurrentTouch.x > l and CurrentTouch.x < r then | |
if CurrentTouch.y > b and CurrentTouch.y < t then | |
showKeyboard() | |
bcolor = 1 | |
end | |
end | |
end | |
--see comments in Keyboard example | |
function keyboard(key) -- move keyboardBuffer to str when return is pressed | |
if key == RETURN then | |
str = keyboardBuffer() | |
hideKeyboard() | |
bcolor = 0 | |
end | |
end | |
--# Timer | |
--Timer | |
--delete the next line if you copy this to your own project | |
if localise then PN=PN+1 localise(PN,"Timer") end | |
function setup() | |
et=0 --set elapsed time to 0 | |
end | |
function draw() | |
background(40, 40, 50) | |
fill(255) | |
timer() --check timer status | |
--showText is used to tell draw what to do | |
if showText then | |
text("show this text until 5 is reached "..math.ceil(et-ElapsedTime), | |
WIDTH/2,HEIGHT/2) | |
end | |
if not showText then | |
text("tap screen to start timer",WIDTH/2,HEIGHT/2) | |
end | |
end | |
--if the variable s is provided, then we are starting the timer with s seconds | |
--if it is not provided, we are just checking whether it is time to turn it off | |
function timer(s) | |
if s~=nil then --start the timer | |
et=ElapsedTime+s --ElapsedTime = time since program started | |
showText=true --used by draw | |
end | |
if et-5<ElapsedTime then --if time is up, then disable the timer | |
showText=false | |
end | |
end | |
--restart the timer with 15 seconds every time the screen is touched | |
function touched(t) | |
if t.state==BEGAN then | |
timer(15) | |
end | |
end | |
--# Restart | |
-- restart program example | |
--delete the next line if you copy this to your own project | |
if localise then PN=PN+1 localise(PN,"Restart") end | |
--create a couple of physics objects to bounce | |
function setup() | |
c1 = physics.body(CIRCLE,50) | |
c1.x=300 | |
c1.y=900 | |
c2 = physics.body(CIRCLE,50) | |
c2.x=300 | |
c2.y=200 | |
c2.type=STATIC | |
end | |
--restart when they collide | |
function collide(contact) | |
if contact.state == BEGAN then | |
print("\nrestart program") | |
restart() --this is what we came for! | |
end | |
end | |
function draw() | |
background(30, 30, 30, 25) | |
stroke(255) | |
strokeWidth(1) | |
noFill() | |
ellipse(c1.x,c1.y,100,100) | |
ellipse(c2.x,c2.y,100,100) | |
end | |
--# TableFunctions | |
-- execute functions from a table | |
--delete the next line if you copy this to your own project | |
if localise then PN=PN+1 localise(PN,"Table functions") end | |
--we'll start with three functions a1, a2, a3 | |
function a1() | |
print("function a1 executed") | |
end | |
function a2() | |
print("function a2 executed") | |
end | |
function a3() | |
print("function a3 executed") | |
end | |
--in setup, we'll put them in a table | |
--we can put functions into a table because the name screen1 doesn't actually hold a function, but | |
--the address of the function. This address is numeric and can be stored in a table | |
function setup() | |
tab={a1,a2,a3} | |
--now loop through and run each function | |
for z=1,#tab do | |
tab[z]() --the function name is in tab[z] and the () tells Codea to run it | |
end | |
end | |
--this isn't needed if you copy this to your own project | |
--It's needed here, because if we don't have it, Codea may try | |
--to run one of the draw functions in the other code tabs | |
function draw() | |
background(40,40,50) | |
end | |
--# State | |
--Use states to manage what happens (and is drawn) | |
--delete the next line if you copy this to your own project | |
if localise then PN=PN+1 localise(PN,"State") end | |
function setup() | |
s=1 --initialise state at 1 | |
--there are 3 states, numbered 1 to 3, one for each screen | |
end | |
function draw() | |
fontSize(40) | |
if s==1 then | |
screen1() | |
end | |
if s==2 then | |
screen2() | |
end | |
if s==3 then | |
screen3() | |
end | |
end | |
--there is a separate function to draw eahc different screen | |
--this keeps your code neat | |
function screen1() | |
background(255, 220, 0, 94) | |
fill(255,0,0) | |
text("screen 1",WIDTH/2,HEIGHT/2) | |
text("tap screen for next screen",WIDTH/2,HEIGHT/2-200) | |
end | |
function screen2() | |
background(95, 255, 0, 95) | |
fill(255,0,0) | |
text("screen 2",WIDTH/2,HEIGHT/2) | |
text("tap screen for next screen",WIDTH/2,HEIGHT/2-200) | |
end | |
function screen3() | |
background(0, 255, 239, 95) | |
fill(255,0,0) | |
text("screen 3",WIDTH/2,HEIGHT/2) | |
text("tap screen for next screen",WIDTH/2,HEIGHT/2-200) | |
end | |
--go to the next screen when the screen is touched | |
function touched(t) | |
if t.state==BEGAN then | |
s=s+1 | |
if s>3 then | |
s=1 | |
end | |
end | |
end | |
--# State2 | |
--Use NAMED states to manage what happens (and is drawn) | |
--delete the next line if you copy this to your own project | |
if localise then PN=PN+1 localise(PN,"State") end | |
function setup() | |
s=1 --initialise state at 1 | |
--there are 3 states, numbered 1 to 3, one for each screen | |
--we'll give them names and their own drawing functions, like so | |
--naming them makes the later code easier to read and reduces error | |
states={"Screen1","Screen2","Screen3"} --table of state names | |
--and a table of functions to draw each of them (see aso TableFunctions example) | |
--we can put functions into a table because the name screen1 doesn't actually hold a function, but | |
--the address of the function. This address is numeric and can be stored in a table | |
stateFunctions={screen1,screen2,screen3} | |
end | |
function draw() | |
fontSize(40) | |
--run the function for the current state | |
--the function name is stateFunctions[2] | |
--we tell Codea to run that function by attaching () on the end | |
--neat, huh? | |
stateFunctions[s]() | |
end | |
--there is a separate function to draw each different screen | |
--this keeps your code neat | |
function screen1() | |
background(255, 220, 0, 94) | |
fill(255,0,0) | |
text("screen 1",WIDTH/2,HEIGHT/2) | |
text("tap screen for next screen",WIDTH/2,HEIGHT/2-200) | |
end | |
function screen2() | |
background(95, 255, 0, 95) | |
fill(255,0,0) | |
text("screen 2",WIDTH/2,HEIGHT/2) | |
text("tap screen for next screen",WIDTH/2,HEIGHT/2-200) | |
end | |
function screen3() | |
background(0, 255, 239, 95) | |
fill(255,0,0) | |
text("screen 3",WIDTH/2,HEIGHT/2) | |
text("tap screen for next screen",WIDTH/2,HEIGHT/2-200) | |
end | |
--go to the next screen when the screen is touched | |
function touched(t) | |
if t.state==BEGAN then | |
s=s+1 | |
--if we've got past the last screen, go back to the first | |
if s>#states then | |
s=1 | |
end | |
end | |
end | |
--# Menu | |
--Menu example | |
--this example prints your choice at the left, it doesn't change the screen | |
--if you want to show different screens when a choice is pressed, why not look at the State or State2 examples | |
--delete the next line if you copy this to your own project | |
if localise then PN=PN+1 localise(PN,"Menu") end | |
function setup() | |
end | |
function draw() | |
menu() | |
end | |
function menu() | |
background(0,0,200) | |
local w=WIDTH/2 -- set width value | |
local eh=HEIGHT-350 -- set height of different options | |
local nh=HEIGHT-500 -- eh easy, nh normal, hh hard | |
local hh=HEIGHT-650 | |
pushMatrix() --store style settings | |
font("Zapfino") -- set font used | |
fontSize(48) -- set font size | |
fill(255,0,0) -- set font color | |
local menuTitle1="Main Menu" -- main title | |
local menuTitle2="Select Option" | |
text(menuTitle1,w,HEIGHT-75) -- display titles | |
text(menuTitle2,w,HEIGHT-200) | |
fill(0,255,0) -- set easy values | |
local t1="Easy" | |
text(t1,w,eh) | |
local w1,h1=textSize(t1) -- width and height of easy text | |
local t2="Normal" -- set normal values | |
text(t2,w,nh) | |
local w2,h2=textSize(t2) -- width and height of normal text | |
local t3="Hard" -- set hard values | |
text(t3,w,hh) | |
local w3,h3=textSize(t3) -- width and height of hard text | |
popStyle() --restore style settings | |
end | |
--see Touch example for how touch works | |
function touched(t) | |
if t.state==BEGAN then | |
--check if touch is on one of the options | |
if t.x>w-w1/2 and t.x<w+w1/2 and t.y>eh-h1/2 and t.y<eh+h1/2 then | |
print("easy option selected") -- call easy routine here | |
end | |
if t.x>w-w2/2 and t.x<w+w2/2 and t.y>nh-h2/2 and t.y<nh+h2/2 then | |
print("normal option selected") -- call normal routine here | |
end | |
if t.x>w-w3/2 and t.x<w+w3/2 and t.y>hh-h3/2 and t.y<hh+h3/2 then | |
print("hard option selected") -- call hard routine here | |
end | |
end | |
end | |
--# MultiScreen | |
-- multiple screen example | |
--this shows yet another way to manage different states of the program | |
--delete the next line if you copy this to your own project | |
if localise then PN=PN+1 localise(PN,"Multi screen") end | |
function setup() | |
--set the function to use for drawing, we will change this when the user makes choices | |
--we can put functions into a variable because the name screen1 doesn't actually hold a function, but | |
--the address of the function. This address is numeric and can be stored in a variable | |
func=menu -- start screen | |
buttonTab={} -- buttons table | |
-- button(x,y,width,height,button name,button screen,button function) | |
-- buttons that show on the menu screen | |
table.insert(buttonTab,button(350,600,100,50,"Screen 1",menu,screen1)) | |
table.insert(buttonTab,button(350,500,100,50,"Screen 2",menu,screen2)) | |
table.insert(buttonTab,button(350,400,100,50,"Screen 3",menu,screen3)) | |
table.insert(buttonTab,button(700,50,100,50,"EXIT",menu,close)) | |
-- buttons that show on screen1 | |
table.insert(buttonTab,button(350,600,150,50,"Google",screen1,url1)) | |
table.insert(buttonTab,button(350,500,150,50,"twolivesleft",screen1,url2)) | |
table.insert(buttonTab,button(350,100,150,50,"Menu",screen1,menu)) | |
-- buttons that show on screen2 | |
table.insert(buttonTab,button(350,600,150,50,"map quest",screen2,url3)) | |
table.insert(buttonTab,button(350,100,150,50,"Menu",screen2,menu)) | |
-- buttons that show on screen3 | |
table.insert(buttonTab,button(350,600,150,50,"amazon",screen3,url4)) | |
table.insert(buttonTab,button(350,100,150,50,"Menu",screen3,menu)) | |
end | |
function draw() | |
background(40, 40, 50) | |
fill(255) | |
func() -- call the current function | |
end | |
--check if any of the buttons were touched | |
--see Touch example for more on touch | |
--see Snake example for more on pairs function | |
function touched(t) -- check if a button was pressed | |
if t.state==BEGAN then | |
for a,b in ipairs(buttonTab) do | |
if b:touched(t) then --see button:touched below | |
break | |
end | |
end | |
end | |
end | |
function menu() | |
background(58, 97, 136, 255) | |
fontSize(30) | |
text("Menu Screen",350,700) | |
drawButtonTab() | |
end | |
function screen1() | |
background(101, 43, 43, 255) | |
fontSize(30) | |
text("Screen 1",350,700) | |
drawButtonTab() | |
end | |
function screen2() | |
background(110, 165, 74, 255) | |
fontSize(30) | |
text("Screen 2",350,700) | |
drawButtonTab() | |
end | |
function screen3() | |
background(150, 144, 44, 255) | |
fontSize(30) | |
text("Screen 3",350,700) | |
drawButtonTab() | |
end | |
--a set of functions to act on your choices | |
--note how func is set to a different function, to tell the program what to do next | |
function url1() | |
openURL('http://www.google.com',true) | |
func=screen1 -- return to screen1 | |
end | |
function url2() | |
openURL('http://twolivesleft.com',true) | |
func=screen1 -- return to screen2 | |
end | |
function url3() | |
openURL('http://www.mapquest.com',true) | |
func=screen2 -- return to screen3 | |
end | |
function url4() | |
openURL('http://www.amazon.com',true) | |
func=screen3 -- return to screen4 | |
end | |
function drawButtonTab() -- draw selected buttons from button table | |
fontSize(20) | |
for a,b in ipairs(buttonTab) do | |
b:draw() --draw each button, see button:draw below | |
end | |
end | |
--this is an example of a class | |
--it controls everything about each button | |
button=class() | |
--this initialises a new button, and is given a set of inputs | |
function button:init(x,y,w,h,name,screen,func) | |
--the prefix "self" stores the variable within a special copy of the class just for this current button | |
self.x=x -- x position | |
self.y=y -- y position | |
self.w=w -- width | |
self.h=h -- height | |
self.name=name -- name to put on the button | |
self.screen=screen -- screen to draw the button on | |
self.func=func -- function to call when the button is pressed | |
end | |
--note it is button:draw, not button.draw | |
--the colon tells Codea to pass through which button it is | |
--then we can use the self prefix to get hold of the details for this particular button | |
function button:draw() | |
if func==self.screen then -- draw the button | |
fill(31, 178, 212, 255) | |
ellipse(self.x,self.y,self.w,self.h) | |
fill(255, 0, 0, 255) | |
text(self.name,self.x,self.y) | |
end | |
end | |
--similar to button:draw | |
--is run from the touched function above when a touch happens | |
function button:touched(t) | |
if func==self.screen then -- only check current screen button | |
if t.x>self.x-self.w/2 and t.x<self.x+self.w/2 and | |
t.y>self.y-self.h/2 and t.y<self.y+self.h/2 then | |
func=self.func | |
return true | |
end | |
return false | |
end | |
end | |
--# Collision | |
--collision example using physics objects (which will handle all the bouncing) | |
--delete the next line if you copy this to your own project | |
if localise then PN=PN+1 localise(PN,"Collision") end | |
function setup() | |
b=65 -- starting value for letter A, this is the number code | |
--(we use numbers because then we can increase or decrease them easily) | |
--there are a few things to set up for each physics object | |
c1 = physics.body(CIRCLE,5) -- create boundary for the letter | |
c1.x=295 | |
c1.y=900 | |
c1.restitution=.8 --bounciness | |
c2 = physics.body(CIRCLE,50) -- create boundary for 1st circle | |
c2.type=STATIC --this won't move | |
c2.x=300 | |
c2.y=600 | |
c3 = physics.body(CIRCLE,50) -- create boundary for 2nd circle | |
c3.type=STATIC | |
c3.x=120 | |
c3.y=400 | |
end | |
function draw() | |
a=string.char(b) -- convert number code of character to a letter | |
background(30, 30, 30, 25) | |
stroke(255) | |
strokeWidth(1) | |
noFill() | |
--draw circles, we just use their current positions | |
--the physics engine calculates those automatically for us | |
ellipse(c2.x,c2.y,100,100) -- draw the 1st circle | |
ellipse(c3.x,c3.y,100,100) -- draw the 2nd circle | |
fill(255) | |
fontSize(30) | |
text(a,c1.x,c1.y) -- draw the letter | |
-- get next letter when previous gets below y position of 20 | |
if c1.y<20 then | |
c1.y=900 | |
c1.x=295 | |
c1.linearVelocity=vec2(0,0) | |
b = b + 1 | |
if b>90 then | |
b=65 | |
end | |
end | |
end | |
--this is only needed when used in this project with many other tabs | |
--you can delete it if you copy the code to your own project | |
function cleanup() | |
if c1 then | |
c1:destroy() c1=nil | |
c2:destroy() c2=nil | |
c3:destroy() c3=nil | |
end | |
end | |
--# Collision2 | |
--collision example printing data | |
--delete the next line if you copy this to your own project | |
if localise then PN=PN+1 localise(PN,"Collision 2") end | |
-- all of this info can be found in the online manual | |
-- see the physics tab | |
function setup() | |
-- creates a circle that doesn't move | |
c1 = physics.body(CIRCLE,100) -- create body for 1st circle | |
c1.type=STATIC -- static means the circle doesn't move | |
c1.x=WIDTH/2 -- starting x,y values | |
c1.y=300 | |
-- creates a circle that is influenced by gravity | |
c2 = physics.body(CIRCLE,50) -- create body for 2nd circle | |
c2.x=WIDTH/2 -- starting x,y values | |
c2.y=800 | |
c2.restitution=1 -- how much the circle bounces when collided | |
end | |
function draw() | |
background(40,40,50) | |
stroke(255) | |
strokeWidth(1) | |
noFill() | |
ellipse(c1.x,c1.y,200,200) -- draw the 1st circle position | |
ellipse(c2.x,c2.y,100,100) -- draw the 2nd circle position | |
end | |
function collide(c) | |
if c.state==BEGAN then -- do this when the collision begins | |
print("\ncollision") -- \n makes Codea go to the next line down | |
print(c.id) | |
print("radius of body A ",c.bodyA.radius) | |
print("radius of body B ",c.bodyB.radius) | |
print("position of body A ",c.bodyA.x) | |
print("position of body A ",c.bodyA.y) | |
-- see physics.contact and physics.body in the reference manual | |
-- for other info that's available during a collision | |
end | |
end | |
--this is only needed when used in this project with many other tabs | |
--you can delete it if you copy the code to your own project | |
function cleanup() | |
if c1 then | |
c1:destroy() c1=nil | |
c2:destroy() c2=nil | |
end | |
end | |
--# Rotate | |
-- rotate example | |
--delete the next line if you copy this to your own project | |
if localise then PN=PN+1 localise(PN,"Rotate") end | |
function setup() | |
w=WIDTH | |
w2=WIDTH/2 | |
h=100 | |
--draw physics edges to screen so our ball bounces | |
e1=physics.body(EDGE,vec2(0,h),vec2(w2,0)) | |
e2=physics.body(EDGE,vec2(w2,0),vec2(w,h)) | |
e3=physics.body(EDGE,vec2(w,0),vec2(w,HEIGHT)) | |
--ball | |
r1=physics.body(CIRCLE,40) | |
r1.x=0 | |
r1.y=500 | |
r1.restitution=.8 --bounciness | |
r1.linearVelocity=vec2(210,0) | |
end | |
function draw() | |
background(40, 40, 50) | |
noFill() | |
stroke(255) | |
strokeWidth(2) | |
--draw lines to show edges of screen | |
line(0,h,w2,0) | |
line(w2,0,w,h) | |
line(w,0,w,HEIGHT) | |
pushMatrix() --store current location of origin (0,0) and rotation | |
translate(r1.x,r1.y) --move 0,0 to the position x=r1.x, y=r1.y | |
--so if we draw anything at 0,0 it will actually draw at r1.x, r1.y | |
--but the reason we do this is that all rotation happens around 0,0 | |
--we want to rotate around the centre of our object, at r1.x, r1.y | |
--that is why we "translate" to that position, so rotation will be centred on our object | |
xx=r1.angle | |
rotate(xx) --whee! | |
ellipse(0,0,80) --draw our circle and line | |
line(0,0,0,38) | |
popMatrix() --restore previous origin position and rotation | |
end | |
--# Block | |
-- 3D block example | |
--don't expect to understand much of this if you've never worked with 3D before | |
--if you want to learn about it, look for 3D topics on the Wiki link in the Codea forum | |
--delete the next line if you copy this to your own project | |
if localise then PN=PN+1 localise(PN,"3D block") end | |
function setup() | |
b=CreateBlock(10,20,15) --create block mesh with dimensions 10,20,15 | |
--set up some parameters for user to play with | |
parameter.integer("rotateX",0,360,200) | |
parameter.integer("rotateY",0,360,150) | |
parameter.integer("rotateZ",0,360,200) | |
parameter.integer("Distance",0,1000,100) | |
print("Use the sliders above to rotate the block (drag this print area down to see all the sliders)") | |
end | |
function draw() | |
background(0) | |
perspective() --sets up 3D with (default) 45 degree angle and current screen shape | |
camera(0,0,0,0,0,-1000) --camera located at 0,0,0 and points at 0,0,-1000 | |
pushMatrix() | |
translate(0,0,-Distance) --z is negative in OpenGL | |
--rotate on our three axes by the current angle, one by one | |
rotate(rotateX,1,0,0) | |
rotate(rotateY,0,1,0) | |
rotate(rotateZ,0,0,1) | |
b:draw() --draw | |
popMatrix() | |
end | |
--creates a block mesh | |
function CreateBlock(w,h,d) | |
local block = mesh() | |
--we'll centre it on 0,0,0 so it needs to be half on each side of 0 | |
local ww,hh,dd=w/2,h/2,d/2 | |
--define the 8 corners of our block | |
local v = { vec3(-ww,-hh,dd),vec3(-ww,hh,dd), | |
vec3(ww,-hh,dd),vec3(ww,hh,dd), | |
vec3(-ww,-hh,-dd),vec3(-ww,hh,-dd), | |
vec3(ww,-hh,-dd),vec3(ww,hh,-dd) } | |
--each of the 6 faces is made up of two triangles, ie a sequence of 6 corners | |
local faces = { v[1],v[2],v[3],v[2],v[3],v[4], | |
v[2],v[4],v[6],v[4],v[6],v[8], | |
v[1],v[2],v[5],v[2],v[5],v[6], | |
v[3],v[4],v[7],v[4],v[7],v[8], | |
v[1],v[3],v[5],v[3],v[5],v[7], | |
v[5],v[6],v[7],v[6],v[7],v[8] } | |
--splash of colour | |
local c = { color(255, 0, 0, 255), color(0, 255, 0, 255), | |
color(255, 243, 0, 255), color(0, 0, 255, 255), | |
color(255, 255, 255, 255), color(255, 0, 189, 255)} | |
local vertColors={} | |
local n=0 | |
for i=1,6 do | |
for j=1,6 do | |
n=n+1 | |
vertColors[n]=c[i] | |
end | |
end | |
--attach the vertices and colours to our mesh | |
block.vertices = faces | |
block.colors = vertColors | |
return block | |
end | |
--# Joint1 | |
-- joint example | |
--delete the next line if you copy this to your own project | |
if localise then PN=PN+1 localise(PN,"Joint 1") end | |
function setup() | |
c1 = physics.body(CIRCLE,0) | |
c1.x = 400 | |
c1.y = 800 | |
c1.restitution = 1 | |
c1.type = STATIC | |
p1=physics.body(POLYGON,vec2(-10,25),vec2(-10,-25),vec2(10,-25),vec2(10,25)) | |
p1.x=100 | |
p1.y=800 | |
j1 = physics.joint(REVOLUTE, c1, p1,c1.position) | |
end | |
function draw() | |
background(40, 40, 50) | |
strokeWidth(2) | |
line(c1.x,c1.y,p1.x,p1.y) | |
pushMatrix() | |
translate(p1.x,p1.y) | |
rotate(p1.angle) | |
local points = p1.points | |
for j = 1,#points do | |
a = points[j] | |
b = points[(j % #points)+1] | |
line(a.x, a.y, b.x, b.y) | |
end | |
popMatrix() | |
end | |
--only needed because there are other physics demos in this project, delete if you copy code elsewhere | |
function cleanup() | |
if c1 then | |
c1:destroy() c1=nil | |
p1:destroy() p1=nil | |
j1:destroy() j1=nil | |
end | |
end | |
--# Joint2 | |
--joint example 2 | |
--delete the next line if you copy this to your own project | |
if localise then PN=PN+1 localise(PN,"Joint 2") end | |
function setup() | |
c1 = physics.body(CIRCLE,0) | |
c1.x = 400 | |
c1.y = 1000 | |
c1.type = STATIC | |
c2 = physics.body(CIRCLE,25) | |
c2.x = 200 | |
c2.y = 900 | |
c3 = physics.body(CIRCLE, 25) | |
c3.x = 500 | |
c3.y = 950 | |
c4 = physics.body(CIRCLE, 25) | |
c4.x = 300 | |
c4.y = 850 | |
p1=physics.body(POLYGON,vec2(-10,25),vec2(-10,-25),vec2(10,-25),vec2(10,25)) | |
p1.x=400 | |
p1.y=850 | |
joint1 = physics.joint(REVOLUTE,c1,c2,c1.position) | |
joint2 = physics.joint(REVOLUTE, c2, c3,vec2(c2.x,c2.y)) | |
joint3 = physics.joint(REVOLUTE, c3, c4,vec2(c3.x,c3.y)) | |
joint4 = physics.joint(REVOLUTE, c4, p1,vec2(c4.x,c4.y)) | |
end | |
function draw() | |
background(40, 40, 50) | |
fill(255) | |
strokeWidth(2) | |
line(c1.x,c1.y,c2.x,c2.y) | |
line(c2.x,c2.y,c3.x,c3.y) | |
line(c3.x,c3.y,c4.x,c4.y) | |
line(c4.x,c4.y,p1.x,p1.y) | |
ellipse(c1.x,c1.y,8) | |
ellipse(c2.x,c2.y,8) | |
ellipse(c3.x,c3.y,8) | |
ellipse(c4.x,c4.y,8) | |
translate(p1.x,p1.y) | |
rotate(p1.angle) | |
points = p1.points | |
for j = 1,#points do | |
a = points[j] | |
b = points[(j % #points)+1] | |
line(a.x, a.y, b.x, b.y) | |
end | |
end | |
--only needed because there are other physics demos in this project, delete if you copy code elsewhere | |
function cleanup() | |
if c1 then | |
c1:destroy() c1=nil | |
c2:destroy() c2=nil | |
c3:destroy() c3=nil | |
c4:destroy() c4=nil | |
p1:destroy() p1=nil | |
joint1:destroy() joint1=nil | |
joint2:destroy() joint2=nil | |
joint3:destroy() joint3=nil | |
joint4:destroy() joint4=nil | |
end | |
end | |
--# Joint3 | |
--joint example 3 | |
--delete the next line if you copy this to your own project | |
if localise then PN=PN+1 localise(PN,"Joint 3") end | |
function setup() | |
a1=physics.body(CIRCLE,0) | |
a1.x=0 | |
a1.y=0 | |
a1.type=STATIC | |
c1=physics.body(CIRCLE,15) | |
c1.x=40 | |
c1.y=700 | |
p1=physics.body(POLYGON, | |
vec2(0,0), | |
vec2(-100,-30), | |
vec2(100,-30)) | |
p1.x=0 | |
p1.y=0 | |
j1=physics.joint(REVOLUTE,a1,p1,vec2(0,0)) | |
end | |
function draw() | |
background(40, 40, 50) | |
if c1.y<-200 then | |
c1.y=700 | |
c1.x=40 | |
c1.linearVelocity=vec2(0,0) | |
end | |
pushMatrix() | |
translate(250,600) | |
ellipse(0,0,10) | |
ellipse(a1.x,a1.y,10) | |
ellipse(p1.x,p1.y,10) | |
line(0,0,p1.x,p1.y) | |
ellipse(c1.x,c1.y,c1.radius*2) | |
noFill() | |
stroke(255) | |
strokeWidth(2) | |
xx=p1.angle | |
rotate(xx) | |
line(0,0,-100,-30) | |
line(-100,-30,100,-30) | |
line(100,-30,0,0) | |
popMatrix() | |
end | |
--only needed because there are other physics demos in this project, delete if you copy code elsewhere | |
function cleanup() | |
if a1 then | |
a1:destroy() a1=nil | |
c1:destroy() c1=nil | |
p1:destroy() p1=nil | |
j1:destroy() j1=nil | |
end | |
end | |
--# Mortgage | |
-- mortgage calculator | |
--delete the next line if you copy this to your own project | |
if localise then PN=PN+1 localise(PN,"Mortgage") end | |
function setup() | |
boxTab={} -- table of input/output boxes | |
-- x,y,w,h,type,text | |
table.insert(boxTab,input(100,500,120,30,1,"Loan $ amount")) | |
table.insert(boxTab,input(300,500,120,30,1,"Yearly % ( 5%=5 )")) | |
table.insert(boxTab,input(500,500,120,30,1,"Number of years")) | |
table.insert(boxTab,input(300,400,120,30,2,"Monthly payment")) | |
table.insert(boxTab,input(500,400,120,30,2,"Total payments")) | |
end | |
function draw() | |
background(34, 74, 82, 255) -- screen color | |
fill(255,0,0) -- set color to red | |
pushStyle() | |
fontSize(40) | |
text("MORTGAGE CALCULATOR",WIDTH/2,HEIGHT-50) -- draw text | |
popStyle() | |
fill(224, 149, 127, 255) -- set color | |
text("( Tap each box to input values )",WIDTH/2,HEIGHT-100) -- draw text | |
for a,b in pairs(boxTab) do -- loop thru table | |
b:draw() -- draw each box | |
end | |
amt=tonumber(boxTab[1].val) -- starting amount | |
int=tonumber(boxTab[2].val/100) -- yearly interest | |
year=tonumber(boxTab[3].val) -- number of years | |
-- perform interest calculation | |
i=int/12 -- interest per month | |
n=year*12 -- total months | |
w=(1+i)^n | |
m=amt*i*w/(w-1) -- calculate monthly amount | |
boxTab[4].val=string.format("%.2f",m) -- save monthly payment | |
boxTab[5].val=string.format("%.2f",m*n) -- save total payments | |
end | |
function touched(t) -- check which box is selected | |
for nbr,box in pairs(boxTab) do -- loop thru table | |
if box:touched(t) then -- box touched | |
return -- dont check other boxes, exit function | |
end | |
end | |
end | |
function keyboard(k) | |
for nbr,box in pairs(boxTab) do -- loop thru table | |
box:keyboard(k) -- get input from box | |
end | |
end | |
input=class() | |
function input:init(x,y,w,h,type,txt) | |
self.x=x -- x position | |
self.y=y -- y position | |
self.w=w -- width | |
self.h=h -- height | |
self.type=type -- 1=input box 2=output box | |
self.txt=txt -- text to show above box | |
self.val="0" -- data keyed in box | |
self.sel=false -- box selected true/false | |
end | |
function input:draw() | |
pushStyle() | |
rectMode(CORNER) | |
textMode(CORNER) | |
fill(0) -- set background for box | |
if self.sel then -- set selected color for box | |
fill(105, 101, 31, 255) | |
end | |
stroke(255, 66, 0, 255) -- box outline color | |
strokeWidth(2) -- outline size | |
rect(self.x,self.y,self.w,self.h) -- draw box | |
fill(255) -- set text color | |
text(self.txt,self.x,self.y+self.h) -- box name | |
text(self.val,self.x+4,self.y+4) -- box text | |
popStyle() | |
end | |
function input:keyboard(k) | |
if self.sel then | |
if k==BACKSPACE then -- backspace key pressed | |
str=str:sub(1,str:len()-1) -- remove last digit | |
if str=="" then -- blank | |
str="0" -- make 0 | |
end | |
elseif k>="0" and k<="9" or k=="." then -- only digits 1 thru 9 | |
if str:sub(1,1)=="0" then -- check if leading 0 | |
str="" -- clear leading 0 | |
end | |
str=str..k -- update keyed value | |
end | |
self.val=str -- save keyed value | |
end | |
end | |
function input:touched(t) | |
if t.state==BEGAN then | |
if not isKeyboardShowing() then | |
showKeyboard() -- show keyboard if its not displayed | |
end | |
str="0" -- clear value | |
for z=1,#boxTab do -- clear selected flag for all boxes | |
boxTab[z].sel=false | |
end | |
-- check which box was selected | |
if t.x>self.x and t.x<self.x+self.w and | |
t.y>self.y and t.y<self.y+self.h and self.type==1 then | |
self.val="0" -- reset val | |
self.sel=true -- set selected flag | |
return true -- a box was selected | |
end | |
end | |
return false -- no box was selected | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment