Coding Problem (getting nil value)

I believe I have everything settled up correctly… It’s saying I have a nil value! I have my player defined in the Main class so idk what I did wrong. Please help

Player = class()
function Player:init(img,x,y)
    self.image = img
    self.x = x
    self.y = y
    self.width, self.height = spriteSize(self.image)
     
end

function Player:draw()
    sprite(self.image,self.x,self.y,self.width,self.height)
    end

function Player:left()
    if time < 1 then
        if self.image == ("Documents:PL1")then
            self.image = ("Documents:PL2")     
        elseif self.image == ("Documents:PL2") then
            self.image = ("Documents:PL3") 
        elseif self.image == ("Documents:PL3") then
            self.image = ("Documents:PL4")     
        elseif self.image == ("Documents:PL4") then
            self.image = ("Documents:PL1")
            end
        end
end

function Player:right()
    
    if time < 1 then
        if self.image == ("Documents:PL1") then
            self.image = ("Documents:PL2")     
        elseif self.image == ("Documents:PL2") then
            self.image = ("Documents:PL3") 
        elseif self.image == ("Documents:PL3") then
            self.image = ("Documents:PL4")     
        elseif self.image == ("Documents:PL4") then
            self.image = ("Documents:PL1")
            end
            
            
            
            
            
            
        end
end

Tough one to find. When your brain knows what you meant your eyes see what they expect.

which line or item is giving a nil value?

Any selfs… Like in player:right, player:left

I tried calling self.width but it didn’t like that too much

this kind of error is almost always from an instance call with a ‘.’ instead of a ‘:’ . Look for a player1.right() instead of a player1:right() in your main or elsewhere.

Still getting an error… Nil value. The only thing that works is calling player.width and player.image… What’s the pont of using self if u can’t -_-

Post the code that causes the error, ie where you are trying to run player functions. We don’t think the problem is in the code you posted above.

Player = class()
function Player:init(img,x,y)
    self.image = img
    self.x = x
    self.y = y
    self.width, self.height = spriteSize(self.image)
     
end

function Player:draw()
    if playerface == 1 then
        sprite(self.image,self.x,self.y,self.width,self.height)
    elseif playerface == -1 then
        sprite(self.image,self.x,self.y,-self.width,self.height)
        end
    end

function Player:left()
    if time < 1 then
        if self.image == ("Documents:PL1")then
            self.image = ("Documents:PL2")     
        elseif self.image == ("Documents:PL2") then
            self.image = ("Documents:PL3") 
        elseif self.image == ("Documents:PL3") then
            self.image = ("Documents:PL4")     
        elseif self.image == ("Documents:PL4") then
            self.image = ("Documents:PL1")
            end
        end
end

function Player:right()
    if time < 1 then
         
        if self.image == ("Documents:PL1") then
            self.image = ("Documents:PL2")     
        elseif self.image == ("Documents:PL2") then
            self.image = ("Documents:PL3") 
        elseif self.image == ("Documents:PL3") then
            self.image = ("Documents:PL4")     
        elseif self.image == ("Documents:PL4") then
            self.image = ("Documents:PL1")
            end
            
            
            
            
            
            
        end
end


Main class.................


-- Visit From Space
sprite("Cargo Bot:Command Left")
-- Use this function to perform your initial setup
function setup()
    time = 0
    playerface = 1
    left = Button("Cargo Bot:Command Left",600,100,80,100)
    right = Button("Cargo Bot:Command Right",700,100,80,100)
    for i=0,1 do
        x = math.random(300,500)
        y = math.random(300,500)
        Enemy(x,y)
        end
    player = Player("Documents:PL1",400,100)
end

-- This function gets called once every frame
function draw()
    time = time + 1 
    if time > 10 then
        time =  0
    end
    
    -- This sets a dark background color 
    background(40, 40, 50)
    Enemy:draw()
    player:draw()
    left:draw()
    right:draw()
    left:touched()
    right:touched()
    -- This sets the line thickness
    strokeWidth(5)

    -- Do your drawing here
    
end

Idk why it’s not working :frowning:

You haven’t provided code for the Enemy and Button class. I assume they are working correctly. I can’t see an obvious problem with Player.

Also, if you post code, please put three ~ before and after the code so it looks nice. I fixed your post above to do this.

@Ignatz The enemy and button class are perfectly working fine. It’s just that the player class won’t accept the self values from the :init(). I have the same in the button class and it works fine so I am very confused.

-- Game
Button = class()

function Button:init(img,x,y,width,height)
    self.image = img
    self.x = x
    self.y = y
    self.angle = 0
    self.width = width
    self.height = height
end

function Button:draw()
    pushMatrix()
    resetMatrix()
    rotate(self.angle)  
    sprite(self.image,self.x,self.y,self.width,self.height)
    popMatrix()
    end

function Button:touched(touch)
    --print(CurrentTouch)
    if CurrentTouch.x > (self.x - self.width/2) and
        CurrentTouch.x < (self.x + self.width/2) and
        CurrentTouch.y > (self.y - self.height/2) and
        CurrentTouch.y < (self.y + self.height/2) and
        CurrentTouch.state < 2 then
            if self.image == "Cargo Bot:Command Left" then
                player.x = player.x -5
                playerface = 1
                Player.left()
            else
                player.x = player.x +5
                Player:right()
                playerface = -1
            end
        end
    end

@Crazypkr1099 - look in function Button:touched(touch)

you say

Player.left()

when you mean to say

player:left()

@Jmv38 was right. Problems with self are almost always caused by using a full stop instead of a colon!

EDIT @Ingatz still nil value :frowning:

@Crazypykr1099, likely there is a similar problem in the Enemey code.

Enemy = class()
enemies = {}
bullets = {}

function Enemy:init(x,y)
    self.x = x
    self.y = y
    table.insert(enemies,vec2(self.x,self.y))
end

function Enemy:draw()
    for a,b in pairs(enemies) do
        b.x = b.x + 1 
        sprite("Documents:UFO",b.x,b.y,100,120)
        
        if b.x > WIDTH then
            table.remove(enemies,a)
            end
        if b.x > player.x and
            b.x < player.x+7 then
                if time <= 1 then
                    table.insert(bullets,vec2(b.x+3,b.y-45))
                end
            end
        end 
    Enemy:shoot()
end

function Enemy:shoot()
    for a,b in pairs(bullets) do
        sprite("Space Art:Red Bullet",b.x,b.y)
        b.y = b.y - 2 
        if b.y < 0 then
            table.remove(bullets,a)
        end
    end
end

I’m not getting an error but when I try and call the self.image in the draw program, it gives me a nil values:(

@Crazypkr1099 - you also had an error with Player.right() in the Button class, did you see that?

if that’s not it, you need to debug the problem

I usually put print statements into the code, for example, check that in the init function, the self.image gets set correctly by printing it, then print various things after that to check that everything is working. Try to figure out where it goes wrong, step by step.

Figured it out! I was calling a function without giving it a name. I ment to do player:right() not Player:right() thanks everything for helping me debug!

function Button:touched(touch)
    --print(CurrentTouch)
    if CurrentTouch.x > (self.x - self.width/2) and
        CurrentTouch.x < (self.x + self.width/2) and
        CurrentTouch.y > (self.y - self.height/2) and
        CurrentTouch.y < (self.y + self.height/2) and
        CurrentTouch.state < 2 then
            if self.image == "Cargo Bot:Command Left" then
                player.x = player.x -5
                playerface = 1
                Player.left()
            else
                player.x = player.x +5
                Player:right()
                playerface = -1
            end
        end
    end

@ignatz @Pops @JakAttak @Jmv38

1 more question… are they any way to find out if the button is touched and stoped (such as state == ENDED). When I try touch.state == ENDED it gives me an error… I understand why it does but I cant figure out another way. Thanks everyone in advance, learning how to do all this will benefit me with making games :slight_smile:

@Crazypkr1099 Why are you using CurrentTouch in the touched function. You should be using touch.x and touch.y . CurrentTouch is used when you don’t want to use the touched function.

@dave1707

Touch.x gives me an error…

Index local touch gives nil value… Stupid nils xD