refactor code to use 2d vector structs
shouldn't change functionality hopefully? but cleaner code :)
This commit is contained in:
parent
d198bcc5e6
commit
bb4175d279
|
@ -1,8 +1,8 @@
|
|||
class Funfriend::ChatterContext < Funfriend::WindowContext
|
||||
getter renderer : TextRenderer
|
||||
getter parent : WindowContext?
|
||||
property parent_relative_pos : NamedTuple(x: Int32, y: Int32)
|
||||
getter window_size : NamedTuple(width: Int32, height: Int32)
|
||||
property parent_relative_pos : Vec2 = Vec2.zero
|
||||
getter window_size : Vec2
|
||||
property timer : Float64
|
||||
|
||||
WINDOW_SIZE = {width: 256, height: 32}
|
||||
|
@ -10,19 +10,16 @@ class Funfriend::ChatterContext < Funfriend::WindowContext
|
|||
|
||||
PADDING = 10
|
||||
|
||||
def initialize(text : String, position : NamedTuple(x: Int32, y: Int32), duration : Float64 = DEFAULT_DURATION, parent : WindowContext? = nil)
|
||||
def initialize(text : String, position : Vec2, duration : Float64 = DEFAULT_DURATION, parent : WindowContext? = nil)
|
||||
sheet = FontMan.parse_bm(File.read "assets/fonts/SpaceMono.fnt")
|
||||
|
||||
position_data = FontMan.position_text(text, sheet)
|
||||
|
||||
@window_size = {
|
||||
width: position_data[:width] + PADDING * 2,
|
||||
height: position_data[:height] + PADDING * 2
|
||||
}
|
||||
@window_size = Vec2.new(position_data[:width], position_data[:height]) + PADDING * 2
|
||||
|
||||
super(
|
||||
title: "??__FUNFRIEND__?? > CHATTER",
|
||||
width: window_size[:width], height: window_size[:height],
|
||||
width: window_size.x_i, height: window_size.y_i,
|
||||
transparent: false
|
||||
)
|
||||
|
||||
|
@ -30,31 +27,20 @@ class Funfriend::ChatterContext < Funfriend::WindowContext
|
|||
window.make_context_current
|
||||
|
||||
@timer = duration
|
||||
@renderer = TextRenderer.new(text, sheet, window_size[:width], window_size[:height])
|
||||
@renderer = TextRenderer.new(text, sheet, window_size.x_i, window_size.y_i)
|
||||
|
||||
window.position = {
|
||||
x: position[:x] - window_size[:width]//2,
|
||||
y: position[:y] - window_size[:height]//2,
|
||||
}
|
||||
window.position = (position - window_size / 2).xy_i
|
||||
|
||||
@parent = parent
|
||||
if parent
|
||||
@parent_relative_pos = {
|
||||
x: position[:x] - (parent.window.position[:x] + parent.window.size[:width] // 2),
|
||||
y: position[:y] - (parent.window.position[:y] + parent.window.size[:height] // 2),
|
||||
}
|
||||
else
|
||||
@parent_relative_pos = {x: 0, y: 0}
|
||||
@parent_relative_pos = position - (Vec2.new(parent.window.position) + Vec2.new(parent.window.size) / 2)
|
||||
end
|
||||
end
|
||||
|
||||
def update_position
|
||||
if parent
|
||||
p = parent.not_nil!
|
||||
window.position = {
|
||||
x: p.window.position[:x] + p.window.size[:width] // 2 + parent_relative_pos[:x] - window_size[:width] // 2,
|
||||
y: p.window.position[:y] + p.window.size[:height] // 2 + parent_relative_pos[:y] - window_size[:height] // 2,
|
||||
}
|
||||
window.position = (Vec2.new(p.window.position) + Vec2.new(p.window.size) / 2 + parent_relative_pos - window_size / 2).xy_i
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -82,10 +68,7 @@ class Funfriend::ChatterContext < Funfriend::WindowContext
|
|||
end
|
||||
|
||||
def bump
|
||||
@parent_relative_pos = {
|
||||
x: parent_relative_pos[:x],
|
||||
y: parent_relative_pos[:y] - window_size[:height] - 10
|
||||
}
|
||||
@parent_relative_pos.y -= window_size.y + 10
|
||||
update_position
|
||||
end
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ require "crystimage"
|
|||
|
||||
require "./log.cr"
|
||||
require "./ease.cr"
|
||||
require "./vec2.cr"
|
||||
require "./gl.cr"
|
||||
require "./configman.cr"
|
||||
require "./textureman.cr"
|
||||
|
|
|
@ -24,16 +24,16 @@ class Funfriend::FunfriendContext < Funfriend::WindowContext
|
|||
property chatter_array : Array(String)? = CHATTER_ARRAY.sample
|
||||
|
||||
property held : Bool = false
|
||||
property held_at : NamedTuple(x: Int32, y: Int32) = {x: 0, y: 0}
|
||||
property started_holding_at : NamedTuple(x: Int32, y: Int32) = {x: 0, y: 0}
|
||||
property held_at : Vec2 = Vec2.zero
|
||||
property started_holding_at : Vec2 = Vec2.zero
|
||||
STAY_STILL_AFTER_HELD = 1.0
|
||||
property held_timer : Float64 = 0.0
|
||||
property waiting_for_stable_pos : Bool = false
|
||||
|
||||
property static_pos : NamedTuple(x: Int32, y: Int32)
|
||||
property static_pos : Vec2
|
||||
|
||||
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_from : Vec2 = Vec2.zero
|
||||
property easing_to : Vec2 = Vec2.zero
|
||||
property easing_dur : Float64 = 0.0
|
||||
property easing_t : Float64 = 0.0
|
||||
|
||||
|
@ -43,7 +43,7 @@ class Funfriend::FunfriendContext < Funfriend::WindowContext
|
|||
def initialize
|
||||
super(
|
||||
title: "??_FUNFRIEND_??",
|
||||
width: window_size[:width], height: window_size[:height],
|
||||
width: window_size.x_i, height: window_size.y_i,
|
||||
transparent: true
|
||||
)
|
||||
|
||||
|
@ -60,12 +60,12 @@ class Funfriend::FunfriendContext < Funfriend::WindowContext
|
|||
SoundMan.play_sound("assets/sfx/talk#{(1..8).sample}.ogg")
|
||||
@easing_dur = 0.0
|
||||
@held = true
|
||||
@held_at = {
|
||||
@held_at = Vec2.new({
|
||||
x: window.cursor.position[:x].to_i,
|
||||
y: window.cursor.position[:y].to_i,
|
||||
}
|
||||
})
|
||||
if @held_timer <= 0
|
||||
@started_holding_at = window.position
|
||||
@started_holding_at = Vec2.new(window.position)
|
||||
LOG.info { "starting holding at #{started_holding_at}" }
|
||||
end
|
||||
@held_timer = STAY_STILL_AFTER_HELD
|
||||
|
@ -90,12 +90,12 @@ class Funfriend::FunfriendContext < Funfriend::WindowContext
|
|||
y: monitor.position[:y] + (monitor.video_mode.size[:height] * rand((0.0..1.0))).to_i
|
||||
}
|
||||
window.position = random_pos
|
||||
@static_pos = random_pos
|
||||
@static_pos = Vec2.new(random_pos)
|
||||
end
|
||||
|
||||
def window_size
|
||||
funfriend_size = ConfigMan.config["window"]["funfriend_size"].as(Int32)
|
||||
{width: (funfriend_size * 1.3).to_i, height: (funfriend_size * 1.3).to_i}
|
||||
Vec2.new((funfriend_size * 1.3).floor)
|
||||
end
|
||||
|
||||
def render(dt : Float64)
|
||||
|
@ -103,13 +103,13 @@ class Funfriend::FunfriendContext < Funfriend::WindowContext
|
|||
window.make_context_current
|
||||
|
||||
# draw funfriend
|
||||
renderer.render(dt, window_size[:width], window_size[:height])
|
||||
renderer.render(dt, window_size.x_i, window_size.y_i)
|
||||
end
|
||||
|
||||
def goto(pos : NamedTuple(x: Int32, y: Int32), dur : Float64, set_as_static : Bool = true)
|
||||
def goto(pos : Vec2, dur : Float64, set_as_static : Bool = true)
|
||||
@easing_t = 0.0
|
||||
@easing_dur = dur
|
||||
@easing_from = window.position
|
||||
@easing_from = Vec2.new(window.position)
|
||||
@easing_to = pos
|
||||
|
||||
if set_as_static
|
||||
|
@ -140,10 +140,7 @@ class Funfriend::FunfriendContext < Funfriend::WindowContext
|
|||
@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,
|
||||
}
|
||||
window.position = (@easing_from * (1.0 - a) + @easing_to * a).xy_i
|
||||
|
||||
@wander_timer = WANDER_TIMER
|
||||
else
|
||||
|
@ -151,18 +148,15 @@ class Funfriend::FunfriendContext < Funfriend::WindowContext
|
|||
when .wander?
|
||||
@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, set_as_static: false)
|
||||
goto(@static_pos + Vec2.rand((0 .. 40)), 4.0, set_as_static: false)
|
||||
end
|
||||
when .follow?
|
||||
if !moving
|
||||
x_dist = window.cursor.position[:x]
|
||||
y_dist = window.cursor.position[:y]
|
||||
|
||||
x_target = window.position[:x]
|
||||
y_target = window.position[:y]
|
||||
x_target = window.position[:x].to_f
|
||||
y_target = window.position[:y].to_f
|
||||
|
||||
if x_dist.abs > FOLLOW_DIST
|
||||
x_target = window.position[:x] + x_dist - FOLLOW_DIST * x_dist.sign
|
||||
|
@ -171,10 +165,7 @@ class Funfriend::FunfriendContext < Funfriend::WindowContext
|
|||
y_target = window.position[:y] + y_dist - FOLLOW_DIST * y_dist.sign
|
||||
end
|
||||
|
||||
goto({
|
||||
x: x_target.to_i,
|
||||
y: y_target.to_i,
|
||||
}, 1.0)
|
||||
goto(Vec2.new(x_target, y_target), 1.0)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -182,11 +173,8 @@ class Funfriend::FunfriendContext < Funfriend::WindowContext
|
|||
|
||||
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
|
||||
@static_pos = Vec2.new(window.position) - held_at + Vec2.new(window.cursor.position)
|
||||
window.position = @static_pos.xy_i
|
||||
else
|
||||
@held_timer = @held_timer - dt
|
||||
if @held_timer <= 0
|
||||
|
@ -195,7 +183,7 @@ class Funfriend::FunfriendContext < Funfriend::WindowContext
|
|||
if @waiting_for_stable_pos
|
||||
@waiting_for_stable_pos = false
|
||||
|
||||
stable_pos_dist = (@static_pos[:x] - @started_holding_at[:x]).abs + (@static_pos[:y] - @started_holding_at[:y]).abs
|
||||
stable_pos_dist = @static_pos.dist(@started_holding_at)
|
||||
LOG.info { "travelled #{stable_pos_dist}" }
|
||||
|
||||
if !speaking
|
||||
|
@ -221,10 +209,10 @@ class Funfriend::FunfriendContext < Funfriend::WindowContext
|
|||
end
|
||||
end
|
||||
|
||||
Funfriend.add_context(ChatterContext.new(text, {
|
||||
x: window.position[:x] + window_size[:width] // 2,
|
||||
y: window.position[:y] - 20
|
||||
}, parent: self))
|
||||
Funfriend.add_context(ChatterContext.new(text, Vec2.new(
|
||||
window.position[:x] + window_size.x / 2,
|
||||
window.position[:y] - 20
|
||||
), parent: self))
|
||||
|
||||
SoundMan.play_sound("assets/sfx/talk#{(1..8).sample}.ogg")
|
||||
end
|
||||
|
|
|
@ -0,0 +1,181 @@
|
|||
require "math"
|
||||
|
||||
include Math
|
||||
|
||||
module Funfriend
|
||||
struct Vec2
|
||||
property x : Float64
|
||||
property y : Float64
|
||||
|
||||
def initialize(@x = 0.0, @y = 0.0)
|
||||
end
|
||||
def initialize(xy : Int32)
|
||||
@x = @y = xy
|
||||
end
|
||||
def initialize(xy : Float64)
|
||||
@x = @y = xy
|
||||
end
|
||||
def initialize(xy : NamedTuple(x: Int32, y: Int32))
|
||||
initialize(xy[:x], xy[:y])
|
||||
end
|
||||
def initialize(xy : NamedTuple(x: Float64, y: Float64))
|
||||
initialize(xy[:x], xy[:y])
|
||||
end
|
||||
def initialize(wh : NamedTuple(width: Int32, height: Int32))
|
||||
initialize(wh[:width], wh[:height])
|
||||
end
|
||||
|
||||
# swizzles
|
||||
|
||||
def xy
|
||||
{x: @x, y: @y}
|
||||
end
|
||||
def yx
|
||||
{x: @y, y: @x}
|
||||
end
|
||||
|
||||
# int swizzles
|
||||
|
||||
def xy_i
|
||||
{x: @x.to_i, y: @y.to_i}
|
||||
end
|
||||
def yx_i
|
||||
{x: @y.to_i, y: @x.to_i}
|
||||
end
|
||||
|
||||
def x_i
|
||||
x.to_i
|
||||
end
|
||||
def y_i
|
||||
y.to_i
|
||||
end
|
||||
|
||||
# simpler swizzle
|
||||
|
||||
def values
|
||||
{x, y}
|
||||
end
|
||||
|
||||
def dot(other : Vec2)
|
||||
x * other.x + y * other.y
|
||||
end
|
||||
|
||||
def cross(other : Vec2)
|
||||
Vec2.new(
|
||||
self.x * other.y - self.y * other.x,
|
||||
self.y * other.x - self.x * other.y
|
||||
)
|
||||
end
|
||||
|
||||
def angle
|
||||
atan2(y, x)
|
||||
end
|
||||
|
||||
def len
|
||||
sqrt(x ** 2 + y ** 2)
|
||||
end
|
||||
def square_len
|
||||
x ** 2 + y ** 2
|
||||
end
|
||||
|
||||
def angle(other : Vec2)
|
||||
self ** other / (self.length * other.length)
|
||||
end
|
||||
|
||||
def +(other : Vec2)
|
||||
Vec2.new(self.x + other.x, self.y + other.y)
|
||||
end
|
||||
def +(other : Number)
|
||||
Vec2.new(self.x + other, self.y + other)
|
||||
end
|
||||
def -(other : Vec2)
|
||||
Vec2.new(self.x - other.x, self.y - other.y)
|
||||
end
|
||||
def -(other : Number)
|
||||
Vec2.new(self.x - other, self.y - other)
|
||||
end
|
||||
def -
|
||||
Vec2.new(-self.x, -self.y)
|
||||
end
|
||||
def *(other : Vec2)
|
||||
Vec2.new(self.x * other.x, self.y * other.y)
|
||||
end
|
||||
def *(other : Number)
|
||||
Vec2.new(self.x * other, self.y * other)
|
||||
end
|
||||
def /(other : Vec2)
|
||||
Vec2.new(self.x / other.x, self.y / other.y)
|
||||
end
|
||||
def /(other : Number)
|
||||
Vec2.new(self.x / other, self.y / other)
|
||||
end
|
||||
|
||||
def clone
|
||||
Vec2.new(self.x, self.y)
|
||||
end
|
||||
|
||||
def normalize!
|
||||
m = length
|
||||
unless m == 0
|
||||
inverse = 1.0 / m
|
||||
self.x *= inverse
|
||||
self.y *= inverse
|
||||
end
|
||||
self
|
||||
end
|
||||
|
||||
def normalize
|
||||
clone.normalize!
|
||||
end
|
||||
|
||||
def scale!(scale : Float64)
|
||||
normalize!
|
||||
self.x *= scale
|
||||
self.y *= scale
|
||||
end
|
||||
|
||||
def scale(scale : Float64)
|
||||
clone.scale!(scale)
|
||||
end
|
||||
|
||||
def dist(other : Vec2)
|
||||
(self - other).len
|
||||
end
|
||||
def square_dist(other : Vec2)
|
||||
(self - other).square_len
|
||||
end
|
||||
|
||||
def ==(other : Vec2)
|
||||
self.x == other.x && self.y == other.y
|
||||
end
|
||||
|
||||
def !=(other : Vec2)
|
||||
self.x != other.x || self.y != other.y
|
||||
end
|
||||
|
||||
def to_s
|
||||
"(#{x}, #{y})"
|
||||
end
|
||||
def inspect
|
||||
"(x: #{x.inspect}, y: #{y.inspect})"
|
||||
end
|
||||
|
||||
def self.zero
|
||||
Vec2.new(0.0)
|
||||
end
|
||||
def self.additive_identity
|
||||
Vec2.new(0.0)
|
||||
end
|
||||
def self.multiplicative_identity
|
||||
Vec2.new(1.0)
|
||||
end
|
||||
|
||||
def self.from_polar(angle : Float64, length : Float64)
|
||||
Vec2.new(cos(angle) * length, sin(angle) * length)
|
||||
end
|
||||
|
||||
def self.rand(length : Range = (0 .. 1))
|
||||
from_polar((0..360).sample, length.sample)
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue