Class: ExampleApp::World
- Inherits:
-
ZifExampleScene
- Object
- Zif::Scene
- ZifExampleScene
- ExampleApp::World
- Defined in:
- app/scenes/world.rb
Overview
An example which uses Zif::Layers::LayerGroup and Zif::Layers::Camera
Instance Attribute Summary collapse
-
#avatar ⇒ Object
Returns the value of attribute avatar.
-
#camera ⇒ Object
Returns the value of attribute camera.
-
#finished_at ⇒ Object
For init.
-
#last_rendered_camera ⇒ Object
Returns the value of attribute last_rendered_camera.
-
#map ⇒ Object
Returns the value of attribute map.
-
#pixie ⇒ Object
Returns the value of attribute pixie.
-
#progress ⇒ Object
For init.
-
#ready ⇒ Object
For init.
Attributes inherited from ZifExampleScene
#next_scene, #scene_timer, #tracer_service_name
Attributes included from Zif::Traceable
Instance Method Summary collapse
- #distance_from_center(x1, y1, x2 = @map.logical_width.idiv(2), y2 = @map.logical_height.idiv(2)) ⇒ Object
- #finish_initialization ⇒ Object
-
#initialization_percent(kind = :tiles) ⇒ Object
For loading bar.
-
#initialize ⇒ World
constructor
A new instance of World.
-
#initialize_tiles ⇒ Object
If we attempt to initialize the entire map in 1 tick, everything will freeze up until it finishes.
- #map_clicked(_sprite, point) ⇒ Object
- #perform_tick ⇒ Object
-
#perform_tick_debug_labels ⇒ Object
rubocop:disable Layout/LineLength.
- #prepare_scene ⇒ Object
- #refresh_map ⇒ Object
- #translate_point_to_camera(point) ⇒ Object
Methods inherited from ZifExampleScene
#display_context_labels, #display_timer_bar
Methods included from Zif::Traceable
#mark, #mark_and_print, #mark_prefix, #tracer
Methods inherited from Zif::Scene
Methods included from Zif::Serializable
#exclude_from_serialize, #inspect, #serialize, #to_s
Constructor Details
#initialize ⇒ World
Returns a new instance of World.
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
# File 'app/scenes/world.rb', line 9 def initialize super @next_scene = :load_double_buffer_render_test mark('#initialize: Begin') @map = Zif::Layers::LayerGroup.new(logical_width: 50, logical_height: 50) @map.new_tiled_layer(:tiles) @map.new_active_layer(:avatar) mark('#initialize: Map + layers created') @map.force_refresh @map.layers[:tiles].should_render = false mark('#initialize: Map refreshed') @avatar = Avatar.new( $game.services[:sprite_registry].construct('dragon_1'), 500, 700, @map.max_width, @map.max_height ) @pixie = Pixie.new @pixie.x = 1659 @pixie.y = 1659 @pixie.spin @pixie.float_to(@avatar) @map.layers[:avatar].sprites << @avatar @map.layers[:avatar].sprites << @pixie @ready = false @progress = Hash.new(0) @finished_at = Hash.new((@map.logical_width * @map.logical_height) - 1) puts "World#initialize: Initializing #{@map.logical_width}x#{@map.logical_height}" puts " =#{@finished_at[:tiles] + 1} Tiles" mark_and_print('#initialize: Nearly finished') initialize_tiles mark_and_print('#initialize: Tiles initialized') end |
Instance Attribute Details
#avatar ⇒ Object
Returns the value of attribute avatar.
4 5 6 |
# File 'app/scenes/world.rb', line 4 def avatar @avatar end |
#camera ⇒ Object
Returns the value of attribute camera.
4 5 6 |
# File 'app/scenes/world.rb', line 4 def camera @camera end |
#finished_at ⇒ Object
For init
7 8 9 |
# File 'app/scenes/world.rb', line 7 def finished_at @finished_at end |
#last_rendered_camera ⇒ Object
Returns the value of attribute last_rendered_camera.
4 5 6 |
# File 'app/scenes/world.rb', line 4 def last_rendered_camera @last_rendered_camera end |
#map ⇒ Object
Returns the value of attribute map.
4 5 6 |
# File 'app/scenes/world.rb', line 4 def map @map end |
#pixie ⇒ Object
Returns the value of attribute pixie.
4 5 6 |
# File 'app/scenes/world.rb', line 4 def pixie @pixie end |
#progress ⇒ Object
For init
7 8 9 |
# File 'app/scenes/world.rb', line 7 def progress @progress end |
#ready ⇒ Object
For init
7 8 9 |
# File 'app/scenes/world.rb', line 7 def ready @ready end |
Instance Method Details
#distance_from_center(x1, y1, x2 = @map.logical_width.idiv(2), y2 = @map.logical_height.idiv(2)) ⇒ Object
106 107 108 109 |
# File 'app/scenes/world.rb', line 106 def distance_from_center(x1, y1, x2=@map.logical_width.idiv(2), y2=@map.logical_height.idiv(2)) dist = Zif.distance(x1, y1, x2, y2) 1.0 - dist.fdiv(@map.logical_width.idiv(2)) end |
#finish_initialization ⇒ Object
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
# File 'app/scenes/world.rb', line 111 def finish_initialization puts 'World#finish_initialization: Begin' @camera = Zif::Layers::Camera.new( layer_sprites: @map.layer_containing_sprites, starting_width: Zif::Layers::Camera::DEFAULT_SCREEN_WIDTH, starting_height: Zif::Layers::Camera::DEFAULT_SCREEN_HEIGHT, initial_x: 0, initial_y: 400 ) @map.layers[:tiles].should_render = true refresh_map @map.layers[:tiles].should_render = false @map.layers[:tiles].containing_sprite.on_mouse_up = lambda do |sprite, point| map_clicked(sprite, translate_point_to_camera(point)) end @map.layers[:tiles].containing_sprite.on_mouse_down = ->(_sprite, point) { puts "Map clicked down! #{point}" } $game.services[:action_service].register_actionable(@avatar) $game.services[:action_service].register_actionable(@camera) $game.services[:action_service].register_actionable(@pixie) $game.services[:input_service].register_clickable(@map.layers[:tiles].containing_sprite) $game.services[:input_service].register_scrollable(@camera) $gtk.args.outputs.static_sprites << @camera.layers # $gtk.args.outputs.static_labels << @hud_labels puts 'World#finish_initialization: Initialized World' end |
#initialization_percent(kind = :tiles) ⇒ Object
For loading bar
51 52 53 |
# File 'app/scenes/world.rb', line 51 def initialization_percent(kind=:tiles) @ready ? 1.0 : (@progress[kind] / @finished_at[kind].to_f) end |
#initialize_tiles ⇒ Object
If we attempt to initialize the entire map in 1 tick, everything will freeze up until it finishes. So this is a method for loading which is designed to prevent this and allow us to show a loading bar. The idea is that we run this once per tick, several times until initialization is finished.
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'app/scenes/world.rb', line 58 def initialize_tiles mark_and_print('#initialize_tiles: Begin') return if @ready %i[tiles].each do |kind| # stuff next if @progress[kind] >= @finished_at[kind] cur_y, cur_x = @progress[kind].divmod @map.logical_width # puts "World#initialize_tiles(#{kind}): #{@progress[kind]}/#{@finished_at[kind]} =" # puts " #{(initialization_percent * 100).floor}%" start_t = Time.now center = [@map.logical_width.idiv(2), @map.logical_height.idiv(2)] cur_y.upto(@map.logical_height - 1) do |y| # Invert Y so sprites lower on the screen overlap higher ones actual_y = (@map.logical_height - 1) - y cur_x.upto(@map.logical_width - 1) do |x| @progress[kind] += 1 cur_tile = case kind when :tiles $game.services[:sprite_registry].construct(:white_1).tap do |s| rads = Zif.radian_angle_between_points(x, actual_y, *center) hue = (rads + Math::PI).fdiv(2 * Math::PI) * 360 r, g, b = Zif.hsv_to_rgb(hue, 100, 100 * distance_from_center(x, actual_y)) s.name = "floor_#{x}_#{actual_y}" s.r = r s.g = b s.b = g end when :stuff # TODO: Add some stuff end @map.layers[kind].add_positioned_sprite(sprite: cur_tile, logical_x: x, logical_y: actual_y) if cur_tile # Allow this to execute for 8ms (half a tick at 60fps). return if (Time.now - start_t) >= 0.008 # rubocop:disable Lint/NonLocalExitFromIterator end cur_x = 0 end end puts 'World#initialize_tiles: Finished' @ready = true end |
#map_clicked(_sprite, point) ⇒ Object
165 166 167 168 169 |
# File 'app/scenes/world.rb', line 165 def map_clicked(_sprite, point) puts "Map clicked! #{point}" @avatar.start_walking(point) end |
#perform_tick ⇒ Object
143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 |
# File 'app/scenes/world.rb', line 143 def perform_tick mark('#perform_tick: Begin') $gtk.args.outputs.background_color = [0, 0, 0, 0] mark('#perform_tick: Init') @camera.start_following(@avatar) if @avatar.walking mark('#perform_tick: Main sequence finished') refresh_map mark('#perform_tick: Map refreshed') perform_tick_debug_labels mark('#perform_tick: Finished') super end |
#perform_tick_debug_labels ⇒ Object
rubocop:disable Layout/LineLength
185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 |
# File 'app/scenes/world.rb', line 185 def perform_tick_debug_labels color = {r: 255, g: 255, b: 255, a: 255} if @avatar $gtk.args.outputs.labels << { x: 8, y: 720 - 68, text: "Avatar: #{@avatar.xy.join('x')}" }.merge(color) # $gtk.args.outputs.labels << { x: 8, y: 720 - 28, text: "Moving: #{$gtk.args.inputs.directional_vector}" }.merge(color) if $gtk.args.inputs.directional_vector $gtk.args.outputs.labels << { x: 8, y: 720 - 48, text: "Moving: #{@avatar.moving_to}" }.merge(color) unless @avatar.moving_to&.all?(&:zero?) end return unless @camera point = [$args.inputs.mouse.x, $args.inputs.mouse.y] $gtk.args.outputs.labels << { x: 8, y: 720 - 88, text: "Camera: #{@camera.pos.join('x')} -> #{@camera.cur_w}x#{@camera.cur_h}. Target #{@camera.target_x}x#{@camera.target_y}" }.merge(color) $gtk.args.outputs.labels << { x: 8, y: 720 - 108, text: "Mouse: #{point} window -> #{translate_point_to_camera(point)} world" }.merge(color) end |
#prepare_scene ⇒ Object
175 176 177 178 179 180 181 182 |
# File 'app/scenes/world.rb', line 175 def prepare_scene mark_and_print('#prepare_scene: Begin') super finish_initialization if @ready && @camera.nil? @avatar.run_animation_sequence(:fly) mark_and_print('#prepare_scene: Complete') end |
#refresh_map ⇒ Object
171 172 173 |
# File 'app/scenes/world.rb', line 171 def refresh_map @map.refresh end |
#translate_point_to_camera(point) ⇒ Object
161 162 163 |
# File 'app/scenes/world.rb', line 161 def translate_point_to_camera(point) @camera.translate_pos(point) end |