Love2d / LUA grid locked movement NO DIAGONAL - lua

I thought this would be a common problem but after days of research I can't find a solution. Very new to programming in general and LUA specifically. I'm building a SUPAPLEX clone as a CS50 personal project: the character moves along the grid based map and there's a code that everyone seems to suggest (attached). On release of arrow buttons the movement is continued until the end of a tile, smoothly. But if 2 movement buttons are pushed, it causes brief diagonal movement and that's the problem I'm unsuccessfully trying to solve.
Basically I'm trying to either ignore any input until the movement of the sprite is finished at the end of the grid tile or prevent updating until movement in one direction is complete. Seems like a simple thing but I'm about to give up this whole thing. Frustrating. Any input is hiiiighly appreciated and I'm sure this would be a lot of help for very many people...
function love.load()
love.keyboard.setKeyRepeat(true)
player = {
grid_x = 256,
grid_y = 256,
act_x = 256,
act_y = 256,
speed = 5,
}
map = {
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 },
{ 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1 },
{ 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1 },
{ 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1 },
{ 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 },
{ 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
{ 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
{ 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
{ 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1 },
{ 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 },
{ 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }
}
function testMap(x, y)
if map[(player.grid_y / 32) + y][(player.grid_x / 32) + x] == 1 then
return false
end
return true
end
function love.keypressed(key)
if key == "up" then
player.grid_y = player.grid_y - 32
elseif key == "down" then
player.grid_y = player.grid_y + 32
elseif key == "left" then
player.grid_x = player.grid_x - 32
elseif key == "right" then
player.grid_x = player.grid_x + 32
end
end
end
function love.update(dt)
player.act_y = player.act_y - ((player.act_y - player.grid_y) * player.speed * dt)
player.act_x = player.act_x - ((player.act_x - player.grid_x) * player.speed * dt)
end
function love.draw()
love.graphics.rectangle("fill", player.act_x, player.act_y, 32, 32)
for y=1, #map do
for x=1, #map[y] do
if map[y][x] == 1 then
love.graphics.rectangle("line", x * 32, y * 32, 32, 32)
end
end
end
end

you're trying to get it to only walk along grid-lines?
take out love.keyboard.setKeyRepeat(true)
and don't use love.keypressed(key)
that's for one-at-a-time keypresses, and it would be hard to use that
with love.keyreleased() to see if all the other keys are released.
use isDown instead, and if one of them isDown, then none of the other dir keys allow input. (along with the couple player.act lines you already have in your update)
player = {
grid_x = 256,
grid_y = 256,
act_x = 256,
act_y = 256,
speed = 5,
dir = ''
}
function love.update(dt)
if love.keyboard.isDown("up", "down", "left", "right") then
if love.keyboard.isDown("up") and ( player.dir == 'up' or player.dir == '' ) then
player.dir = 'up' -- only go up if currently held, or no other dir key being pressed
player.grid_y = player.grid_y - 32
elseif love.keyboard.isDown("down") and ( player.dir == 'down' or player.dir == '' ) then
player.dir = 'down' -- only go down if currently held...
player.grid_y = player.grid_y + 32
elseif key == "left" and ( player.dir == 'left' or player.dir == '' ) then
player.dir = 'left'
player.grid_x = player.grid_x - 32
elseif key == "right" and ( player.dir == 'right' or player.dir == '' ) then
player.dir = 'right'
player.grid_x = player.grid_x + 32
end
else -- none of those keys are being pressed, so player is idle
player.dir = ''
end -- isDown()
player.act_y = player.act_y - ((player.act_y - player.grid_y) * player.speed * dt)
player.act_x = player.act_x - ((player.act_x - player.grid_x) * player.speed * dt)
end -- update()

Related

how to parse strings from a file?

I have a text file.
each block parameter is separated by a colon
WoodBlock : 0.886275, 0.607843, 0.25098 : 2, 2, 2 : true : -75.5656891, -11.899992, -416.506866, 1, 0, 0, 0, 1, 0, 0, 0, 1 : 0, 0, 0 : 0, 0, 0
RustedBlock : 0.639216, 0.635294, 0.647059 : 2, 2, 2 : true : -35.5656891, -11.899992, -424.506866, 1, 0, 0, 0, 1, 0, 0, 0, 1 : 0, 0, 0 : 0, 0, 0
StoneBlock : 0.639216, 0.635294, 0.647059 : 2, 2, 2 : true : -50.5656891, -11.899992, -425.506866, 1, 0, 0, 0, 1, 0, 0, 0, 1 : 0, 0, 0 : 0, 0, 0
MetalRod : 0.388235, 0.372549, 0.384314 : 1, 3, 1 : true : -51.5656891, -11.399992, -412.506866, 1, 0, 0, 0, 1, 0, 0, 0, 1 : 0, 0, 0 : 0, 0, 0
Each line contains information about a block. I want to make an algorithm that will work like this:
the first line is selected
the second parameter of the line is selected - the script does something with this parameter
the third parameter of the line is selected - the script does something with this parameter
the fourth parameter of the line is selected - the script does something with this parameter
select the fifth parameter of the line - the script does something with this parameter
etc.
I tried using gsub but I don't know how I can select a certain line or parameter in it
You can use string.gmatch to match all parameters in the colon-delimited string. The pattern used to indicate the separator is [^:]+, which translates to "match everything but : (a colon)".
Here's an example script that loops over each line, then prints each parameter.
for line in io.lines("blocks.txt") do
for param in string.gmatch(line, "[^:]+") do
print(param)
end
end

(gLua) Derma not working. attempt to call method 'Close' (a nil value)

Error at function ContextClose()
And all derma menu not working
attempt to call method 'Close' (a nil value)
I've create derma menu and it worked in garrysmod\lua folder,
then I moved flies to addon floder and it stopped working.
cl_init.lua
AddCSLuaFile("pbfhud.lua")
include("pbfhud.lua")
pbfhud.lua
AddCSLuaFile()
local statBarW, statBarH = ScrW() / 400, ScrH() / 10
local barW, barH = ScrW() / 4, ScrH() / 10
local btnW, btnH = ScrW() / 4, ScrH() / 20
surface.CreateFont( "NotDermaDefault", {
font = "Arial",
extended = false,
size = 25,
weight = 500,
blursize = 0,
scanlines = 0,
antialias = true,
underline = false,
italic = false,
strikeout = false,
symbol = false,
rotary = false,
shadow = false,
additive = false,
outline = false,
} )
local function DrawInventorySlot( )
end
local function DrawBar(x, y, w, h, color, text, val, name)
local rtext = text .. ": " .. val
local tW, tH = surface.GetTextSize(rtext)
tH = tH / 2
if (name == true) then
tW = tW / 7
end
draw.RoundedBox(0, x, y, w, h, color)
draw.SimpleText(rtext, "NotDermaDefault", barW / 2 - tW / 7, barH / 2 - tH + y, Color( 255, 255, 255, 255 ), TEXT_ALIGN_CENTER, TEXT_ALIGN_TOP)
end
function ContextOpen()
gui.EnableScreenClicker( true )
menu = vgui.Create("DFrame")
menu:SetSize(ScrW(), ScrH() + 100)
menu:ShowCloseButton(false)
menu:SetTitle("")
menu:Center()
menu:SetDraggable(false)
menu:SetBackgroundBlur(true)
menu:SetMouseInputEnabled(true)
menu.Paint = function()
draw.RoundedBox(0, 0, 0, ScrW(), ScrH(), Color(0,0,0,100))
local blur = Material("pp/blurscreen")
local function blurPanel(panel, amount)
local x, y = panel:LocalToScreen(0, 0)
local scrW, scrH = ScrW(), ScrH()
surface.SetDrawColor(255, 255, 255)
surface.SetMaterial(blur)
for i = 1, 6 do
blur:SetFloat("$blur", (i / 3) * (amount or 6))
blur:Recompute()
render.UpdateScreenEffectTexture()
surface.DrawTexturedRect(x * -1, y * -1, scrW, scrH)
end
end
blurPanel(menu, 5)
draw.RoundedBox(0, 0, 0, ScrW() / 4, ScrH(), Color(0,0,0,50))
-- Stats
DrawBar(0, 0, barW, barH, Color(235, 235, 235, 140), "Имя", LocalPlayer():getDarkRPVar("rpname"), true )
DrawBar(0, statBarH, LocalPlayer():Health() * statBarW, barH, Color(255, 50, 43, 140), "Здоровье", LocalPlayer():Health(), false )
DrawBar(0, statBarH * 2, LocalPlayer():Armor() * statBarW, barH, Color(43, 128, 255, 140), "Броня", LocalPlayer():Armor(), false )
DrawBar(0, statBarH * 3, barW, barH, Color(255, 149, 43, 140), "Работа", LocalPlayer():getDarkRPVar("job"), false )
DrawBar(0, statBarH * 4, barW, barH, Color(0, 138, 11, 140), "Зарплата", LocalPlayer():getDarkRPVar("salary"), false )
-- Inventory
draw.RoundedBox(0, barW, 0, ScrW() / 1.7, ScrH(), Color(0,0,0,50))
end
-- Buttons
--fb = vgui.Create("DButton", menu)
--fb:SetSize(btnW, btnH)
--fb:SetPos(0, btnH * 12)
--fb:SetText("")
end
function ContextClose()
menu:Close()
gui.EnableScreenClicker( false )
end
hook.Add ("OnContextMenuOpen", "Context", ContextOpen)
hook.Add ("OnContextMenuClose", "Context", ContextClose)
Files location
..addons\pbf_hud\lua\autorun\client\cl_init.lua
..addons\pbf_hud\lua\autorun\client\pbfhud.lua
SOLVED
I used same identifiers for hooks. If you have same problem just change hook indentifier:
From:
hook.Add ("OnContextMenuOpen", "Context", ContextOpen)
hook.Add ("OnContextMenuClose", "Context", ContextClose)
To:
hook.Add ("OnContextMenuOpen", "Context_open", ContextOpen)
hook.Add ("OnContextMenuClose", "Context_close", ContextClose)

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

I've a game project due in the next month(simple maze game) but I keep running into this error. I'd really appreciate it if someone took a look at it. I'm new to Lua so it's probably very simple. The error seems to be originating around line 131. I've put line 131 between a load of stars (*****...). You'd make my day if you took a few minutes to look at it. :) The error is : Main.lua:131: attempt to index local ‘up’ (a nil value) stack traceback:
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()

Attempt to index local ‘up’ (a nil value) (LUA)

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()
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!

How to repeat an image like css in lua?

https://gyazo.com/d0d0bab65c0a7060972988a5e73c7959
That was achieved by the this:
local x = script.Parent.Smile
local y = script.Parent.Smile2
while true do
x:TweenPosition(UDim2.new(0, 0, 1, 0))
y:TweenPosition(UDim2.new(0, 0, 1, 0))
wait(.1)
x.Position = y.Position + UDim2.new(0, 0, -1, 0)
y.Position = UDim2.new(0, 0, 0, 0)
end
I was wondering if there was a better way to do it and make it smoother(slower)?
If you want it to look as if it endlessly descends, try adding a "Linear" parameter to your tweens. It will keep the tween constant in speed. For example:
local x = script.Parent.Smile
local y = script.Parent.Smile2
while true do
x:TweenPosition(UDim2.new(0, 0, 1, 0),"Out","Linear",0.1)
y:TweenPosition(UDim2.new(0, 0, 1, 0),"Out","Linear",0.1)
wait(.105) -- making sure to tween again after 0.1 seconds, the 0.105 safely accounts for any latency in the game
x.Position = y.Position + UDim2.new(0, 0, -1, 0)
y.Position = UDim2.new(0, 0, 0, 0)
end
Try that script above, if it doesn't work you can blame me for it

Resources