lua basic how to loop? - lua

hi I'm kinda new in this scripting im trying to make automation script from macro app ios/android that using lua language called autotouch https://autotouch.net/server/doc/en.html#autotouch-document
i'm clueless where to start from scratch is there lua function like this?
searching for color in whole screen then tap it
the script is similar to this
loop
color = PixelSearch(x coord, y coord, #somergbColor codes)
If (color) is found in screen then
tap it
else
tap teleport skill/walk to search for target button
endif
endloop
end

The loop isn't too specific. You could do the inner actions in two 2 ways using findColor(color, count, region) provided by AutoTouch, or getColor(x, y) (essentialy faster in octet-size than getColors(locations) in my opinion, because of the return's value; but the problem is from the developers if they don't put a byte array API for handling lower and unsigned integers, of course).
findColor() is being limited to only find 1 pixel at max..
local target = 0x447111;
local location = findColor(target, 1);
local first = location[1];
if location and first then
touchDown(1, first[1], first[2]);
else
-- I don't understand this action?
end
So, if you want to find your color manually you can use getColor().
local target = 0x447111;
local w, h = getScreenResolution();
local broken = false;
for y = 1, h do
for x = 1, w do
local cur = getColor(x, y);
if cur == target then
broken = true;
break;
end
end
if broken then
break;
end
end
if broken then
touchDown(1, 1, 1);
end

Related

Drawing a Matrix

Im trying to generate a random map using a matrix but I dont really know how. Here is the
function for the matrix. wMap and hMap are the width and height, and mapSprites is a table containing some ground sprites. Also how can I draw the matrix? Im sorry if this is too much of a question, but Im really in need for some help
function buildMap(wMap, hMap)
for i = 1, wMap do
mt[i] = {}
for j = 1, hMap do
mt[i][j] = math.random(mapSprites)
end
end
end
Generating a random map in any programming language will utilize two core concepts: The language's random function and nested for loops, two for the case of a map/matrix/2d array.
The first problem, is you may or may not have mt initialized outside the function. This function assumes the variable exists outside of the function and each time the function is called it will overwrite mt (or initialize it for the first function call) with random values.
The second problem, the width, wMap, and height, hMap, of the map are in the wrong order, as maps/matrices/2d arrays first iterate over the height (y dimension) and then the width (x dimension).
The last problem, mapSpripes also has to be declared outside the function (which is not clear with your code snippet), which will be the highest possible value the random function can generate. You can read more about math.random here: http://lua-users.org/wiki/MathLibraryTutorial
Consider this function I wrote that makes those adjustments as well as has some additional variables for the minimum and maximum random value. Of course, you can remove these to have it fit your intended purposes.
function buildMap(wMap, hMap)
local minRand = 10
local maxRand = 20
for y = 1, hMap do
matrix[y] = {}
for x = 1, wMap do
matrix[y][x] = math.random(minRand, maxRand)
end
end
end
I suggest you use this function as inspiration for your future iteratins. You can make minRand and maxRand parameters or make matrix a returned value rather than manipulating an already declared matrix value outside of the function.
Best of luck!
EDIT:
Regarding your second question. Look back at the section I wrote about nested for loops. This will be crucial to "drawing" your map. I believe you have the building blocks to resolve this issue yourself as there isn't enough context provided about what "drawing" looks like. Here is a fundamentally similiar function, based on my previous function, on printing the map:
function printMap(matrix)
for i = 1, #matrix do
for j = 1, #matrix[i] do
io.write(matrix[i][j] .. " ")
end
io.write("\n")
end
end
For choosing random sprite, I recommend you to create a table of sprites and then save index of sprite in matrix. Then you can draw it in same loop, but now, you will iterate over matrix and draw sprite based on sprite index saved in matrix in position given by matrix position (x and y in loop) times size of sprite.
local sprites, mt = {}, {}
local spriteWidth, spriteHeight = 16, 16 -- Width and height of sprites
function buildMap(wMap, hMap)
mt = {}
for i = 1, wMap do
mt[i] = {}
for j = 1, hMap do
mt[i][j] = math.random(#sprites) -- We choose random sprite index (#sprites is length of sprites table)
end
end
end
function love.load()
sprites = {
love.graphics.newImage('sprite1.png'),
love.graphics.newImage('sprite2.png'),
-- ...
}
buildMap()
end
function love.draw()
for y, row in ipairs(mt) do
for x, spriteIndex in ipairs(row) do
-- x - 1, because we want to start at 0, 0, but lua table indexing starts at 1
love.graphics.draw(sprites[spriteIndex], (x - 1) * spriteWidth, (y - 1) * spriteHeight)
end
end
end

Lua move up (Y) 5 values from self?

I just wanted to instantly be 5 values up above my head from where I am in the world, but this code is also pushing me (X and Z) to another Same Remembered Location. do you see anything wrong with the code?
function Behavior:Awake()
local pos = self.gameObject.transform:GetLocalPosition()
self.posy = pos.y
if CS.Input.WasButtonJustPressed("sobe1") then
self.gameObject.transform:SetPosition( Vector3:New( self.posy + 5 ) )
your Behavior:Awake() function is being called, probably when you get out of bed, or whenever that event is triggered.
Those self.posx .posy & .posz values get stored in your character table, until you later access them from within your Behavior:Update() function.
You need to just call :getLocalPosition() at the moment you need those values. So try getting rid of the :Awake() portion, and combine those coordinates into your update vector routine.
function Behavior:Update()
if CS.Input.WasButtonJustPressed('sobe1') then
local pos = self.gameObject.transform:GetLocalPosition()
self.gameObject.transform:SetPosition( Vector3:New( pos.x, pos.y +4.78, pos.z ) )
end -- 'sobe1'
end -- Update()

Getting data from a table

Using Tiled I generated a Lua file which contains a table. So I figured that I'd write a for loop which cycles through the table gets the tile id and checks if collision is true and add collision if it was. But, I've been unable to get the tile id's or check they're properties. But it returned a error saying that I tried to index nil value tileData.
Here is the Map file
return {
version = "1.1",
luaversion = "5.1",
-- more misc. data
tilesets = {
{
name = "Tileset1",
firstgid = 1,
tilewidth = 16,
tileheight = 16,
tiles = {
{
id = 0,
properties = {
["Collision"] = false
}
},
}
}
layers = {
{
type = "tilelayer",
name = "Tile Layer 1"
data = {
-- array of tile id's
}
}
}
}
And here is the for loop I wrote to cycle through the table
require("Protyping")
local map = love.filesystem.load("Protyping.lua")()
local tileset1 = map.tilesets
local tileData = tileset1.tiles
local colision_layer = map.layers[1].data
for y=1,16 do
for x=1,16 do
if tileData[colision_layer[x*y]].properties["Colision"] == true then
world:add("collider "..x*y,x*map.tilewidth, y*tileheight,tilewidth,tileheight)
end
end
end
Try this:
tileset1 = map.tilesets[1]
instead of
tileset1 = map.tilesets
lhf's answer (map.tilesets[1] instead of map.tilesets) fixes the error you were getting, but there are at least two other things you'll need to fix for your code to work.
The first is consistent spelling: you have a Collision property in your map data and a Colision check in your code.
The second thing you'll need to fix is the way that the individual tiles are being referenced. Tiled's layer data is made of 2-dimensional tile data laid out in a 1-dimensional array from left-to-right, starting at the top, so the index numbers look like this:
You would think you could just do x * y to get the index, but if you look closely, you'll see that this doesn't work. Instead, you have to do x + (y - 1) * width.
Or if you use zero-based x and y, it looks like this:
Personally, I prefer 0-based x and y (but as I get more comfortable with Lua, that may change, as Lua has 1-based arrays). If you do go with 0-based x and y, then the formula is x + 1 + y * width.
I happen to have just written a tutorial this morning that goes over the Tiled format and has some helper functions that do exactly this (using the 0-based formula). You may find it helpful: https://github.com/prust/sti-pg-example.
The tutorial uses Simple Tiled Implementation, which is a very nice library for working with Tiled lua files. Since you're trying to do collision, I should mention that STI has a plugins for both the bump collision library and the box2d (physics) collision library.

Change position on Y axis based on distance

I've been trying to make a game where you're in a square and when you go to the sides, parts come up and block you.
I've gotten far to the point where it's working fine, except for a few problems:
the parts go below the square when not raised, I want them to be visible when they're not raised
the parts go down when you jump, making it easy to escape.
the parts go up too early
This is the code that deals with the wall positioning.
for _, v in pairs(model:GetChildren()) do
if string.sub(v.Name,1,4) == "Wall" then
local walls = {}
walls[v] = {v.CFrame,Vector3.new(1, 1, 1)}
game:GetService("RunService").RenderStepped:connect(function()
if(workspace[game.Players.LocalPlayer.Name]:FindFirstChild("HumanoidRootPart")) then
local mag = (v.Position - workspace[game.Players.LocalPlayer.Name]:FindFirstChild("HumanoidRootPart").Position).magnitude
sizeFactor = math.floor(mag)
v.CFrame = walls[v][1]*CFrame.new(0,-sizeFactor+(walls[v][1].Y*1.8),0)
end
end)
end
end
You can see my game here: https://www.roblox.com/games/400391033/Marble-walls
See commented code.
for _, v in pairs(model:GetChildren()) do
if string.sub(v.Name,1,4) == "Wall" then
local walls = {}
walls[v] = {v.CFrame,Vector3.new(1, 1, 1)}
game:GetService("RunService").RenderStepped:connect(function()
if(workspace[game.Players.LocalPlayer.Name]:FindFirstChild("HumanoidRootPart")) then
local mag = (v.Position - workspace[game.Players.LocalPlayer.Name]:FindFirstChild("HumanoidRootPart").Position).magnitude
if (mag <= 2) then --[[
Currently your issue is that you never actually do ANYTHING regarding magnitude
you essentially change the y-Axis as soon as the player spawns.. hence why it does it too early
kappa
]]
sizeFactor = math.floor(mag)
v.CFrame = walls[v][1]*CFrame.new(0,-sizeFactor+(walls[v][1].Y*1.8),0)
end;
end
end)
end
end

Corona SDK adding physics bodies/ not accepting collisions

I am attempting to add/remove objects from the physics engine (addBody() and removeBody()) in an app I am working on. The app I am working on is modular so the issue is in one of two files.
The objects file (TransmitterObject) or the main file (main):
This is the relevant code for both:
main.lua
local physics = require("physics")
physics.start()
physics.setGravity(0,0)
physics.setDrawMode( "debug" )
local TransmitterObject = require("TransmitterObject")
function updateGame(event)
if(ITERATIONS % 100 == 0) then
tran1:activate() --create new physics object here
end
ITERATIONS = ITERATIONS + 1
--print(ITERATIONS)
end
Runtime:addEventListener("enterFrame", updateGame)
TransmitterObject.lua
function transmitter.new(props) --constructor
Transmitter =
{
x = props.x,
y = props.y,
receivers = props.receivers
}
return setmetatable( Transmitter, transmitter_mt )
end
function transmitter:activate()
local group = math.random(1, #self.receivers)
local receiver = math.random(1,#self.receivers[group])
local x , y = self.receivers[group][receiver][1], self.receivers[group][receiver][2]
local d = math.sqrt(math.pow((self.x-x),2) + math.pow((self.y-y),2))
local dx = math.abs(self.x - x)
local angle = math.deg(math.acos(dx/d))
local beam = display.newRect(self.x,self.y, d, 10)
beam:setReferencePoint(display.TopLeftReferencePoint)
beam.rotation = 180 + angle
beam:setFillColor(0,255,0)
beam.alpha = 0
local function add(event)
physics.addBody(beam, "static")
end
local function delete(event)
physics.removeBody(beam)
end
transition.to( beam, { time=1000, alpha=1.0, onComplete=add } )
transition.to( beam, { time=1000, delay=2500, alpha=0, onComplete=delete})
end
Now let me try to describe the issue a little better. basically every 100th time that 'enterFrame' fires I tell the transmitter object (tran1) to call its function 'activate'
which then preforms some basic math to get coordinates. Then it creates a rectangle (beam) using the calculated information and sets some properties. That is all basic stuff. Next I tell it to transition from not visible (alpha = 0) to visible over the span of 1 second. When does it is to call the function 'add' which adds the object to the physics engine. Likewise with the next line where it removes the objects.
That being said, when i set physics.setDrawMode( "debug" ) the beam object appears as a static body, but does not accept collisions. Does anyone know why the above code would not accept collisions for the beam object?
Keep in mind I have other objects that do work properly within the physics engine.
Wow, I'm answering super late!
On collisions, modifying bodies aren't supported.
What I propose you is to create a new function,
local function addBody ( event )
physics.addBody(ball, "static")
end
and in your collision event you have to add this,
timer.performWithDelay(500, addBody)
The only thing that may cause some problems it's the delay, but as the collision doesn't take too much time it should be ok.
Sorry for this necroposting,
It's just to help other people that may have that problem,
Fannick

Resources