Roblox Studio skipping for loops - lua

I have a script that gradually teleports the player to a part:
for y = 0, math.floor((part.Y-player.Y)/steps), 1 do
wait(0.3)
print "1"
game.Players:FindFirstChild(username).Character.HumanoidRootPart.CFrame = game.Players:FindFirstChild(username).Character.HumanoidRootPart.CFrame + Vector3.new(0, steps, 0)
end
for x = 0, math.floor((part.X-player.X)/steps), 1 do
wait(0.3)
print "2"
game.Players:FindFirstChild(username).Character.HumanoidRootPart.CFrame = game.Players:FindFirstChild(username).Character.HumanoidRootPart.CFrame + Vector3.new(steps, 0, 0)
end
for z = 0, math.floor((part.Z-player.Z)/steps), 1 do
wait(0.3)
print "3"
game.Players:FindFirstChild(username).Character.HumanoidRootPart.CFrame = game.Players:FindFirstChild(username).Character.HumanoidRootPart.CFrame + Vector3.new(0, 0, steps)
end
Whenever I run the script on roblox studio it skips the Y for loop and the Z for loop and only runs the X for loop. Any idea why?

As #Egor Skriptunoff said, if the part Y, X or Z values are smaller than the player's Y, X or Z values then the loop will not run.
An easy way to fix this would be to use the math.abs() method around the subtraction like so,
for y = 0, math.floor(math.abs(part.Y-player.Y)/steps), 1 do
wait(0.3)
print "1"
game.Players:FindFirstChild(username).Character.HumanoidRootPart.CFrame = game.Players:FindFirstChild(username).Character.HumanoidRootPart.CFrame + Vector3.new(0, steps, 0)
end
This makes sure that the result will always be positive as math.abs just gets rid of the negative symbol.

Related

Lua Logitech - Sensitivity adjustment

Good day to everyone.
I want to create a "No Recoil" scenario with the ability to specify my own aiming sensitivity value.
At the moment, the code that you can see below works exclusively with one setting, namely with the dpi800 and the in-game sensitivity on the X and Y axes equal to 7, is it possible to make it so that I can change literally two digits, for example, not 7, but 9 or 10 and so on, and the script changed using some formula values in line 7(r_p["Weapon1"]) and 8(r_p["Weapon2"])
local r_p = {Weapon1}
local r_o = r_p[o_s_a] or {Weapon2}
local o_s_a = "Weapon2"
local n_o_s_a = {Weapon2 = "Weapon1", Weapon1 = "Weapon2"}
r_p["Weapon1"] = {0, 0, 0, 0, 25, 100, -1, 17, 600, -1, 20, 500, -1, 21, 800}
r_p["Weapon2"] = {0, 0, 0, 0, 22, 150, -1, 17, 400, -1, 20, 700, -1, 20, 300, -1, 20, 150, -2, 21, 400, -2, 21, 550, -2, 21, 300, -2, 21, 250, -2, 21, 100}
function Log()
if not IsKeyLockOn("scrolllock") then
ClearLog()
OutputLogMessage("Current mode: List of weapons | Scroll lock is OFF\n\n")
OutputLogMessage("Selected: %s\n\n", o_s_a)
OutputLogMessage(" (%s) | Weapon1 (%s) | Weapon2\n\n", o_s_a == "Weapon1", o_s_a == "Weapon2")
end
end
function OnEvent(event, arg)
EnablePrimaryMouseButtonEvents(true)
if event == "MOUSE_BUTTON_PRESSED" and arg == 5 and IsModifierPressed("lctrl") and not IsKeyLockOn("scrolllock") then
o_s_a = n_o_s_a[o_s_a]
r_o = r_p[o_s_a] or {}
Log()
else if event == "MOUSE_BUTTON_PRESSED" and arg == 1 and IsMouseButtonPressed(3) and not IsKeyLockOn("capslock") then
for xy = 3, #r_o, 3 do
local c_t = GetRunningTime()
local h_r = r_o[xy-2]
local v_r = r_o[xy-1]
local r_d = r_o[xy]
repeat
local d_t = GetRunningTime() - c_t, r_d
MoveMouseRelative(h_r, v_r)
Sleep(10)
until d_t >= r_d or not IsMouseButtonPressed(1) or not IsMouseButtonPressed(3)
if not IsMouseButtonPressed(1) or not IsMouseButtonPressed(3) then break end
end
end
end
end
I tried using multiplayer, but in this version you can use only 2 values, where sensitivity 12 is standard, when you activate multiplayer, all your sensitivity settings are divided by 2 and as a result you get sensitivity 6, but this is a bit not the option that I need.
Thank you very much for any help if all.
You can modify the values on-the-fly instead of changing values in lines 7(r_p["Weapon1"]) and 8(r_p["Weapon2"]).
Replace the following lines
local h_r = r_o[xy-2]
local v_r = r_o[xy-1]
with
local h_r = round(r_o[xy-2] * sens / 6)
local v_r = round(r_o[xy-1] * sens / 6)
where sens is a variable with default value 6, but you can modify it.
round is a function, define it before OnEvent:
function round(x)
return math.floor(x + 0.5)
end
sens = 6
UPDATE:
The solution above has a drawback: due to rounding errors, the cursor gradually shifts to the left and/or to the top.
The solution below accumulates fractional parts to avoid such shift.
Define the function MoveMouseRelativeFractional which accepts fractional arguments and use it instead of the standard MoveMouseRelative.
The definition should be inserted at the very beginning of the whole script:
local remainder_fractional_x, remainder_fractional_y = 0, 0
local function MoveMouseRelativeFractional(x, y)
x = remainder_fractional_x + x
y = remainder_fractional_y + y
local x_int = math.floor(x + 0.5)
local y_int = math.floor(y + 0.5)
remainder_fractional_x = x - x_int
remainder_fractional_y = y - y_int
MoveMouseRelative(x_int, y_int)
end
Remove round:
local h_r = r_o[xy-2] * sens / 13
local v_r = r_o[xy-1] * sens / 13
Replace MoveMouseRelative with MoveMouseRelativeFractional:
MoveMouseRelativeFractional(h_r, v_r)

How can I combine blocks of the same type in rectangular prisms in an efficient mannor?

I'm making a block-based city building game and I'm trying to figure out an efficient way of merging multiple blocks of the same type into boxes for optimization purposes. So let's say there's a wall of a building and it's 16x30x16 blocks of brick. Rather than draw the 7,680 blocks, I can draw them as one giant flat rectangular prism with a repeating texture, which would be eons more efficient.
I started on this by creating strips, which I intended to further combine into panes, but it seems that this method is already too slow, as it has to loop through every block in a plot(chunk), check if it can be merged into the current strip, and then merge it if yes.
Thanks in advance
local function Draw(plot)
local blocks = plot.blocks
local slabs = NewAutotable(3)
local slabList = {}
for y = 1, 32 do
for x = 1, 16 do
local currentSlab = NewSlab(x, y, 1, 1, 1, 1, blocks[x][y][1])
slabs[x][y][1] = currentSlab
slabList[#slabList + 1] = currentSlab
for z = 2, 16 do
if currentSlab[7] == blocks[x][y][z] then
GrowSlab(currentSlab, 0, 0, 1)
else
currentSlab = NewSlab(x, y, z, 1, 1, 1, blocks[x][y][z + 1])
slabs[x][y][z] = currentSlab
slabList[#slabList + 1] = currentSlab
end
end
end
end
end

How to use bounding box in Love2d?

I've been using some extremely bulky code to detect collision between simple objects, and I've heard about bounding boxes. I can't find any tutorials on how to use it, so I'm asking about how to use it. Here is how I detect collision:
function platform.collision()
if player.x + player.width / 2 <= platform.x + platform.width and
player.x + player.width / 2 >= platform.x and
player.y + player.height <= platform.y + platform.height and
player.y + player.height >= platform.y then
The MDN has a rather concise article on 2D collision detection. Being the MDN, the examples are in javascript, but are easily translated to, and applicable in, any language - including Lua.
Let's take a look:
Axis-Aligned Bounding Box
One of the simpler forms of collision detection is between two rectangles that are axis aligned — meaning no rotation. The algorithm works by ensuring there is no gap between any of the 4 sides of the rectangles. Any gap means a collision does not exist.
Their example, translated to Lua:
local rect1 = { x = 5, y = 5, width = 50, height = 50 }
local rect2 = { x = 20, y = 10, width = 10, height = 10 }
if
rect1.x < rect2.x + rect2.width and
rect1.x + rect1.width > rect2.x and
rect1.y < rect2.y + rect2.height and
rect1.height + rect1.y > rect2.y
then
-- collision detected!
end
-- filling in the values =>
if
5 < 30 and
55 > 20 and
5 < 20 and
55 > 10
then
-- collision detected!
end
A live example, again in JavaScript, demonstrates this well.
Here's a quick (and imperfect) Love2D example you can throw into a main.lua and play around with.
local function rect (x, y, w, h, color)
return { x = x, y = y, width = w, height = h, color = color }
end
local function draw_rect (rect)
love.graphics.setColor(unpack(rect.color))
love.graphics.rectangle('fill', rect.x, rect.y,
rect.width, rect.height)
end
local function collides (one, two)
return (
one.x < two.x + two.width and
one.x + one.width > two.x and
one.y < two.y + two.height and
one.y + one.height > two.y
)
end
local kp = love.keyboard.isDown
local red = { 255, 0, 0, 255 }
local green = { 0, 255, 0, 255 }
local blue = { 0, 0, 255, 255 }
local dim1 = rect(5, 5, 50, 50, red)
local dim2 = rect(20, 10, 60, 40, green)
function love.update ()
if kp('up') then
dim2.y = dim2.y - 1
end
if kp('down') then
dim2.y = dim2.y + 1
end
if kp('left') then
dim2.x = dim2.x - 1
end
if kp('right') then
dim2.x = dim2.x + 1
end
dim2.color = collides(dim1, dim2) and green or blue
end
function love.draw ()
draw_rect(dim1)
draw_rect(dim2)
end
Oka explained it very well. This works for everything rectangular, not rotated and axis aligned. And you even already did it that way. This is great for buttons and the like!
But what I like doing is using (invisible) circles around objects and see if these collide. This works for everything where height is about the same as the width (which is the case for many sidescrolling platformers or top-down RPGs).
It's quite handy if you want to have the object centered at the current position. And it's especially helpful to simulate a finger on a touchscreen device, because a finger is quite a bit bigger than a mouse cursor. ;)
Here's an example on how to use this method. You can copy it as an actual game, it'll work.
--[[ Some initial default settings. ]]
function love.load()
settings = {
mouseHitbox = 5, -- A diameter around the mouse cursor.
-- For a finger (thouchscreen) this could be bigger!
}
objects = {
[1] = {
x = 250, -- Initial X position of object.
y = 200, -- Initial Y position of object.
hitbox = 100, -- A diameter around the CENTER of the object.
isHit = false -- A flag for when the object has been hit.
},
[2] = {
x = 400,
y = 250,
hitbox = 250,
isHit = false
}
}
end
--[[ This is the actual function to detect collision between two objects. ]]
function collisionDetected(x1,y1,x2,y2,d1,d2)
-- Uses the x and y coordinates of two different points along with a diameter around them.
-- As long as these two diameters collide/overlap, this function returns true!
-- If d1 and/or d2 is missing, use the a default diameter of 1 instead.
local d1 = d1 or 1
local d2 = d2 or 1
local delta_x = x2 - x1
local delta_y = y2 - y1
local delta_d = (d1 / 2) + (d2 / 2)
if ( delta_x^2 + delta_y^2 < delta_d^2 ) then
return true
end
end
--[[ Now, some LÖVE functions to give the collisionDetection() some context. ]]
function love.draw()
for i=1,#objects do -- Loop through all objects and draw them.
if ( objects[i].isHit ) then
love.graphics.setColor(255, 0, 0) -- If an object is hit, it will flash red for a frame.
objects[i].isHit = false
else
love.graphics.setColor(255, 255, 255)
end
love.graphics.circle("line", objects[i].x, objects[i].y, objects[i].hitbox/2)
end
end
-- You can use the following to check, if any object has been clicked on (or tapped on a touch screen device).
function love.mousepressed(x,y,button)
if ( button == 1 ) then
local i = objectIsHit(x,y) -- Check, if an object has been hit.
if ( i ) then
-- The object number 'i' has been hit. Do something with this information!
objects[i].isHit = true
end
end
end
function objectIsHit(x,y)
for i=1,#objects do -- Loop through all objects and see, if one of them has been hit.
if ( collisionDetected(x, y, objects[i].x, objects[i].y, settings.mouseHitbox, objects[i].hitbox) ) then
return i -- This object has been hit!
end
end
end
-- For the sake of completeness: You can use something like the following to check, if the objects themselves collide.
-- This would come in handy, if the objects would move around the screen and then bounce from each other, for example.
function love.update(dt)
if ( collisionDetected(objects[1].x, objects[1].y, objects[2].x, objects[2].y, objects[1].hitbox, objects[2].hitbox) ) then
-- The objects collided. Do something with this information!
end
end
As you can see, the collisionDetection() function is quite easy and intuitive to use.
Hopefully I could give you some more insight. And have fun with LÖVE 2D! :)

Love2d drawing grid and manipulating it i have few problems

Hello i made grid code but it doesn't look like how i wanted to, i want to to be will look like down there i tried a lot but i wasn't able to find right formula to do that
Here is my code
function love.load()
num = 32-- how many cell are going to be in each axis
w = 20
h = 20
color = {128, 128, 128}
backgroundcolor = {192, 192, 192}
end
function love.update(dt)
end
function love.draw()
for y = 1, num do
for x = 1, num do
if (x + y)%2 == 0 then
love.graphics.setColor(unpack(color))
else
love.graphics.setColor(unpack(backgroundcolor))
end
love.graphics.rectangle("fill", (x - 1)*w ,(y - 1)*h, w, h)
end
end
end
Result:
I want to achieve this each cell is 16 x 16.
Note: I don't want to use 2 x 2 cell i need 32 x 32 of them that is the problem i am facing right now.

Binary clock with Lua, how to remove dots that aren't used?

I have the following binary clock that I grabbed from this wiki article (the one that's for v1.5.*) for the awesome WM:
binClock = wibox.widget.base.make_widget()
binClock.radius = 1.5
binClock.shift = 1.8
binClock.farShift = 2
binClock.border = 1
binClock.lineWidth = 1
binClock.colorActive = beautiful.bg_focus
binClock.fit = function(binClock, width, height)
local size = math.min(width, height)
return 6 * 2 * binClock.radius + 5 * binClock.shift + 2 * binClock.farShift + 2 * binClock.border + 2 * binClock.border, size
end
binClock.draw = function(binClock, wibox, cr, width, height)
local curTime = os.date("*t")
local column = {}
table.insert(column, string.format("%04d", binClock:dec_bin(string.sub(string.format("%02d", curTime.hour), 1, 1))))
table.insert(column, string.format("%04d", binClock:dec_bin(string.sub(string.format("%02d", curTime.hour), 2, 2))))
table.insert(column, string.format("%04d", binClock:dec_bin(string.sub(string.format("%02d", curTime.min), 1, 1))))
table.insert(column, string.format("%04d", binClock:dec_bin(string.sub(string.format("%02d", curTime.min), 2, 2))))
table.insert(column, string.format("%04d", binClock:dec_bin(string.sub(string.format("%02d", curTime.sec), 1, 1))))
table.insert(column, string.format("%04d", binClock:dec_bin(string.sub(string.format("%02d", curTime.sec), 2, 2))))
local bigColumn = 0
for i = 0, 5 do
if math.floor(i / 2) > bigColumn then
bigColumn = bigColumn + 1
end
for j = 0, 3 do
if string.sub(column[i + 1], j + 1, j + 1) == "0" then
active = false
else
active = true
end
binClock:draw_point(cr, bigColumn, i, j, active)
end
end
end
binClock.dec_bin = function(binClock, inNum)
inNum = tonumber(inNum)
local base, enum, outNum, rem = 2, "01", "", 0
while inNum > (base - 1) do
inNum, rem = math.floor(inNum / base), math.fmod(inNum, base)
outNum = string.sub(enum, rem + 1, rem + 1) .. outNum
end
outNum = inNum .. outNum
return outNum
end
binClock.draw_point = function(binClock, cr, bigColumn, column, row, active)
cr:arc(binClock.border + column * (2 * binClock.radius + binClock.shift) + bigColumn * binClock.farShift + binClock.radius,
binClock.border + row * (2 * binClock.radius + binClock.shift) + binClock.radius, 2, 0, 2 * math.pi)
if active then
cr:set_source_rgba(0, 0.5, 0, 1)
else
cr:set_source_rgba(0.5, 0.5, 0.5, 1)
end
cr:fill()
end
binClocktimer = timer { timeout = 1 }
binClocktimer:connect_signal("timeout", function() binClock:emit_signal("widget::updated") end)
binClocktimer:start()
First, if something isn't by default already in Lua that's because this is to be used in the config file for awesome. :)
OK, so what I need is some guidance actually. I am not very familiar with Lua currently, so some guidance is all I ask so I can learn. :)
OK, so first, this code outputs a normal binary clock, but every column has 4 dots (44,44,44), instead of a 23,34,34 setup for the dots, as it would be in a normal binary clock. What's controlling that in this code? So that I can pay around with it.
Next, what controls the color? Right now it's gray background and quite a dark green, I want to brighten both of those up.
And what controls the smoothing? Right now it's outputting circles, would like to see what it's like for it to output squares instead.
That's all I need help with, if you can point me to the code and some documentation for what I need, that should be more than enough. :)
Also, if somebody would be nice enough to add some comments, that also would be awesome. Don't have to be very detailed comments, but at least to the point where it gives an idea of what each thing does. :)
EDIT:
Found what modifies the colors, so figured that out. None of the first variables control if it's a square or circle BTW. :)
The draw_point function draws the dots.
The two loops in the draw function are what create the output and is where the columns come from. To do a 23/34/34 layout you would need to modify the inner loop skip the first X points based on the counter of the outer loop I believe.

Resources