It should be controlled by buttons on the screen above… (7 long * 3 high)
The sides are for nuke control, the bottom is for emergancy door close
--[[
Launch Control Program
Prints four buttons on a monitor. When pressed, the redstone output
assigned to the button will go on for an interval then turn off.
The user can press the q key in the computer to quit.
Under these settings, will operate on a single monitor
]]
--[[
Set local variables
]]
local monitorSide = "top"-- change this to reflect your monitor side
local monitor = peripheral.wrap(monitorSide)
local buttonColorReady = colors.lime
local buttonColorFire = colors.red
local textColorReady = colors.white
local textColorFire = colors.yellow
local buttonWidth = 7
local buttonHeight = 5
local launchInterval = 3 -- how long to keep signal on in seconds
local buttons = {
[1]={
label = "Silo1";
startX = 1;
startY = 1;
side = "left"; -- redstone output side
};
[2]={
label = "Silo2";
startX = 2+buttonWidth;
startY = 1;
side = "right"
};
[3]={
label = "Silo3";
startX = 1;
startY = 2+buttonHeight;
side = "back";
};
[4]={
label = "Silo4";
startX = 2+buttonWidth;
startY = 2+buttonHeight;
side = "bottom"
};
}
--[[
These are all of the functions
]]
local function drawButton(startX,startY,label,buttonColor,textColor)
-- draw a single button
monitor.setBackgroundColor(buttonColor)
monitor.setTextColor(textColor)
for i = 1,buttonHeight do
monitor.setCursorPos(startX,startY+i-1)
monitor.write(string.rep(" ",buttonWidth))
end
-- create button label to be centered on button.
if #label > buttonWidth-2 then -- restrict label to 13 wide
label = string.sub(label,1,buttonWidth-2)
end
label = string.rep(" ",math.floor((buttonWidth-#label)/2)) .. label
monitor.setCursorPos(startX,startY + math.floor(buttonHeight/2))
monitor.write(label)
monitor.setBackgroundColor (colors.black)
end
local function allRedstoneOff()
-- Turn all redstone output off
for k,v in pairs(rs.getSides()) do
rs.setOutput(v,false)
end
end
local function drawAllButtons()
-- draws all buttons
monitor.clear()
monitor.setTextScale(0.5)
-- cycle through buttons table
for i = 1,#buttons do
drawButton(buttons[i].startX,buttons[i].startY,buttons[i].label,buttonColorReady,textColorReady)
end
end
local function launchMissile(missile)
-- this function updates button, and turns redstone on/off for the interval
drawButton(buttons[missile].startX,buttons[missile].startY,"Fire!",buttonColorFire,textColorFire)
rs.setOutput(buttons[missile].side,true)
sleep(launchInterval)
rs.setOutput(buttons[missile].side,false)
drawButton(buttons[missile].startX,buttons[missile].startY,buttons[missile].label,buttonColorReady,textColorReady)
end
--[[
This is the main program
]]
monitor.clear()
allRedstoneOff()
drawAllButtons()
-- event loop. Will listen for react to only
-- monitor_touch and keu events
while true do
event = {os.pullEvent()}
if event[1]=="monitor_touch" then -- monitor was pressed
for i,v in ipairs(event) do
print (v)
end
-- For each button, test if it was pressed based on x,y of click
for i = 1, #buttons do
local startX,startY = buttons[i].startX,buttons[i].startY
-- this is how to test if button in question was pressed
if (event[3] >= startX and event[3] <= startX+buttonWidth) and (event[4] >= startY and event[4] <= startY+buttonHeight) then
launchMissile(i)
break;
end
end
elseif event[1]=="key" and event[2] == keys.q then -- user wants to quit
break
end
end
-- quit program
monitor.clear()
allRedstoneOff()
print ("Done.")
--[[
--[[
Door Control Program
Prints three buttons on a monitor. When pressed, the redstone output
assigned to the button will go on for an interval then turn off,
or it will toggle depending on settings.
Redstone settings at startup can be controlled with options
to leave alone, turn off or turn on.
The user can press the q key in the computer to quit.
Under these settings, will operate on a single monitor
]]
--[[
Set local variables
]]
local monitorSide = "top"-- change this to reflect your monitor side
local monitor = peripheral.wrap(monitorSide)
local buttonColorOn = colors.lime
local buttonColorOff = colors.red
local textColorOn = colors.white
local textColorOff = colors.yellow
local buttonWidth = 13
local buttonHeight = 3
local xMargin = 1
local buttons = {
[1]={
label = "Left";
startX = 1 + xMargin;
startY = 1;
side = "left"; -- redstone output side
pulse = true; -- toggle (false) or pulse (true)
pulseInterval = 2; -- how long to pulse
startState = 0; --redstone start state (-1 leave alone, 0 off, 1 on)
};
[2]={
label = "Right";
startX = 1 + xMargin;
startY = 2+buttonHeight;
side = "right";
pulse = false;
pulseInterval = 0;
startState = 1;
};
[3]={
label = "Bottom";
startX = 1 + xMargin;
startY = 2*(buttonHeight)+3;
side = "bottom";
pulse = false;
pulseInterval = 0;
startState = 0;
};
}
--[[
These are all of the functions
]]
local function drawButton(startX,startY,label,buttonColor,textColor)
-- draw a single button
monitor.setBackgroundColor(buttonColor)
monitor.setTextColor(textColor)
for row = 1,buttonHeight do
monitor.setCursorPos(startX,startY+row-1)
monitor.write(string.rep(" ",buttonWidth))
end
-- create button label to be centered on button.
if #label > buttonWidth-2 then -- restrict label to 2 less than buttonWidth
label = string.sub(label,1,buttonWidth-2)
end
-- this will center label on button
monitor.setCursorPos(startX+math.floor((buttonWidth-#label)/2),startY + math.floor(buttonHeight/2))
monitor.write(label)
monitor.setBackgroundColor (colors.black)
end
local function allRedstoneOff()
-- Turn all redstone output off
for k,v in pairs(rs.getSides()) do
rs.setOutput(v,false)
end
end
local function updateButton(button)
if rs.getOutput(buttons[button].side) then
drawButton(buttons[button].startX,buttons[button].startY,buttons[button].label,buttonColorOn,textColorOn)
else
drawButton(buttons[button].startX,buttons[button].startY,buttons[button].label,buttonColorOff,textColorOff)
end
end
local function drawAllButtons()
-- draws all buttons
monitor.clear()
monitor.setTextScale(0.5)
-- cycle through buttons table
for button = 1,#buttons do
updateButton(button)
end
end
local function toggle(button)
-- this function updates button, and turns redstone on/off for the interval
local side = buttons[button].side;
local pulse = buttons[button].pulse
rs.setOutput(side,not rs.getOutput(side))
updateButton(button)
if pulse then
sleep(buttons[button].pulseInterval)
rs.setOutput(side,(not rs.getOutput(side)))
updateButton(button)
end
end
local function checkStates()
for button = 1, #buttons do
updateButton(button)
end
end
local function setStartStates()
for button = 1, #buttons do
if buttons[button].startState == 0 then
rs.setOutput(buttons[button].side,false)
elseif buttons[button].startState == 1 then
rs.setOutput(buttons[button].side,true)
end
end
end
--[[
This is the main program
]]
monitor.clear()
setStartStates()
drawAllButtons()
-- event loop. Will listen for and react to
-- only monitor_touch and key events
while true do
local event = {os.pullEvent()}
if event[1]=="monitor_touch" then -- monitor was pressed
-- For each button, test if it was pressed based on x,y of click
for button = 1, #buttons do
local startX,startY = buttons[button].startX,buttons[button].startY
-- this is how to test if button in question was pressed
if (event[3] >= startX and event[3] <= startX+buttonWidth) and (event[4] >= startY and event[4] <= startY+buttonHeight) then
toggle(button)
break;
end
end
elseif event[1]=="key" and event[2] == keys.q then -- user wants to quit
break
end
end
-- quit program
monitor.clear()
print ("Done.")
Anyone can add in:
2. ewwwww, you used global variables within in a function….. :o/> … i feel sullied and unusual :)/>
Thanks for writing that surferpup, let's see if it fits his needs.
don't worry, i was only been jocular, not dismissing your code - sorry if you took my tone wrongly
there's several others tho… monitor/buttonheight/buttonwidth - but i'm purely being purist for "comedy" effect … i did hint that my pedantry was irrelevant in the circumstances :)/>
You are welcome. Care to use it as the basis for a tutorial? This question seems to come up a lot. I tried to incorporate a few good practices in making it (use of tables for buttons, self-documenting code, event loop with both monitor touch and key events tested, local variables – thanks ingie – use of functions, organized code, checking redstone states, allow for both toggle and pulse). All elements of a good door control with touch button tutorial are here.
I took you at your tone – that's why I said you were whining in my correction :P/>
For the record, the table buttons is local as are all the keys defined thereunder. Also, the variables monitor, buttonHeight and buttonWidth are declared local. You must have misread the code (shocking, right?). You are absolutely correct in pointing out that it is best practice to use local variables unless a global is absolutely essential. The only global I found was event, and I changed it. Good catch.
if you get me :)/>
I get you. I actually wrote it because I have seen so many of these "Can you help me write a quick touch screen button program?" questions. So, instead of just cranking out a hack, I wanted to show that it is a relatively straightforward program that can be extended if you use good coding practices. Again – basis for a good tutorial…
my bad in my definition, by global, i mean variables scoped outside the function… i.e. not local to the function - which is bad-ish practice for later abstraction. I always pass such variables in as params even if they are local to the main program, as that way it's simpler to extract the functions to a separate API later if needed, without any changes to the method.
I have a similar table for my door proximity opening system - where additionally one of the values of a "door" item is the function by which the trigger is activated - it's things like this that make me love lua for its first-class functional style ability
Did you miss a link to your code demonstrating this?