It looks like you're new here. If you want to get involved, click one of these buttons!
Okay. So I'm trying to learn to code in Codea but I feel there's a lack of tutorials so I've just been trying to figure things out.
My goal is simply to move my character using buttons.
I have a LeftBtn class and Character class and I'm wondering how to change the x position of the character from the button class as I don't want my Main class to deal with my character's movements. I like a clean Main class.
Here's My code:
MAIN CLASS
-- Use this function to perform your initial setup
function setup()
displayMode(FULLSCREEN)
char = Character()
charX = WIDTH/2
charY = HEIGHT/2
char:init(charX,charY)
LeftBtn:init(WIDTH/4-200,HEIGHT/4,100,100)
RightBtn:init(WIDTH/4-50,HEIGHT/4,100,100)
end
-- This function gets called once every frame
function draw()
-- This sets a dark background color
background(255, 255, 255, 255)
-- This sets the line thickness
strokeWidth(5)
textSize(20)
text(charX, 500, 500)
-- Do your drawing here
char:draw()
LeftBtn:draw()
RightBtn:draw()
end
function touched(touch)
-- Codea does not automatically call this method
LeftBtn:touched(touch)
end
CHARACTER CLASS
Character = class()
function Character:init(x,y)
-- you can accept and set parameters here
self.x = x
self.y = y
end
function Character:draw()
-- Codea does not automatically call this method
sprite("Planet Cute:Character Boy", self.x, self.y, 101, 171)
end
function touched(touch)
-- Codea does not automatically call this method
end
LEFTBTN CLASS
LeftBtn = class()
function LeftBtn:init(x,y,w,h)
-- you can accept and set parameters here
self.x = x
self.y = y
self.w = w
self.h = h
end
function LeftBtn:draw()
-- Codea does not automatically call this method
fill(87, 87, 87, 50)
rectMode(CENTER)
noStroke()
rect(self.x, self.y, self.w, self.h)
fill(0)
font("MarkerFelt-Wide")
fontSize(80)
text("L", self.x, self.y)
end
function LeftBtn:touched(touch)
-- Codea does not automatically call this method
if touch.state == BEGAN then character.x = character.x - 4 else end
end
Comments
(Firstly, code blocks are delimited by three tildes, not three dashes)
Your code updates the
x
field of thecharacter
table. But there is notcharacter
table. There is aCharacter
class (note the capital) which is really just a table in disguise, and achar
object which is an instance of theCharacter
class, but again is just a table in disguise. What you really want to update ischar.x
so you could putchar.x
in place ofcharacter.x
.But I wouldn't do that. I'd rather make
LeftBtn
not know anything about what it is acting on - it makes it easier to change things later on. So when initialisingLeftBtn
, I'd pass it thechar
object:then in the initialisation code:
and in the touched function
finally, the character has to know what to do:
In fact, I'd probably go a bit further and define one button class of which both the left and right were instances, which would mean passing the text as well. I'd also make it even less tied to the Character class and send a callback function, but that would need a bit more restructuring.
The last point to make is that
charX
never gets updated. This is because in the line (using my code, but it's the same in yours)self.x = self.x + x
then this assigns toself.x
(a pointer to) the result of the computationself.x + x
. What it does not do is update the value thatself.x
was pointing to before. SocharX
happily goes on pointing toWIDTH/2
whileself.x
wanders all over the screen.You responded so fast that I can only assume ur awesome. Thank u, let me try out what u suggested
I think I did what you said but nothing happens
DId I miss something? I don't think the left button's "touch" function are being called but I clearly put it in the Main class, right?
MAIN
CHARACTER
LEFTBTN
It seems like it should work
I usually put a print() statement in the function I am testing to see if it is called. Really helps !
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.
Thank u. I figured out a way to do it but simply forgot to update it here. I will, however, try out what u suggested as the code greatly differs from mine. (kinda makes mine look too simple and mediocre)
@RichGala1, nice if you update your code here. Thanks in advance (I'm a newbie too) :-D
Hi, @Reefwing. Thanks for using the button mesh class and adding some functionality. When I made that I promised to update with callbacks and such and never got around to it. I think the way you did works pretty well.
@RichGala1 - nothing wrong with simple if it gets the job done. Well done on sorting it out on your own, that is one of the joys of coding. Most of the code in my solution is the general button class. Actually moving the Sprite doesn't take much code at all.
@Vega - great button class, I am using it exclusively now, along with some of the other code you have contributed. I used the call back pattern from @Simeon's button class so I cant take any credit for it.
how does the global "local" thing work?
Global variables are available throughout your code. If you dont specify then a variable is global.
If you specify a variable as local (by using the local keyword) then the variable is only available in the block where they are declared. A block can be the body of a control structure, the body of a function, or a chunk (unit of execution). For example, in the contrived example below:
You should try to use local variables as much as possible, access to them is much faster than for globals and using globals can make your code harder to read and maintain.