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

Announcer with Scrolling&Changing Text

Started by TheTiceisRight, 31 May 2015 - 06:40 PM
TheTiceisRight #1
Posted 31 May 2015 - 08:40 PM
So I picked up a sort of "dead" project of mine and started working on it again… this time with mods… Its basically just a "for-looks" subway system, and I've been using computer craft for displays that show things such as train "destination". What I wanted to do is have a screen inside the train that would display text like "This station is blahblahblah" for a little bit, then change to another piece of text after a while. So it would end up going "This station is a." (a few moments later) "The next station is b." (later…) "This station is b." etc. I already have a code that just loops one piece of text:

m = peripheral.wrap("monitor_0")
mn = peripheral.wrap("monitor_1")
pos = 14
ps = 14
m.clear()
mn.clear()
m.setTextScale(1.5)
mn.setTextScale(1.5)
while true do
  if pos==-130 then
   pos = 14
  end
  if ps==-130 then
   ps = 14
  end

  m.clear()
  mn.clear()
  m.setCursorPos(pos,3)
  mn.setCursorPos(ps,3)
  m.write("This is Block Hill Road. Change for the Northern Line and District Link. This is a Circle Line Train to Bankside (via Iron Hill).")
  pos = pos-1
  mn.write("This is Block Hill Road. Change for the Northern Line and District Link. This is a Circle Line Train to Bankside (via Iron Hill).")
  ps = ps-1
  sleep(0.15)
end
(Looping it on two monitors, with scrolling text)
If there is a way to expand on this to fit what I'm trying to do that would be nice. -Tice
Bomb Bloke #2
Posted 01 June 2015 - 12:54 AM
Let's say we had a table with some strings in it:

local myString = {
	"This is Block Hill Road. Change for the Northern Line and District Link. This is a Circle Line Train to Bankside (via Iron Hill).",
	"This is Iron Hill. Some other station's coming up next.",
	"This is some other station. Bomb Bloke doesn't have much of an imagination for placenames."
}

We can then refer to these strings as myString[1], myString[2], etc, meaning a simple counter variable can be used to switch between them. Eg, have your monitors draw whatever myString[counter] is, and just change the value of "counter" whenever it's appropriate to do so.

To determine when to switch, I suppose it'd be easiest to wait for a redstone signal along the track; but I've no idea if that's possible with whatever sort of train you're using…?
TheTiceisRight #3
Posted 02 June 2015 - 02:23 AM
Wrote a little script for the thing… it works decently well…

m = peripheral.wrap("back")
pos = 20
num = 1
dest = {
  "This is Bank, Change for District Link Services. This is a Circle Line train to Bankside (via Town Hall & Block Hill Road)",
  "The next station is Cannon Street.",
  "This is Cannon Street. This is a Circle Line train to Bankside (via Town Hall & Block Hill Road)",
  "The next station is Sloane Square.",
  "This is Sloane Square. This is a Circle Line train to Bankside (via Town Hall & Block Hill Road)",
  "The next station is closed. This train will not stop at Blackfriars.",
  "The next station is Town Hall.",
  "This is Town Hall, Change for the Piccadilly Line. This is a Circle Line train to Bankside (via Block Hill Road)",
  "This is Block Hill Road, Change for the Northern Line and District Link. This is a Circle Line train to Bankside (via Iron Hill)"
}
m.clear()
m.setTextScale(1.5)
while true do
  if pos==-125 and num==1 then
   pos = 20
  end
  if pos==-35 and num==2 then
   pos = 20
  end
  if pos==-100 and num==3 then
   pos = 20
  end
  if pos==-35 and num==4 then
   pos = 20
  end
  if pos==-100 and num==5 then
   pos = 20
  end
  if pos==-70 and num==6 then
   pos = 20
  end
  if pos==-35 and num==7 then
   pos = 20
  end
  if pos==-120 and num==8 then
   pos = 20
  end
  if pos==-130 and num==9 then
   pos = 20
  end
  if num==10 then
   num = 1
  end
  if rs.getInput("left") then
   num = num+1
   pos = 20
  else
   num = num
  end

  m.clear()
  m.setCursorPos(pos,3)
  m.write(dest[num])
  pos = pos-1
  sleep(0.15)
end
There's a lot of "if and" statements for the scrolling part… I also took a quick video of the train and other things…
https://youtu.be/wJm-Kv47Yeo
Bomb Bloke #4
Posted 02 June 2015 - 02:37 AM
If you stick a hash symbol (#) in front of a given object, you can get its length - for example, #dest[1] is 122, the number of characters in the string, whereas #dest gives you 9, the number of indexes in your table.

This means you could just do something like:

if pos == -(#dest[num] + 3) then pos = 20 end

You'll probably also want to perform your "if num==10 then" check immediately after you increment num, as opposed to how you're doing it now - immediately before. And better again, make it a "if num > #dest then" check!
TheTiceisRight #5
Posted 07 June 2015 - 10:13 PM
And I've gotten the code to this point and it seems to be working fine… except for a few things…

m = peripheral.wrap("back")
pos = 20
num = 1
dest = {
  "This is Embankment. Change for other Circle Line Services in the direction of Bankside & Iron Road. This is a Inner Rail Circle Line train to Bankside (via Town Hall & Block Hill Road)",
  "This is Bank, Change for District Link Services. This is a Circle Line train to Bankside (via Town Hall & Block Hill Road)",
  "The next station is Cannon Street.",
  "This is Cannon Street. This is a Circle Line train to Bankside (via Town Hall & Block Hill Road)",
  "The next station is Sloane Square.",
  "This is Sloane Square. This is a Circle Line train to Bankside (via Town Hall & Block Hill Road)",
  "The next station is closed. This train will not stop at Blackfriars.",
  "The next station is Town Hall.",
  "This is Town Hall, Change for the Piccadilly Line. This is a Circle Line train to Bankside (via Block Hill Road)",
  "This is Block Hill Road, Change for the Northern Line and District Link. This is a Circle Line train to Bankside (via Iron Hill)"
}
m.clear()
m.setTextScale(1.5)
while true do
  if pos==-(#dest[num] + 1) then
   pos = 20
  end
  if rs.getInput("left") then
   num = num+1
   pos = 20
  else
   num = num
  end
  if num==11 then
   num = 1
  end
  m.clear()
  m.setCursorPos(pos,3)
  m.write(dest[num])
  pos = pos-1
  sleep(0.15)
end
It displays the text, scrolls it, and changes… that's where the issue then comes up. Before (when I had 4,000 "if" statements) I could just press a button and it would cycle it to the next piece of text in the list… but now that its in a different order and different code it somehow cycles all the way through to the one it was one, from the first announcement back to the first announcement. (Whilst typing has sudden realization) And I just remembered that I had also added in an extra announcement to the list… I think it would cycle the value "num" 10 times… (1 greater than the original 9 announcements…) so it would… *slams face into desk* So how can I get it to just change once and not cycle through the whole list? some simple thing I'm overlooking probably…
Bomb Bloke #6
Posted 08 June 2015 - 12:31 AM
One way around it is to throw in another variable, to hold a boolean. We set it when we first detect a redstone signal, and unset it when the signal goes away. We only increment num if it's unset.

Eg, we'd change this:

  if rs.getInput("left") then
   num = num+1
   pos = 20
  else
   num = num
  end

… to this:

  if rs.getInput("left") and not incremented then
   num = num+1
   pos = 20
  end
  incremented = rs.getInput("left")
Edited on 07 June 2015 - 10:33 PM