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

Need help with open peripherals program

Started by flup52, 30 November 2013 - 05:07 PM
flup52 #1
Posted 30 November 2013 - 06:07 PM
Hi everyone
I have written a program which is for use terminal glasses to show ingame time.
All works fine exept of one thing: I'm not able to return the chat_command at the end of the program to change format or exit.

Please help!

Sorry for bad english ;)/>


glass = peripheral.wrap("right")
glass.clear()
timeFormat = true
function sleeping()
  while true do
	event, command = os.pullEvent("chat_command")
	if command == "start" then
	  break
	end
  end
end

function openAnimation()
  Xsize = 0
  Ysize = 3
  while Xsize < 100 or Ysize < 45 do
	glass.clear()
	glass.addBox(6, 6, Xsize, Ysize, 0xFFFFFF, 0.5)
	if Xsize < 100 then
	  Xsize = Xsize + 10
	elseif Ysize < 100 then
	  Ysize = Ysize + 10
	end
	sleep(0.01)
  end
  glass.clear()
end
function backGround()
  backgroundbox = glass.addBox(6, 6, 100, 45, 0xFFFFFF, 0.5)
end
function showTime(format)
  clockWidth = 74
  while true do
	glass.clear()
	backGround()
	clock = textutils.formatTime(os.time(), format)
	day = os.day()
	dayText = glass.addText(8, 8, "Day: "..day, 0x3366FF)
	dayText.setZIndex(2)
	clockText = glass.addText((56 - clockWidth / 2), 20, clock, 0x33CCFF)
	clockText.setScale(3)
	clockWidth = clockText.getWidth()
	clockText.setZIndex(2)
	sleep(0.1)
	os.queueEvent("event_marker")
	local breakOut = false
	while true do
	  e, command2 = os.pullEvent()
	  if e == "chat_command" then
		breakOut = true
	  elseif e == "event_marker" then
		break
	  end
	end
	if breakOut == true then
	  break
	end
  end
  return command2
end
sleeping()
openAnimation()
backGround()
sleep(0.3)
while true do
  command2 = showTime(timeFormat)
  if command2 == "format" then
	if timeFormat == true then
	  timeFormat = false
	else
	  timeFormat = true
	end
  elseif command2 == "exit" then
	break
  end
end
theoriginalbit #2
Posted 30 November 2013 - 08:34 PM
ok so there is a design problem that is causing your problem. and that is the use of multiple loops and yielding. You could easily shrink these into one. Chances are, the reason you are missing the event is because it is being consumed by that the sleep of 0.1 in your time loop.

Also avoid using the clear method on the bridge and then redrawing everything again, it can cause flicker. Calling each of the add methods actually returns a table of more methods that you can use to modify the element.

Here is an example for some code you could do. Some of the code may not be exactly how you want it, but it is an example, not me giving you code.

--# wrap and clear the glasses bridge
local bridge = peripheral.wrap('right')
bridge.clear()

--# add the boxes and text objects
local  backgroundBox = bridge.addBox(6, 6, 5, 5, 0xFFFFFF, 0.5) --# this is the small size before the animation
local timeText = bridge.addText(10, 10, '', 0x33CCFF) --# have it empty so we can animate first

--# animate the box larger
local function introAnimation()
  for i = 10, 100, 10 do --# run 10 loops, incrementing by 10 each time
    backgroundBox.setWidth(i)
    backgroundBox.setHeight(i)
  end
end

local function refreshTime()
  timeText.setText( textutils.formatTime(os.time(), false) )
end

--# this is a timer that will fire after 0.7 seconds, we will use it to know when to refresh the time
local timeRefresh = os.startTimer(0.7)

introAnimation()
while true do
  --# wait for an event and store the contents of it in a table
  local event = { os.pullEvent() }

  --# check if a timer finished, and if it was our timer
  if event[1] == "timer" and event[2] == timeRefresh then
    refreshTime()
    timeRefresh = os.startTimer(0.7) --# restart the timer, since it just finished

  --# check if it was a chat command that was sent through
  elseif event[1] == "chat_command" then

    --# lower the command they sent and then check what it was
    if event[2]:lower() == "exit" then
      break
    end
  end
end

bridge.clear()

I hope the above code makes sense, if you have any questions, feel free to ask.
flup52 #3
Posted 01 December 2013 - 04:25 AM
Thank you very much for the fast reply.
I edited my program like you recommended and it works!

Here's the code:

local glass = peripheral.wrap("right")
glass.clear()
local timeFormat = true
local clockWidth = 74
local function sleeping()
  while true do
    event, command = os.pullEvent("chat_command")
    if command == "start" then
	  break
    end
  end
end

local function openAnimation()
  local Xsize = 0
  local Ysize = 3
  for i = 10, 180, 10 do
    glass.clear()
    glass.addBox(6, 6, Xsize, Ysize, 0xFFFFFF, 0.5)
    if Xsize < 130 then
	  Xsize = Xsize + 10
    elseif Ysize < 50 then
	  Ysize = Ysize + 10
    end
    sleep(0.01)
  end
  glass.clear()
end
local function exitAnimation()
  local Xsize = 130
  local Ysize = 50
  for i = 10, 180, 10 do
    glass.clear()
    glass.addBox(6, 6, Xsize, Ysize, 0xFFFFFF, 0.5)
    if Ysize >= 13 then
	  Ysize = Ysize - 10
    elseif Xsize >= 10 then
	  Xsize = Xsize - 10
    end
    sleep(0.01)
  end
  glass.clear()
end
	 
local function backGround()
  local backgroundbox = glass.addBox(6, 6, 130, 50, 0xFFFFFF, 0.5)
end
local function showTime(format)
  glass.clear()
  backGround()
  local clock = textutils.formatTime(os.time(), format)
  local day = os.day()
  local dayText = glass.addText(8, 8, "Day: "..day, 0x3366FF)
  dayText.setZIndex(2)
  local clockText = glass.addText((71 - clockWidth / 2), 20, clock, 0x33CCFF)
  clockText.setScale(3)
  clockWidth = clockText.getWidth()
  clockText.setZIndex(2)
  local helpText1 = glass.addText(8, 45, "Change time format: $$format", 0x66FFFF)
  local helpText2 = glass.addText(8, 50, "Exit: $$exit", 0x66FFFF)
  helpText1.setScale(0.5)
  helpText1.setZIndex(2)
  helpText2.setScale(0.5)
  helpText2.setZIndex(2)
end
while true do
  sleeping()
  openAnimation()
  backGround()
  sleep(0.3)
  local timeRefresh = os.startTimer(0.7)
  while true do
    local event = { os.pullEvent() }
    if event[1] == "timer" and event[2] == timeRefresh then
	  showTime(timeFormat)
	  timeRefresh = os.startTimer(0.7)
    elseif event[1] == "chat_command" then
	  if event[2]:lower() == "format" then
	    if timeFormat == true then
		  timeFormat = false
	    else
		  timeFormat = true
	    end
	  elseif event[2]:lower() == "exit" then
	    break
	  end
    end 
  end
  exitAnimation()
  glass.clear()
end

Do with it whatever you want.