This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
Nawiks's profile picture

Save coordinates in a table

Started by Nawiks, 05 April 2016 - 05:40 PM
Nawiks #1
Posted 05 April 2016 - 07:40 PM
Hello, i'm french with bah english :/
I want to save coordinates in a table when the player click on a monitor. When he click the pixel become red and after 2 seconds it become blue.
My code :


tactile = {}
pixel = 1
while true do
event, side, xpos, ypos = os.pullEvent("monitor_touch")

paintutils.drawPixel(xpos, ypos, colors.red)
    tactile[pixel] = {}
    tactile[pixel][1] = xpos
    tactile[pixel][2] = ypos
    pixel = pixel + 1
 
   sleep(2)
   X = tactile[pixel][1]
   Y = tactile[pixel][2]
   paintutils.drawPixel(X,Y, colors.blue)
end


But with this code the pixel become red but after not blue….
Thanks for your help ! :)/>
moTechPlz #2
Posted 05 April 2016 - 07:53 PM
You increase your index variable 'pixel' by one before trying to read the data back into 'X' and 'Y'.
Edited on 05 April 2016 - 05:55 PM
Nawiks #3
Posted 05 April 2016 - 10:33 PM
Sorry i failed when i write but with changes it is the same thing, the pixel become red but after not blue…


tactile = {}
pixel = 1
while true do
event, side, xpos, ypos = os.pullEvent("monitor_touch")
paintutils.drawPixel(xpos, ypos, colors.red)
    tactile[pixel] = {}
    tactile[pixel][1] = xpos
    tactile[pixel][2] = ypos
    pixel = pixel + 1

   sleep(2)
   X = tactile[1l][1]
   Y = tactile[1][2]
   paintutils.drawPixel(X,Y, colors.blue)
end
Bomb Bloke #4
Posted 06 April 2016 - 01:31 AM
Looks like you meant to do:

tactile = {}
pixel = 1
while true do
    event, side, xpos, ypos = os.pullEvent("monitor_touch")

    paintutils.drawPixel(xpos, ypos, colors.red)
    sleep(2)
    paintutils.drawPixel(xpos, ypos, colors.blue)

    tactile[pixel] = {xpos, ypos}
    pixel = pixel + 1
end

Another way to write it, using os.startTimer() instead of sleep() (so that you can keep clicking while waiting for pixels to change colour):

term.redirect(peripheral.find("monitor"))

local tactile = {}

while true do
	local myEvent = {os.pullEvent()}
	
	if myEvent[1] == "monitor_touch" then
		paintutils.drawPixel(myEvent[3], myEvent[4], colors.red)
		
		tactile[#tactile + 1] = {myEvent[3], myEvent[4], os.startTimer(2)}  --# Add to end of table

	elseif myEvent[1] == "timer" and myEvent[2] == tactile[1][3] then  --# If timer event for entry at front of table
		paintutils.drawPixel(tactile[1][1], tactile[1][2], colors.blue)
		
		table.remove(tactile, 1)  --# Remove entry at front of table (moving the next entry to the front)
	
	end
end
KingofGamesYami #5
Posted 06 April 2016 - 01:42 AM
I would improve on BB's code by using the unique timer ID as the reference.


term.redirect(peripheral.find("monitor"))

local tactile = {}

while true do
        local myEvent = {os.pullEvent()}

        if myEvent[1] == "monitor_touch" then
                paintutils.drawPixel(myEvent[3], myEvent[4], colors.red)

                tactile[ os.startTimer( 2 ) ] = {myEvent[3], myEvent[4]}  --# Add to table

        elseif myEvent[1] == "timer" and tactile[ myEvent[2] ] then  --# If timer event occurred
                paintutils.drawPixel(tactile[ myEvent[ 2 ] ][1], tactile[ myEvent[ 2 ] ][2], colors.blue)

                tactile[ myEvent[ 2 ] ] = nil --# Remove entry
        end
end
Edited on 06 April 2016 - 05:29 PM
Lyqyd #6
Posted 06 April 2016 - 05:23 AM
Your code would need to nil the index, not call table.remove.
Nawiks #7
Posted 06 April 2016 - 02:57 PM
Thanks you ! :D/>
Nawiks #8
Posted 06 April 2016 - 06:37 PM
Now I have another problem…. I save coordinates in a table when i click, and if I click in the same coordinates the old coordinates are deleted of the table :


term.redirect(peripheral.wrap("right"))
local coordinatesPixel = {}
while true do
local myEvent = {os.pullEvent()}
function deleteCoordinates(x,y)
for k, value in pairs(coordinatesPixel ) do
		if coordinatesPixel [k][1] == x and coordinatesPixel [k][2] == y then
			table.remove(coordinatesPixel , k)
		end
	  end
end

if myEvent[1] == "monitor_touch" then
deleteCoordinates(myEvent[3],myEvent[4])
paintutils.drawPixel(myEvent[3], myEvent[4], colors.red)
coordinatesPixel [#coordinatesPixel + 1] = {myEvent[3], myEvent[4]}
end

end

WIth this code when i click on my monitor the pixel become red, and when i click on the same pixel I receive this error :
"Interface:6: Invalid key to 'next'" This error is for the line 6 : "for k, value in pairs(coordinatesPixel ) do"
Coordonates are save well because this error appears only if I click on the already red pixel not for other pixel not red.

Can you help me please ? :/
Edited on 06 April 2016 - 04:40 PM
Dragon53535 #9
Posted 06 April 2016 - 07:15 PM
Like lyqyd said, you need to nil the index.

replace

table.remove(coordinatesPixel , k)
with

coordinatesPixel[k] = nil
The reason for this is that when you use table.remove shifts the consecutive indexes down which would cause your loop to try to grab an index that isn't there anymore.


local tbl = {1,2,3,4,5}
--#In this, 1 is at 1, 2 is at 2, etc
table.remove(tbl,3)
--#tbl is now {1,2,4,5} so now 4 is at 3, and 5 is at 4.
If you were to loop through this table, and run table.remove as you do up above, it might try to look for something at index 5, which no longer exists, and error because it couldn't find anything.


Edit: I might be entirely wrong, and you would instead have to save what changes you want to make and do those when you're not looping through the table.
Edited on 06 April 2016 - 05:16 PM
Nawiks #10
Posted 06 April 2016 - 09:29 PM
Yes but with :


coordinatesPixel[k] = nil

I have the same error :/

Sorry i didn't see your edit, but i don't understand what I have to make :/
Dragon53535 #11
Posted 06 April 2016 - 09:53 PM
Oh, and take your function out of the while true loop


function deleteCoordinates(x,y)
  local key = ""
  for k, value in pairs(coordinatesPixel ) do
	   if coordinatesPixel [k][1] == x and coordinatesPixel [k][2] == y then
		  key = k --#Since we're going to delete this pixel coordinate we need to know what key to delete
		  break --#Since we're only deleting one coordinate, we have found it at this point, it's pointless to continue this loop
		  --#break will leave the loop entirely
	   end
  end
  if (key ~= "") then --#Making sure that we actually found the key
	coordinatesPixel[key] = nil
  end
end

Edit: adding an explanation about what I'm doing

Edit2: You're just deleting one thing actually, let me revise this.
Edited on 06 April 2016 - 08:05 PM
Nawiks #12
Posted 06 April 2016 - 10:57 PM
Thanks you ! :D/>