cube-tube/app/util/util.rb

176 lines
4.2 KiB
Ruby
Raw Permalink Normal View History

2023-03-08 03:06:29 +00:00
###########
# utility, math, and misc methods
# returns random val between min & max, inclusive
# needs integers, use rand if you don't need min/max and don't care much
def random(a, b = nil)
min = 0
max = 1
if a.is_a?(Range)
min = a.begin
max = a.last(1)[0]
elsif a.is_a?(Numeric) && b.is_a?(Numeric)
min = Integer(a)
max = Integer(b)
else
min = 0
max = a
end
2023-03-08 03:06:29 +00:00
rand((max + 1) - min) + min
end
# returns true the passed in % of the time
# ex: `percent_chance?(25)` -- 1/4 chance of returning true
def percent_chance?(percent)
error("percent param (#{percent}) can't be above 100!") if percent > 100.0
return false if percent == 0.0
return true if percent == 100.0
rand() < (percent / 100.0)
end
# strips away the junk added by GTK::OpenEntity
def open_entity_to_hash(open_entity)
open_entity.as_hash.except(:entity_id, :entity_name, :entity_keys_by_ref, :__thrash_count__)
end
# Executes the block for each intersection of the collections. Doesn't check
# intersections within a parameter
#
# Block arguments are an instance of each collection, ordered by the parameter
# order.
#
# ex:
# collide(tiles, enemies) do |tile, enemy|
# # do stuff!
# end
#
# collide(player, enemies) do |player, enemy|
# player.health -= enemy.power
# end
def collide(col1, col2, &block)
col1 = [col1] unless col1.is_a?(Array)
col2 = [col2] unless col2.is_a?(Array)
col1.each do |i|
col2.each do |j|
if i.intersect_rect?(j)
block.call(i, j)
end
end
end
end
# +angle+ is expected to be in degrees with 0 being facing right
def vel_from_angle(angle, speed)
[speed * Math.cos(deg_to_rad(angle)), speed * Math.sin(deg_to_rad(angle))]
end
# returns diametrically opposed angle
# uses degrees
def opposite_angle(angle)
add_to_angle(angle, 180)
end
# returns a new angle from the og `angle` one summed with the `diff`
# degrees! of course
def add_to_angle(angle, diff)
((angle + diff) % 360).abs
end
def deg_to_rad(deg)
(deg * Math::PI / 180).round(4)
end
# Returns degrees
def angle_for_dir(dir)
case dir
when DIR_RIGHT
0
when DIR_LEFT
180
when DIR_UP
90
when DIR_DOWN
270
else
error("invalid dir: #{dir}")
end
end
# checks if the passed in `rect` is outside of the `container`
# `container` can be any rectangle-ish data structure
def out_of_bounds?(container, rect)
rect.x > container.right ||
rect.x + rect.w < container.left ||
rect.y > container.top ||
rect.y + rect.h < container.bottom
end
# Raises an exception with the passing in error message
# `msg` - String
def error(msg)
raise StandardError.new(msg)
end
# The version of your game defined in `metadata/game_metadata.txt`
def version
$gtk.args.cvars['game_metadata.version'].value
end
# Name of who make the game
def dev_title
$gtk.args.cvars['game_metadata.devtitle'].value
end
# Title of the game
def title
$gtk.args.cvars['game_metadata.gametitle'].value
end
# debug mode is what's running when you're making the game
# when you build and ship your game, it's in production mode
def debug?
@debug ||= !$gtk.production
end
# whether or not you're on a mobile device (or simulating one)
def mobile?
$gtk.platform?(:mobile) || $gtk.args.state.simulate_mobile
end
# sets the passed in entity's color for the specified number of ticks
def flash(entity, color, tick_count)
entity.flashing = true
entity.flash_ticks_remaining = tick_count
entity.flash_color = color
end
def tick_flasher(entity)
if entity.flashing
entity.flash_ticks_remaining -= 1
entity.merge!(entity.flash_color)
if entity.flash_ticks_remaining <= 0
entity.flashing = false
reset_color(entity)
end
end
end
def reset_color(entity)
entity.a = nil
entity.r = nil
entity.g = nil
entity.b = nil
end
# Returns a hash of the x and y position coords of the center of the entity.
# The passed in `entity` must have x, y, h, and w attributes
#
# Ex:
# center_of({ x: 100, y: 100, w: 200, h: 250 })
# # => { x: 200.0, y: 225.0 }
def center_of(entity)
raise StandardError.new("entity does not have needed properties to find center; must have x, y, w, and h properties") unless entity.x && entity.y && entity.h && entity.w
{ x: entity.x + entity.w / 2, y: entity.y + entity.h / 2 }
end