268 lines
9.0 KiB
Lua
268 lines
9.0 KiB
Lua
|
|
math.randomseed(os.time())
|
|
local WINDOW_WIDTH, WINDOW_HEIGHT = 800, 400
|
|
|
|
local TALK_FONT = love.graphics.newFont(18)
|
|
local OPTIONS_FONT = love.graphics.newFont(10)
|
|
|
|
local markov = require "markov"
|
|
|
|
--- Colors
|
|
|
|
local COLOR_WHITE = {1,1,1}
|
|
local COLOR_BLACK = {0,0,0}
|
|
|
|
local COLOR_CLOCK_FRAME = {200/255,200/255,200/255,}
|
|
local COLOR_CLOCK_INNER = COLOR_WHITE
|
|
local COLOR_CLOCK_HAND = {50/255,50/255,50/255}
|
|
|
|
local COLOR_BOARDS = {(240 + math.random() * 10)/255, (200 + math.random() * 10)/255, (120 + math.random() * 30)/255}
|
|
|
|
local COLOR_PROJECTOR_CONTENTS = {82/255, 106/255, 108/255, 30/255}
|
|
local COLOR_WHITEBOARD = {200/255, 200/255, 200/255}
|
|
local COLOR_BOLTS = {149/255, 141/255, 128/255}
|
|
local COLOR_CRACKS = {28/255, 19/255, 20/255}
|
|
local COLOR_BEAMS = {127/255, 94/255, 61/255}
|
|
local COLOR_PROJECTOR_AREA = {210/25/2555, 210/255, 210/255}
|
|
local COLOR_WHITEBOARD_BORDERS = {149/255, 141/255, 128/255}
|
|
|
|
local COLOR_HAIR = {59/255, 37/255, 24/255}
|
|
local COLOR_SUIT = {87/255, 107/255, 56/255}
|
|
local COLOR_HEAD = {163/255, 118/255, 100/255}
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Background
|
|
|
|
|
|
local function randomize_projector_color ()
|
|
for i = 1, 3 do
|
|
COLOR_PROJECTOR_CONTENTS[i] = (math.random(80) + 100)/255
|
|
end
|
|
end
|
|
|
|
local function draw_clock (x, y, r, t)
|
|
love.graphics.setColor(COLOR_CLOCK_FRAME)
|
|
love.graphics.circle('fill', x, y, r)
|
|
love.graphics.setColor(COLOR_CLOCK_INNER)
|
|
love.graphics.circle('fill', x, y, r - 2)
|
|
love.graphics.setColor(COLOR_CLOCK_HAND)
|
|
love.graphics.setLineWidth(3)
|
|
love.graphics.line(x, y, x + math.cos(t * (2*math.pi) / 42000 - math.pi / 2) * r * 0.4, y + math.sin(t * (2*math.pi) / 42000 - math.pi / 2) * r * 0.4)
|
|
love.graphics.setLineWidth(2)
|
|
love.graphics.line(x, y, x + math.cos(t * (2*math.pi) / 3600 - math.pi / 2) * r * 0.6, y + math.sin(t * (2*math.pi) / 3600 - math.pi / 2) * r * 0.6)
|
|
love.graphics.setLineWidth(1)
|
|
love.graphics.line(x, y, x + math.cos(math.floor(t) * (2*math.pi) / 60 - math.pi / 2) * r * 0.8, y + math.sin(math.floor(t) * (2*math.pi) / 60 - math.pi / 2) * r * 0.8)
|
|
end
|
|
|
|
local function draw_background ()
|
|
|
|
-- FLOOR --
|
|
love.graphics.setColor(COLOR_BOARDS)
|
|
love.graphics.rectangle('fill',0, 0, WINDOW_WIDTH, WINDOW_HEIGHT)
|
|
|
|
-- TODO
|
|
|
|
-- WALL --
|
|
|
|
-- Color of cracks
|
|
love.graphics.setColor(COLOR_CRACKS)
|
|
love.graphics.rectangle('fill',0, 0, WINDOW_WIDTH, 250 + 10)
|
|
|
|
-- "Beams"
|
|
love.graphics.setColor(COLOR_BEAMS)
|
|
for xi = 0.25, 100 do
|
|
love.graphics.rectangle('fill',xi*8, 0, 4, 250)
|
|
end
|
|
-- "Bolts"
|
|
love.graphics.setColor(COLOR_BOLTS)
|
|
for xi = 0.25, 100 do
|
|
for yi = 0.7, 5 do
|
|
love.graphics.rectangle('fill',xi*8+1, yi*50, 2, 2)
|
|
end
|
|
end
|
|
|
|
-- Whiteboards and projector area --
|
|
|
|
-- Whiteboard
|
|
love.graphics.setColor(COLOR_WHITEBOARD)
|
|
love.graphics.rectangle('fill', 100, 100, WINDOW_WIDTH - 100*2, 100)
|
|
-- Projector Area
|
|
love.graphics.setColor(COLOR_PROJECTOR_AREA)
|
|
love.graphics.rectangle('fill', 100, 0, WINDOW_WIDTH - 100*2, 100)
|
|
|
|
-- Whiteboard and projector borders
|
|
love.graphics.setColor(COLOR_WHITEBOARD_BORDERS)
|
|
love.graphics.rectangle('fill', (WINDOW_WIDTH-2)/2, 100, 2, 100)
|
|
love.graphics.rectangle('fill', 100, 100, WINDOW_WIDTH - 100*2, 2)
|
|
love.graphics.rectangle('fill', 100, 100+100-2, WINDOW_WIDTH - 100*2, 2)
|
|
love.graphics.rectangle('fill', 100, 0, 2, 100+100)
|
|
love.graphics.rectangle('fill', 100+WINDOW_WIDTH-100*2-2, 0, 2, 100+100)
|
|
|
|
-- Projector contents
|
|
love.graphics.setColor(COLOR_PROJECTOR_CONTENTS)
|
|
for i = 5, 20, 2 do
|
|
love.graphics.rectangle('fill', (100+i), 0, WINDOW_WIDTH - (100+i)*2, 100 - i)
|
|
end
|
|
|
|
|
|
-- OTHER PEOPLE --
|
|
|
|
-- TODO
|
|
|
|
-- FOREGROUND
|
|
|
|
-- TODO
|
|
-- TEMP:
|
|
love.graphics.setColor(COLOR_WHITE)
|
|
love.graphics.rectangle('fill',0, 400, WINDOW_WIDTH, WINDOW_HEIGHT)
|
|
end
|
|
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Teacher
|
|
|
|
local TEACHER = { x = WINDOW_WIDTH/2, y = WINDOW_HEIGHT - 100, h = 60, w = 30, head_r = 12}
|
|
TEACHER.tx = TEACHER.x
|
|
TEACHER.ty = TEACHER.y
|
|
|
|
function TEACHER:draw ()
|
|
-- Hair
|
|
love.graphics.setColor(COLOR_HAIR)
|
|
love.graphics.circle('fill', self.x, self.y - self.h - self.head_r - 4, self.head_r+1)
|
|
love.graphics.rectangle('fill', self.x - 10, self.y - self.h - self.head_r, 10 * 2, self.head_r)
|
|
-- Suite
|
|
love.graphics.setColor(COLOR_SUIT)
|
|
love.graphics.polygon('fill', self.tx, self.ty, self.x - self.w / 2, self.y - self.h, self.x + self.w / 2, self.y - self.h )
|
|
-- Head
|
|
love.graphics.setColor(COLOR_HEAD)
|
|
love.graphics.circle('fill', self.x, self.y - self.h - self.head_r, self.head_r)
|
|
end
|
|
|
|
function TEACHER:update (dt)
|
|
TEACHER.tx = TEACHER.tx + ( TEACHER.x - TEACHER.tx ) * 6 * dt
|
|
TEACHER.ty = TEACHER.ty + ( TEACHER.y - TEACHER.ty ) * 10 * dt
|
|
end
|
|
|
|
function TEACHER:move (dx, dy)
|
|
self.x = math.max(50, math.min(self.x + dx, WINDOW_WIDTH - 50))
|
|
self.y = math.max(250 + 30, math.min(self.y + dy, WINDOW_HEIGHT - 10))
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Text Bobble
|
|
|
|
local TEXT_BUBBLE = { tracking = TEACHER, x = 100, y = 100, text = "Hej Markov Chains! ;)", w = 300, h = 100 }
|
|
TEXT_BUBBLE.text = 'God morgen alle sammen, velkommen til interaktiones-design forelæsningen.'
|
|
|
|
function TEXT_BUBBLE:draw ()
|
|
-- Draw textbobble
|
|
love.graphics.setColor(COLOR_WHITE)
|
|
love.graphics.rectangle('fill', self.x, self.y, self.w, self.h, 10)
|
|
love.graphics.polygon('fill', self.x, self.y + self.h / 2, self.tracking.x, self.tracking.y - 100, self.x + self.w, self.y + self.h / 2)
|
|
|
|
-- Draw text
|
|
love.graphics.setFont(TALK_FONT)
|
|
love.graphics.setColor(COLOR_BLACK)
|
|
local text_height = TALK_FONT:getHeight() * #select(2, TALK_FONT:getWrap(self.text, self.w - 10*2))
|
|
local text_x, text_y = math.floor(self.x + 10 + 0.5), math.floor(self.y + (self.h - text_height) / 2 + 0.5)
|
|
love.graphics.printf(self.text, text_x, text_y, self.w - 10*2, 'center')
|
|
end
|
|
|
|
function TEXT_BUBBLE:update (dt)
|
|
local tx, ty = self:getTargetPos()
|
|
local cx, cy = self.x + (tx - self.x) * dt, self.y + (ty - self.y) * dt
|
|
self.x = math.max(10, math.min(cx, WINDOW_WIDTH - 10 - self.w))
|
|
if ty < cy then cy = self.y + (ty - self.y) * dt * 6 end
|
|
self.y = cy
|
|
end
|
|
|
|
function TEXT_BUBBLE:getTargetPos ()
|
|
local y_distance = self.h + self.tracking.h + self.tracking.head_r * 2 + 30
|
|
local tx, ty = self.tracking.x - self.w * 0.5, self.tracking.y - y_distance
|
|
return tx, ty
|
|
end
|
|
|
|
local TEXT_BUBBLE_MARKOV_CHAIN
|
|
|
|
do
|
|
local ALPHABET = {"a","b","c","d","e","f","g","h","i","j","k","l","m",
|
|
"n","o","p","q","r","s","t","u","v","w","x","y","z",'æ','ø','å',
|
|
'?',',', '.', ' ','0', '1','2','3','4','5','6','7','8','9'}
|
|
|
|
local chain = markov.VoMarkovChain.new(ALPHABET, 6)
|
|
TEXT_BUBBLE_MARKOV_CHAIN = markov.StringWrapper.new(chain)
|
|
|
|
local t = {}
|
|
local lines = love.filesystem.lines('/sentences.txt')
|
|
TEXT_BUBBLE_MARKOV_CHAIN:train(lines, true)
|
|
end
|
|
|
|
local function randomize_text_bubble_text ()
|
|
local text
|
|
repeat text = TEXT_BUBBLE_MARKOV_CHAIN:generate(100)
|
|
until text:len() > 80
|
|
local first_space_index = text:find(' ')
|
|
local final_space_index = text:find' [^ ]-$'
|
|
TEXT_BUBBLE.text = ('.' .. text:sub(first_space_index, final_space_index)):gsub("(%. *)(%l)(%w*)", function(c, a,b) return c .. ' ' .. string.upper(a) .. b end):gsub('%s+', ' '):sub(2)
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Callbacks
|
|
|
|
local TEACHER_TARGET = { x = 0, y = 0 }
|
|
|
|
local function randomize_teacher_target ()
|
|
repeat
|
|
TEACHER_TARGET.x = math.random() * (WINDOW_WIDTH - 50*2) + 50
|
|
TEACHER_TARGET.y = math.random() * 100 + 280
|
|
until math.sqrt((TEACHER_TARGET.x-TEACHER.x)^2 + (TEACHER_TARGET.y-TEACHER.y)^2) > 200
|
|
end
|
|
|
|
function love.load ()
|
|
|
|
end
|
|
|
|
local TIMER_PROJECTOR, TIMER_TEXT, TIMER_MOVE = 0, 10, 0
|
|
local TIMER_FULL = 15 * 60
|
|
|
|
function love.update (dt)
|
|
TEACHER:update(dt)
|
|
TEXT_BUBBLE:update(dt)
|
|
|
|
-- Update timers
|
|
TIMER_PROJECTOR, TIMER_TEXT, TIMER_MOVE = TIMER_PROJECTOR - dt, TIMER_TEXT - dt, TIMER_MOVE - dt
|
|
TIMER_FULL = TIMER_FULL + dt
|
|
|
|
-- Quit game
|
|
if TIMER_FULL > 60 * 60 + 5 then love.event.quit() end
|
|
if TIMER_FULL > 60 * 60 then TEXT_BUBBLE.text = 'Hov, den er vist 13:00. Tak for i dag, og vi ses næste uge!'; return end
|
|
|
|
-- Events occur
|
|
if TIMER_PROJECTOR < 0 then TIMER_PROJECTOR = math.random() * 10 + 5; randomize_projector_color() end
|
|
if TIMER_TEXT < 0 then TIMER_TEXT = math.random() * 2 + 6; randomize_text_bubble_text() end
|
|
if TIMER_MOVE < 0 then TIMER_MOVE = math.random() * 10 + 5; randomize_teacher_target() end
|
|
|
|
-- Move teacher
|
|
local dist_x, dist_y = TEACHER_TARGET.x - TEACHER.x, TEACHER_TARGET.y - TEACHER.y
|
|
local dist = math.sqrt(dist_x*dist_x + dist_y*dist_y)
|
|
local speed = 60
|
|
if dist < 2 then return end
|
|
TEACHER:move(speed*dt*dist_x/dist, speed*dt*dist_y/dist)
|
|
end
|
|
|
|
function love.keypressed (key)
|
|
if key == 'f' then
|
|
love.event.quit()
|
|
end
|
|
end
|
|
|
|
function love.draw ()
|
|
draw_background()
|
|
draw_clock(WINDOW_WIDTH - 50 + 2, 60, 14, TIMER_FULL)
|
|
TEACHER:draw()
|
|
TEXT_BUBBLE:draw()
|
|
|
|
love.graphics.setFont(OPTIONS_FONT)
|
|
love.graphics.print('Muligheder: \n- F: Du lærer intet fra det her, du kan lige så godt bare gå!', 20, WINDOW_HEIGHT - 40)
|
|
end
|