Error Drawing Platforms

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
Tomatotumtum
Prole
Posts: 2
Joined: Thu Aug 13, 2020 4:35 pm

Error Drawing Platforms

Post by Tomatotumtum »

Hello,

New to Lua/Game dev in general here. I'm trying to write a code to draw the background of my game. I have four different spritesheets for things related to setting:
[*] Background - which contains the drawn "background image" of the game
[*] Platforms - which contain the platform sprites of the game
[*] objectsBig - which contain the relatively bigger drawn objects in the background (example rocks, seaweed, etc)
[*] objectsSmall - which contain the relatively smaller drawn objects (smaller rocks, plants, etc)

I made a function, called generateQuads which is in my Util.lua file, which, given a spritesheet, splices it up into the different sprites in the spritesheet and returns those sprites. It is as follows:

Code: Select all

-- Function to generate quads/cut the spritesheet
function generateQuads(atlas, tileWidth, tileHeight)
    local sheetWidth = atlas:getWidth() / tileWidth
    local sheetHeight = atlas:getHeight() / tileHeight

    local sheetCounter = 1
    local quads = {}

    -- for every line of the sprite sheet
    for y = 0, sheetHeight - 1 do
        -- for every piece in the width
        for x = 0, sheetWidth - 1 do
            -- quads generated will be the ones specified by tileWidth and tileHeight
            quads[sheetCounter] = love.graphics.newQuad(x * tileWidth, y * tileHeight, tileWidth, 
                tileHeight, atlas:getDimensions())
            sheetCounter = sheetCounter + 1
        end
    end

    return quads

end
I also have a class called Map, which is meant to contain information for the Map. The following are the functions in it:
FUNCTION TO SET UP THE CLASS

Code: Select all

function Map:init()
    -- Load the background sprite into variable
    -- Each is 500x500, total is 1500x500
    self.background = love.graphics.newImage('Graphics/platform/background/full.png')
    
    -- Load all the ground platforms into variable
    -- Each is 60x30, total is 240x30
    self.platforms = love.graphics.newImage('Graphics/platform/ground/all.png')

    -- Load all the bigger misc objects into variable
    -- Each is 15x20, total is 15x120
    self.objectsBig = love.graphics.newImage('Graphics/platform/objects/15x20/all.png')

    -- Load all the smaller misc objects into variable
    -- Each is 15x15, total is 60x15
    self.objectsSmall = love.graphics.newImage('Graphics/platform/objects/15x15/all.png')

    -- Setting the size for each of the variables IN PIXELS
    self.backgroundWidth = 500
    self.backgroundHeight = 1500

    self.platformWidth = 60
    self.platformHeight = 30

    self.objectsBigWidth = 15
    self.objectsBigHeight = 20

    self.objectsSmallWidth = 15
    self.objectsSmallHeight = 15

    -- Setting the map size IN TILES
    -- EXPERIMENTAL, CHECK AGAIN
    self.mapWidth = 432
    self.mapHeight = 243

    -- Setting the width of the map IN PIXELS (in relation to platforms)
    self.mapWidthPixels = self.backgroundWidth
    self.mapHeightPixels = self.backgroundHeight

    -- Storing our map features
    self.tiles = {}

    -- Storing the camera points, starting from the bottom
    -- The 243 is the VIRTUAL_HEIGHT, which we needed to subtract to account for the
    -- offset of the screen
    self.camX = 0
    self.camY = self.backgroundHeight - 243

    -- Cutting each of the spritesheets
    self.backgroundSprite = generateQuads(self.background, self.backgroundWidth, self.backgroundHeight)
    self.platformSprite = generateQuads(self.platforms, self.platformWidth, self.platformHeight)
    self.objectsBigSprite = generateQuads(self.objectsBig, self.objectsBigWidth, self.objectsBigHeight)
    self.objectsSmallSprite = generateQuads(self.objectsSmall, self.objectsSmallWidth, self.objectsSmallHeight)

    -- 'Setting' the tiles for the map to be background 
    for y = 1, self.mapHeight do
        for x = 1, self.mapWidth do
            self:setTile(x, y, BACKGROUND)
        end
    end

    -- 'Setting' the platform tiles for where we start
    for x = 1, self.mapWidth do
        self:setTile(x, self.mapHeight - 303, GROUND_MIDDLE)
    end
end
FUNCTION TO 'SET' WHERE IN THE X, Y COORDINATE THE TILES SHOULD BE

Code: Select all

function Map:setTile(x, y, tile)
    -- The table 'tiles' is going to store what tile should be in what x and y position
    -- subtracting y by 1 so that it's 0 indexed, not 1 indexed
    self.tiles[(y - 1) * self.mapWidth + x] = tile
end
FUNCTION TO RETURN WHAT TILE IS IN THE X, Y COORDINATE

Code: Select all

function Map:getTile(x, y, tile)
    -- This function is going to tell us what tile is set at this x and y position
    return self.tiles[(y - 1) * self.mapWidth + x]
end
FUNCTION TO UPDATE

Code: Select all

function Map:update(dt)
    -- Moving the camera depending on the key being pressed
    if love.keyboard.isDown('w') then
        -- up movement, clamped between 0 and the other
        self.camY = math.max(0, math.floor(self.camY - SCROLL_SPEED * dt))
    elseif love.keyboard.isDown('a') then
        -- left movement
        self.camX = math.max(0, math.floor(self.camX - SCROLL_SPEED * dt))
    elseif love.keyboard.isDown('s') then
        -- down movement, subtracting VIRTUAL_HEIGHT to account for the screen offset
        self.camY = math.min(self.backgroundHeight - VIRTUAL_HEIGHT, math.floor(self.camY + SCROLL_SPEED * dt))
    elseif love.keyboard.isDown('d') then
        -- right movement
        self.camX = math.min(self.backgroundWidth - VIRTUAL_WIDTH, math.floor(self.camX + SCROLL_SPEED * dt))
    end
end
FUNCTION TO RENDER

Code: Select all

function Map:render()
    for y = 1, self.mapHeight do
        for x = 1, self.mapWidth do
            -- Drawing the background first
            love.graphics.draw(self.background, self.backgroundSprite[self:getTile(x, y)],
                (x - 1) * self.backgroundWidth, (y - 1) * self.backgroundHeight)
            love.graphics.draw(self.platform, self.platformSprite[self:getTile(x, y)],
                (x - 1) * self.platformWidth, (y - 1) * self.platformHeight)
        end
    end
end
What I'm trying to do is splice up each spritesheet, and for set the background and bottom tiles so that I can see a bottom floor. I'm trying to do this through giving numbers to the components in my spritesheet, so that, for example, in a 1500x500 spritesheet for the background, the entire thing is considered 'one' sprite, and treated as such. Its number, 1, is given in a variable. Another example is a 240x30 platform spritesheet, where each 60x30 is considered 'one' sprite, and given a corresponding number, like so:

Code: Select all

-- Know where the platforms are in the spritesheet
GROUND_LEFT = 1
GROUND_RIGHT = 2
GROUND_SMALL = 3
GROUND_MIDDLE = 4

-- Know where the backgrounds are in the spritesheet
BACKGROUND = 1

[...]
I want to then store each in the self.tiles list, so that I can access them at any time from the table (Do note that most of this is taken from the CS50 implementation of mario, and so I understand if I've gotten any concepts wrong). When I run this code, though, I get the following error:

Code: Select all

Error

Error

Map.lua:135: bad argument #1 to 'draw' (Texture expected, got nil)


Traceback

[C]: in function 'draw'
Map.lua:135: in function 'render'
main.lua:48: in function 'draw'
[C]: in function 'xpcall'
Essentially, I just want to know a way in which I can set the bottom platform tiles, and then be able to iterate over the map and 'set' where the other object sprites should be. The background alone works fine, but once I added the:

Code: Select all

  -- 'Setting' the platform tiles for where we start
    for x = 1, self.mapWidth do
        self:setTile(x, self.mapHeight - 303, GROUND_MIDDLE)
    end
and

Code: Select all

            love.graphics.draw(self.platform, self.platformSprite[self:getTile(x, y)],
                (x - 1) * self.platformWidth, (y - 1) * self.platformHeight)
lines, the program wouldn't run.

Any help is appreciated!
User avatar
CogentInvalid
Prole
Posts: 27
Joined: Sat Dec 14, 2013 12:15 am

Re: Error Drawing Platforms

Post by CogentInvalid »

I think in your draw call, self.platform should be self.platforms.
Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot], Google [Bot] and 234 guests