Connecting a grid up with rope constraints - lua

I'm trying to make a kind of "cloth simulation" by using ROBLOX's new rope constraints and a grid of parts.
Currently, I've made a 10x10 grid of .4x.4x.4 blocks and now I want to connect each one up with rope constraints.
I've named each part in the grid after their row and column (eg: first part in the grid being 1 1, last one being 10 10)
and then I get the parts around each individual grid part using their name and string manipulation.
I then insert 4 attachments into each part and 4 rope constraints.
Here's the code (ab stands for above, be stands for below, etc) :
for i2 = 1, #gParts do
local ab = tostring(tonumber(gParts[i2].Name:match("^(%S+)"))-5).." "..tostring(tonumber(string.sub(gParts[i2].Name,-1))-1)
local be = tostring(tonumber(gParts[i2].Name:match("^(%S+)"))+5).." "..tostring(tonumber(string.sub(gParts[i2].Name,-1))+1)
local le = tostring(tonumber(gParts[i2].Name:match("^(%S+)"))-1).." "..tostring(tonumber(string.sub(gParts[i2].Name,-1)))
local ri = tostring(tonumber(gParts[i2].Name:match("^(%S+)"))+1).." "..tostring(tonumber(string.sub(gParts[i2].Name,-1)))
for i3 = 1, 4 do
local atchm = Instance.new("Attachment",gParts[i2])
local ropeconst = Instance.new("RopeConstraint",gParts[i2])
end
end
Rope constraint has 2 main properties I need to use; attachment 1 and attachment 2.

I've never really messed with the new constraints, but I believe this should work.
Do keep in mind that the constraints are a new Instance in Roblox, and that they are likely still experimental.
X = 10;
Y = 10;
spread = 4;
--Spread is the Length of the Constraint. You may have to increase this, especially if it's stiff.
function createAttachments()
--This is under the assumption that gParts is a table filled with the Part Instances
for i,v in pairs(gParts) do
local atch = Instance.new("Attachment",v);
end;
end;
function connectConstraints(part,x,y)
if x ~= X then
connectRight = x+1.." "..y;
end;
if y ~= Y then
connectDown = x.." "..y+1;
end;
if connectRight ~= nil then
local ropeconst = Instance.new("RopeConstraint",part);
ropeconst.Length = spread;
ropeconst.Attachment0 = part.Attachment;
ropeconst.Attachment1 = connectRight.Attachment;
end;
if connectLeft ~= nil then
local ropeconst = Instance.new("RopeConstraint",part);
ropeconst.Length = spread;
ropeconst.Attachment0 = part.Attachment;
ropeconst.Attachment1 = connectLeft.Attachment;
end
end
createAttachments();
connectConstraints();
If this does not work for you, please let me know. I can contact you from the site itself if needed.

Related

/Lua/ How to do this (idk how to call that lol)

I need to make a trolleybus number, which won't repeat for game. For example, there is a number "101" and there musn't be more "101". How to do that? I have a code, but I know, he won't work and I won't test it lol
function giveNumber()
local number = math.random(100, 199)
local takedNumbers = {}
local i = 0
local massiv = i+1
script.Parent.pered.SurfaceGui.TextLabel.Text = number
script.Parent.zad.SurfaceGui.TextLabel.Text = number
script.Parent.levo.SurfaceGui.TextLabel.Text = number
script.Parent.pravo.SurfaceGui.TextLabel.Text = number
takedNumbers[massiv] = {number}
end
script.Parent.Script:giveNumber() // what I wrote here? idk...
if number == takedNumbers[massiv] then
giveNumber()
end
i didn't test it, because I think it won't work because this code is something bad
I think this will serve your needs.
In the function generateUniqueNumber, the script loops until it found a number that is not yet in the array. (in other words, that it hasn't given out yet)
Once it found that number, it will insert it into the table to remember that it has given it out, and then it will return the number.
Then on the bottom of the script we just give the numbers to the buses :-)
--[[
Goal: Give all buses a unique number
]]
-- Variables
local takenNumbers = {};
-- This function returns a random number in the range [100, 199] that has not been taken yet
function generateUniqueNumber()
local foundNumber = false;
while not foundNumber do
randomNumber = math.random(100, 199);
if not table.find(takenNumbers, randomNumber) then
table.insert(takenNumbers, randomNumber);
return randomNumber;
end
end
end
-- This function sets the number of the bus
script.Parent.pered.SurfaceGui.TextLabel.Text = tostring(generateUniqueNumber());
script.Parent.zad.SurfaceGui.TextLabel.Text = tostring(generateUniqueNumber());
script.Parent.levo.SurfaceGui.TextLabel.Text = tostring(generateUniqueNumber());
script.Parent.pravo.SurfaceGui.TextLabel.Text = tostring(generateUniqueNumber());
2 things:
I didn't test this code as Roblox is not installed on the pc I'm currently on.
Please try formatting your code nicely next time. It greatly improves the readability! For example, you can use this website:
https://codebeautify.org/lua-beautifier
Simpler
Fill a table with free numbers...
local freenumbers = {}
for i = 1, 99 do freenumbers[i] = i + 100 end
...for every new takennumbers use table.remove() on freenumbers
local takennumbers = {}
if #freenumbers > 0 then
takennumbers[#takennumbers + 1] = table.remove(freenumbers, math.random(1, #freenumbers))
end

Lua spawnpoint random

my problem is that he uses all 3 spawn points instead of only 1 of the 3 that I put there to choose from
YY_Pos = {}
YY_Pos[1] = {m=3017299663, x=1700, y=13154, z=2450}
YY_Pos[2] = {m=3017299663, x=1775, y=12413, z=2436}
YY_Pos[3] = {m=3017299663, x=1775, y=12413, z=2500}
function YY_tmhz_1_OnCreatureDisappear(MapID, InstanceID, Creatur ID, x, y, z)
for i = 1,3 do
local Index_pos = math.random(1,3)
local CreatureID = map.MapCreateCreature(YY_Pos[i].m, InstanceID, 1534207, YY_Pos[i].x, YY_Pos[i].y, YY_Pos[i].z)
end
end
You create a random value Index_pos but you never use it.
Instead you use the loop counter variable i to index your coordinate table.
Also note that the code as is will not use 1 of three coordinates but 3 random coordinates.
You would have to move the math.random call out of the loop if you want to do something 3 times for the same random index.

Lua Nested Table Getting Elements

I have a nested table like so:
t1 ={}
t1[1] = {col1=1,col2=1,col3=1,col4=1}
t1[2] = {col1=1,col2=1,col3=1,col4=1}
t1[3] = {col1=1,col2=1,col3=1,col4=1}
t1[4] = {col1=1,col2=1,col3=1,col4=1}
it's actually much larger with 250 items in t1 and 30 items per nested table so what I want to do is loop through and get sub table values like this:
for i = 2, 4 do
local width = t1[draw.ID].col1 --draw.ID is got elsewhere
end
but changing the number part of .col1 to the i part so when it loops through it gets:
t1[draw.ID].col2
t1[draw.ID].col3
t1[draw.ID].col4
I'm using Lua 5.1.
for i= 2, 4 do
local width = t1[draw.ID]["col" .. i] --draw.ID is got elsewhere
end
Ideally, col would be or would contain an array-like table or sequence. This is a much more scalable way to accomplish what you're trying to do. String concatenation ['col' .. i] to access table keys in the fashion that you'd access them as an array is costly and unnecessary, if it can be avoided. This is especially important if this is something you plan to do often and want to work quickly.
-- Elements of t1 contain tables with cols.
local t1 = {}
t1[1] = {cols = {1,1,1,1}}
t1[2] = {cols = {1,1,1,1}}
t1[3] = {cols = {1,1,1,1}}
t1[4] = {cols = {1,1,1,1}}
for i=2, 4 do
local width = t1[draw.ID].cols[i]
end
-- Elements of t1 are the cols.
local t1 = {}
t1[1] = {1,1,1,1}
t1[2] = {1,1,1,1}
t1[3] = {1,1,1,1}
t1[4] = {1,1,1,1}
for i=2, 4 do
local width = t1[draw.ID][i]
end
Edit: If it's unavoidable that you have to use table keys in the style of ['col' .. i], then the best you could do is to cache them for faster access.
-- Cache all the possible keys that you'll need.
local colkeys = {}
for i=1, 30 do colkeys[i] = 'col' .. i end
for i=2, 4 do
local width = t1[draw.ID][colkeys[i]]
end
This method is anywhere from 4 to 8 times faster than concatenating a string each time that you need to index the table. It's not the ideal solution, but it works if you're stuck with the likes of col1 to col30.

How to design a "Dynamic inventory system" for a point and click game?

I have done lots of research on invetory system for point and click game in Lua and corona.
I have come across this example,I am doing something similar to this,but I need a dynamic inventory system.
I mean if I have 4 slots,and all them are full the fifth object go to next slot,so there will be an arrow to the right so I can click on ;and go to the next page.
And imagine there are 5 items,and I have 4 slots,the fifth slot would be on the next page.
I use the third item,and third slot would then be empty,so I want the fourth and fifth item automatically move back to third and fourth slot.
I have hard time figuring this out.
Thanks for advance.
local myInventoryBag={}
local maxItems = 10 -- change this to how many you want
myInventoryBag[5]=3 -- Hammer for instance
myInventoryBag[4]=7 -- A metal Pipe for instance
local function getImageForItem(thisItem)
local itemNumber = tonumber(thisItem)
local theImage=""
if itemNumber==3 then
theImage="hammer.png"
elseif itemNumber == 7 then
theImage="metalpipe.png"
elseif ... -- for other options
...
else
return nil
end
local image = display.newImage(theImage)
return image
end
local function displayItems()
local i
for i=1,#myInventoryBag do
local x = 0 -- calculate based on the i
local y = 0 -- calculate based on the i
local image = getImageForItem(myInventoryBag[i])
if image==nil then return end
image.setReferencePoint(display.TopLeftReferencePoint)
image.x = x
image.y = y
end
end
local itemImages =
{
[0] = display.newImage('MISSING_ITEM_IMAGE.PNG'),
[3] = display.newImage('hammer.png'),
[7] = display.newImage('metalpipe.png'),
}
function getImageForItem(itemId)
return itemImages[itemId] or itemImages[0]
end
local myInventoryBag={}
local maxItems = 10 -- change this to how many you want
local visibleItems = 4 -- show this many items at a time (with arrows to scroll to others)
-- show inventory items at index [first,last]
local function displayInventoryItems(first,last)
local x = 0 -- first item goes here
local y = 0 -- top of inventory row
for i=first,last do
image = getImageForItem(myInventoryBag[i])
image.x = x
image.y = y
x = x + image.width
end
end
-- show inventory items on a given "page"
local function displayInventoryPage(page)
page = page or 1 -- default to showing the first page
if page > maxItems then
-- error! handle me!
end
local first = (page - 1) * visibleItems + 1
local last = first + visibleItems - 1
displayInventoryItems(first, last)
end
myInventoryBag[5] = 3 -- Hammer for instance
myInventoryBag[4] = 7 -- A metal Pipe for instance
displayInventoryPage(1)
displayInventoryPage(2)
Basically what you would do is loop through all the inventory slots and check if the slot is empty. If it's empty, place the item in that slot and stop the loop. If it's not, go to the next one.
If you want to remove an item from the inventory, you can simply call table.delete(myInventoryBag, slotToEmpty).
For pages, you'd simply have a page variable. When drawing the inventory slots, just loop from slots (page-1) * 4 + 1 to page * 4.
(Edit: I'd highly recommend using proper indentation, as it will make the code much much more readable.)

How Lua tables work

I am starting to learn Lua from Programming in Lua (2nd edition)
I didn't understand the following in the book. Its very vaguely explained.
a.) w={x=0,y=0,label="console"}
b.) x={math.sin(0),math.sin(1),math.sin(2)}
c.) w[1]="another field"
d.) x.f=w
e.) print (w["x"])
f.) print (w[1])
g.) print x.f[1]
When I do print(w[1]) after a.), why doesn't it print x=0
What does c.) do?
What is the difference between e.) and print (w.x)?
What is the role of b.) and g.)?
You have to realize that this:
t = {3, 4, "eggplant"}
is the same as this:
t = {}
t[1] = 3
t[2] = 4
t[3] = "eggplant"
And that this:
t = {x = 0, y = 2}
is the same as this:
t = {}
t["x"] = 0
t["y"] = 2
Or this:
t = {}
t.x = 0
t.y = 2
In Lua, tables are not just lists, they are associative arrays.
When you print w[1], then what really matters is line c.) In fact, w[1] is not defined at all until line c.).
There is no difference between e.) and print (w.x).
b.) creates a new table named x which is separate from w.
d.) places a reference to w inside of x. (NOTE: It does not actually make a copy of w, just a reference. If you've ever worked with pointers, it's similar.)
g.) Can be broken up in two parts. First we get x.f which is just another way to refer to w because of line d.). Then we look up the first element of that table, which is "another field" because of line c.)
There's another way of creating keys in in-line table declarations.
x = {["1st key has spaces!"] = 1}
The advantage here is that you can have keys with spaces and any extended ASCII character.
In fact, a key can be literally anything, even an instanced object.
function Example()
--example function
end
x = {[Example] = "A function."}
Any variable or value or data can go into the square brackets to work as a key. The same goes with the value.
Practically, this can replace features like the in keyword in python, as you can index the table by values to check if they are there.
Getting a value at an undefined part of the table will not cause an error. It will just give you nil. The same goes for using undefined variables.
local w = {
--[1] = "another field"; -- will be set this value
--["1"] = nil; -- not save to this place, different with some other language
x = 0;
y = 0;
label = "console";
}
local x = {
math.sin(0);
math.sin(1);
math.sin(2);
}
w[1] = "another field" --
x.f = w
print (w["x"])
-- because x.f = w
-- x.f and w point one talbe address
-- so value of (x.f)[1] and w[1] and x.f[1] is equal
print (w[1])
print ((x.f)[1])
print (x.f[1])
-- print (x.f)[1] this not follows lua syntax
-- only a function's has one param and type of is a string
-- you can use print "xxxx"
-- so you print x.f[1] will occuur error
-- in table you can use any lua internal type 's value to be a key
-- just like
local t_key = {v=123}
local f_key = function () print("f123") end
local t = {}
t[t_key] = 1
t[f_key] = 2
-- then t' key actualy like use t_key/f_key 's handle
-- when you user t[{}] = 123,
-- value 123 related to this no name table {} 's handle

Resources