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

help with modifying scrolling news board program

Started by JamiePhonic, 29 September 2012 - 08:07 PM
JamiePhonic #1
Posted 29 September 2012 - 10:07 PM
i found a forum post with the code to make a scrolling news board, it looks like this: (sort of)

+—————-+
|news| <== centred
+—————-+
this bit scrolls|t <==loops
+—————-+

thats it really, what i want to do is modify this to show more than one line of scrolling test so that i can make it into more of a to-do list type thing, e.g.

+—————-+
|news| <== centred
+—————-+
this bit scrolls|t <==loops
+—————-+
so dose this|so <==loops
+—————-+
and this|and th <==loops
+—————-+

(copy paste job)

here is the code for it…
Spoiler

mon = peripheral.wrap("left")
function lineBreak()
	x, y = mon.getCursorPos()
	if y ~= 1 then
			y = y + 1
	end
	mon.setCursorPos(1, y)
	width, height = mon.getSize()
	mon.write("+" .. string.rep("-", width - 2) .. "+")
end
function printString(sString)
	x, y = mon.getCursorPos()
	y = y + 1
	mon.setCursorPos(1, y)
	mon.write(sString)
end
function printStringCentre(sString)
	x, y = mon.getCursorPos()
	y = y + 1
	mon.setCursorPos(1, y)
	width, height = mon.getSize()
	nStringCentre = math.floor(string.len(sString) / 2)
	nMonitorCentre = math.floor(width / 2)
	x = math.floor(nMonitorCentre - nStringCentre)
	mon.setCursorPos(x, y)
	mon.write(sString)
end
function printStringRight(sString)
width, height = mon.getSize()
x, y = mon.getCursorPos()
y = y + 1
x = math.ceil(width - string.len(sString))
mon.setCursorPos(x, y)
mon.write(sString)
end
function scrollText(tStrings, nRate)
nRate = nRate or 5
if nRate < 0 then
  error("rate must be positive")
end
local nSleep = 1 / nRate
width, height = mon.getSize()
x, y = mon.getCursorPos()
	sText = ""
	for n = 1, #tStrings do
			sText = sText .. tostring(tStrings[n])
  sText = sText .. " | "
	end
	sString = "| "
	if width / string.len(sText) < 1 then
			nStringRepeat = 3
	else
			nStringRepeat = math.ceil(width / string.len(sText) * 3)
	end
for n = 1, nStringRepeat do
  sString = sString .. sText
end
while true do
  for n = 1, string.len(sText) do
   sDisplay = string.sub(sString, n, n + width - 1)
   mon.clearLine()
   mon.setCursorPos(1, y)
   mon.write(sDisplay)
   sleep(nSleep)
  end
end
end
mon.clear()
mon.setCursorPos(1, 1)
lineBreak()
printStringCentre("|To Do List|")
lineBreak()
printString("")
lineBreak()
tScrollText = {}
tScrollText[1] = "BREAKING NEWS"
tScrollText[2] = "Giant cookies falling from sky"
x, y = mon.getCursorPos()
y = y - 1
mon.setCursorPos(1, y)
scrollText(tScrollText)
jag #2
Posted 29 September 2012 - 10:18 PM
When I run it, I'm getting the error
scrollingText:68: attempt to index ? (a nil value)
And on line 68 you are running
mon.clear()

EDIT: Never mind, I didn't got a monitor left to the computer. Derp
jag #3
Posted 29 September 2012 - 10:32 PM
Spoiler
I guess that your problem is that you can't have multiply scrolling texts..
Pharap #4
Posted 30 September 2012 - 02:33 AM
Do you want them to scroll vertically or horizontally? (eg end credit style or scrolling strip style)

Either way I can probably chuck something together and make it clear how everything works.
JamiePhonic #5
Posted 30 September 2012 - 09:16 PM
Do you want them to scroll vertically or horizontally? (eg end credit style or scrolling strip style)

Either way I can probably chuck something together and make it clear how everything works.

just the way it is in the code i posted. (horizontal, like you see on news programs and such)
its for a to-do list so that i can use 1 line per "thing" and have it scroll, thus saving space on my monitors ill post pics of why if needed.

not meaning to burden you, but could you do both? the credit style would be perfect for a "wall of contributors" type thing im planning.
JamiePhonic #6
Posted 03 October 2012 - 07:23 PM
bump
Pharap #7
Posted 05 October 2012 - 04:29 AM
Sorry for the slow reply, things have been busy lately.
I started work on it, but the only solution I have at the minute is one that, while you might understand how to implement it, you may not understand how it works.
Is that ok?

I can always work on a simplified one afterwards, but college work does beckon.
JamiePhonic #8
Posted 05 October 2012 - 10:23 PM
Sorry for the slow reply, things have been busy lately.
I started work on it, but the only solution I have at the minute is one that, while you might understand how to implement it, you may not understand how it works.
Is that ok?

thats not a problem. just stick a comments in where i've to put the text. i may be able to suss out how it works. i do a fair amount of VB (i know VB is nothing like lua, but its the principles (loops, if's and so on) that are part of every programming language) so i should be able to work it out


but college work does beckon.

tell me about it….
jag #9
Posted 06 October 2012 - 07:46 PM
What you could do is just remove any while loops, and then at the end you do the while loop.
And so you got something like this:
mon.clear()
mon.setCursorPos(1, 1)
lineBreak()
printStringCentre("|To Do List|")
lineBreak()
printString("")
lineBreak()
printString("")
lineBreak()
printString("")
lineBreak()

while true do
  mon.setCursorPos(1,4)
  scrollText(tScrollTextOne)
  mon.setCursorPos(1, 6)
  scrollText(tScrollTextTwo)
  mon.setCursorPos(1, 8)
  scrollText(tScrollTextThree)
end
Pharap #10
Posted 07 October 2012 - 09:45 PM
thats not a problem. just stick a comments in where i've to put the text. i may be able to suss out how it works. i do a fair amount of VB (i know VB is nothing like lua, but its the principles (loops, if's and so on) that are part of every programming language) so i should be able to work it out

tell me about it….

VB isn't the best language to start off on, but it's the one I started on so I can respect it.
I recommend moving to C# after you feel that you've got a firm grasp of the concepts.

anyway, for the lua stuff, this is the best I could whip up during my break from my other projects:

textscrolling = function()
local obj ={}
obj.front = {}
obj.text = {}
obj.text.add = function(text)
obj.text[table.maxn(obj.text)+1] = text
obj.front[table.maxn(obj.front)+1] = 1
end
obj.write = function()
for cnt = 1, table.maxn(obj.text) do
local w,h = term.getSize()
if (obj.front[cnt]-1 < -string.len(obj.text[cnt])) then obj.front[cnt] = w end
obj.front[cnt] = obj.front[cnt] - 1
term.setCursorPos(obj.front[cnt],cnt)
term.write(obj.text[cnt])
--if (obj.front[cnt]+1==w) then obj.front[cnt] = 1 else obj.front[cnt] = obj.front[cnt] + 1 end
--term.write(string.sub(string.rep(obj.text[cnt],2),obj.front[cnt],string.len(obj.text[cnt])))
--if (obj.front[cnt]+1==string.len(obj.text[cnt])) then obj.front[cnt] = 1 else obj.front[cnt] = obj.front[cnt] + 1 end
end
end
return obj
end
local var = textscrolling()
var.text.add("Item 1 - Go and collect some fruit")
var.text.add("Item 2 - Go and collect some more fruit")
var.text.add("Item 3 - Find diamond :D/>/>")
while true do
term.clear()
var.write()
sleep(0.2)
end

1-assign a variable with textscrolling(), for example : local var = textscrolling()
2-add your lines of text with var.text.add("your text goes here")
3-call var.write() in a loop with a delay added to avoid the no-yielding problem with loops

This variation will scroll text all across the screen and the lines will become desynchronised;
If you want them synchronised, I can make it do that, but each scroll may take a bit longer;
I could also centre the items, but again, pressed for time, it's already late and I do have other projects to get back to;
I hope this is what you want, if you want something better, I'd need more time or you'd have to get one of the others around here to do it if you're particularly pressed for time.
eventually I may turn this into an API, but for now, since there is only one person wanting it, a one-off program will suffice.
JamiePhonic #11
Posted 08 October 2012 - 07:42 PM
1-assign a variable with textscrolling(), for example : local var = textscrolling()
2-add your lines of text with var.text.add("your text goes here")
3-call var.write() in a loop with a delay added to avoid the no-yielding problem with loops

is this an explanation or instructions?
the program gives an "attempted to index ? (a nil value)" on line 29 (f.write)
Pharap #12
Posted 13 October 2012 - 04:28 AM
1-assign a variable with textscrolling(), for example : local var = textscrolling()
2-add your lines of text with var.text.add("your text goes here")
3-call var.write() in a loop with a delay added to avoid the no-yielding problem with loops

is this an explanation or instructions?
the program gives an "attempted to index ? (a nil value)" on line 29 (f.write)

Sorry, f is supposed to be var. I started using f as the variable name for quickness but changed it to var to make it more reabable.
And yes, those are instructions on how to use it.

Don't worry about what's going on inside the function, just know that this will work up to as many lines as the computer/monitor can take.
JamiePhonic #13
Posted 04 November 2012 - 07:23 AM
is there any chance you could make a credits style one? i'm planning a "wall of contributers" thing for my server.
Pharap #14
Posted 04 November 2012 - 03:07 PM

local contributors ={}
local maxw,maxh=term.getSize()
local offset=0
while true
term.clear()
   for cnt = 1,maxh do
   print(contributors[cnt+offset])
   end
sleep(0.5)
   if(offset+1<(#contributors-maxh))
   then offset=offset+1
   else offset=0
   end
end

Best I could knock together in 5 minutes.
Just be sure to add names to the contributors list (in quotes ofc, to prevent errors).
It should work, if not, tell me the problems and I'll spend more than 5 minutes on it.