0
votes

Main.lua:131 attempt to index local ‘up’ (a nil value)

Hi Guys, Hope you’re having a good day. I appologise if the error I’ve made is really simple. I’m new to lua and am still figuring it out. If you have a few minutes to spare I’d really appreciate if you took a look at the code. The error I’m getting is: Main.lua:131 attempt to index local ‘up’ (a nil value) I’ve put line 131 and the line I believe to be causing the error in stars so you don’t have to count every line. I don’t think controls.displayGroup has been initialized correctly but I’m not sure how to fix it.

local screenWidth = display.contentWidth
local screenHeight = display.contentHeight
local controllerWidth = screenWidth / 6
local rightMargin = 30
local maze = {
    { 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
    { 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
    { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1 },
    { 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1 },
    { 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1 },
    { 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1 },
    { 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0 },
    { 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1 },
    { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1 },
    { 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1 },
    { 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1 },
    { 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1 },
}
maze.rows = table.getn(maze)
maze.columns = table.getn(maze[1])
maze.xStart, maze.yStart = 1, 1
maze.xFinish, maze.yFinish = 24, 7

local grid = {}
grid.xSquares = maze.columns
grid.ySquares = maze.rows
grid.totalWidth = screenWidth - controllerWidth - rightMargin
grid.squareSize = grid.totalWidth / grid.xSquares
grid.xStart = controllerWidth
grid.yStart = 60
grid.displayGroup = display.newGroup()
grid.displayGroup.x = grid.xStart
grid.displayGroup.y = grid.yStart

grid.functions = {
  left = function(gridSquare)
        if gridSquare.x == 0 then
            return gridSquare
        else
            return grid[gridSquare.y][gridSquare.x - 1]
        end
    end,
  right = function(gridSquare)
        if gridSquare.x + 1 == grid.xSquares then
            return gridSquare
        else
            return grid[gridSquare.y][gridSquare.x + 1]
        end
    end,
  above = function(gridSquare)
        if gridSquare.y == 0 then
            return gridSquare
        else
            return grid[gridSquare.y - 1][gridSquare.x]
        end
    end,
  below = function(gridSquare)
        if gridSquare.y + 1 == grid.ySquares then
            return gridSquare
        else
            return grid[gridSquare.y + 1][gridSquare.x]
        end
    end,
}

for y = 0, grid.ySquares - 1 do
  grid[y] = {y = y}
  for x = 0, grid.xSquares - 1 do
    grid[y][x] = {x = x, y = y}
    local rect = display.newRect(grid.displayGroup,
        grid.squareSize * x, grid.squareSize * y,
        grid.squareSize, grid.squareSize)
    if maze[y + 1][x + 1] == 0 then
            rect:setFillColor(245, 215, 98)
        else
            grid[y][x].wall = true
            rect:setFillColor(32, 96, 32, 255)
        end
    grid[y][x].displayObject = rect
    grid[y][x].left = grid.functions.left
        grid[y][x].right = grid.functions.right
        grid[y][x].above = grid.functions.above
        grid[y][x].below = grid.functions.below
  end
end
grid[maze.yStart - 1][maze.xStart - 1].start = true
grid[maze.yStart - 1][maze.xStart - 1].displayObject:setFillColor(192, 192, 255)
grid[maze.yFinish - 1][maze.xFinish - 1].displayObject:setFillColor(192, 128, 128)
grid[maze.yStart - 1][maze.xStart - 1].start = true
grid[maze.yFinish - 1][maze.xFinish - 1].finish = true

local runner = { image = "runner.png" }
function runner:enter(gridSquare)
  if self.displayObject == nil then
        self.displayObject = display.newImageRect(grid.displayGroup,
        self.image, grid.squareSize, grid.squareSize)
        self.displayObject:setFillColor(92, 92, 92)
    end
  self.displayObject.x = gridSquare.displayObject.x
    self.displayObject.y = gridSquare.displayObject.y
  self.gridSquare = gridSquare
  self.x = gridSquare.x
    self.y = gridSquare.y
  if self.gridSquare.finish then
        finish()
    end
end
function runner:canEnter(gridSquare)
    return gridSquare.wall == nil
end

local controlCenterX = controllerWidth / 2
local controlCenterY = screenHeight - screenHeight / 5
local controlCenterRadius = controllerWidth / 2 - rightMargin
local upDownWidth = 27
local upDownHeight = 60
local leftRightWidth = 60
local leftRightHeight = 27
local controls = {
    up    = {},
    down  = {},
    right = {},
    left  = {},
}

****
controls.displayGroup = display.newGroup()
****

local circlePad = display.newCircle(controls.displayGroup,
    controlCenterX, controlCenterY, controlCenterRadius)
  circlePad:setFillColor(128, 128, 128)

*****
local up = display.newImageRect(controls.displayGroup, "arrow_up.png",
    upDownWidth, upDownHeight)
up.x = controlCenterX
up.y = controlCenterY - upDownHeight / 2
controls.up.displayObject = up
*****

local down = display.newImageRect(controls.displayGroup, "arrow_down.png",
  upDownWidth, upDownHeight)
down.x = controlCenterX
down.y = controlCenterY + upDownHeight / 2
controls.down.displayObject = down
local right = display.newImageRect(controls.displayGroup, "arrow_right.png",
    leftRightWidth, leftRightHeight)
right.x = controlCenterX + leftRightWidth / 2
right.y = controlCenterY
controls.right.displayObject = right
local left = display.newImageRect(controls.displayGroup, "arrow_left.png",
    leftRightWidth, leftRightHeight)
left.x = controlCenterX - leftRightWidth / 2
left.y = controlCenterY
controls.left.displayObject = left
controls.hide = function(controls)
    controls.displayGroup.isVisible = false
end
controls.show = function(controls)
    controls.displayGroup.isVisible = true
end

local function pressLeft(event)
    if event.phase == "began" then
        local nextSquare = runner.gridSquare:left()
        if runner:canEnter(nextSquare) then
            runner:enter(nextSquare)
        end
    end
end
local function pressRight(event)
    if event.phase == "began" then
        local nextSquare  = runner.gridSquare:right()
        if runner:canEnter(nextSquare) then
            runner:enter(nextSquare)
        end
    end
end
local function pressUp(event)
    if event.phase == "began" then
        local nextSquare  = runner.gridSquare:above()
        if runner:canEnter(nextSquare) then
            runner:enter(nextSquare)
        end
    end
end
local function pressDown(event)
    if event.phase == "began" then
        local nextSquare  = runner.gridSquare:below()
        if runner:canEnter(nextSquare) then
            runner:enter(nextSquare)
        end
    end
end
controls.left.displayObject:addEventListener("touch", pressLeft)
controls.right.displayObject:addEventListener("touch", pressRight)
controls.up.displayObject:addEventListener("touch", pressUp)
controls.down.displayObject:addEventListener("touch", pressDown)
local startButton = {}
startButton.displayGroup = display.newGroup()
startButton.displayObject = display.newCircle(startButton.displayGroup,
    controlCenterX, controlCenterY, controlCenterRadius)
  startButton.displayObject.strokeWidth = 6
startButton.displayObject:setStrokeColor(244, 244, 64)
startButton.text = display.newText(startButton.displayGroup,
    "Start", controlCenterX - controlCenterRadius + 20, controlCenterY - 18,
    native.systemFont, 24)
  startButton.text:setTextColor(0, 0, 0)
  startButton.touch = function(event)
    if event.phase == "began" then
        startButton:hide()
        start()
    end
end
startButton.displayGroup:addEventListener("touch", startButton.touch)
startButton.show = function(button)
    button.displayGroup.isVisible = true
end
startButton.hide = function(button)
    button.displayGroup.isVisible = false
end
local playAgainButton = {}
playAgainButton.displayGroup = display.newGroup()

playAgainButton.displayObject = display.newCircle(playAgainButton.displayGroup,
    controlCenterX, controlCenterY, controlCenterRadius)
  playAgainButton.displayObject.strokeWidth = 6
playAgainButton.displayObject:setStrokeColor(244, 244, 64)
playAgainButton.text = display.newText(playAgainButton.displayGroup,
    "Again", controlCenterX - controlCenterRadius + 20, controlCenterY - 18,
    native.systemFont, 24)
  playAgainButton.text:setTextColor(0, 0, 0)
  playAgainButton.touch = function(event)
    if event.phase == "began" then
        playAgainButton:hide()
        play()
    end
end
playAgainButton.displayGroup:addEventListener("touch", playAgainButton.touch)
playAgainButton.show = startButton.show
playAgainButton.hide = startButton.hide

function play()
  runner:enter(grid[maze.yStart - 1][maze.xStart - 1])
  playAgainButton:hide()
  controls:hide()
  startButton:show()
end

function start()
    controls:show()
end

function finish()
    controls:hide()
    playAgainButton:show()
end
play()
1

1 Answers

0
votes

display.newImageRect will return nothing, being the variable nil, if the image file doesn't exist, you might have noticed this already by checking the console, to fix this issue it's as easy as adding the missing assets to the project folder!