From cc93b5993d0ca3f4dc82d6bc97c163c1249f1d44 Mon Sep 17 00:00:00 2001 From: Cyberarm Date: Sun, 6 Oct 2019 21:34:39 -0500 Subject: [PATCH] Updated Camera to use Matrix, Map now draws image tiles instead of rects, fixed selected units order pushing full array instead of contents of array. --- assets/tilesets/default.png | Bin 1459 -> 4746 bytes lib/camera.rb | 29 +++++++++++++++-------------- lib/map.rb | 16 +++++++--------- lib/orders/selected_units.rb | 2 +- lib/states/game.rb | 25 ++++++++++++++----------- lib/window.rb | 3 +++ 6 files changed, 40 insertions(+), 35 deletions(-) diff --git a/assets/tilesets/default.png b/assets/tilesets/default.png index b9942df12da12b4f3dadad2e689b30bf82cbe1f1..aaddf19be0c20f0dfcfde75864dafc8f130c2804 100644 GIT binary patch literal 4746 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 b1eG5DX$njcGL^Xa=+hYAH@#P>2aEVGPUl#x delta 1441 zcmV;S1z!4!C9?~VB!3BTNLh0L04^f{04^f|c%?sf00007bV*G`2jc<^6D<)q=ty7y z000?uMObu0Z*6U5Zgc=ca%Ew3Wn>_CX>@2HM@dakSAh-}000FoNklnwa2&ns|#C z@Bs}92EmG2Dx*a%1ydM`w1q-xnHe9>?}U>&h$bc+$X?0LoY`leIZ3~7t@W+7ccbR_ zsBj7G_452n`Ffsv>$OYz{>tVjql>L67V;55bL+5Y&AvTgf-gFsoV+JAxNl41rhTrA|z0jq!~fKFf| z&ZZ1K4gRIl~|0kUUzneVp&hk?6I1prIDzeQcp2pmmmgK38UZNTrqBH$*ghBK}u ztpNf7vS-VI2UPvXfrrfh=LGp2un>3w*aQp$O@{p;U@Nc`7!S+_o&|b=L#B}s0WxfL zz)oPmuz%eSv;j%ZjwD5`;C~Ff0<2cgHF>??G*Kt;ANb5nps2PWh`?;xPM|}P*9u%G zcr|+YKHw9eCsposJ73bN7pVdIfnC5#;AP-Z(?$eD#X>#`5gwp5VM}5!^%n{fIV6i0V1MW#hgpYs^O@A46io%gVfNWYH@Tt+@XW%8EUU4_% znnvsV0f{mt^?Xfg?IRMR&B(G>B8>zQm`zK{we13VgPd?vD* z2!B;T2Cdd`UJ}$ps{2|X58Po7pcnXBPcJG4Crg&YK#Sn77x0qnPKPou`<@@AMk}z! zJikQn<`}fzN^G#d1KRGyzuuw*s#!4sRrG7w<`>nLvOHT3K&i=~!Xor{Bmh-tgWl z$oCrh=K>Q1x5aevj-h@K*pUK0=_>>gn14|LxI*Q>+R)wW{CG>c36^*_>)o>ye`UuB z1>+y~1iFE<)m|6~kUg6NJSF%Qh1>B|srQqgw-fIH^h<&h;+ZowEL0QxU%;O!Bp+WDic->?8 zKdMGJ2z=)J8{S)!>KBYlkt}F{EQWvg1d7DlzPlwtBk+wSV3~N6Xn|foS@pkL@Rtyu z7RnKy18DKymlt|*AVBu4OSO*?Ab+x?+n4g@wZtvrdh7ch8$iqK8?^ZSq-2;VS(XCF zfbRnVvTZqQ{7$QYxqd%lb7#5&uvZTs(fenoNK&#gNTNa47|l@$1h_neVWVRP@kY*V z#NEKR1+|rUBWNM#&kmG`&kp=3i4N-do5l*kK!9x8DF=dofViVq3v9LlRDW@<*Rn4; zJJ4o&K*Ds{I~ZrA2pZrrvt<9jkecgEiN|BaCxpHe=%>ZCgY!qfCK*8vSUv^= @viewport.min.x - @position.x && @@ -99,7 +100,7 @@ class IMICRTS when Gosu::MS_WHEEL_DOWN @zoom = (@zoom - 0.25).clamp(@min_zoom, @max_zoom) when Gosu::MS_MIDDLE - @drag_start = CyberarmEngine::Vector.new(window.mouse_x, window.mouse_y) - @position + @drag_start = pick(CyberarmEngine::Vector.new(window.mouse_x, window.mouse_y)) end end diff --git a/lib/map.rb b/lib/map.rb index 6e0ce34..81e20d1 100644 --- a/lib/map.rb +++ b/lib/map.rb @@ -1,11 +1,13 @@ class IMICRTS class Map - Tile = Struct.new(:position, :color, :size) + Tile = Struct.new(:position, :color, :image) def initialize(width:, height:, tile_size: 32) @width, @height = width, height @tile_size = tile_size + @tileset = Gosu::Image.load_tiles("#{ASSETS_PATH}/tilesets/default.png", tile_size, tile_size, retro: true) + @tiles = [] height.times do |y| @@ -14,7 +16,7 @@ class IMICRTS Tile.new( CyberarmEngine::Vector.new(x * @tile_size, y * @tile_size, ZOrder::TILE), Gosu::Color.rgb(rand(25), rand(150..200), rand(25)), - @tile_size + @tileset.sample ) ) end @@ -23,11 +25,7 @@ class IMICRTS def draw(camera) visible_tiles(camera).each do |tile| - Gosu.draw_rect( - tile.position.x, tile.position.y, - @tile_size, @tile_size, - tile.color, tile.position.z - ) + tile.image.draw(tile.position.x, tile.position.y, tile.position.z) end end @@ -38,10 +36,10 @@ class IMICRTS top_left.x = top_left.x.ceil top_left.y = top_left.y.ceil - top_left /= @tiles.first.size + top_left /= @tile_size # +1 to overdraw a bit to hide pop-in - _width = ($window.width / @tile_size) + 1 + _width = ($window.width / @tile_size) + 1 _height = ($window.height / @tile_size) + 1 _height.times do |y| diff --git a/lib/orders/selected_units.rb b/lib/orders/selected_units.rb index 65756b0..08c3aae 100644 --- a/lib/orders/selected_units.rb +++ b/lib/orders/selected_units.rb @@ -1,5 +1,5 @@ IMICRTS::Order.define_handler(IMICRTS::Order::SELECTED_UNITS, arguments: [:player_id, :ids]) do |order, director| director.player(order.player_id).selected_entities.clear - director.player(order.player_id).selected_entities.push(order.ids) + director.player(order.player_id).selected_entities.push(*order.ids) end diff --git a/lib/states/game.rb b/lib/states/game.rb index 09f5068..ac78f34 100644 --- a/lib/states/game.rb +++ b/lib/states/game.rb @@ -53,17 +53,20 @@ class IMICRTS def draw super - Gosu.draw_rect(0, 0, window.width, window.height, Gosu::Color.rgb(10, 175, 35)) + # Gosu.draw_rect(0, 0, window.width, window.height, Gosu::Color.rgb(10, 175, 35)) @player.camera.draw do @director.map.draw(@player.camera) @director.entities.each(&:draw) @selected_entities.each(&:selected_draw) - # draw_rect(@camera.center.x - 10, @camera.center.y - 10, 20, 20, Gosu::Color::BLACK, Float::INFINITY) + draw_rect(@player.camera.center.x - 10, @player.camera.center.y - 10, 20, 20, Gosu::Color::RED, Float::INFINITY) + + mouse = @player.camera.pick(window.mouse) + draw_rect(mouse.x - 10, mouse.y - 10, 20, 20, Gosu::Color::YELLOW, Float::INFINITY) + + draw_rect(@goal.x - 10, @goal.y - 10, 20, 20, Gosu::Color::WHITE, Float::INFINITY) if @goal - # mouse = @camera.mouse_pick(window.mouse_x, window.mouse_y) - # draw_rect(mouse.x - 10, mouse.y - 10, 20, 20, Gosu::Color::YELLOW, Float::INFINITY) Gosu.draw_rect(@box.min.x, @box.min.y, @box.width, @box.height, Gosu::Color.rgba(50, 50, 50, 150), Float::INFINITY) if @box end @@ -76,7 +79,7 @@ class IMICRTS @director.update @player.camera.update - @selected_entities.each do |ent| + @player.selected_entities.each do |ent| ent.rotate_towards(@goal) if @goal end @@ -84,13 +87,13 @@ class IMICRTS select_entities end - mouse = @player.camera.mouse_pick(window.mouse_x, window.mouse_y) + mouse = @player.camera.pick(window.mouse) @debug_info.text = %( FPS: #{Gosu.fps} Aspect Ratio: #{@player.camera.aspect_ratio} Zoom: #{@player.camera.zoom} - Window Mouse X: #{window.mouse_x} - Window Mouse Y: #{window.mouse_y} + Window Mouse X: #{window.mouse.x} + Window Mouse Y: #{window.mouse.y} World Mouse X: #{mouse.x} World Mouse Y: #{mouse.y} @@ -107,7 +110,7 @@ class IMICRTS case id when Gosu::MS_LEFT unless @sidebar.hit?(window.mouse_x, window.mouse_y) - @selection_start = CyberarmEngine::Vector.new(window.mouse_x, window.mouse_y) - @player.camera.position + @selection_start = @player.camera.pick(window.mouse) end when Gosu::MS_RIGHT @anchor = nil @@ -120,7 +123,7 @@ class IMICRTS case id when Gosu::MS_RIGHT - @goal = @player.camera.mouse_pick(window.mouse_x, window.mouse_y) + @goal = @player.camera.pick(window.mouse) when Gosu::MS_LEFT @box = nil @selection_start = nil @@ -132,7 +135,7 @@ class IMICRTS end def select_entities - @box = CyberarmEngine::BoundingBox.new(@selection_start, CyberarmEngine::Vector.new(window.mouse_x, window.mouse_y) - @player.camera.position) + @box = CyberarmEngine::BoundingBox.new(@selection_start, @player.camera.pick(window.mouse)) selected_entities = @player.entities.select do |ent| @box.point?(ent.position - ent.radius) || diff --git a/lib/window.rb b/lib/window.rb index 46c90e6..56b25af 100644 --- a/lib/window.rb +++ b/lib/window.rb @@ -1,7 +1,9 @@ class IMICRTS class Window < CyberarmEngine::Engine + attr_reader :mouse def setup @last_update_time = Gosu.milliseconds + @mouse = CyberarmEngine::Vector.new self.caption = "#{IMICRTS::NAME} (#{IMICRTS::VERSION} #{IMICRTS::VERSION_NAME})" if ARGV.join.include?("--fast") @@ -14,6 +16,7 @@ class IMICRTS end def update + @mouse.x, @mouse.y = self.mouse_x, self.mouse_y super @last_update_time = Gosu.milliseconds