Calling a class with a string

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!

You are probably calling the class draw function like this

MyClass.draw()

instead of like this, with a colon

MyClass:draw()

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 set self.AnimationName = PlayerStanding and self.AnimationName:draw() should work

Unfortunately 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 using self.AnimationName as an argument for text (perhaps for debugging?). Sounds like you might need to split that variable into two, a string animationName and a pointer to a method animationMethod. 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 “”

Sounds like you might need to split that variable into two, a string animationName and a pointer to a method animationMethod.

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.

DrawFunction=DrawSplash

And then your normal draw function looks like this

function draw()
    DrawFunction() --runs whatever function is in there
end

When the user starts playing, you set

DrawFunction=DrawPlay

And now your normal draw function will draw the playing screen

If your brain can take a little more, when you write

function A()
    --some code
end

This is the same as writing

A=function()
        --some code
    end

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!