Hi I want my lua code in Computercraft to allow the user to turn the redstone signal on/off by right clicking on a monitor on top, but I can't get it to work.
monitor = peripheral.wrap("top")
monitor.clear()
monitor.setTextColor(colors.red)
monitor.setCursorPos(1, 1)
monitor.setTextScale(1)
monitor.write("Hello")
function rubber()
monitor.setCursorPos(1, 2)
monitor.clearLine()
if rs.getOutput("right", true) then
monitor.write("Rubber farm is on")
elseif rs.getOutput("right", false) then
monitor.write("Rubber farm is off")
end
local event = { os.pullEvent() }
if event == "monitor_touch" then
if rs.getOutput("right") == true then
rs.setOutput("right", false)
else
rs.setOutput("right", true)
end
else
write("test")
end
rubber()
end
Right now all it displays is 'hello' and I don't know how to fix it, anyone know how? Also I'm a beginner at Lua so I've probably made some pretty simple mistakes. Thanks
local event = { os.pullEvent() }
if event == "monitor_touch" then
os.pullEvent returns a tuple. In your code, you're packing this tuple into a table. That's fine, but you then compare that table to a string. Tables can't be equal to strings - they're a table. Either don't pack the tuple into a table, and keep the first return value (the type):
local event = os.pullEvent()
if event == "monitor_touch" then
Or extract the first element when comparing
local event = { os.pullEvent() }
if event[1] == "monitor_touch" then
The problem is you wanted to have that function infinitly looping, but you have not called your function outside your function.... also you should look into using while loops
while true do
//stuff here
end
just add
rubber()
to the last line after your last end tag.
You have to call the function.
rubber()
You need to close your function
function rubber()
monitor.setCursorPos(1,1)
monitor.clearLine()
end
The end is it you need to make this little word
this is a simple fix, simply add rubber() after you finish the function rubber, cause while you have created the function rubber, you have not called for it to start yet.
The "monitor_touch" event is what you should be using. Also, make sure the monitor you are using is an advanced monitor (the one with the yellow border).
If you need help in understanding the event, check out this page: http://computercraft.info/wiki/Monitor_touch_(event)
Related
An example would have been like
local E = game:GetService('UserInputService').SetKeyDown(Enum.KeyCode.E)
but it doesnt work ofcourse because i cant jsut make my game press E by itself with this thing, so it requieres soemthing longer and if you find the solution can you also do one where it makes it pressed down?
The input can only be registered on the client, therefore you will have to code in a LocalScript. There are 2 services which are used to get the player's input:-
UserInputService
This example shows how to use the UserInputService in getting the player's LeftMouseButton input.
local UserInputService = game:GetService("UserInputService")
local function onInputBegan(input)
if input.UserInputType == Enum.UserInputType.MouseButton1 then
print("The left mouse button has been pressed!")
end
end
UserInputService.InputBegan:Connect(onInputBegan)
ContextActionService
This example properly shows how to use ContextActionService in binding user input to a contextual action. The context is the tool being equipped; the action is reloading some weapon.
local ContextActionService = game:GetService("ContextActionService")
local ACTION_RELOAD = "Reload"
local tool = script.Parent
local function handleAction(actionName, inputState, inputObject)
if actionName == ACTION_RELOAD and inputState == Enum.UserInputState.Begin then
print("Reloading!")
end
end
tool.Equipped:Connect(function ()
ContextActionService:BindAction(ACTION_RELOAD, handleAction, true, Enum.KeyCode.R)
end)
You should take a look at the Wiki pages.
It sounds like you want to write a script to press the E key, but that isn't possible.
You can bind actions to keypresses, just like in the examples Giant427 provided, and you can also manually call the functions that are bound to those actions, but you cannot write a script to fire keyboard inputs.
Firstly, I do not want to use the Mouse object, so MouseButton1Click is not an option. I want to use UserInputService, but my solution still seems unclean.
ModuleScript:
function GuiModule.Click(Input)
if Input.UserInputType == Enum.UserInputType.MouseButton1 or Input.UserInputType == Enum.UserInputType.Touch then
return true
else
return false
end
end
LocalScript:
local GuiModule = require(game.Players.LocalPlayer.PlayerGui.GuiModule)
Button.InputEnded:Connect(function(Input)
if GuiModule.Click(Input) then --I really have to write an if statement for every InputEnded event?
print("Button clicked")
end
end)
Ideally, I want something like this, where .Clicked is a custom event that utilizes object-oriented programming in a module script. I've looked into metatables and metafunctions but I can't fully grasp their functionality to implement this, if its possible.
local GuiModule = require(game.Players.LocalPlayer.PlayerGui.GuiModule)
Button.Clicked:Connect(function(Input)
print("Button clicked")
end)
Try the Activated event instead. It automatically handles different input types so you don't have to detect whether it's mouse or touch input.
Button.Activated:Connect(function()
print("Button clicked or tapped")
end)
I want to add an ability in my game where if you hold t then the enemies are slowed down. love.keyboard.isDown won't let me put the enemies back to their original speed once the t key has been released. Is their another way I could do this?
Use love.keyreleased.
Note that unlike love.keyboard.isDown, it's a callback function. Use it to register the action when the key t is released.
Using love.keyboard.isDown will let you put their original speed back if you check when it's false, like so:
if love.keyboard.isDown('t') then
enemy_speed = 15
else
enemy_speed = 30 -- 't' key has been released
end
but there is an another way to do this. Use love.keypressed and love.keyreleased, like so:
function love.keypressed(key)
if key == 't' then
enemy_speed = 15
end
end
function love.keyreleased(key)
if key == 't' then
enemy_speed = 30 -- 't' key has been released
end
end
if I understand, love.keyboard.isDown("t") is for to the love.update() function, and it will just repeat the function no matter what. so in this case create a function like this in your main.lua file:
function love.keypressed(k)
if k == "t" then
// Code goes in here
end
end
like this, it should activate once the key is pressed.
ok, Im almost completely new to lua and computercraft but I have alot of creativity. I'm trying to write code that will reprint a variable every second. here is what I have so far:
display = "Loading..."
While true do
sleep(1)
term.clear()
term.setCursorPos(1,1)
print (display)
end
sleep(3)
display = "hello"
I want to use it to render a 2d game, the "display" variable would change often and thus why i want it to be updated every second.
It does indeed refresh every second when I run the code but for some reason I cant seem to get the "display" variable to change after 3 seconds to test it.
What am I doing wrong?
while true is an infinite loop. The script never reaches sleep(3).
Perhaps you want to replace while true with for i=1,3.
I am not experienced in Lua, but this might be a solution: answer on SO
In the UI thread, run:
while ((status=lua_resume(L_coroutine, 0)) == LUA_YIELD) {
semaphore_wait(); /* whatever the appropriate C# call is */
}
"Wait for response" should look something like:
while not results[my_result] do
coroutine.yield()
end
The "incoming message" function should look like the following in Lua:
results[cur_result]=parsed_message
I'm trying to create a while true do loop, that reacts to clicks, using os.pullEvent, and also updates a monitor.
Problem being, it only updates the screen when I press one of the on screen buttons, and I've found out that's because pullEvent stops the script, until an event is fired.
Is it possible to make it so pullEvent doesn't stop me updating the monitor?
function getClick()
event,side,x,y = os.pullEvent("monitor_touch")
button.checkxy(x,y)
end
local tmp = 0;
while true do
button.label(2, 2, "Test "..tmp)
button.screen()
tmp++
getClick()
end
You can easily use the parallel api to run both codes essentially at the same time. How it works is it runs them in sequence until it hits something that uses os.pullEvent and then swaps over and does the other side, and if both stop at something that does os.pullEvent then it keeps swapping between until one yields and continues from there.
local function getClick()
local event,side,x,y = os.pullEvent("monitor_touch")
buttoncheckxy(x,y)
end
local tmp = 0
local function makeButtons()
while true do
button.label(2,2,"Test "..tmp)
button.screen()
tmp++
sleep(0)
end
end
parallel.waitForAny(getClick,makeButtons)
Now if you notice, first thing, I've made your while loop into a function and added a sleep inside it, so that it yields and allows the program to swap. At the end you see parallel.waitForAny() which runs the two functions that are specified and when one of them finishes, which in this case whenever you click on a button, then it ends. Notice however inside the arguments that I'm not calling the functions, I'm just passing them.
I don't have computercraft handy right now or look up the functions but i know that you can use the function os.startTimer(t) that will cause an event in t seconds (I think it is seconds)
usage:
update_rate = 1
local _timer = os.startTimer(update_rate)
while true do
local event = os.pullEvent()
if event == _timer then
--updte_screen()
_timer = os.startTimer(update_rate)
elseif event == --some oter events you want to take action for
--action()
end
end
note: the code is not tested and I didn't use computercraft in quite a while so pleas correct me if i did a mistake.