Hello there.
I am currently working on recreating the game “The Battle of Polytopia” (Previously known as Super Tribes) in Codea. At the moment I am working on the menu. Heres what I’ve got so far:
-- __________
-- | MyVars |
RECT = 1
TouchObjects = {}
-- ________________
-- | Animatables |
-- Text
Text = class()
-- Animatable Text
function Text:init(str, x, y, size)
self.str = str
self.x = x
self.y = y
self.size = size or false
self.originalState = {str = self.str, x = self.x, y = self.y, size = self.size}
end
function Text:draw()
-- If size is not defined, use the size already set.
if self.size then
fontSize(self.size)
end
text(self.str, self.x, self.y)
end
-- Colour
Colour = class()
-- Animatable colour
function Colour:init(r,g,b,a)
-- you can accept and set parameters here
self.r = r
self.g = g or false
self.b = b or false
self.a = a or 255
if not (g and b) then
self.g = self.r.g
self.b = self.r.b
self.a = self.r.a
self.r = self.r.r or 255
end
self.originalState = {r = self.r, g = self.g, b = self.b, a = self.a}
end
function Colour:draw()
-- Codea does not automatically call this method
return color(self.r, self.g, self.b, self.a)
end
-- roundRect and animatable (taken from Sound Example)
function roundRect(x,y,w,h,r)
pushStyle()
insetPos = vec2(x+r,y+r)
insetSize = vec2(w-2*r,h-2*r)
--Copy fill into stroke
local red,green,blue,a = fill()
stroke(red,green,blue,a)
noSmooth()
rectMode(CORNER)
rect(insetPos.x,insetPos.y,insetSize.x,insetSize.y)
if r > 0 then
smooth()
lineCapMode(ROUND)
strokeWidth(r*2)
line(insetPos.x, insetPos.y,
insetPos.x + insetSize.x, insetPos.y)
line(insetPos.x, insetPos.y,
insetPos.x, insetPos.y + insetSize.y)
line(insetPos.x, insetPos.y + insetSize.y,
insetPos.x + insetSize.x, insetPos.y + insetSize.y)
line(insetPos.x + insetSize.x, insetPos.y,
insetPos.x + insetSize.x, insetPos.y + insetSize.y)
end
popStyle()
end
RoundRect = class()
function RoundRect:init(x,y,w,h,r)
self.x = x
self.y = y
self.w = w
self.h = h
self.r = r
self.originalState = {x = self.x, y = self.y, w = self.w, h = self.h, r = self.r}
end
function RoundRect:draw()
roundRect(self.x, self.y, self.w, self.h, self.r)
end
-- ________
-- | Main |
-- Use this function to perform your initial setup
function setup()
-- Scenes
menu = Menu()
-- Set current scene to menu
setScene(menu)
end
function setScene(s)
scene = s
-- Setup the current scene
scene:setup()
end
-- This function gets called once every frame
function draw()
-- Call draw function for current scene
scene:draw()
end
function touched(touch)
scene:touched(touch)
Touch:touched(vec2(touch.x, touch.y))
end
-- _________
-- | Menu |
Menu = class()
function Menu:init()
-- you can accept and set parameters here
end
function Menu:setup()
-- Colours for opening colour sequence
bg = Colour(235, 69, 217, 255)
t1 = tween(1, bg, {r = 241, g = 233, b = 45})
t2 = tween(1, bg, {r = 0, g = 184, b = 255})
-- Animatable text
title = Text("POLY\
TOPIA", WIDTH/2, HEIGHT+100, 90)
t3 = tween(0.6, title, {y = HEIGHT-230})
t4 = tween(0.4, title, {y = HEIGHT-270, size = 111})
tween.sequence(t1, t2, t3, t4)
t1, t2, t3, t4 = nil
-- Button Animation
start = Button("Start", RECT, 12, WIDTH/2, 150, 100, 11)
end
function Menu:draw()
-- Set the background colour
background(bg:draw())
-- Title text
font("GillSans-Light")
textAlign(CENTER)
textMode(CENTER)
fill(255, 255, 255, 255)
title:draw()
start:draw()
end
function Menu:touched(touch)
end
-- _________
-- | Touch |
-- Problem #1: start:touched() not being triggered
-- Trigger the touch function of an object only if that object is touched
Touch = class()
function Touch:init(object)
table.insert(TouchObjects, object)
end
function Touch:draw()
-- Codea does not automatically call this method
end
function Touch:touched(p)
-- Check if the touch is inside any of the objects
for i,object in pairs(TouchObjects) do
local l = object.pos.x - object.size.x/2
local r = object.pos.x + object.size.x/2
local t = object.pos.y + object.size.y/2
local b = object.pos.y - object.size.y/2
if p.x > l and p.x < r and
p.y > b and p.y < t then
object:touched()
end
end
end
-- __________
-- | Button |
-- Problem #2: [Solved] What's wrong with textSize()?
Button = class()
function Button:init(str,t,s,x,y,r)
-- you can accept and set parameters here
self.displayText = str
self.form = t
self.x = x
self.y = y
self.w = w
self.r = r or 0
if s then
self.s = s
else
self.s = fontSize()
end
-- Create a custom button to fit the text.
fontSize(self.s)
self.text = {}
self.text.w,self.text.h = textSize(self.displayText)
print(self.text.w.." "..self.text.h)
self.w = self.text.w*1.5
self.h = self.text.h*1.5
print(self.w)i
print(self.h)
-- For Touch()
self.pos = vec2(0,0)
self.size = vec2(0,0)
-- Save original state
self.originalState = {str = self.str, form = self.form, s = self.s, x = self.x, y = self.y, r = self.r, w = self.w, h = self.h}
-- Save button to Touch()
Touch(self)
end
function Button:draw()
-- Codea does not automatically call this method
if self.form == RECT then
fill(255, 0, 196, 255)
roundRect(self.x-self.w/2, self.y-self.h/2, self.w, self.h, self.r)
fill(255, 255, 255, 255)
textAlign(CENTER)
textMode(CENTER)
fontSize(self.s)
text(self.displayText, self.x, self.y)
end
end
function Button:touched(touch)
-- Codea does not automatically call this method
print("Bumbo")
end
I am facing two problems:
One, if you run the code you’ll notice the immense size of the start button. This button was supposed to automatically fit the text perfectly using the textSize()
function. If someone could explain to me what is going wrong and how to fix it (even if it a stupidly obvious mistake, which I can assure you is very likely).
Two, you may have noticed my Touch()
function. The way this is supposed to work is when creating an object (e.g. A button) you run Touch(self)
, which adds the object to an table. Every time Codea senses a touch, the function cycles through all the objects within the table and checks if the touch is inside any of these, and then calls the touched()
function for that specific objects. In the code above it calls start:touched()
.
Thank you for taking the time to read this through.
Toodles.
EDIT: Problem #1 solved thanks to @dave1707