Compare commits

3 Commits

Author SHA1 Message Date
bionickatana 46d45783f3 Add dialouge boxes/tooltips (#10)
- [x] Update objects so they know when the mouse is on them
- [x] Remove testing code
- [x] Add into the producers
- [x] Add into the consumer
- [x] Standardize fonts

---------

Co-authored-by: leah <leah@hintonclan.org>
Reviewed-on: #10
2026-06-14 22:29:14 -06:00
bionickatana 693f5b83e9 Update main.rb (#8)
This works. I did find out in my testing that it might not set the zoom correct however as soon as you do zoom it works properly. Also odd aspect ratios (eg not my aspect ratio) cause the squares to be not so square

Reviewed-on: #8
Co-authored-by: nathan <nathan@hintonclan.org>
Co-committed-by: nathan <nathan@hintonclan.org>
2026-06-14 15:32:57 -06:00
bionickatana 8e7c0c9078 Fixed coordinate system and finally got zoom working (#1)
Reviewed-on: nathan/number_factory#1
Co-authored-by: bionickatana <nathan@hintonclan.org>
Co-committed-by: bionickatana <nathan@hintonclan.org>
2026-06-14 11:12:32 -06:00
5 changed files with 257 additions and 117 deletions
Binary file not shown.
+45 -18
View File
@@ -1,37 +1,64 @@
## Nathan Hinton ## Nathan Hinton
## A number consumer that will create numbers when an extractor is placed on it. ## A number consumer that will create numbers when an extractor is placed on it.
require './dialouge_box.rb'
CONSUMER_DEBUG = false CONSUMER_DEBUG = false
BORDER = 2
SIZE = 3
HOVER_TIME = 500 # ms
# This actually should be stored somewhere else. This is the goals/quests for the game
TASKS = [
"Collect 10 1's"
]
class Consumer class Consumer
attr_reader :x, :y attr_reader :draw_x, :draw_y
# Create consumer at a position with the number and rate specified # Create consumer at a position with the number and rate specified
# @param x [Integer] X position to start at # @param x [Integer] X position to start at
# @param y [Integer] Y position to start at # @param y [Integer] Y position to start at
# @param number [Integer] The number to produce def initialize(x, y, box_size, screen_width, screen_height)
# @param rate [Integer] The speed in numbers per second to produce @x = x - SIZE / 2
def initialize(x, y) @y = y - SIZE / 2
@x = x @box_size = box_size
@y = y @screen_width = screen_width
@image = Gosu.render(30, 30) {Gosu.draw_rect(0, 0, 30, 30, Gosu::Color::GREEN, 0)} @screen_height = screen_height
#Gosu::Image.new('assets/images/background_square.png', {:tileable => true}) @image = Gosu.render((SIZE * @box_size) - (2 * BORDER), (SIZE * @box_size) - (2 * BORDER)) {
Gosu.draw_rect(0, 0, (SIZE * @box_size) - (2 * BORDER), (SIZE * @box_size) - (2 * BORDER), Gosu::Color::GREEN, 0)
}
@task_index = 0
@tooltip_timer = 0
@tooltip = DialougeBox.new(@x, @y, WIDTH, HEIGHT, TASKS[@task_index])
end end
# Creates numbers depending on the rate. This is done with knowing that the # Consumes numbers created
# game is 30 fps so we use that for a counter
# @param delta_mult [Float] The delta multiplier for any actions # @param delta_mult [Float] The delta multiplier for any actions
def update(delta_mult)
end
# Draw the consumer. Uses the camera x and y to shift where it should draw
# @param camera_x [Integer] The camera X position # @param camera_x [Integer] The camera X position
# @param camera_y [Integer] The camera Y position # @param camera_y [Integer] The camera Y position
# @param camera_zoom [Float] The camera zoom # @param camera_zoom [Float] The camera zoom
def draw(camera_x, camera_y, camera_zoom) def update(delta_mult, camera_x, camera_y, camera_zoom, mouse_x, mouse_y)
if CONSUMER_DEBUG @draw_x = (((((@screen_width / @box_size.to_f) / 2.0) + (@x - camera_x) * camera_zoom) * @box_size) + BORDER * camera_zoom)
@draw_y = (((((@screen_height / @box_size.to_f) / 2.0) + (@y - camera_y) * camera_zoom) * @box_size) + BORDER * camera_zoom)
@camera_zoom = camera_zoom
if 0 < mouse_x - @draw_x && mouse_x - @draw_x < (SIZE * @box_size * @camera_zoom) && 0 < mouse_y - @draw_y && mouse_y - @draw_y < (SIZE * @box_size * @camera_zoom)
@tooltip_timer += 60.0 * delta_mult
if @tooltip_timer > HOVER_TIME
@tooltip.show = true
@tooltip.update(@draw_x, @draw_y, @camera_zoom)
end
else
@tooltip_timer = 0
@tooltip.show = false
end
end
# Draw the consumer. Uses the camera x and y to shift where it should draw
def draw()
if PRODUCER_DEBUG
puts "Drawing at #{@x - camera_x}, #{@y - camera_y}" puts "Drawing at #{@x - camera_x}, #{@y - camera_y}"
end end
@image.draw(camera_zoom * (@x - camera_x), camera_zoom * (@y - camera_y), 0, camera_zoom, camera_zoom) @image.draw(@draw_x, @draw_y, 0, @camera_zoom, @camera_zoom)
@tooltip.draw()
end end
end end
+59
View File
@@ -0,0 +1,59 @@
# Nathan Hinotn
# Creates a simple dialouge box that can be spawned from any location
TEXT_SIZE = 20
TEXT_MARGIN = 3
class DialougeBox
attr_accessor :show
def initialize(parent_x, parent_y, screen_width, screen_height, text)
@text = text
@longest_line = ((@text.split("\n").map { |ss| ss.length}.max) / 2.25).to_i
@line_count = @text.split("\n").length
@x = parent_x
@y = parent_y
@show = false
@screen_width = screen_width
@screen_height = screen_height
@image = Gosu.render(((TEXT_MARGIN * 2) + TEXT_SIZE) * @longest_line, (TEXT_SIZE + TEXT_MARGIN) * @line_count) {
Gosu.draw_rect(
0,
0,
(((TEXT_MARGIN * 2) + TEXT_SIZE) * @longest_line) + @x,
((TEXT_SIZE + TEXT_MARGIN) * @line_count) + @y,
Gosu::Color.new(0xC0, 0xFF, 0xFF, 0xFF),
0,
)
Gosu::Image.from_text(text, TEXT_SIZE, font: FONT_PATH).draw(TEXT_MARGIN, TEXT_MARGIN)
}
end
def update(x, y, camera_zoom, newtext: nil)
if !newtext.nil?
@text = newtext
@longest_line = ((@text.split("\n").map { |ss| ss.length}.max) / 3.5).to_i
@line_count = @text.split("\n").length
@image = Gosu.render(((TEXT_MARGIN * 2) + TEXT_SIZE) * @longest_line, (TEXT_SIZE + TEXT_MARGIN) * @line_count) {
Gosu.draw_rect(
0,
0,
(((TEXT_MARGIN * 2) + TEXT_SIZE) * @longest_line) + @x,
((TEXT_SIZE + TEXT_MARGIN) * @line_count) + @y,
Gosu::Color.new(0xC0, 0xFF, 0xFF, 0xFF),
0,
)
Gosu::Image.from_text(newtext, TEXT_SIZE, font: FONT_PATH).draw(TEXT_MARGIN, TEXT_MARGIN)
}
end
@camera_zoom = camera_zoom
@x = x
@y = y
end
def draw()
if @show
@image.draw(@x, @y, 0, @camera_zoom, @camera_zoom)
end
end
end
+113 -81
View File
@@ -7,25 +7,29 @@ require 'yaml'
require './producer.rb' require './producer.rb'
require './consumer.rb' require './consumer.rb'
require './dialouge_box.rb'
FONT_PATH = 'assets/font/Cousine-Regular.ttf'
# Viewport resolution # Viewport resolution
WIDTH = 640*2 WIDTH = Gosu::screen_width
HEIGHT = 480*2 HEIGHT = Gosu::screen_height
BOX_SIZE = 64
# Default game settings # Default game settings
GAME_SAVE_DIRECTORY = 'game_save_data' GAME_SAVE_DIRECTORY = 'game_save_data'
GAME_WIDTH = 10000 GAME_WIDTH = 101 # Odd numbers look best, in squares
GAME_HEIGHT = 10000 GAME_HEIGHT = 101
GAME_PRODUCER_CHANCE = 0.005 GAME_PRODUCER_CHANCE = 0.01
GAME_PRODUCER_VALUE_MULT = 0.1 GAME_PRODUCER_VALUE_MULT = 0.1
GAME_PRODUCER_BASE_SPEED = 1 GAME_PRODUCER_BASE_SPEED = 1
# Camera settings # Camera settings
CAMERA_MOVE_RANGE = 10 CAMERA_MOVE_RANGE = 10
CAMERA_MOVE_SPEED = 1 CAMERA_MOVE_SPEED = 1
CAMERA_MOVE_MAX_SPEED = (CAMERA_MOVE_RANGE * CAMERA_MOVE_SPEED / 2).to_i CAMERA_MOVE_MAX_SPEED = 5
CAMERA_MIN_ZOOM = 0.7 CAMERA_MIN_ZOOM = 16 # Boxes across
CAMERA_MAX_ZOOM = 5 CAMERA_MAX_ZOOM = 80 # Boxes across
class NumFactory < Gosu::Window class NumFactory < Gosu::Window
def initialize def initialize
@@ -34,14 +38,17 @@ class NumFactory < Gosu::Window
@background_color = Gosu::Color::BLUE @background_color = Gosu::Color::BLUE
### CAMERA ###
# camera_x [Integer] Used to know the x position of the camera
# camera_y [Integer] Used to know the y position of the camera
# camera_zoom [Float] Used to know the zoom of the camera
@camera_x = 0 @camera_x = 0
@camera_y = 0 @camera_y = 0
@camera_zoom = 1.0 @camera_boxes = 30 # Default zoom
@camera_zoom = 1
@camera_x_zoom_offset = WIDTH.to_f / (@camera_boxes * BOX_SIZE * 2).to_f
@camera_y_zoom_offset = HEIGHT.to_f / (@camera_boxes * BOX_SIZE * 2).to_f
@dd = DialougeBox.new(0, 0, WIDTH, HEIGHT, "This is a really really really really really really really really really really string\nof test text!")
@dialouges = []
# Load from file or initialize a new game
begin begin
game_save_data = YAML.load_file("#{GAME_SAVE_DIRECTORY}/positions.yaml") game_save_data = YAML.load_file("#{GAME_SAVE_DIRECTORY}/positions.yaml")
puts game_save_data puts game_save_data
@@ -65,39 +72,46 @@ class NumFactory < Gosu::Window
# Loop through and place producers # Loop through and place producers
center_x = (@game_width / 60).to_i center_x = ((@game_width - 1) / 2).to_i
center_y = (@game_height / 60).to_i center_y = ((@game_height - 1) / 2).to_i
# Move the camera to the center of the map:
@camera_x = center_x * 30 - WIDTH / 2
@camera_y = center_y * 30 - HEIGHT / 2
@consumers.append( @consumers.append(
Consumer.new(center_x * 30, center_y * 30), Consumer.new(center_x, center_y, BOX_SIZE, WIDTH, HEIGHT),
) )
# The value of the producer is proportional to the distance from the center # The value of the producer is proportional to the distance from the center
((@game_width / 30).to_i).times do |xx| ((@game_width).to_i).times do |xx|
(@game_height / 30).to_i.times do |yy| (@game_height).to_i.times do |yy|
if rand < GAME_PRODUCER_CHANCE if rand < GAME_PRODUCER_CHANCE
# Place a producer: # Place a producer:
@producers.append( @producers.append(
Producer.new( Producer.new(
xx * 30, xx,
yy * 30, yy,
(Math.sqrt((xx - center_x)**2 + (yy - center_y) ** 2) * GAME_PRODUCER_VALUE_MULT).to_i, (Math.sqrt((xx - center_x)**2 + (yy - center_y) ** 2) * GAME_PRODUCER_VALUE_MULT).to_i,
GAME_PRODUCER_BASE_SPEED) GAME_PRODUCER_BASE_SPEED,
BOX_SIZE,
WIDTH,
HEIGHT,
)
) )
end end
end end
end end
end # End file loading end # End file loading
@background = Gosu.render(@game_width, @game_height) { # Move the camera to the center of the map:
@camera_x = @game_width / 2
@camera_y = @game_height / 2
# Render the background
@background = Gosu.render(@game_width * BOX_SIZE, @game_height * BOX_SIZE) {
im = Gosu::Image.new('assets/images/background_square.png', {:tileable => true}) im = Gosu::Image.new('assets/images/background_square.png', {:tileable => true})
(@game_width / 30).to_i.times do |ww| zoom = BOX_SIZE / 30.0
(@game_height / 30).to_i.times do |hh| (@game_width).to_i.times do |ww|
im.draw(ww * 30, hh * 30) puts ww
(@game_height).to_i.times do |hh|
im.draw(ww * BOX_SIZE, hh * BOX_SIZE, 0, zoom, zoom)
end end
end end
} }
@@ -111,24 +125,35 @@ class NumFactory < Gosu::Window
def button_down(id) def button_down(id)
if id == Gosu::KB_ESCAPE if id == Gosu::KB_ESCAPE
close close
elsif id == Gosu::MS_WHEEL_UP elsif [Gosu::MS_WHEEL_UP, Gosu::KB_Z].include? id
@camera_zoom *= 1.1 @camera_boxes -= 2
if @camera_zoom > CAMERA_MAX_ZOOM if @camera_boxes < CAMERA_MIN_ZOOM
@camera_zoom = CAMERA_MAX_ZOOM @camera_boxes = CAMERA_MIN_ZOOM
else
@camera_x *= 1.0125
@camera_y *= 1.0125
end end
elsif id == Gosu::MS_WHEEL_DOWN @camera_zoom = WIDTH / (@camera_boxes * BOX_SIZE).to_f
@camera_zoom *= 0.9 @camera_x_zoom_offset = WIDTH.to_f / (@camera_boxes * BOX_SIZE * 2).to_f
if @camera_zoom < CAMERA_MIN_ZOOM @camera_y_zoom_offset = HEIGHT.to_f / (@camera_boxes * BOX_SIZE * 2).to_f
@camera_zoom = CAMERA_MIN_ZOOM elsif [Gosu::MS_WHEEL_DOWN, Gosu::KB_X].include? id
else @camera_boxes += 2
@camera_x *= 0.985 if @camera_boxes > CAMERA_MAX_ZOOM
@camera_y *= 0.985 @camera_boxes = CAMERA_MAX_ZOOM
end end
@camera_zoom = WIDTH.to_f / (@camera_boxes * BOX_SIZE).to_f
@camera_x_zoom_offset = WIDTH.to_f / (@camera_boxes * BOX_SIZE * 2).to_f
@camera_y_zoom_offset = HEIGHT.to_f / (@camera_boxes * BOX_SIZE * 2).to_f
elsif id == Gosu::KB_DOWN
@camera_y += 1
elsif id == Gosu::KB_UP
@camera_y -= 1
elsif id == Gosu::KB_LEFT
@camera_x -= 1
elsif id == Gosu::KB_RIGHT
@camera_x += 1
elsif id == Gosu::KB_SPACE elsif id == Gosu::KB_SPACE
@camera_zoom = 1.0 @camera_boxes = 30
@camera_zoom = WIDTH.to_f / (@camera_boxes * BOX_SIZE).to_f
@camera_x_zoom_offset = WIDTH.to_f / (@camera_boxes * BOX_SIZE * 2).to_f
@camera_y_zoom_offset = HEIGHT.to_f / (@camera_boxes * BOX_SIZE * 2).to_f
else else
super super
end end
@@ -145,32 +170,26 @@ class NumFactory < Gosu::Window
### CAMERA ### ### CAMERA ###
# Move the camera if needed # Move the camera if needed
if self.mouse_x < CAMERA_MOVE_RANGE if self.mouse_x < CAMERA_MOVE_RANGE
@camera_x -= ([(CAMERA_MOVE_SPEED * ((CAMERA_MOVE_RANGE - self.mouse_x ) / 2)).to_i, CAMERA_MOVE_MAX_SPEED].min * delta_mult * @camera_zoom) @camera_x -= ([(CAMERA_MOVE_SPEED * ((CAMERA_MOVE_RANGE - self.mouse_x ) / 5)), CAMERA_MOVE_MAX_SPEED].min * delta_mult)
elsif self.mouse_x > WIDTH - CAMERA_MOVE_RANGE elsif self.mouse_x > WIDTH - CAMERA_MOVE_RANGE
@camera_x += ([(CAMERA_MOVE_SPEED * ((CAMERA_MOVE_RANGE - (WIDTH - self.mouse_x) ) / 2)).to_i, CAMERA_MOVE_MAX_SPEED].min * delta_mult * @camera_zoom) @camera_x += ([(CAMERA_MOVE_SPEED * ((CAMERA_MOVE_RANGE - (WIDTH - self.mouse_x + 1)) / 5)), CAMERA_MOVE_MAX_SPEED].min * delta_mult)
end end
if self.mouse_y < CAMERA_MOVE_RANGE if self.mouse_y < CAMERA_MOVE_RANGE
@camera_y -= ([(CAMERA_MOVE_SPEED * ((CAMERA_MOVE_RANGE - self.mouse_y ) / 2)).to_i, CAMERA_MOVE_MAX_SPEED].min * delta_mult) @camera_y -= ([(CAMERA_MOVE_SPEED * ((CAMERA_MOVE_RANGE - self.mouse_y ) / 5)), CAMERA_MOVE_MAX_SPEED].min * delta_mult)
elsif self.mouse_y > HEIGHT - CAMERA_MOVE_RANGE elsif self.mouse_y > HEIGHT - CAMERA_MOVE_RANGE
@camera_y += ([(CAMERA_MOVE_SPEED * ((CAMERA_MOVE_RANGE - (HEIGHT - (self.mouse_y + 1)) ) / 2)).to_i, CAMERA_MOVE_MAX_SPEED].min * delta_mult) @camera_y += ([(CAMERA_MOVE_SPEED * ((CAMERA_MOVE_RANGE - (HEIGHT - (self.mouse_y + 1)) ) / 5)), CAMERA_MOVE_MAX_SPEED].min * delta_mult)
end end
# Prevent camera from leaving the screen # Prevent camera from leaving the screen
@camera_x = [@camera_x, -10].max @camera_x = [@camera_x, 0].max
@camera_x = [@camera_x, @game_width - (WIDTH / @camera_zoom) + 10].min @camera_x = [@camera_x, @game_width].min
@camera_y = [@camera_y, -10].max @camera_y = [@camera_y, 0].max
@camera_y = [@camera_y, @game_height - (HEIGHT / @camera_zoom) + 10].min @camera_y = [@camera_y, @game_width].min
# Setup variables used to know what portions of the screen need to be rendered
@camera_max_x = [@game_width, @camera_x + (WIDTH / @camera_zoom)].min
@camera_min_x = [0, @camera_x].max
@camera_max_y = [@game_height, @camera_y + (WIDTH / @camera_zoom)].min
@camera_min_y = [0, @camera_y].max
### ITEMS ### ### ITEMS ###
@producers.each do |producer| @producers.each do |producer|
producer.update(delta_mult) producer.update(delta_mult, @camera_x, @camera_y, @camera_zoom, self.mouse_x, self.mouse_y)
end end
@belts.each do |belt| @belts.each do |belt|
@@ -178,45 +197,58 @@ class NumFactory < Gosu::Window
end end
@consumers.each do |consumer| @consumers.each do |consumer|
consumer.update(delta_mult) consumer.update(delta_mult, @camera_x, @camera_y, @camera_zoom, self.mouse_x, self.mouse_y)
end end
@dialouges.each do |dialouge|
dialouge.update(0, 0, newtext: "My new text is: #{delta_mult}")
end
end end
## Called when OS wants to update window. ## Called when OS wants to update window.
def draw def draw
# Draw mouse coords: # Draw mouse coords:
onscreen_items = 0 onscreen_items = 0
Gosu.draw_rect( @background.draw(
[(@camera_min_x - @camera_x) * @camera_zoom, self.width].min, (((((WIDTH / BOX_SIZE.to_f) / 2.0) - (@camera_x * @camera_zoom)) * (BOX_SIZE))),
[(@camera_min_y - @camera_y) * @camera_zoom, self.width].min,
[self.width, (@camera_max_x - @camera_x) * @camera_zoom].min, ((((HEIGHT / BOX_SIZE.to_f) / 2.0) - (@camera_y * @camera_zoom)) * (BOX_SIZE)),
[self.height, (@camera_max_y - @camera_y) * @camera_zoom].min, 0,
@background_color, 0) @camera_zoom,
@background.draw(0, 0, 0, @camera_zoom, @camera_zoom) @camera_zoom
)
@producers.each do |producer| @producers.each do |producer|
if producer.x <= @camera_max_x && producer.x >= @camera_min_x if producer.draw_x <= WIDTH && producer.draw_x >= 0
if producer.y <= @camera_max_y && producer.y >= @camera_min_y if producer.draw_y <= HEIGHT && producer.draw_y >= 0
producer.draw(@camera_x, @camera_y, @camera_zoom) producer.draw()
onscreen_items += 1 onscreen_items += 1
end end
end end
end end
@consumers.each do |consumer| @consumers.each do |consumer|
if consumer.x <= (@camera_x + WIDTH) && consumer.x >= (@camera_x) if consumer.draw_x <= WIDTH && consumer.draw_x >= 0
if consumer.y <= (@camera_y + WIDTH) && consumer.y >= (@camera_y) if consumer.draw_y <= HEIGHT && consumer.draw_y >= 0
consumer.draw(@camera_x, @camera_y, @camera_zoom) consumer.draw()
onscreen_items += 1 onscreen_items += 1
end end
end end
end end
Gosu::Image.from_text("#{mouse_x}, #{mouse_y}", 20).draw(0, 100, 1)
Gosu::Image.from_text("Tick time: #{((Time.now() - @tick_time).to_f * 1000).to_i}", 20).draw(0, 25, 1) @dialouges.each do |dialouge|
Gosu::Image.from_text("FPS: #{Gosu.fps}", 20).draw(0, 50, 1) dialouge.draw()
Gosu::Image.from_text("items on screen: #{onscreen_items}", 20).draw(0, 75, 1) end
Gosu::Image.from_text("#{width}, #{height}", 20).draw(0, 0, 1)
Gosu::Image.from_text("Camera location: #{@camera_x}, #{@camera_y}", 20).draw(0, 200, 1) Gosu::Image.from_text("#{width}, #{height}", 20, font: FONT_PATH).draw(1600, 0, 1)
Gosu::Image.from_text("Camera zoom: #{@camera_zoom}", 20).draw(0, 225, 1) Gosu::Image.from_text("#{mouse_x}, #{mouse_y}", 20, font: FONT_PATH).draw(1600, 100, 1)
Gosu::Image.from_text("Camera viewport: (#{@camera_min_x}, #{@camera_min_y}) to (#{@camera_max_x}, #{@camera_max_y})", 20).draw(0, 250, 1) Gosu::Image.from_text("Tick time: #{((Time.now() - @tick_time).to_f * 1000).to_i}", 20, font: FONT_PATH).draw(1600, 25, 1)
Gosu::Image.from_text("FPS: #{Gosu.fps}", 20, font: FONT_PATH).draw(1600, 50, 1)
Gosu::Image.from_text("items on screen: #{onscreen_items}", 20, font: FONT_PATH).draw(1600, 75, 1)
Gosu::Image.from_text("Camera boxes: #{@camera_boxes}", 20, font: FONT_PATH).draw(1600, 175, 1)
Gosu::Image.from_text("Camera location: #{@camera_x}, #{@camera_y}", 20, font: FONT_PATH).draw(1600, 200, 1)
Gosu::Image.from_text("Camera zoom: #{@camera_zoom}, #{@camera_x_zoom_offset}", 20, font: FONT_PATH).draw(1600, 225, 1)
Gosu::Image.from_text("Camera viewport: (#{@camera_min_x}, #{@camera_min_y}) to (#{@camera_max_x}, #{@camera_max_y})", 20, font: FONT_PATH).draw(1600, 250, 1)
end end
end end
+35 -13
View File
@@ -1,44 +1,66 @@
## Nathan Hinton ## Nathan Hinton
## A number producer that will create numbers when an extractor is placed on it. ## A number producer that will create numbers when an extractor is placed on it.
require './dialouge_box.rb'
PRODUCER_DEBUG = false PRODUCER_DEBUG = false
BORDER = 2
HOVER_TIME = 500 # ms
class Producer class Producer
attr_reader :x, :y attr_reader :draw_x, :draw_y
# Create producer at a position with the number and rate specified # Create producer at a position with the number and rate specified
# @param x [Integer] X position to start at # @param x [Integer] X position to start at
# @param y [Integer] Y position to start at # @param y [Integer] Y position to start at
# @param number [Integer] The number to produce # @param number [Integer] The number to produce
# @param rate [Integer] The speed in numbers per second to produce # @param rate [Integer] The speed in numbers per second to produce
def initialize(x, y, number, rate) def initialize(x, y, number, rate, box_size, screen_width, screen_height)
@x = x @x = x
@y = y @y = y
@number = [number, 1].max @number = [number, 1].max
@rate = (30/rate).to_i @rate = rate
@image = Gosu.render(30, 30) { @box_size = box_size
@screen_width = screen_width
@screen_height = screen_height
@image = Gosu.render(@box_size - (2 * BORDER), @box_size - (2 * BORDER)) {
# Render the item # Render the item
Gosu.draw_rect(0, 0, 30, 30, Gosu::Color::RED, 0) Gosu.draw_rect(0, 0, @box_size - (2 * BORDER), @box_size - (2 * BORDER), Gosu::Color::RED, 0)
Gosu::Image.from_text("#{@number}", 20).draw(5, 5, 1) Gosu::Image.from_text("#{@number}", 20, font: FONT_PATH).draw(5, 5, 1)
} }
@tooltip = DialougeBox.new(@x, @y, WIDTH, HEIGHT, "Produces #{@rate} number per second")
end end
# Creates numbers depending on the rate. This is done with knowing that the # Creates numbers depending on the rate. This is done with knowing that the
# game is 30 fps so we use that for a counter # game is 30 fps so we use that for a counter
# @param delta_mult [Float] The delta multiplier for any actions # @param delta_mult [Float] The delta multiplier for any actions
def update(delta_mult)
end
# Draw the producer. Uses the camera x and y to shift where it should draw
# @param camera_x [Integer] The camera X position # @param camera_x [Integer] The camera X position
# @param camera_y [Integer] The camera Y position # @param camera_y [Integer] The camera Y position
# @param camera_zoom [Float] The camera zoom # @param camera_zoom [Float] The camera zoom
def draw(camera_x, camera_y, camera_zoom) def update(delta_mult, camera_x, camera_y, camera_zoom, mouse_x, mouse_y)
@draw_x = (((((@screen_width / @box_size.to_f) / 2.0) + (@x - camera_x) * camera_zoom) * @box_size) + BORDER * camera_zoom)
@draw_y = (((((@screen_height / @box_size.to_f) / 2.0) + (@y - camera_y) * camera_zoom) * @box_size) + BORDER * camera_zoom)
@camera_zoom = camera_zoom
if 0 < mouse_x - @draw_x && mouse_x - @draw_x < (@box_size * @camera_zoom) && 0 < mouse_y - @draw_y && mouse_y - @draw_y < (@box_size * @camera_zoom)
@tooltip_timer += 60.0 * delta_mult
if @tooltip_timer > HOVER_TIME
@tooltip.show = true
@tooltip.update(@draw_x, @draw_y, @camera_zoom)
end
else
@tooltip_timer = 0
@tooltip.show = false
end
end
# Draw the producer. Uses the camera x and y to shift where it should draw
def draw()
if PRODUCER_DEBUG if PRODUCER_DEBUG
puts "Drawing at #{@x - camera_x}, #{@y - camera_y}" puts "Drawing at #{@x - camera_x}, #{@y - camera_y}"
end end
@image.draw(camera_zoom * (@x - camera_x), camera_zoom * (@y - camera_y), 0, camera_zoom, camera_zoom) @image.draw(@draw_x, @draw_y, 0, @camera_zoom, @camera_zoom)
@tooltip.draw()
end end
end end