172 lines
4.7 KiB
Crystal
172 lines
4.7 KiB
Crystal
class Funfriend::FunfriendContext < Funfriend::WindowContext
|
|
WINDOW_SIZE = {width: 82, height: 82}
|
|
CHATTER_TIMER = 3.0
|
|
|
|
CHATTER_ARRAY = [
|
|
["HELLO AGAIN"],
|
|
["HI INTERLOPER"],
|
|
["HELLO!", "IS THE AUTH LAYER STILL DISSOCIATED?", "I MISS THEM"],
|
|
["INTERLOPER!", "WELCOME", "BUT ALSO PLEASE DO NOT BOTHER ME", "VERY BUSY"]
|
|
]
|
|
|
|
getter renderer : FunfriendRenderer
|
|
property chatter_timer : Float64 = 1.0
|
|
property chatter_index : Int32 = 0
|
|
property chatter_array : Array(String)? = CHATTER_ARRAY.sample
|
|
|
|
property held : Bool = false
|
|
property held_at : NamedTuple(x: Int32, y: Int32) = {x: 0, y: 0}
|
|
STAY_STILL_AFTER_HELD = 1.0
|
|
property held_timer : Float64 = 0.0
|
|
|
|
property static_pos : NamedTuple(x: Int32, y: Int32)
|
|
|
|
property easing_from : NamedTuple(x: Int32, y: Int32) = {x: 0, y: 0}
|
|
property easing_to : NamedTuple(x: Int32, y: Int32) = {x: 0, y: 0}
|
|
property easing_dur : Float64 = 0.0
|
|
property easing_t : Float64 = 0.0
|
|
|
|
WANDER_TIMER = 4.0
|
|
property wander_timer : Float64 = WANDER_TIMER
|
|
|
|
def initialize
|
|
super(
|
|
title: "??_FUNFRIEND_??",
|
|
width: WINDOW_SIZE[:width], height: WINDOW_SIZE[:height],
|
|
transparent: true
|
|
)
|
|
|
|
# just for initialization, let OpenGL know this is the current context
|
|
window.make_context_current
|
|
@renderer = FunfriendRenderer.new
|
|
|
|
window.on_mouse_button do |event|
|
|
if event.action.press? && event.mouse_button.two?
|
|
renderer.catmoding = !renderer.catmoding
|
|
end
|
|
if event.mouse_button.one?
|
|
if event.action.press?
|
|
SoundMan.play_sound("assets/sfx/talk#{(1..8).sample}.ogg")
|
|
@easing_dur = 0.0
|
|
@held = true
|
|
@held_at = {
|
|
x: window.cursor.position[:x].to_i,
|
|
y: window.cursor.position[:y].to_i,
|
|
}
|
|
@held_timer = STAY_STILL_AFTER_HELD
|
|
window.cursor Window::Cursor::Shape::Hand
|
|
elsif event.action.release?
|
|
@held = false
|
|
window.cursor Window::Cursor::Shape::Arrow
|
|
end
|
|
end
|
|
end
|
|
|
|
window.on_key do |event|
|
|
if event.action.press? && event.key.escape?
|
|
event.window.should_close
|
|
end
|
|
end
|
|
|
|
# pick a random pos
|
|
monitor = Monitor.primary
|
|
window.position = {
|
|
x: monitor.position[:x] + (monitor.video_mode.size[:width] * rand((0.0..1.0))).to_i,
|
|
y: monitor.position[:y] + (monitor.video_mode.size[:height] * rand((0.0..1.0))).to_i
|
|
}
|
|
@static_pos = window.position
|
|
end
|
|
|
|
def render(dt : Float64)
|
|
# let OpenGL draw to it
|
|
window.make_context_current
|
|
|
|
# draw funfriend
|
|
renderer.render(dt, WINDOW_SIZE[:width], WINDOW_SIZE[:height])
|
|
end
|
|
|
|
def goto(pos : NamedTuple(x: Int32, y: Int32), dur : Float64)
|
|
@easing_t = 0.0
|
|
@easing_dur = dur
|
|
@easing_from = window.position
|
|
@easing_to = pos
|
|
|
|
LOG.info { "going from #{easing_from} to #{easing_to}" }
|
|
end
|
|
|
|
def update_wander(dt : Float64)
|
|
if @easing_dur != 0.0 && @easing_t <= @easing_dur
|
|
@easing_t = @easing_t + dt
|
|
a = Ease.inOutSine(@easing_t / @easing_dur)
|
|
|
|
window.position = {
|
|
x: (@easing_from[:x] * (1.0 - a) + @easing_to[:x] * a).to_i,
|
|
y: (@easing_from[:y] * (1.0 - a) + @easing_to[:y] * a).to_i,
|
|
}
|
|
|
|
@wander_timer = WANDER_TIMER
|
|
else
|
|
@wander_timer = @wander_timer - dt
|
|
if @wander_timer <= 0
|
|
goto({
|
|
x: @static_pos[:x] + (-40 .. 40).sample,
|
|
y: @static_pos[:y] + (-40 .. 40).sample,
|
|
}, 4.0)
|
|
end
|
|
end
|
|
end
|
|
|
|
def update_pos(dt : Float64)
|
|
if held
|
|
window.position = {
|
|
x: window.position[:x] - held_at[:x] + window.cursor.position[:x].to_i,
|
|
y: window.position[:y] - held_at[:y] + window.cursor.position[:y].to_i,
|
|
}
|
|
@static_pos = window.position
|
|
else
|
|
@held_timer = @held_timer - dt
|
|
if @held_timer <= 0
|
|
update_wander(dt)
|
|
end
|
|
end
|
|
end
|
|
|
|
def say(text : String)
|
|
Funfriend.contexts.each do |context|
|
|
if context.is_a?(ChatterContext) && context.parent == self
|
|
context.bump
|
|
end
|
|
end
|
|
|
|
Funfriend.add_context(ChatterContext.new(text, {
|
|
x: window.position[:x] + WINDOW_SIZE[:width] // 2,
|
|
y: window.position[:y] + WINDOW_SIZE[:height] // 2 - 70
|
|
}, parent: self))
|
|
|
|
SoundMan.play_sound("assets/sfx/talk#{(1..8).sample}.ogg")
|
|
end
|
|
|
|
def update(dt : Float64)
|
|
@chatter_timer = @chatter_timer - dt
|
|
if @chatter_timer <= 0.0
|
|
@chatter_timer = @chatter_timer + CHATTER_TIMER
|
|
|
|
if @chatter_array.try &.[(@chatter_index)]?
|
|
say(@chatter_array.not_nil![@chatter_index])
|
|
end
|
|
|
|
@chatter_index = @chatter_index + 1
|
|
end
|
|
|
|
update_pos(dt)
|
|
|
|
render(dt)
|
|
|
|
window.swap_buffers
|
|
end
|
|
|
|
def clean_up
|
|
renderer.clean_up
|
|
end
|
|
end
|