It looks like you're new here. If you want to get involved, click one of these buttons!
Fellow coders!
I'm new to coding, learning everything bit by bit and copy & pasting but I can't get the below code to work.
Hope you can understand the problem with these snippets:
-- I create the Levels here. One of the parameters is the name of the animation "PlayerStanding"
object[1] = CreateObject (WIDTH/2, HEIGHT/2, WIDTH/25, HEIGHT/10, "player","PlayerStanding",4)
-- This is my animation with table of images and animation speed:
PlayerStanding = Animation ({"Dropbox:PlayerStanding"},12)
-- and here is where my problem arises:
CreateObject = class()
function CreateObject:init(x,y,w,h,Category,AnimationName,ASpeed)
-- Parameters are given to self
self.AnimationName = AnimationName -- this is for the parameter "PlayerStanding" of above
function CreateObject:draw()
-- finally this is giving an error "attempt to call a nil value"
self.AnimationName:draw(self.body.x, self.body.y, self.w)
Apologies for torturing you with snippets only but the code is so beginnerishly organised and terribly long in full.
It seems I did not grasp the calling of classes yet.
Printing self.AnimationName is giving PlayerStanding. So it's not nil.
PlayerStanding:draw(self.body.x,...) works. But how do I call it with a variable so I can process all my objects with different animations?
Thanks so much for your patience!
Comments
You are probably calling the class draw function like this
instead of like this, with a colon
This explanation may help.
https://coolcodea.wordpress.com/2013/03/22/7-classes-in-codea/
Thanks for your reply! I studied the link several times before.
But I think, the : instead of . is not the case here.
As I wrote, PlayerStanding:draw() works fine.
But calling it via a parameter does not: Self.AnimationName:draw() doesn't work.
If I've understood correctly, self.AnimationName is a string,
self.AnimationName = "PlayerStanding"
? That won't work, you can't call a method name with a string. The good news is, as functions and methods are first class in Lua, you can just setself.AnimationName = PlayerStanding
andself.AnimationName:draw()
should workUnfortunately this doesnt work yet:
self.AnimationName = PlayerStanding
self.AnimationName:draw(self.body.x, self.body.y, self.w)
Error: Bad argument #1 to 'text' (string expected, got table)
We're getting close though. Please have another look how PlayerStanding is created:
PlayerStanding = Animation ({"Dropbox:PlayerImage1", "Dropbox:PlayerImage2"},4)
It's difficult to help you with only a fragment of code. Most often, the error is in another part of the code that hasn't been posted, and as a result we prefer to see all the relevant code - in this case, that includes the Animation draw function.
yeah, we need to see more code. You're not even showing us the line that's causing the error, which is calling
text
. Sounds like you were also usingself.AnimationName
as an argument fortext
(perhaps for debugging?). Sounds like you might need to split that variable into two, a stringanimationName
and a pointer to a methodanimationMethod
. But this is just guesswork without more info from you.This is the Animation class I'm using. It's not written by me, so big thanks to the original author!
Animation = class()
function Animation:init(frames, delay)
self.frames = frames -- table of sprite names
self.currentFrame = 1 -- the current frame
self.frameDelay = delay -- how many iterations of main draw loop before changing frame
self.count = 1 -- keeps track of iterations passed
end
function Animation:draw(x, y)
-- Increment the counter
self.count = self.count + 1
-- Check if frame should be updated
if self.count > self.frameDelay then
-- Reset count and increment current frame
self.count = 1
self.currentFrame = self.currentFrame + 1
-- Check if we've reached the last frame
if self.currentFrame > table.maxn(self.frames) then
-- Back to first frame
self.currentFrame = 1
end
end
-- Draw correct frame
sprite(self.frames[self.currentFrame], x, y)
end
Ahh! You see me being very unexperienced here. I thought the 'text' was referring to some type of variable but it was easily a line to see what self.AnimationName was carrying. So the below is the essential part of Class CreateObject
CreateObject = class()
function CreateObject:init(x,y,w,h,Category,AnimationName,ASpeed,Agility)
self.Givenx = x
self.Giveny = y
self.w = w
self.h = h
self.Category = Category
self.AnimationName = AnimationName
end
function CreateObject:draw()
self.AnimationName = PlayerStanding -- this works but it's not a parameter
self.AnimationName:draw(self.body.x, self.body.y, self.w)
--text(self.AnimationName,WIDTH/2,HEIGHT/2)
end
Once I comment the text out, the code works like this. I would just need to pass the PlayerStanding as a parameter which for some reason doesn't work.
As a reminder, this is how the above class is called:
object[1] = CreateObject (WIDTH/2, HEIGHT/2, WIDTH/25, HEIGHT/10, "player",PlayerStanding,4,0) -- tried PlayerStanding with and without ""
Also, when pasting code in the forum, put a line starting with three tildes
~~~
at the top and bottom of the code to format it correctly.Thanks a lot for your help already. I don't know how to create the pointer and how to use it as a param.
Also I read somewhere to put .. In front of a string or variable. What does this do?
Just about every variable is a pointer, in that it only stores a memory address of whatever you put into it.
So as a good example, if your game has several states, eg Splash, Menu,
Settings, Play, GameOver, you could put all the code into the draw function and use an if statement to decide which screens to draw, depending on the state.
A much cleaner approach is this. Write a separate draw function for each of the states, eg DrawSplash, DrawMenu, etc. Then create a variable that stores the function you want to run at the moment. So when you start off, you write.
And then your normal draw function looks like this
When the user starts playing, you set
And now your normal draw function will draw the playing screen
If your brain can take a little more, when you write
This is the same as writing
In other words, Codea creates the function, puts it in memory, and stores the address in A. So your function A is really only holding a memory address, and that's why you can copy it to another variable as I did above.
Thanks for the lesson and all efforts!