First program - for students to learn coordinates

Just bought Codea after struggling with the learning curve for Objective C. (Delphi background) This is so easy to start with compared to Objective C. Would appreciate any comments, this is the result of less than a day with Codea.

-- coOrdinator by John Melki-Wegner

-- Use this function to perform your initial setup
function setup()
    print("coOrdinator!")
    displayMode(FULLSCREEN)
    supportedOrientations(LANDSCAPE_ANY)
    midx=WIDTH/2
    midy=HEIGHT/2
    -- grid scale
    dx=WIDTH/15
    timeleft=5000
    -- playing 0 =not playing, 1 =playing
    playing=0
    -- current point
    cx=0
    cy=0
    -- score
    score=0
    ellipsesize=10
    toggle=true
end

-- get a new point
function getNewPoint()
    cx=math.random(-5,5)
    cy=math.random(-4,4)
end

function onGrid(tx,ty)
    result = true
    if tx>5 or tx<-5 then
        result=false
    end
    if ty>4 or ty<-4 then
        result=false
    end
    return result
end

-- This function gets called once every frame
function draw()
    -- This sets a dark background color 
    background(40, 40, 50)

    -- This sets the line thickness
    strokeWidth(5)

    -- draw grid and other objects=================
    textMode(CORNER)
    fontSize(32)
    fill(3, 243, 24, 255)
    text("coOrdinator",WIDTH-250,HEIGHT-50)
    if playing==0 then
    -- start button
        fill(244, 243, 245, 255)
        stroke(11, 13, 11, 255)
        rect(10,HEIGHT-55,100,50)
        fill(3, 3, 3, 255)
        text("Start",25,HEIGHT-50)
    end
    
    -- draw axes
    stroke(194, 63, 63, 255)
    line(midx,dx,midx,HEIGHT-dx)
    line(dx,midy,WIDTH-dx,midy)
    -- draw grid points
    stroke(132, 185, 85, 255)
    for i=-5,5 do
        for j=-4,4 do
            ellipse(midx+i*dx,midy+j*dx,5,5)
            end
        end
  
    -- show numbers
    fontSize(16)
    fill(248, 248, 248, 255)
    for i=-5,5 do
        text(i,midx+i*dx-5,midy)
        end
    for i=-4,4 do 
        text(i,midx+5,midy+i*dx-10)
    end

    -- show score
    fontSize(30)
    fill(3, 243, 24, 255)
    sscore=string.format("Score=%d",score)
    text(sscore,150,HEIGHT-50)
    --game logic========================= 
    --timer
    if playing==1 then
        timeleft=timeleft-1
        -- end game?
        if timeleft<=0 then
            playing=0
        end
        -- show timeleft by rectangle "progress bar"
        stroke(130, 138, 131, 255)
        fill(113, 156, 117, 255-timeleft/100)
        rect(20,70,30,timeleft/8)
        tl=string.format("%d",timeleft)
        fontSize(14)
        text(tl,20,timeleft/8+70)
    end
    -- touch events
    -- touch position on grid
    tx=math.floor(CurrentTouch.x/dx)-7
    ty=math.floor(CurrentTouch.y/dx)-5
    if playing==1 then
        fill(ellipsesize*5, ellipsesize*5, 11, 255)
        stroke(ellipsesize*2, ellipsesize*2, 11, 255)
        if onGrid(tx,ty) then
            ellipse(midx+tx*dx,midy+ty*dx,ellipsesize,ellipsesize)
            sprite("Tyrian Remastered:Eggstroid",midx+tx*dx,midy+ty*dx)
        end
        fill(3, 243, 24, 255)
        s=string.format("(%d,%d)",cx,cy)
        fontSize(30)
        text(s,midx-30,HEIGHT-50)
    end
    
    -- button pressed?
    if CurrentTouch.x<=110 then
        if CurrentTouch.y>=HEIGHT-55 then
            if playing==0 then
                -- button pressed
                playing=1
                timeleft=5000
                score=0
                getNewPoint()
            end
            end
    end
    -- correct point chosen?
    if tx==cx and ty==cy then
        score = score + 1
        getNewPoint()
        ellipsesize = ellipsesize + 1
        end
    -- annimation for correct point
    if ellipsesize>10 then
        sprite("Tyrian Remastered:Button Glow",midx+tx*dx,midy+ty*dx)
        ellipsesize = ellipsesize + 2
        if ellipsesize>= 50 then
            ellipsesize=10
            end
        end
end

Hello @Allomerus, I liked the game. I found a bug that distracted me at first - when the game starts for the first time, and the score is 0, you can win one point by touching 0,0. :slight_smile:

I tried to make the reverse way, by moving a sprite on the screen and showing the coordinates, BUT I am unable to draw axes due to frame rate I think.
Here is the code.
My youngest daughter is learning coordinates and the @Allomerus program enjoyed her signifiantly.


displayMode(FULLSCREEN)
backingMode()

function setup()
   midx = WIDTH/2
   midy = HEIGHT/2 
   bImg =image(WIDTH, HEIGHT)
   setContext(bImg)

   shipPosition = vec2(WIDTH/2, HEIGHT/2)
   



   local mButtonSize = vec2(100, 50)
   local mLocX = WIDTH - 250
   local mLocY = 100

   shipSpeed = 5
   dx = 15

   leftButton = Button("Left", vec2(mLocX, mLocY), mButtonSize.x, mButtonSize.y)
   XPos = Button("", vec2(0, HEIGHT-50), mButtonSize.x, mButtonSize.y)
   YPos = Button("", vec2(120, HEIGHT-50), mButtonSize.x, mButtonSize.y)

   mLocX = mLocX + 150
   rightButton = Button("Right", vec2(mLocX, mLocY), mButtonSize.x, mButtonSize.y)

   mLocX = mLocX - 75
   mLocY = mLocY + 60
   upButton = Button("Up", vec2(mLocX, mLocY), mButtonSize.x, mButtonSize.y)

   mLocY = mLocY - 120
   downButton = Button("Down", vec2(mLocX, mLocY), mButtonSize.x, mButtonSize.y)

   -- Assign the colours that you want to use in your game.

   blackColour = color(192, 149, 201, 255)
   background(22, 175, 103, 255)
   toggle=true
end


function draw()
    background(40, 40, 50)
    fill(72, 213, 19, 255)
    leftButton:draw()
    rightButton:draw()
    upButton:draw()
    downButton:draw()
    XPos:draw()
    YPos:draw()
   -- This sets a black background color 
   -- background(blackColour)
   
   -- Do your drawing here
   -- Draw your ship at the current co-ordinates stored in shipPosition
   if leftButton.state == "pressing" then
       shipPosition.x = shipPosition.x - 15
       affichepos(shipPosition.x,shipPosition.y)
          
   elseif rightButton.state == "pressing" then
       shipPosition.x = shipPosition.x + 15
       affichepos(shipPosition.x,shipPosition.y)
       -- shipPosition.x = math.min(shipPosition.x + shipSpeed, WIDTH)
   elseif upButton.state == "pressing" then
       shipPosition.y = shipPosition.y + 15
       affichepos(shipPosition.x,shipPosition.y)
       -- shipPosition.y = math.min(shipPosition.y + shipSpeed, HEIGHT)
   elseif downButton.state == "pressing" then
       shipPosition.y = shipPosition.y - 15
       affichepos(shipPosition.x,shipPosition.y)
       -- shipPosition.y = math.max(shipPosition.y - shipSpeed, 0)
   end
    
   sprite("Tyrian Remastered:Button Glow",shipPosition.x, shipPosition.y)
   -- sprite("Tyrian Remastered:Boss D", shipPosition.x, shipPosition.y)

   -- Draw the four directional buttons
    -- stroke(194, 63, 63, 255)
   line(midx,dx,midx,HEIGHT-dx)
   line(dx,midy,WIDTH-dx,midy)
   line(0,HEIGHT/2,WIDTH,HEIGHT/2) 
   

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


function affichepos(x,y)
    XPos.font = "Futura-CondensedExtraBold"
    YPos.font = "Futura-CondensedExtraBold"
    fonSize = 240
    -- text("X :"..x,100,HEIGHT-50)
    -- text("Y :"..y,250,HEIGHT-50)
    X=(midx-shipPosition.x)/15
    Y=(midy-shipPosition.y)/15
    if X==0 then
        XPos.text = X
    else
        XPos.text =-1*X
    end
    if Y==0 then
        YPos.text = Y
    else
        YPos.text =-1*Y
    end
    
    -- shipPosition.x
    -- YPos.text = shipPosition.y
    fill(255)
    rect(100,100,50,50)
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"
           end
           if 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

In fact this program is the combination of two earlier programs from the forum, the second is about shipPosition.
Thanks in advance.

in fact, Pedagogically, I must use different colors according to the quadrant in which the sprite is moving, (color 1 for +/+, color 2 for +/-, color 3 for -/+ and color 4 for -/-).


displayMode(FULLSCREEN)
backingMode()

function setup()
   version = 1.0
   saveProjectInfo("Description", "Move Object Demonstration")
   saveProjectInfo("Author", "Reefwing Software")
   saveProjectInfo("Date", "11th July 2012")
   saveProjectInfo("Version", version)
   print("MoveShip v"..version.."\
")
   midx = WIDTH/2
   midy = HEIGHT/2 
   bImg =image(WIDTH, HEIGHT)
   setContext(bImg)
   
   shipPosition = vec2(WIDTH/2, HEIGHT/2)

   local mButtonSize = vec2(100, 50)
   local mLocX = WIDTH - 250
   local mLocY = 100

   shipSpeed = 5
   dx = 15

   leftButton = Button("Left", vec2(mLocX, mLocY), mButtonSize.x, mButtonSize.y)
   YPos = Button("", vec2(midx-120, HEIGHT-50), mButtonSize.x, mButtonSize.y)
   XPos = Button("", vec2(midx+20, HEIGHT-50), mButtonSize.x, mButtonSize.y)

   mLocX = mLocX + 150
   rightButton = Button("Right", vec2(mLocX, mLocY), mButtonSize.x, mButtonSize.y)

   mLocX = mLocX - 75
   mLocY = mLocY + 60
   upButton = Button("Up", vec2(mLocX, mLocY), mButtonSize.x, mButtonSize.y)

   mLocY = mLocY - 120
   downButton = Button("Down", vec2(mLocX, mLocY), mButtonSize.x, mButtonSize.y)


   blackColour = color(192, 149, 201, 255)
   background(22, 175, 103, 255)
   toggle=true
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()
    background(40, 40, 50)
    fill(72, 213, 19, 255)
    leftButton:draw()
    rightButton:draw()
    upButton:draw()
    downButton:draw()
    XPos:draw()
    YPos:draw()
   -- This sets a black background color 
   -- background(blackColour)
   
   -- Do your drawing here
   -- Draw your ship at the current co-ordinates stored in shipPosition
   if leftButton.state == "pressing" then
       shipPosition.x = shipPosition.x - 15
       affichepos(shipPosition.x,shipPosition.y)
          
   elseif rightButton.state == "pressing" then
       shipPosition.x = shipPosition.x + 15
       affichepos(shipPosition.x,shipPosition.y)
       -- shipPosition.x = math.min(shipPosition.x + shipSpeed, WIDTH)
   elseif upButton.state == "pressing" then
       shipPosition.y = shipPosition.y + 15
       affichepos(shipPosition.x,shipPosition.y)
       -- shipPosition.y = math.min(shipPosition.y + shipSpeed, HEIGHT)
   elseif downButton.state == "pressing" then
       shipPosition.y = shipPosition.y - 15
       affichepos(shipPosition.x,shipPosition.y)
       -- shipPosition.y = math.max(shipPosition.y - shipSpeed, 0)
   end
    
   sprite("Tyrian Remastered:Button Glow",shipPosition.x, shipPosition.y)
   -- sprite("Tyrian Remastered:Boss D", shipPosition.x, shipPosition.y)

   -- Draw the four directional buttons
    -- stroke(194, 63, 63, 255)
   line(midx,dx,midx,HEIGHT-dx)
   line(dx,midy,WIDTH-dx,midy)
   line(0,HEIGHT/2,WIDTH,HEIGHT/2) 
   

end

function touched(touch)
   leftButton:touched(touch) 
   rightButton:touched(touch)
   upButton:touched(touch)
   downButton:touched(touch)
end


function affichepos(x,y)
    XPos.font = "Futura-CondensedExtraBold"
    YPos.font = "Futura-CondensedExtraBold"
    fonSize = 240
    -- text("X :"..x,100,HEIGHT-50)
    -- text("Y :"..y,250,HEIGHT-50)
    X=(midx-shipPosition.x)/15
    Y=(midy-shipPosition.y)/15
    if X==0 then
        XPos.text = X
    else
        XPos.text =-1*X
    end
    if Y==0 then
        YPos.text = Y
    else
        YPos.text =-1*Y
    end
    if X<0 and Y<0 then
        fill(255)
        rect(midx,midy,midx,midy)
    end 
    if X<0 and Y>0 then
        fill(144, 226, 112, 255)
        rect(midx,0,midx,midy)
    end
    if X>0 and Y<0 then
        fill(219, 136, 116, 255)
        rect(0,midy,midx,midy)
    end
    if X>0 and Y>0 then
        fill(246, 23, 148, 255)
        rect(0,0,midx,midy)
    end
end

--# Button
Button = class()


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"
           end
           if 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