4 Commits

22 changed files with 414 additions and 83 deletions
+33
View File
@@ -1,3 +1,36 @@
# number_factory
A game where you create combinations of numbers!
# UI elements
If you hover over the producers you will see the speed at which it produces.
If you hover over the consumer, you can see your next goal or quest
## tools
### Extractor
Extracts numbers. It is a three by three square and populates numbers from any
side (max 12) every time the producer ticks.
### Conveyer belt
Can move numbers around.
### Adder
Can output to either side but will only output to one space. Prefers the slot
on the left. If it is full though it will use the slots to the right
### Multiplier
### Subtractor
### Divider
### Exponent
### Logarithm
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 653 B

After

Width:  |  Height:  |  Size: 754 B

Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 335 B

Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 832 B

Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 550 B

Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 432 B

Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.
+7 -15
View File
@@ -14,11 +14,12 @@ TASKS = [
]
class Consumer
attr_reader :draw_x, :draw_y
attr_reader :draw_x, :draw_y, :size_x, :size_y
# Create consumer at a position with the number and rate specified
# @param x [Integer] X position to start at
# @param y [Integer] Y position to start at
def initialize(x, y, box_size, screen_width, screen_height)
def initialize(parent, x, y, box_size, screen_width, screen_height)
@parent = parent
@x = x - SIZE / 2
@y = y - SIZE / 2
@box_size = box_size
@@ -28,8 +29,8 @@ class Consumer
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])
@tooltip = @parent.register_dialouge(@x, @y, @box_size * SIZE, @box_size * SIZE, TASKS[@task_index], 500)
@size_x = @size_y = 3
end
# Consumes numbers created
@@ -41,16 +42,8 @@ class Consumer
@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
@tooltip.move(@draw_x, @draw_y)
end
# Draw the consumer. Uses the camera x and y to shift where it should draw
@@ -59,6 +52,5 @@ class Consumer
puts "Drawing at #{@x - camera_x}, #{@y - camera_y}"
end
@image.draw(@draw_x, @draw_y, 0, @camera_zoom, @camera_zoom)
@tooltip.draw()
end
end
+40 -26
View File
@@ -3,18 +3,26 @@
TEXT_SIZE = 20
TEXT_MARGIN = 3
class DialougeBox
attr_accessor :show
def initialize(parent_x, parent_y, screen_width, screen_height, text)
# @param draw_x [Integer]
# @param draw_y [Integer]
# @param size_x [Integer] The width that this should open at (in pixels at zero zoom)
# @param size_y [Integer] The height that this should open at (in pixels at zero zoom)
def initialize(x, y, size_x, size_y, screen_width, screen_height, text, box_size, hover_time)
@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
@x = x
@y = y
@size_x = size_x
@size_y = size_y
@screen_width = screen_width
@screen_height = screen_height
@box_size = box_size
@hover_time = hover_time
@show = false
@image = Gosu.render(((TEXT_MARGIN * 2) + TEXT_SIZE) * @longest_line, (TEXT_SIZE + TEXT_MARGIN) * @line_count) {
Gosu.draw_rect(
0,
@@ -26,34 +34,40 @@ class DialougeBox
)
Gosu::Image.from_text(text, TEXT_SIZE, font: FONT_PATH).draw(TEXT_MARGIN, TEXT_MARGIN)
}
@timer = 0
@draw_x = 0
@draw_y = 0
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
# Used to move the dialouge box around
# @param x [Integer] The x position to move to.
# @param y [Integer] The y position to move to.
def move(x, y)
@draw_x = x
@draw_y = y
end
# Update called every delta time
def update(delta_mult, camera_zoom, mouse_x, mouse_y)
@camera_zoom = camera_zoom
@x = x
@y = y
if 0 < mouse_x - @draw_x && mouse_x - @draw_x < (@size_x * @camera_zoom) && 0 < mouse_y - @draw_y && mouse_y - @draw_y < (@size_y * @camera_zoom)
@timer += 60.0 * delta_mult
if @timer > @hover_time
@show = true
end
else
@timer = 0
@show = false
end
end
## Draw the dialouge if it is supposed to be shown.
def draw()
if @show
@image.draw(@x, @y, 0, @camera_zoom, @camera_zoom)
@image.draw(@draw_x, @draw_y, 0, @camera_zoom, @camera_zoom)
end
end
end
+28
View File
@@ -0,0 +1,28 @@
# Nathan Hinton
#
# When placed it will extract numbers at a specified rate and place them on any
# conveyer belts that are adjacent to it.
class Extractor
attr_reader :draw_x, :draw_y, :size_x, :size_y
def initialize(x, y, box_size)
@size_x = @size_y = 3
@x = x - @size_x / 2
@y = y - @size_y / 2
@box_size = box_size
@image = Gosu.render((@size_x * @box_size) - (2 * BORDER), (@size_y * @box_size) - (2 * BORDER)) {
Gosu::Image.new('assets/images/extractor.png').draw(0, 0, 0, @box_size / 32.0, @box_size / 32.0)
Gosu::Image.from_text("#{@number}", 20, font: FONT_PATH).draw(10 / 32.0 * @box_size, (8 / 32.0 * @box_size), 1, 2, 2, 0xFFFA32C0)
}
end
def update(delta_mult, camera_x, camera_y, camera_zoom)
@draw_x = (((((WIDTH / @box_size.to_f) / 2.0) + (@x - camera_x) * camera_zoom) * @box_size) + BORDER * camera_zoom)
@draw_y = (((((HEIGHT / @box_size.to_f) / 2.0) + (@y - camera_y) * camera_zoom) * @box_size) + BORDER * camera_zoom)
@camera_zoom = camera_zoom
end
def draw()
@image.draw(@draw_x, @draw_y, 0, @camera_zoom, @camera_zoom)
end
end
+71
View File
@@ -0,0 +1,71 @@
# Nathan Hinton
# Holds a grid of each otem in the game
class GameGrid
def initialize(game_width, game_height)
@game_grid = []
game_width.times do |xx|
@game_grid.append(Array.new(game_height))
end
end
## Add an item to the grid
# @param x [Integer] The x position (top left corner of item)
# @param y [Integer] The y position (top left corner of item)
# @param item [Object] The item to add. Should be an actual reference to the item
# @retval [Boolean] True if the item was placed, false otherwise (space conflict)
def add_item(x, y, item)
size_x = item.size_x
size_y = item.size_y
puts "#{item.to_s}"
puts "top left: (#{x}, #{y}), size: (#{size_x}, #{size_y})"
# Check that the grid is empty in those spots:
size_x.times do |xx|
size_y.times do |yy|
unless @game_grid[x + xx][y + yy].nil?
puts "Failed to add item: #{item.to_s}:"
puts " - top left: (#{x}, #{y}), size: (#{size_x}, #{size_y}), collision: (#{xx}, #{yy})"
return false
end
end
end
# place item in grid
size_x.times do |xx|
size_y.times do |yy|
@game_grid[x + xx][y + yy] = item
end
end
return true
end
## Add an item to the grid
# @param x [Integer] The x position (top left corner of item)
# @param y [Integer] The y position (top left corner of item)
# @param item [Object] The item to remove. Used to ensure we are removing the right thing.
def remove_item(x, y, item)
size_x = item.size_x
size_y = item.size_y
# Check that the grid is empty in those spots:
size_x.times do |xx|
size_y.times do |yy|
if @game_grid[x + xx][y + yy] != item
raise RuntimeError.new('Item mismatch in internal game grid! Game state corrupted1')
end
end
end
# place item in grid
size_x.times do |xx|
size_y.times do |yy|
@game_grid[x + xx][y + yy] = nil
end
end
end
end
+144 -21
View File
@@ -5,9 +5,12 @@
require 'gosu'
require 'yaml'
require './gamegrid.rb'
require './extractor.rb'
require './producer.rb'
require './consumer.rb'
require './dialouge_box.rb'
require './ui.rb'
FONT_PATH = 'assets/font/Cousine-Regular.ttf'
@@ -18,8 +21,8 @@ BOX_SIZE = 64
# Default game settings
GAME_SAVE_DIRECTORY = 'game_save_data'
GAME_WIDTH = 101 # Odd numbers look best, in squares
GAME_HEIGHT = 101
GAME_WIDTH = 201 # Odd numbers look best, in squares
GAME_HEIGHT = 201
GAME_PRODUCER_CHANCE = 0.01
GAME_PRODUCER_VALUE_MULT = 0.1
GAME_PRODUCER_BASE_SPEED = 1
@@ -32,11 +35,16 @@ CAMERA_MIN_ZOOM = 16 # Boxes across
CAMERA_MAX_ZOOM = 80 # Boxes across
class NumFactory < Gosu::Window
attr_accessor :current_tool
def initialize
super WIDTH, HEIGHT, :fullscreen => true
self.caption = "Number factory"
@background_color = Gosu::Color::BLUE
@cursor_image = Gosu::Image.new('assets/images/cursor.png')
@cursor = @cursor_image
@cursor_offset = 16
@camera_x = 0
@camera_y = 0
@@ -45,9 +53,19 @@ class NumFactory < Gosu::Window
@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!")
@ui = UI.new(self, WIDTH, HEIGHT)
@current_tool = nil
@extractor_image = Gosu::Image.new('assets/images/extractor.png')
@belt_image = Gosu::Image.new('assets/images/belt.png')
@adder_image = Gosu::Image.new('assets/images/adder.png')
@delete_image = Gosu::Image.new('assets/images/delete.png')
@dialouges = []
@extractors = []
# Setup the game grid
@game_grid = GameGrid.new(GAME_WIDTH, GAME_HEIGHT)
# Load from file or initialize a new game
begin
game_save_data = YAML.load_file("#{GAME_SAVE_DIRECTORY}/positions.yaml")
@@ -74,18 +92,20 @@ class NumFactory < Gosu::Window
# Loop through and place producers
center_x = ((@game_width - 1) / 2).to_i
center_y = ((@game_height - 1) / 2).to_i
@consumers.append(
Consumer.new(center_x, center_y, BOX_SIZE, WIDTH, HEIGHT),
)
consumer = Consumer.new(self, center_x, center_y, BOX_SIZE, WIDTH, HEIGHT)
if @game_grid.add_item(center_x, center_y, consumer)
@consumers.append(consumer)
end
# The value of the producer is proportional to the distance from the center
((@game_width).to_i).times do |xx|
(@game_height).to_i.times do |yy|
if rand < GAME_PRODUCER_CHANCE
# Place a producer:
@producers.append(
producer =
Producer.new(
self,
xx,
yy,
(Math.sqrt((xx - center_x)**2 + (yy - center_y) ** 2) * GAME_PRODUCER_VALUE_MULT).to_i,
@@ -94,7 +114,10 @@ class NumFactory < Gosu::Window
WIDTH,
HEIGHT,
)
)
# Add an item to the game with checking that the internal game state is good
if @game_grid.add_item(xx, yy, producer)
@producers.append(producer)
end
end
end
end
@@ -121,8 +144,44 @@ class NumFactory < Gosu::Window
end
# Disable cursor in the window
def needs_cursor?
false
end
def button_down(id)
### Process mouse ###
mouse_used = @ui.update(self.mouse_x, self.mouse_y)
# They clicked in the game screen, attempt to place an item
if !mouse_used && id == Gosu::MS_LEFT
case @current_tool
when 'delete'
@cursor = @delete_image
@cursor_offset = @delete_image.height
#break
when 'belt'
@cursor = @belt_image
@cursor_offset = @belt_image.height
#break
when 'adder'
@cursor = @adder_image
@cursor_offset = @adder_image.height
#break
when 'extractor'
#xx = @camera_x + ((((self.mouse_x) - (WIDTH/2)) / BOX_SIZE - 1) * @camera_zoom).to_i
#yy = @camera_y + ((((self.mouse_y) - (HEIGHT/2)) / BOX_SIZE - 1) * @camera_zoom).to_i
xx = @camera_x + ((self.mouse_x - @cursor_offset + (BOX_SIZE * @camera_zoom)) / (BOX_SIZE * @camera_zoom)).to_i
yy = @camera_y + ((self.mouse_y - @cursor_offset + (BOX_SIZE * @camera_zoom)) / (BOX_SIZE * @camera_zoom))
extractor = Extractor.new(xx, yy, BOX_SIZE)
if @game_grid.add_item(xx, yy, extractor)
@extractors.append(extractor)
end
#break
end
end
### Process keyboard ###
if id == Gosu::KB_ESCAPE
close
elsif [Gosu::MS_WHEEL_UP, Gosu::KB_Z].include? id
@@ -154,12 +213,34 @@ class NumFactory < Gosu::Window
@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_G
@cursor = @cursor_image
@cursor_offset = 16
@current_tool = nil
else
super
end
end
## Register a dialouge into the game
# @param x [Integer] The x position that the dialouge should be drawn at.
# @param y [Integer] The y position that the dialouge should be drawn at.
# @param size_x [Integer] The pixel width
# @param size_y [Integer] The pixel width
# @param text [String] The text for the dialouge box
def register_dialouge(x, y, size_x, size_y, text, popup_time)
dialouge = DialougeBox.new(x, y, size_x, size_y, WIDTH, HEIGHT, text, BOX_SIZE, popup_time)
@dialouges.append(dialouge)
return dialouge
end
## Remove a dialouge from the game
# @param dialouge [DialougeBox] The dialouge to remove
def deregister_dialouge(dialouge)
@dialouges.delete(dialouge)
end
## Called every frame
def update
@delta_time = Time.now() - @tick_time
@@ -182,36 +263,58 @@ class NumFactory < Gosu::Window
end
# Prevent camera from leaving the screen
@camera_x = [@camera_x, 0].max
@camera_x = [@camera_x, @game_width].min
@camera_y = [@camera_y, 0].max
@camera_y = [@camera_y, @game_width].min
@camera_x = [@camera_x.to_i, 0].max
@camera_x = [@camera_x.to_i, @game_width].min
@camera_y = [@camera_y.to_i, 0].max
@camera_y = [@camera_y.to_i, @game_width].min
### ITEMS ###
@producers.each do |producer|
producer.update(delta_mult, @camera_x, @camera_y, @camera_zoom, self.mouse_x, self.mouse_y)
producer.update(delta_mult, @camera_x, @camera_y, @camera_zoom)
end
@belts.each do |belt|
belt.update(delta_mult)
@extractors.each do |extractor|
extractor.update(delta_mult, @camera_x, @camera_y, @camera_zoom)
end
@consumers.each do |consumer|
consumer.update(delta_mult, @camera_x, @camera_y, @camera_zoom, self.mouse_x, self.mouse_y)
end
# Finally process the dialouges
@dialouges.each do |dialouge|
dialouge.update(0, 0, newtext: "My new text is: #{delta_mult}")
dialouge.update(delta_mult, @camera_zoom, self.mouse_x, self.mouse_y)
end
case @current_tool
when 'delete'
@cursor = @delete_image
@cursor_offset = @delete_image.height
#break
when 'belt'
@cursor = @belt_image
@cursor_offset = @belt_image.height
#break
when 'adder'
@cursor = @adder_image
@cursor_offset = @adder_image.height
#break
when 'extractor'
@cursor = @extractor_image
@cursor_offset = @extractor_image.height
#break
end
end
## Called when OS wants to update window.
def draw
# Draw mouse coords:
onscreen_items = 0
# TODO: The background does *not* actually need to move. It can just stay
# in one spot and scale... This would make the program load so much faster
# as well as allow for larger maps.
@background.draw(
(((((WIDTH / BOX_SIZE.to_f) / 2.0) - (@camera_x * @camera_zoom)) * (BOX_SIZE))),
((((HEIGHT / BOX_SIZE.to_f) / 2.0) - (@camera_y * @camera_zoom)) * (BOX_SIZE)),
0,
@camera_zoom,
@@ -226,6 +329,15 @@ class NumFactory < Gosu::Window
end
end
end
@extractors.each do |extractor|
if extractor.draw_x <= WIDTH && extractor.draw_x >= 0
if extractor.draw_y <= HEIGHT && extractor.draw_y >= 0
extractor.draw()
onscreen_items += 1
end
end
end
@consumers.each do |consumer|
if consumer.draw_x <= WIDTH && consumer.draw_x >= 0
@@ -240,8 +352,12 @@ class NumFactory < Gosu::Window
dialouge.draw()
end
@ui.draw()
Gosu::Image.from_text("#{width}, #{height}", 20, font: FONT_PATH).draw(1600, 0, 1)
Gosu::Image.from_text("#{mouse_x}, #{mouse_y}", 20, font: FONT_PATH).draw(1600, 100, 1)
Gosu::Image.from_text("#{@camera_x + ((self.mouse_x - @cursor_offset + (BOX_SIZE * @camera_zoom)) / (BOX_SIZE * @camera_zoom)).to_i}, #{@camera_y + ((self.mouse_y - (HEIGHT/2)) / BOX_SIZE * @camera_zoom).to_i}", 20, font: FONT_PATH).draw(1600, 125, 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)
@@ -249,6 +365,13 @@ class NumFactory < Gosu::Window
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)
if @cursor == @cursor_image
@cursor.draw(self.mouse_x - @cursor_offset, self.mouse_y - @cursor_offset, 10)
else
@cursor.draw(self.mouse_x - @cursor_offset, self.mouse_y - @cursor_offset, 10, BOX_SIZE / 32.0 * @camera_zoom, BOX_SIZE / 32.0 * @camera_zoom, 0x88_888888)
end
Gosu.draw_rect(self.mouse_x - 2, self.mouse_y - 2, 4, 4, Gosu::Color::RED)
end
end
+12 -21
View File
@@ -1,23 +1,20 @@
## Nathan Hinton
## A number producer that will create numbers when an extractor is placed on it.
require './dialouge_box.rb'
PRODUCER_DEBUG = false
BORDER = 2
HOVER_TIME = 500 # ms
class Producer
attr_reader :draw_x, :draw_y
attr_reader :draw_x, :draw_y, :size_x, :size_y
# Create producer at a position with the number and rate specified
# @param x [Integer] X position to start at
# @param y [Integer] Y position to start at
# @param number [Integer] The number to produce
# @param rate [Integer] The speed in numbers per second to produce
def initialize(x, y, number, rate, box_size, screen_width, screen_height)
def initialize(parent, x, y, number, rate, box_size, screen_width, screen_height)
@x = x
@y = y
@parent = parent
@number = [number, 1].max
@rate = rate
@box_size = box_size
@@ -25,12 +22,15 @@ class Producer
@screen_height = screen_height
@image = Gosu.render(@box_size - (2 * BORDER), @box_size - (2 * BORDER)) {
# Render the item
Gosu.draw_rect(0, 0, @box_size - (2 * BORDER), @box_size - (2 * BORDER), Gosu::Color::RED, 0)
Gosu::Image.from_text("#{@number}", 20, font: FONT_PATH).draw(5, 5, 1)
Gosu::Image.new('assets/images/producer.png').draw(0, 0, 0, @box_size / 32.0, @box_size / 32.0)
Gosu::Image.from_text("#{@number}", 20, font: FONT_PATH).draw(10 / 32.0 * @box_size, (8 / 32.0 * @box_size), 1, 2, 2, 0xFFFA32C0)
}
@tooltip = DialougeBox.new(@x, @y, WIDTH, HEIGHT, "Produces #{@rate} number per second")
puts "X: #{@x}, Y: #{@y}"
@tooltip = @parent.register_dialouge(@x, @y, @box_size, @box_size, "Produces #{@rate} number per second", 500)
@size_x = @size_y = 1
end
# Creates numbers depending on the rate. This is done with knowing that the
# game is 30 fps so we use that for a counter
@@ -39,20 +39,12 @@ class Producer
# @param camera_x [Integer] The camera X position
# @param camera_y [Integer] The camera Y position
# @param camera_zoom [Float] The camera zoom
def update(delta_mult, camera_x, camera_y, camera_zoom, mouse_x, mouse_y)
def update(delta_mult, camera_x, camera_y, camera_zoom)
@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
@tooltip.move(@draw_x, @draw_y)
end
# Draw the producer. Uses the camera x and y to shift where it should draw
@@ -61,6 +53,5 @@ class Producer
puts "Drawing at #{@x - camera_x}, #{@y - camera_y}"
end
@image.draw(@draw_x, @draw_y, 0, @camera_zoom, @camera_zoom)
@tooltip.draw()
end
end
+79
View File
@@ -0,0 +1,79 @@
# Nathan Hinton
# This is the UI for the game and will contain all of the sub elements required.
# There will be three main areas that we will be in charge of. First, the
# bottom bar has the selector of item types. There will be a menu in the top
# right as well as any store things that we need/
class UI
# Setup for the UI
# @param width [Integer] Width of screen in pixels
# @param height [Integer] Height of the screen in pixels
def initialize(parent, width, height)
@parent = parent
@width = width
@height = height
@tool_selector = []
@toolbar_width = width / 2
@toolbar_height = height / 9
@tool_info = [
['extractor', 96],
['belt', 32],
['adder', 64],
['delete', 32],
]
@tool_selector_image = Gosu.render(@toolbar_width, @toolbar_height) {
Gosu.draw_rect(
0,
0,
@toolbar_width,
@toolbar_height,
Gosu::Color.new(0xC0, 0xFF, 0xFF, 0xFF),
0)
# Loop through the tools:
@tool_info.each_with_index do |path, idx|
Gosu::Image.new("assets/images/#{path[0]}.png").draw(
idx * (@toolbar_height + 2),
2,
0,
(@toolbar_height / path[1].to_f),
(@toolbar_height / path[1].to_f),
)
end
}
@x = (@width / 2) - (@toolbar_width / 2)
@y = @height - @toolbar_height
@mouse_down_last_update = false
end
def update(mouse_x, mouse_y)
managed = false
# Only check if we are clicking
if Gosu.button_down?(Gosu::MS_LEFT)
if !@mouse_down_last_update
puts 'mouse clicked'
@mouse_down_last_update = true
# Check if we are in the right y area:
if mouse_y > @y
# Check if we are within the right zone
mouse_x_inset = mouse_x - @x
if 0 < mouse_x_inset && mouse_x_inset < @toolbar_width
managed = true
item_index = mouse_x_inset / (@toolbar_height + 2)
if item_index < @tool_info.length
@parent.current_tool = @tool_info[item_index][0]
puts "Selected item!"
end
end
end
end
else
@mouse_down_last_update = false
end
return managed
end
def draw()
@tool_selector_image.draw(@x, @y)
end
end