It looks like you're new here. If you want to get involved, click one of these buttons!
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\n 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
Comments
In your code where you have start=Button(...) you're passing 7 parameters but the function only accepts 6, so the size of r is 100. Don't have time to look at the other problem now.
I'm not sure what you're trying to do with the touched class. Are you trying to setup stuff for touch when you create a button.
@jaj_TheDeveloper Is this what your trying to do when you create a button. In the code below, you define the button in setup and it creates a round rect button a little larger than the text. The button:touched function checks if a button is touched.
@dave1707 Thanks, my btn problem is now solved. In regards to the to Touch, I would prefer to have a function that checks if the touch is in any objects, such as Units or squares of landthat will call the
touched()
function for the corresponding object and that object alone. You know the saying, "Never type the same code twice."