#lua #game-development #love2d
#lua #разработка игры #love2d
Вопрос:
Новичок в Lua / Game dev в целом. Я пытаюсь написать код для рисования фона моей игры. У меня есть четыре разных таблицы спрайтов для вещей, связанных с настройками:
- Background — который содержит нарисованное «фоновое изображение» игры
- Платформы — которые содержат платформенные спрайты игры
- objectsBig — которые содержат относительно большие нарисованные объекты на заднем плане (например, камни, морские водоросли и т.д.)
- Объекты Small — которые содержат нарисованные объекты относительно меньшего размера (камни меньшего размера, растения и т.д.)
Я создал функцию, вызываемую generateQuads()
из моего Util.lua
файла, которая, получив таблицу спрайтов, разбивает ее на разные спрайты в таблице спрайтов и возвращает эти спрайты. Это выглядит следующим образом:
-- 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
У меня также есть класс с именем Map
, который предназначен для хранения информации для карты. Ниже приведены функции в нем:
ФУНКЦИЯ ДЛЯ НАСТРОЙКИ КЛАССА
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
ФУНКЦИЯ ДЛЯ «УСТАНОВКИ», ГДЕ В КООРДИНАТАХ X, Y ДОЛЖНЫ НАХОДИТЬСЯ ПЛИТКИ
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
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
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
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
Что я пытаюсь сделать, так это объединить каждую таблицу спрайтов и установить фоновые и нижние плитки, чтобы я мог видеть нижний этаж. Я пытаюсь сделать это, присваивая номера компонентам в моей таблице спрайтов, чтобы, например, в таблице спрайтов размером 1500×500 для фона все это считалось «одним» спрайтом и обрабатывалось как таковое. Ее номер, 1, указан в переменной. Другим примером является таблица спрайтов платформы 240×30, где каждый спрайт размером 60×30 считается «одним» и ему присваивается соответствующий номер, вот так:
-- 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
[...]
Затем я хочу сохранить каждую из них в списке self.tiles, чтобы я мог получить к ним доступ в любое время из таблицы (обратите внимание, что большая часть этого взята из реализации mario CS50, и поэтому я понимаю, если я неправильно понял какие-либо концепции). Однако, когда я запускаю этот код, я получаю следующую ошибку:
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'
По сути, я просто хочу знать способ, которым я могу установить нижние плитки платформы, а затем иметь возможность выполнять итерации по карте и «устанавливать», где должны быть другие объектные спрайты. Фон сам по себе работает нормально, но как только я добавил:
-- 'Setting' the platform tiles for where we start
for x = 1, self.mapWidth do
self:setTile(x, self.mapHeight - 303, GROUND_MIDDLE)
end
и
love.graphics.draw(self.platform, self.platformSprite[self:getTile(x, y)],
(x - 1) * self.platformWidth, (y - 1) * self.platformHeight)
строки, программа не запускалась.
Любая помощь приветствуется!
РЕДАКТИРОВАТЬ: строка, в которой я получаю ошибку, является self.platform
единственной.
Комментарии:
1. Какая строка Map.lua:135? Это о
self.background
илиself.platform
?2. Это self.platform one! С этим у меня проблемы.
3. Ок,
self.platform
естьnil
, поэтому вы не можете ее нарисовать. Где вы инициализировали полеplatform
? Я не вижу этого в вашем коде.4.
-- 'Setting' the platform tiles for where we start for x = 1, self.mapWidth do self:setTile(x, self.mapHeight - 303, GROUND_MIDDLE) end
Не будет ли инициализироваться нужные мне части карты?5.
setTile
инициализируетtiles
, неplatform
Ответ №1:
у меня была такая же проблема раньше, и это оказалось опечаткой при вводе переменной. посмотрев на ваш код, я увидел, что его не было self.platform
, вместо этого там было self.platforms
.
попробуйте:
love.graphics.draw(self.platforms, self.platformSprite[self:getTile(x, y)],
(x - 1) * self.platformWidth, (y - 1) * self.platformHeight)