I want to know how to edit my script below to make the color lower or higher depending on the health amount instead of a set amount in the script. Everything works currently, i'm just trying to edit the script to do what I said above.
local parts = script.Parent.Parent:WaitForChild("Collectables"):GetChildren()
for i, v in pairs(parts) do
if v:IsA("Part") then
if v:WaitForChild("ClickDetector") then
if v:FindFirstChild("Values") then
local Values = v:FindFirstChild("Values")
Values.Red.Value = 0
Values.Green.Value = 255
Values.Blue.Value = 0
Values.Health.Value = 100
Values.Change.Value = true
v.SurfaceGui.TextLabel.Text = 100
Values.Color.Value = Color3.fromRGB(Values.Red.Value,Values.Green.Value,Values.Blue.Value)
v.SurfaceGui.TextLabel.TextColor3 = Values.Color.Value
v.ClickDetector.MouseClick:Connect(function()
if Values.Health.Value > 5 then
Values.Health.Value -= 5
else
v:Destroy()
end
if v:FindFirstChild("SurfaceGui") then
v.SurfaceGui.TextLabel.Text = v.SurfaceGui.TextLabel.Text - 5
if Values.Change.Value == true then
if Values.Red.Value < 250 then
Values.Red.Value += 50
elseif Values.Red.Value == 250 then
Values.Red.Value += 5
elseif Values.Red.Value == 255 and Values.Green.Value > 5 then
Values.Green.Value -= 50
elseif Values.Green.Value == 5 then
Values.Green.Value -= 5
Values.Change.Value = false
end
Values.Color.Value = Color3.fromRGB(Values.Red.Value,Values.Green.Value,Values.Blue.Value)
v.SurfaceGui.TextLabel.TextColor3 = Values.Color.Value
end
end
end)
end
end
end
end
Rather than use your stepwise function for calculating the color, a more simple way to handle this might be to define the colors you want ahead of time or simplify it down to ranges of colors based on health. Like,
if it's between 100 - 60, the color is green.
if it's between 60 - 30, it's yellow.
if it's less than 30, it is red.
And to make the color react to the health, I would set up a series of dependencies using the Changed signal on your NumberValue objects.
The ClickDetector's only job is to modify the health of the block. But when the health changes, the color values change. And when the color values change, the text color changes too.
First off, delete the R, G, and B NumberValues, you can set the text color without them.
local DEFAULT_HEALTH = 100
local HEALTH_PER_CLICK = 5
-- colors are sorted by health in descending order, add more as desired
local COLORS = {
{ health = 60, color = Color3.fromRGB( 0, 255, 0)}, -- green
{ health = 30, color = Color3.fromRGB(255, 255, 0)}, -- yellow
{ health = 0, color = Color3.fromRGB(255, 0, 0)}, -- red
}
local function observeHealthChanges(values, textLabel)
-- whenever the health changes, update the text and the text color
local health = values.Health
health.Changed:Connect(function(newValue)
textLabel.Text = tostring(newValue)
-- set the color based on the health by looping through the colors to find the right ones
for i, colorData in ipairs(COLORS) do
local colorRange = colorData.health
local healthColor = colorData.color
if newValue > colorRange then
textLabel.TextColor3 = healthColor
break
end
end
end)
end
local function observeClicks(part, values, detector)
local health = values.Health
-- listen for clicks to reduce the health
detector.MouseClick:Connect(function()
if health.Value > HEALTH_PER_CLICK then
health.Value -= HEALTH_PER_CLICK
else
part:Destroy()
end
end)
end
local parts = script.Parent.Parent:WaitForChild("Collectables"):GetChildren()
for _, v in ipairs(parts) do
-- escape if the object isn't a part
if v:IsA("Part") then
-- escape if the part doesn't have Values, a ClickDetector, and a SurfaceGui
local Values = v.Values
local Detector = v.ClickDetector
local Gui = v.SurfaceGui
if Values and Detector and Gui then
-- register the change listeners
local textLabel = v.SurfaceGui.TextLabel
observeHealthChanges(Values, textLabel)
observeClicks(v, Values, Detector)
-- set the health and all the rest will follow
Values.Health.Value = DEFAULT_HEALTH
end
end
end
I've been trying to understand how bmp files work so I can render some Mandelbrot set pictures and output them as bmp files since that seems to be one of the easiest methods but for some reason when I use an aspect ratio that isn't 1:1 even though its something to the power of 4 (so no padding is needed) I get weird artifacts like these 200:100 48:100 what I'm trying to do is turning an array of pixels that has white for even numbers and black for odd numbers into a bmp, this (100:100) is what it looks like with 1:1 aspect ratio.
I've tried reading through the wikipedia article to see if I can figure out what I'm doing wrong but I still don't get what I'm missing.
This is the script I've written in Lua so far:
ResolutionX = 100
ResolutionY = 100
local cos, atan, sin, atan2, sqrt, floor = math.cos, math.atan, math.sin, math.atan2, math.sqrt, math.floor
local insert, concat = table.insert, table.concat
local sub, char, rep = string.sub, string.char, string.rep
io.output("Test.bmp")
function Basen(n,b)
n = floor(n)
if not b or b == 10 then return tostring(n) end
local digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
local t = {}
repeat
local d = (n % b) + 1
n = floor(n / b)
insert(t, 1, digits:sub(d,d))
until n == 0
return rep("0",32-#t)..concat(t,"")
end
FileSize = Basen(ResolutionY*ResolutionX*3 + 54,2)
FileSize4 = tonumber(sub(FileSize,1,8),2) or 0
FileSize3 = tonumber(sub(FileSize,9,16),2) or 0
FileSize2 = tonumber(sub(FileSize,17,24),2) or 0
FileSize1 = tonumber(sub(FileSize,25,32),2) or 0
Width = Basen(ResolutionX,2)
print("Width: ",Width)
Width4 = tonumber(sub(Width,1,8),2) or 0
Width3 = tonumber(sub(Width,9,16),2) or 0
Width2 = tonumber(sub(Width,17,24),2) or 0
Width1 = tonumber(sub(Width,25,32),2) or 0
Height = Basen(ResolutionY,2)
print("Height: ",Height)
Height4 = tonumber(sub(Height,1,8),2) or 0
Height3 = tonumber(sub(Height,9,16),2) or 0
Height2 = tonumber(sub(Height,17,24),2) or 0
Height1 = tonumber(sub(Height,25,32),2) or 0
BMPSize = Basen(ResolutionY*ResolutionX*3,2)
BMPSize4 = tonumber(sub(BMPSize,1,8),2) or 0
BMPSize3 = tonumber(sub(BMPSize,9,16),2) or 0
BMPSize2 = tonumber(sub(BMPSize,17,24),2) or 0
BMPSize1 = tonumber(sub(BMPSize,25,32),2) or 0
print("TotalSize: ",FileSize1,FileSize2,FileSize3,FileSize4,"\nWidth: ",Width1,Width2,Width3,Width4,"\nHeight: ",Height1,Height2,Height3,Height4,"\nImage data: ",BMPSize1,BMPSize2,BMPSize3,BMPSize4)
Result = {"BM"..char( --File type
FileSize1,FileSize2,FileSize3,FileSize4,--File size
0,0,0,0, --Reserved
54,0,0,0, --Where the pixel data starts
40,0,0,0, --DIB header
Width1,Width2,Width3,Width4, --Width
Height1,Height2,Height3,Height4, --Height
1,0, --Color planes
24,00, --Bit depth
0,0,0,0, --Compression
BMPSize1,BMPSize2,BMPSize3,BMPSize4, --The amount of bytes pixel data will consume
Width1,Width2,Width3,Width4,
Height1,Height2,Height3,Height4,
0,0,0,0, --Number of colors in palatte
0,0,0,0
)}
for X = 0, ResolutionX - 1 do
for Y = 0, ResolutionY - 1 do
insert(Result,rep(char(255 * ((X + 1) % 2) * ((Y + 1) % 2)),3))
end
end
io.write(table.concat(Result))
Ok, here's a BMP version. I've put things in a module so it might be easier to use.
local writeBMP = {}
local floor = math.floor
local insert, concat = table.insert, table.concat
local sub, char, rep = string.sub, string.char, string.rep
local function Basen(n,b)
n = floor(n)
if not b or b == 10 then return tostring(n) end
local digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
local t = {}
repeat
local d = (n % b) + 1
n = floor(n / b)
insert(t, 1, digits:sub(d,d))
until n == 0
return rep("0",32-#t)..concat(t,"")
end
local function nextMul4(x)
if ( x % 4 == 0 ) then
return x
else
return x+4-(x%4)
end
end
local function clamp(x)
local y = x
if ( x > 255 ) then
y = 255
elseif ( x < 0 ) then
y = 0
end
return floor(y)
end
-- Accepts array of type pixelsXYC[X][Y][C] of numbers 0-255
-- C=1,2,3 are the red, green and blue channels respectively
-- X increases left to right, and Y increases top to bottom
function writeBMP.data(pixelsXYC, resolutionX, resolutionY)
local Pixels = pixelsXYC
local ResolutionX = resolutionX
local ResolutionY = resolutionY
assert(#Pixels == ResolutionX, "Table size and X resolution mismatch")
assert(#Pixels[1] == ResolutionY, "Table size and Y resolution mismatch")
local FileSize = Basen(ResolutionY*nextMul4(3*ResolutionX) + 54,2)
local FileSize4 = tonumber(sub(FileSize,1,8),2) or 0
local FileSize3 = tonumber(sub(FileSize,9,16),2) or 0
local FileSize2 = tonumber(sub(FileSize,17,24),2) or 0
local FileSize1 = tonumber(sub(FileSize,25,32),2) or 0
local Width = Basen(ResolutionX,2)
local Width4 = tonumber(sub(Width,1,8),2) or 0
local Width3 = tonumber(sub(Width,9,16),2) or 0
local Width2 = tonumber(sub(Width,17,24),2) or 0
local Width1 = tonumber(sub(Width,25,32),2) or 0
local Height = Basen(ResolutionY,2)
local Height4 = tonumber(sub(Height,1,8),2) or 0
local Height3 = tonumber(sub(Height,9,16),2) or 0
local Height2 = tonumber(sub(Height,17,24),2) or 0
local Height1 = tonumber(sub(Height,25,32),2) or 0
local BMPSize = Basen(ResolutionY*nextMul4(3*ResolutionX),2)
local BMPSize4 = tonumber(sub(BMPSize,1,8),2) or 0
local BMPSize3 = tonumber(sub(BMPSize,9,16),2) or 0
local BMPSize2 = tonumber(sub(BMPSize,17,24),2) or 0
local BMPSize1 = tonumber(sub(BMPSize,25,32),2) or 0
local Result = {}
Result[1] = "BM" .. char( --File type
FileSize1,FileSize2,FileSize3,FileSize4,--File size
0,0, --Reserved
0,0, --Reserved
54,0,0,0, --Where the pixel data starts
40,0,0,0, --DIB header
Width1,Width2,Width3,Width4, --Width
Height1,Height2,Height3,Height4, --Height
1,0, --Color planes
24,0, --Bit depth
0,0,0,0, --Compression
BMPSize1,BMPSize2,BMPSize3,BMPSize4, --The amount of bytes pixel data will consume
37,22,0,0, --Pixels per meter horizontal
37,22,0,0, --Pixels per meter vertical
0,0,0,0, --Number of colors in palatte
0,0,0,0
)
local Y = ResolutionY
while( Y >= 1 ) do
for X = 1, ResolutionX do
local r = clamp( Pixels[X][Y][1] )
local g = clamp( Pixels[X][Y][2] )
local b = clamp( Pixels[X][Y][3] )
Result[#Result+1] = char(b)
Result[#Result+1] = char(g)
Result[#Result+1] = char(r)
end
-- byte alignment
if ( ( (3*ResolutionX) % 4 ) ~= 0 ) then
local Padding = 4 - ((3*ResolutionX) % 4)
Result[#Result+1] = rep(char(0),Padding)
end
Y = Y - 1
end
return table.concat(Result)
end
function writeBMP.write(pixelsXYC, resolutionX, resolutionY, filename)
local file = io.open(filename,"wb")
local data = writeBMP.data(pixelsXYC, resolutionX, resolutionY)
file:write(data)
end
return writeBMP
A simple test:
-- writeBMP example
local writeBMP = require "writeBMP"
local resolutionX = 100
local resolutionY = 100
-- Pixel data
local pixels = {}
for x=1,resolutionX do
pixels[x] = {}
for y=1, resolutionY do
pixels[x][y] = {}
local red = 255*(resolutionX-x+resolutionY-y)/(resolutionX+resolutionY)
local green = 255*y/resolutionY
local blue = 255*x/resolutionX
pixels[x][y][1] = red
pixels[x][y][2] = green
pixels[x][y][3] = blue
end
end
writeBMP.write(pixels,resolutionX,resolutionY,"testwritebmp.bmp")
return
Note: In BMP, the Y axis starts on the bottom. I am more used to Y axis going from top down in computer graphics (so I wrote it that way).
Thanks HAX for the code.
Welcome to Stack Exchange :)
I suggest having a look at PPM files, they are easy. They can be converted with other tools to png or bmp with other tools.
Wikipedia PPM Specification
Here is a PPM solution:
ResolutionX = 48
ResolutionY = 100
local cos, atan, sin, atan2, sqrt, floor = math.cos, math.atan, math.sin, math.atan2, math.sqrt, math.floor
local insert, concat = table.insert, table.concat
local sub, char, rep = string.sub, string.char, string.rep
local file = io.open("Test.ppm","w")
-- PPM File headers
local Output = { }
Output[1] = "P3"
Output[2] = tostring(ResolutionX) .. " " .. tostring(ResolutionY)
Output[3] = "255"
-- Image body
for Y = 0, ResolutionY - 1 do
for X = 0, ResolutionX - 1 do
local value = 255 * ((X + 1) % 2) * ((Y + 1) % 2)
Output[#Output+1] = rep(tostring(floor(value)),3," ")
end
end
-- Join lines together
local Result = table.concat(Output,"\n")
file:write(Result)
Notes: I could not get your code to write to file (see my usage of file). The inner loop must be X (columns) and the outer loop must be Y (rows) if the write order is English reading order (left-right down-up).
In a game I'm making, there's a square where the game is happening inside. I want the circles that spawn in to start at the top and travel down to the bottom. In the original program, they travel from left to right. How would I go about this? I don't know how to get it to start at the top and travel down instead of starting at the left and traveling to the right.
Here's the original code (I know it's a lot, sorry). I am trying to help a friend.
--Made by Joms or /u/jomy582
--Please credit me if using this in a battle.
spawntimer = 0
timerspawn = 0
storedtime = Time.time
bullets = {}
bulletsbig = {}
bulletswarn = {}
dir = 1
bigheight = {33, 98}
function Update()
spawntimer = spawntimer + (Time.dt*Time.mult)
timerspawn = timerspawn + (Time.dt*Time.mult)
--normal bullets
--change the number in the if statement to make them spawn more frequently/less frequently
--EX: spawntimer > 0.2 spawns them pretty fast
--EX2: spawntimer > 1 spawns them pretty slow
--Make sure to change the subtraction method in the if statement
if spawntimer > 0.16 then
spawntimer = spawntimer-0.16
local bullet = CreateProjectile("bullet", -Arena.width/2, math.random(-Arena.height/2, Arena.height/2))
bullet.SetVar("deadly", true)
table.insert(bullets, bullet)
end
--warning. spawns a warning every 5 seconds
--You could change it, but that may cause some bugs
if timerspawn > 2.2 then
timerspawn = timerspawn-2.2
dir = math.random(1,2)
local bulletwarn = CreateProjectile("warning", 0, Arena.height/2 - bigheight[dir])
bulletwarn.SetVar("warningtimer", 0)
bulletwarn.SetVar("soundtimer", 0)
bulletwarn.SetVar("animtimer", 0)
bulletwarn.SetVar("anim", 1)
table.insert(bulletswarn, bulletwarn)
end
--controlling normal bullets
--a simple method that moves the bullets 1 pixel each frame
--you can change it by editing the bullet.move
--EX: bullet.Move(5*Time.mult, 0) moves the bullets 5 pixels each frame
for i=1, #bullets do
local bullet = bullets[i]
if bullet.isactive then
bullet.Move(2*Time.mult, 0)
if bullet.y > -Arena.height/2 then
bullet.Remove()
end
end
end
--controlling warning timer
--a method that controls the warning timer
for i=1, #bulletswarn do
local bullet = bulletswarn[i]
if bullet.isactive then
local warningtimer = bullet.GetVar("warningtimer") + (Time.mult*Time.dt)
local soundtimer = bullet.GetVar("soundtimer") + (Time.mult*Time.dt)
local animtimer = bullet.GetVar("animtimer") + (Time.mult*Time.dt)
local bulletSprite = bullet.sprite
local anim = bullet.GetVar("anim")
--flashing colors
--change the animtimer > TIME where time is how often you want the warning to blink
--warnings last for 3 seconds. Can change that as well
--to get different colors, find the rgb value of the color you want and insert them below
if animtimer > 0.08 then
animtimer = animtimer-0.08
if anim == 1 then
local r = 0 --put Red value here
local g = 0 --put Green value here
local b = 169 --put Blue value here
bulletSprite.color = {r/255, g/255, b/255} -- changes the color to whatever you'd like. Uses RGB.
bullet.SetVar("anim", 2)
elseif anim == 2 then
local r = 0 --put Red value here
local g = 0 --put Green value here
local b = 255 --put Blue value here
bulletSprite.color = {r/255, g/255, b/255} -- changes the color to whatever you'd like. Uses RGB.
bullet.SetVar("anim", 1)
end
end
--plays a timer evert 10 frames for 3 seconds.
--change the soundname to change the sound
--change the soundtimer > 0.16 to change how often it plays
--can change how long it lasts as well by changing the less than statement
if soundtimer > 0.10 then
soundtimer = soundtimer-0.10
Audio.PlaySound("alarm")
end
--this controls when to spawn the bullets
--change the statement to change how long the warning timer is
if warningtimer > 2 then
warningtimer = warningtimer-2
Audio.PlaySound("shoot")
local bullet1 = CreateProjectile("leftbigbullet", Arena.width/2+30, Arena.height/2 - bigheight[dir]) --where to spawn them
bullet1.SetVar("speed", -4) --how fast
bullet1.SetVar("deadly", true)
local bullet2 = CreateProjectile("rightbigbullet", -Arena.width/2-30, Arena.height/2 - bigheight[dir]) --where to spawn them
bullet2.SetVar("speed", 4) --how fast
bullet2.SetVar("deadly", true)
table.insert(bulletsbig, bullet1)
table.insert(bulletsbig, bullet2)
bullet.Remove()
end
bullet.SetVar("warningtimer", warningtimer)
bullet.SetVar("animtimer", animtimer)
bullet.SetVar("soundtimer", soundtimer)
end
end
--controlling big bullets
--this method controls the big bullets
for i=1, #bulletsbig do
local bullet = bulletsbig[i]
if bullet.isactive then
local speed = bullet.GetVar("speed")
bullet.SendToBottom()
bullet.Move(speed*Time.mult, 0)
if bullet.absx > 700 or bullet.absx < -70 then
bullet.Remove()
end
end
end
end
function OnHit(bullet)
if(bullet.getVar("deadly")) then
Player.Hurt(3)
end
end
So I have this module, where all of its activity during the game is in. In t.physics I add a collision event listener (differentiating if target is a group or a single object). When the concerning objects detect a collision though, the property col of the other object (event.other) seems to be nil, although I initially set it to a string representing a color in t.create. I just can't find the cause for that, can anyone?
Thanks for your help.
Greetings, Nils
local fence = require("lib.fence")
local physics = require("physics")
local t = {}
local stages = {yellow = 1, lila = 1, red = 1}
local sizes = {1, 3.625, 7.25}
t.colors = {"yellow", "lila", "red"}
t.growing = false
t.setSize = function(fill)
local tHeight = fill.contentHeight * sizes[stages[fill.col]]
local tScale = tHeight / fill.contentHeight
fill.yScale = tScale
end
t.grow = function(group, color, hero)
local counter = 0
stages[color] = stages[color] + 1
for i = 1, group.numChildren, 1 do
if group[i].col == color then
counter = counter + 1
local function newPhysics() t.physics(group) end
if counter == 1 then
local function reset() t.growing = false if stages[color] == 3 then stages[color] = 1; newPhysics(); end end
local function start() t.growing = true end
transition.to(group[i], {time = 260, yScale = sizes[stages[color]], onStart = start, onComplete = reset})
else
transition.to(group[i], {time = 250, yScale = sizes[stages[color]], onStart = start})
end
end
end
end
t.physics = function(target)
if target.numChildren == nil then
physics.removeBody(target)
local function add()
physics.addBody( target, "static", {isSensor = true} )
target.collision = function(self, event)
if event.phase == "began" then
target.count = target.count + 1
if target.count == 1 then
t.grow(target.parent, self.col, event.other)
end
elseif event.phase == "ended" then
target.count = 0
end
end
end
timer.performWithDelay(1, add, 1)
else
for i = 1, target.numChildren, 1 do
physics.removeBody( target[i] )
physics.addBody( target[i], "static", {isSensor = true} )
target[i].name = "fill"
local fill = target[i]
fill.count = 0
fill.collision = function(self, event)
if event.phase == "began" then
self.count = self.count + 1
if self.count == 1 and event.other.x ~= nil then
t.grow(target, self.col, event.other)
end
else
fill.count = 0
end
end
fill:addEventListener("collision")
end
end
end
t.setColor = function(fill)
local colors = {
{238 / 255, 228 / 255, 28 / 255},
{38 / 255, 33 / 255, 77 / 255},
{175 / 255, 24 / 255, 52 / 255},
}
local names = {"yellow", "lila", "red"}
local r = math.random(3)
fill.fill = colors[r]
fill.col = names[r]
end
t.create = function(fences, group, colors)
local fills = {}
for i = 1, #fences, 1 do
local rCol = math.random(3)
local col
if rCol == 1 then
col = colors.yellow
elseif rCol == 2 then
col = colors.lila
else
col = colors.red
end
fills[i] = display.newRect(
group, fences[i].x + fences[i].contentWidth * 0.125, fences[i].y,
fences[i].contentWidth * 0.9, (fences[i].contentHeight * 0.5 / 3)
)
fills[i].dPosX = fills[i].x
fills[i].y = display.contentHeight- fills[i].contentHeight / 2
fills[i].fill = col
fills[i].col = t.colors[rCol]
fills[i].increased = false
end
return fills
end
t.move = function(fills, fences, group)
for i = 1, #fills, 1 do
local fill = fills[i]
function fill:enterFrame()
self:translate(fence.speed, 0)
if t.growing == false then
t.setSize(self)
end
if self.x > display.contentWidth + 0.55 * fences[i].contentWidth then
local xT = {}
for i = 1, group.numChildren, 1 do
xT[i] = group[i].x
end
local function compare(a, b) return a < b end
table.sort(xT, compare)
self.x = xT[1] - fences[i].contentWidth * 0.98
t.setColor(self)
local function newPhysics() t.physics(self) end
timer.performWithDelay( 25, newPhysics, 1 )
self:toBack()
end
end
Runtime:addEventListener("enterFrame", fill)
end
end
return t
Solved. Ugh, sorry, I forgot to define the property on the other object involved (hero), that has its own module. What a stupid slip.
Thanks for your answers anyways!
You don't seem to have any dynamic bodies here. What is colliding with what? Could it be that the other object involved in the collision (the value of event.other) is not something initialized in t.create() and so doesn't have the col property?
From the Corona documentation on Collision Detection:
Some body types will — or will not — collide with other body types. In a collision between two physical objects, at least one of the objects must be dynamic, since this is the only body type which collides with any other type.
Also, in your fill.collision(), I think you want to pass event.target as the first argument to t.grow() rather than target. If you try things, please update the question with more information.
Using the Love2D Lua framework, I am trying to program a very basic game much like Nintendo-era RPGs where the heroes' and NPCs' movement was restricted to a tiled grid. So far I've found my past any problems, until I hit this tricky error where the player movement isn't functioning correctly.
function love.load()
love.graphics.setDefaultFilter('nearest', 'nearest', 1)
love.keyboard.setKeyRepeat(true)
font = love.graphics.newFont(14) -- the number denotes the font size
win_size = 6
love.window.setMode(160 * win_size, 144 * win_size)
true_sfc = love.graphics.newCanvas(160,144)
view_sfc = love.graphics.newCanvas(160 * win_size, 144 * win_size)
player = {
grid_x = 3,
grid_y = 3,
act_x = 48,
act_y = 48,
transit = false,
direction = {0, 0}
}
end
function love.update(dt)
if player.transit == true then
-- The idea is that if the player selects a direction, the player will walk in that direction until it stops on the grid.
-- When I press left or right, the movements works as intended- the player square walks until it stops on the grid.
-- However, when I press up or down, the player only moves a single pixel, despite having the same instructions
player.act_x = player.act_x + player.direction[1]
player.act_y = player.act_y + player.direction[2]
if player.act_x == player.grid_x * 16 then
player.direction[1] = 0
player.transit = false
end
if player.act_y == player.grid_y * 16 then
player.direction[2] = 0
player.transit = false
end
-- Now in this if-statement, if I have the program compare the player's y-coordinates before comparing the x coordinates,
-- the program will move the player on the y-axis correctly, with it locking to the 16 pixel grid, while the x coordinates
-- will starts to have the single-pixel movement issue.
end
end
function love.draw()
love.graphics.setCanvas(true_sfc)
love.graphics.setColor( 0, 0, 0)
love.graphics.rectangle("fill", 0, 0, 256, 224)
love.graphics.setColor(255,255,255)
love.graphics.rectangle("fill", player.act_x, player.act_y, 16, 16)
love.graphics.print(player.direction[1], 100, 100)
love.graphics.print(player.direction[2], 100, 120)
love.graphics.setCanvas()
love.graphics.draw(true_sfc, 0, 0, 0, win_size, win_size)
end
function love.keypressed(key)
if player.transit == false then
if key == "up" then
player.grid_y = player.grid_y - 1
player.direction = {0, -1}
player.transit = true
elseif key == "down" then
player.grid_y = player.grid_y + 1
-- press down, the player's map position goes down one tile
player.direction = {0, 1}
player.transit = true
elseif key == "left" then
player.grid_x = player.grid_x - 1
player.direction = {-1, 0}
player.transit = true
elseif key == "right" then
player.grid_x = player.grid_x + 1
player.direction = {1, 0}
player.transit = true
end
end
end
Admittedly I'm pretty new to Lua so I don't understand how it uses variables very well. And I realize that my code isn't very effecient, but that's something I planned on improving over time anyway.
The problem here is that you check if the vertical movement lines up, see that it does, and then you set self.transit to false, preventing any future checks.
You want to also check that you are moving in that direction, before checking if you're lined up:
if player.direction[1] ~= 0 and player.act_x == player.grid_x * 16 then
player.direction[1] = 0
player.transit = false
end
if player.direction[2] ~= 0 and player.act_y == player.grid_y * 16 then
player.direction[2] = 0
player.transit = false
end