Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local component = require("component")
- local event = require("event")
- local term = require("term")
- local math = require("math")
- local computer = require("computer")
- local gpu = component.gpu
- local w, h = gpu.getResolution()
- local buffer = {}
- local showFPS, bouncingMode, running = false, false, true
- local donuts = {}
- local A, B = 0, 0
- local z, b = {}, {}
- local function sin(x) return math.sin(x) end
- local function cos(x) return math.cos(x) end
- local fpsCounter = {
- sampleWindow = 3,
- updateInterval = 0.5,
- frameTimeQueue = {},
- queueSize = 180,
- queueIndex = 1,
- queueSum = 0,
- lastUpdateTime = 0,
- currentFPS = 0,
- update = function(self, dt)
- if #self.frameTimeQueue == self.queueSize then
- self.queueSum = self.queueSum - self.frameTimeQueue[self.queueIndex]
- end
- self.frameTimeQueue[self.queueIndex] = dt
- self.queueSum = self.queueSum + dt
- self.queueIndex = self.queueIndex % self.queueSize + 1
- local numFrames = math.min(#self.frameTimeQueue, self.queueSize)
- local averageFrameTime = self.queueSum / numFrames
- local fps = 1 / averageFrameTime
- local currentTime = computer.uptime()
- if currentTime - self.lastUpdateTime >= self.updateInterval then
- self.currentFPS = math.floor(fps + 0.5)
- self.lastUpdateTime = currentTime
- end
- end,
- draw = function(self)
- if showFPS then
- gpu.set(1, 1, string.format("FPS: %d", self.currentFPS))
- end
- end
- }
- local function cls()
- for i = 1, w * h do buffer[i] = " " end
- end
- local function flush()
- local str = table.concat(buffer)
- gpu.copy(1, 1, w, h, 0, 1)
- gpu.set(1, h, str:sub(1 + (h-1)*w))
- for i = h-1, 1, -1 do
- gpu.set(1, i, str:sub(1 + (i-1)*w, i*w))
- end
- end
- local function createDonut()
- return {
- x = w / 2,
- y = h / 2,
- vx = math.random(1, 2) * (math.random() > 0.5 and 1 or -1),
- vy = math.random(1, 2) * (math.random() > 0.5 and 1 or -1),
- size = math.random(10, 15)
- }
- end
- local function drawMessage()
- local message = "OC-Donut (Press X to quit.) Based on the original donut.c by Andy Sloane <[email protected]> Ported by nonogamer9"
- local oldBg, oldFg = gpu.getBackground(), gpu.getForeground()
- gpu.setBackground(0x0000FF)
- gpu.setForeground(0xFFFFFF)
- gpu.fill(1, h, w, 1, " ")
- gpu.set(1, h, message)
- gpu.setBackground(oldBg)
- gpu.setForeground(oldFg)
- end
- local function drawBouncingMessage(time)
- local message = "Watch The Donuts Bounce!"
- local messageLength = #message
- local yPosition = h - 2
- local xPosition = math.floor(w/2 - messageLength/2 + sin(time) * (w/2 - messageLength/2))
- local oldBg, oldFg = gpu.getBackground(), gpu.getForeground()
- gpu.setBackground(0x000000)
- gpu.setForeground(0xFFFF00)
- gpu.fill(1, yPosition, w, 1, " ")
- gpu.set(xPosition, yPosition, message)
- gpu.setBackground(oldBg)
- gpu.setForeground(oldFg)
- end
- local function updateBouncingDonuts()
- for _, donut in ipairs(donuts) do
- donut.x = donut.x + donut.vx
- donut.y = donut.y + donut.vy
- if donut.x <= donut.size or donut.x >= w - donut.size then
- donut.vx = -donut.vx
- end
- if donut.y <= donut.size or donut.y >= h - donut.size then
- donut.vy = -donut.vy
- end
- end
- end
- event.listen("key_down", function(_, _, _, code)
- if code == 59 then
- showFPS = not showFPS
- if not showFPS then gpu.set(1, 1, string.rep(" ", 10)) end
- elseif code == 60 then
- bouncingMode = not bouncingMode
- if bouncingMode then donuts = {createDonut()} end
- elseif code == 18 and bouncingMode then
- table.insert(donuts, createDonut())
- elseif code == 16 and bouncingMode and #donuts > 1 then
- table.remove(donuts)
- elseif code == 45 then
- running = false
- end
- end)
- while running do
- local frameStartTime = computer.uptime()
- for i = 1, w * h do b[i], z[i] = " ", 0 end
- if bouncingMode then updateBouncingDonuts() end
- local renderDonuts = bouncingMode and donuts or {{x = w/2, y = h/2, size = 30}}
- for _, donut in ipairs(renderDonuts) do
- for j = 0, 6.28, 0.07 do
- for i = 0, 6.28, 0.02 do
- local sini, cosj = sin(i), cos(j)
- local sinA, sinj = sin(A), sin(j)
- local cosA, cosj2 = cos(A), cosj + 2
- local mess = 1 / (sini * cosj2 * sinA + sinj * cosA + 5)
- local cosi, cosB = cos(i), cos(B)
- local sinB = sin(B)
- local t = sini * cosj2 * cosA - sinj * sinA
- local x = math.floor(donut.x + donut.size * mess * (cosi * cosj2 * cosB - t * sinB))
- local y = math.floor(donut.y + donut.size/2 * mess * (cosi * cosj2 * sinB + t * cosB))
- local o = x + w * y
- local N = math.floor(8 * ((sinj * sinA - sini * cosj * cosA) * cosB - sini * cosj * sinA - sinj * cosA - cosi * cosj * sinB))
- if y > 0 and y <= h and x > 0 and x <= w and mess > z[o] then
- z[o] = mess
- b[o] = string.sub(".,-~:;=!*#$@", math.max(N, 1), math.max(N, 1))
- end
- end
- end
- end
- cls()
- for k = 1, w * h do buffer[k] = b[k] end
- flush()
- if bouncingMode then drawBouncingMessage(frameStartTime) else drawMessage() end
- A, B = A + 0.08, B + 0.06
- local frameEndTime = computer.uptime()
- fpsCounter:update(frameEndTime - frameStartTime)
- fpsCounter:draw()
- os.sleep(0.05)
- end
- term.clear()
- print("Thank you for using OC-Donut!")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement