Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- Analogue Clock
- -- (c) Ramdor 2013
- -- v1.6
- --
- -- changes
- -- v1.6 - added non filled face option (bFaceFilled = true ... is the default)
- -- v1.5 - now uses computercraft paintutils line, re-worked circle code, auto find monitor
- -- v1.4 - colours added and some loop derps fixed
- -- v1.3 - added resize/auto scale and 0.5 textsize
- -- to double the effective resolution
- -- v1.2 - changed timer code
- -- v1.1 - tidy up
- -- v1.0 - initial release
- --
- -- You may edit/copy/redistribute/whatever this
- -- code in any way. Just a credit listing this
- -- pastebin link (pastebin.com/LGNUpDzz) will be fine :)
- -- Have fun, I did :)
- -- see http://www.youtube.com/watch?v=RrgOIGW0C-s for some more info
- -- these two settings will hide/show
- -- the M and H that is on the end of the hand
- local bShowHourChar = false
- local bShowMinuteChar = false
- local bFaceFilled = true
- -- coloured clocks anyone?
- local nBackColour = colors.black
- local nFaceColour = colors.white
- local nHandColour = colors.black
- local nTickColour = colors.red
- -- find the monitor and set it up
- local monitor = nil
- local i,side
- for i, side in pairs(rs.getSides()) do
- if peripheral.getType(side) == "monitor" then
- monitor = peripheral.wrap(side)
- break
- end
- end
- if monitor==nil then
- print("NO MONITOR FOUND")
- print("Please attach a monitor and try again.")
- return
- end
- -- calculate scaling
- monitor.setTextScale(0.5)
- -- hackish fix to enable large monitor arrays enough time to initialise?
- os.sleep(1)
- local mw,mh = monitor.getSize()
- mw = mw / (15/10) -- 15x10 is w,h of 0.5 scale single monitor
- local minSize = (math.min(mw,mh) / 2) - 2
- -- clock radius in character. 18 is good for a 6x6 advanced monitor
- -- or you can use minSize which attempts to fit
- -- to monitor size automatically
- local nClockRad = minSize
- -- set up the screens
- term.clear()
- term.setCursorPos(1,1)
- print("Clock by Ramdor (c) 2013")
- print("Press 'Q' to terminate.")
- term.redirect(monitor)
- term.setBackgroundColor(nBackColour)
- term.clear()
- -- some variables
- local h = 0 -- parsed hour
- local m = 0 -- parsed minute
- local nOldHX = -1
- local nOldHY = -1
- local nOldMX = -1
- local nOldMY = -1
- --Hold time string from TimeAPI.org
- local time = ""
- local function plot(s,x,y)
- term.setCursorPos(x,y)
- term.write(s)
- end
- -- the clock face ticks
- local function ticks(nW,nH)
- local nIndex
- local x
- local y
- local xi
- local yi
- local nInRadius = nClockRad-(nClockRad/4)
- local nOutRadius = nClockRad-2
- local nxOutRad = nOutRadius + (nOutRadius/2)
- local nyOutRad = nOutRadius
- local nxInRad = nInRadius + (nInRadius/2)
- local nyInRad = nInRadius
- for nIndex=0,359,(360/12) do
- x = nW + math.sin(math.rad(nIndex)) * nxOutRad
- y = nH + math.cos(math.rad(nIndex)) * nyOutRad
- xi = nW + math.sin(math.rad(nIndex)) * nxInRad
- yi = nH + math.cos(math.rad(nIndex)) * nyInRad
- paintutils.drawLine(xi,yi,x,y,nTickColour)
- end
- end
- -- draw the face (circle)
- -- by working out a quarter of the points
- -- then drawing lines from oposite quarter
- -- results in much faster circle code
- local function face(nW,nH,nRadius)
- local nIndex
- local x
- local y
- local nxRad = nRadius + (nRadius/2)
- local nyRad = nRadius
- local nOldX = -1
- local nOldY = -1
- local points = {}
- local xy
- local n = 1
- for nIndex=0,89 do
- x = math.sin(math.rad(nIndex)) * nxRad
- y = math.cos(math.rad(nIndex)) * nyRad
- x = math.floor(x)
- y = math.floor(y)
- -- only store positions if they are different from last time
- if x~=nOldX or y~=nOldY then
- xy = {}
- xy[1] = x
- xy[2] = y
- points[n] = xy
- if y~=nOldY or not bFaceFilled then
- n=n+1
- end
- nOldX = x
- nOldY = y
- end
- end
- -- plot the circle
- for nIndex=1,#points do
- x = points[nIndex][1]
- y = points[nIndex][2]
- if bFaceFilled then
- paintutils.drawLine(nW-x,nH+y,nW+x,nH+y,nFaceColour)
- paintutils.drawLine(nW-x,nH-y,nW+x,nH-y,nFaceColour)
- else
- paintutils.drawPixel(nW-x,nH+y,nFaceColour)
- paintutils.drawPixel(nW+x,nH+y,nFaceColour)
- paintutils.drawPixel(nW-x,nH-y,nFaceColour)
- paintutils.drawPixel(nW+x,nH-y,nFaceColour)
- end
- end
- end
- -- parse the time into H and M
- -- these are stored globally in h and m
- local function parseTime()
- local t = os.time()
- local sT = textutils.formatTime(t, true)
- local n = string.find(sT, ":")
- if(n>0) then
- h = tonumber(string.sub(sT,1,n-1))
- m = tonumber(string.sub(sT,n+1))
- end
- end
- -- plot minute hand
- -- it removes the previous minute hand
- -- then draws the new one
- local function plotM(nW,nH,nX,nY)
- local nTmpColour
- if(nOldMX==nX and nOldMY==nY) then
- return
- end
- -- remove previous by drawing it again
- -- in the face colour. Also remove the
- -- hand tag
- if(nOldMX~=-1) then
- if bFaceFilled then
- nTmpColour = nFaceColour
- else
- nTmpColour = nBackColour
- end
- paintutils.drawLine(nW,nH,nOldMX,nOldMY,nTmpColour)
- if(bShowMinuteChar) then
- plot(".",nOldMX,nOldMY)
- end
- end
- nOldMX = nX
- nOldMY = nY
- paintutils.drawLine(nW,nH,nX,nY,nHandColour)
- -- draw the centre O
- term.setTextColor(colors.black)
- term.setBackgroundColor(colors.lightGray)
- plot("O",nW,nH)
- if(bShowMinuteChar) then
- -- draw the minute hand tag
- plot("M",nX,nY)
- end
- end
- -- plot hour hand
- -- it removes the previous hour hand
- -- then draws the new one
- local function plotH(nW,nH,nX,nY)
- local nTmpColour
- if(nOldHX==nX and nOldHY==nY) then
- return
- end
- -- remove previous by drawing it again
- -- in the face colour. Also remove the
- -- hand tag
- if(nOldHX~=-1) then
- if bFaceFilled then
- nTmpColour = nFaceColour
- else
- nTmpColour = nBackColour
- end
- paintutils.drawLine(nW,nH,nOldHX,nOldHY,nTmpColour)
- if(bShowHourChar) then
- plot(".",nOldHX,nOldHY)
- end
- end
- nOldHX = nX
- nOldHY = nY
- paintutils.drawLine(nW,nH,nX,nY,nHandColour)
- if(bShowHourChar) then
- -- draw the hour hand tag
- term.setTextColor(colors.black)
- term.setBackgroundColor(colors.lightGray)
- plot("H",nX,nY)
- end
- end
- local function updateTime ()
- local timeHandle = http.get("http://www.timeapi.org/utc/in+two+hours")
- time = timeHandle.readLine()
- timeHandle.close()
- end
- local function getHours ()
- return tonumber(time:sub(12, 13))
- end
- local function getMinutes ()
- return tonumber(time:sub(15, 16))
- end
- local fH
- local fM
- local fXH
- local fYH
- local fXM
- local fYM
- local nyMRadius = nClockRad - (nClockRad / 4)
- local nyHRadius = nClockRad - (nClockRad / 2)
- local nxMRadius = nyMRadius + (nyMRadius / 2)
- local nxHRadius = nyHRadius + (nyHRadius / 2)
- local nW, nH = term.getSize()
- nW = (nW / 2)+1
- nH = (nH / 2)+1
- -- plot the circle
- face(nW,nH,nClockRad + 1)
- local bRunning = true
- local nTimer
- nTimer = os.startTimer(0.25) -- the timer interval to update the clock
- function clockLoop ()
- while (bRunning) do
- --parseTime()
- h = getHours()
- m = getMinutes()
- fH = (((h % 12)/12) + (m/60/12)) * 360
- fM = (m/60) * 360
- -- shift by half a circle
- fH = fH + 180
- fM = fM + 180
- fXH = math.sin(math.rad(-fH))
- fYH = math.cos(math.rad(fH))
- fXM = math.sin(math.rad(-fM))
- fYM = math.cos(math.rad(fM))
- plotH(nW,nH, nW + fXH * nxHRadius, nH + fYH * nyHRadius)
- plotM(nW,nH, nW + fXM * nxMRadius, nH + fYM * nyMRadius)
- -- draw the ticks on
- ticks(nW,nH)
- local event, param1 = os.pullEvent()
- while (not (event=="timer" and param1==nTimer) and event~="char") do
- event, param1 = os.pullEvent()
- end
- if(event=="char") then
- if(param1=="q" or param1=="Q") then
- bRunning=false
- end
- elseif(event=="timer" and param1==nTimer) then
- -- timer timed out, lets start again
- nTimer = os.startTimer(0.25)
- end
- end
- end
- function timeLoop ()
- while true do
- sleep(55)
- updateTime()
- end
- end
- updateTime()
- parallel.waitForAny(clockLoop, timeLoop)
- term.restore()
- print("Ended.")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement