From 8d8390123730b70628db8b396cba340066aa883b Mon Sep 17 00:00:00 2001 From: Cyberarm Date: Sun, 17 Feb 2019 20:06:48 -0600 Subject: [PATCH] Removed usages of Gosu.button_down? in InputMapper allowing for 'virtual input' support, tacked on demo support (recording and playback of camera yaw and pitch along with all key events in Game.), Camera now sets @game_object.y_rotation instead of @game_object setting Camera.yaw in Camera.position_camera. --- lib/managers/input_mapper.rb | 13 +++- lib/objects/game_objects/camera.rb | 34 ++++----- lib/states/game_states/game.rb | 110 ++++++++++++++++++++++++++--- lib/window.rb | 4 ++ 4 files changed, 133 insertions(+), 28 deletions(-) diff --git a/lib/managers/input_mapper.rb b/lib/managers/input_mapper.rb index a0900b2..ec33afb 100644 --- a/lib/managers/input_mapper.rb +++ b/lib/managers/input_mapper.rb @@ -1,6 +1,15 @@ class IMICFPS class InputMapper @@keymap = {} + @@keys = Hash.new(false) + + def self.keydown(id) + @@keys[id] = true + end + + def self.keyup(id) + @@keys[id] = false + end def self.get(category, action) key = @@keymap.dig(category, action) @@ -23,10 +32,10 @@ class IMICFPS if keys.is_a?(Array) keys.detect do |key| - Gosu.button_down?(key) + @@keys[key] end else - Gosu.button_down?(keys) + @@keys[keys] end end diff --git a/lib/objects/game_objects/camera.rb b/lib/objects/game_objects/camera.rb index e428ce1..6040240 100644 --- a/lib/objects/game_objects/camera.rb +++ b/lib/objects/game_objects/camera.rb @@ -6,21 +6,22 @@ class IMICFPS attr_accessor :x,:y,:z, :field_of_view, :pitch, :yaw, :roll, :mouse_sensitivity attr_reader :game_object, :broken_mouse_centering - def initialize(x: 0, y: 0, z: 0, fov: 70.0, distance: 100.0) + def initialize(x: 0, y: 0, z: 0, fov: 70.0, view_distance: 100.0) @x,@y,@z = x,y,z - @render_pitch = 20.0 - @pitch = 20.0 + @pitch = 0.0 @yaw = 0.0 @roll = 0.0 @field_of_view = fov - @view_distance = distance + @view_distance = view_distance + @constant_pitch = 20.0 @game_object = nil - @distance = 5 + @distance = 4 + @origin_distance = @distance self.mouse_x, self.mouse_y = $window.width/2, $window.height/2 @true_mouse = Point.new($window.width/2, $window.height/2) - @mouse_sensitivity = 20.0 + @mouse_sensitivity = 20.0 # Less is faster, more is slower @mouse_captured = true @mouse_checked = 0 @@ -49,11 +50,11 @@ class IMICFPS end def horizontal_distance_from_object - distance_from_object * Math.cos(@pitch) + distance_from_object * Math.cos(@constant_pitch) end def vertical_distance_from_object - distance_from_object * Math.sin(@pitch) + distance_from_object * Math.sin(@constant_pitch) end def position_camera @@ -61,7 +62,7 @@ class IMICFPS if @game_object.first_person_view @distance = 0 else - @distance = 5 + @distance = @origin_distance end end @@ -72,7 +73,8 @@ class IMICFPS @y = @game_object.y + 2 @z = @game_object.z - z_offset - @yaw = 180 - @game_object.y_rotation + # @yaw = 180 - @game_object.y_rotation + @game_object.y_rotation = -@yaw + 180 end def draw @@ -82,7 +84,7 @@ class IMICFPS # Calculates aspect ratio of the window. Gets perspective view. 45 is degree viewing angle, (0.1, 100) are ranges how deep can we draw into the screen gluPerspective(@field_of_view, $window.width / $window.height, 0.1, @view_distance) glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST) - glRotatef(@render_pitch,1,0,0) + glRotatef(@pitch,1,0,0) glRotatef(@yaw,0,1,0) glTranslatef(-@x, -@y, -@z) glMatrixMode(GL_MODELVIEW) # The modelview matrix is where object information is stored. @@ -101,14 +103,14 @@ class IMICFPS if @mouse_captured position_camera if @game_object - @yaw-=Float(@true_mouse.x-self.mouse_x)/(@mouse_sensitivity*@field_of_view)*70 unless @game_object - @game_object.y_rotation+=Float(@true_mouse.x-self.mouse_x)/(@mouse_sensitivity*@field_of_view)*70 if @game_object - - @render_pitch-=Float(@true_mouse.y-self.mouse_y)/(@mouse_sensitivity*@field_of_view)*70 #unless @game_object + delta = Float(@true_mouse.x-self.mouse_x)/(@mouse_sensitivity*@field_of_view)*70 + @yaw -= delta @yaw %= 360.0 - @render_pitch = @render_pitch.clamp(-90.0, 90.0) + + @pitch -= Float(@true_mouse.y-self.mouse_y)/(@mouse_sensitivity*@field_of_view)*70 @pitch = @pitch.clamp(-90.0, 90.0) + @game_object.y_rotation += delta if @game_object free_move unless @game_object self.mouse_x = $window.width/2 if self.mouse_x <= 1 || $window.mouse_x >= $window.width-1 diff --git a/lib/states/game_states/game.rb b/lib/states/game_states/game.rb index a7eed4e..496f6fa 100644 --- a/lib/states/game_states/game.rb +++ b/lib/states/game_states/game.rb @@ -14,7 +14,7 @@ class IMICFPS Tree.new(x: rand(@terrain.width)-(@terrain.width/2.0), z: rand(@terrain.depth)-(@terrain.depth/2.0), terrain: @terrain, game_state: self) end - TestObject.new(terrain: @terrain, game_state: self, scale: 1.0) + TestObject.new(terrain: @terrain, z: 10, game_state: self, scale: 1.0) @player = Player.new(x: 1, y: 0, z: -1, terrain: @terrain, game_state: self) @camera = Camera.new(x: 0, y: -2, z: 1) @@ -29,6 +29,22 @@ class IMICFPS Light.new(x: 3, y: -6, z: 6, game_state: self) Light.new(x: 0, y: 100, z: 0, diffuse: Color.new(1.0, 0.5, 0.1), game_state: self) + + if ARGV.join.include?("--playdemo") + @demo_data = File.read("./demo.dat").lines + @demo_index= 0 + @demo_tick = 0 + + elsif ARGV.join.include?("--savedemo") + @demo_file = File.open("./demo.dat", "w") + @demo_index= 0 + @demo_changed = false + + @demo_last_pitch = @camera.pitch + @demo_last_yaw = @camera.yaw + + at_exit { @demo_file.close } + end end def glError? @@ -67,6 +83,65 @@ class IMICFPS def update @last_frame_time = Gosu.milliseconds + update_text + + @collision_manager.update + @game_objects.each(&:update) + + @skydome.update if @skydome.renderable + + @camera.update + + $window.close if $window.button_down?(Gosu::KbEscape) + $window.number_of_vertices = 0 + @delta_time = Gosu.milliseconds + + if ARGV.join.include?("--playdemo") + if @demo_data[@demo_index]&.start_with?("tick") + if @demo_tick == @demo_data[@demo_index].split(" ").last.to_i + @demo_index+=1 + + until(@demo_data[@demo_index]&.start_with?("tick")) + break unless @demo_data[@demo_index] + + data = @demo_data[@demo_index].split(" ") + if data.first == "up" + self.button_up(data.last.to_i) + elsif data.first == "down" + self.button_down(data.last.to_i) + elsif data.first == "mouse" + @camera.pitch = data[1].to_f + @camera.yaw = data[2].to_f + else + # hmm + end + + @demo_index += 1 + end + end + end + end + + if ARGV.join.include?("--savedemo") + if @camera.pitch != @demo_last_pitch || @camera.yaw != @demo_last_yaw + unless @demo_last_written_index == @demo_index + @demo_last_written_index = @demo_index + @demo_file.puts("tick #{@demo_index}") + end + + @demo_file.puts("mouse #{@camera.pitch} #{@camera.yaw}") + @demo_last_pitch = @camera.pitch + @demo_last_yaw = @camera.yaw + end + + @demo_changed = false + @demo_index += 1 + end + + @demo_tick += 1 if @demo_tick + end + + def update_text begin string = <<-eos OpenGL Vendor: #{glGetString(GL_VENDOR)} @@ -110,20 +185,35 @@ eos else @text.text = "FPS: #{Gosu.fps}" end + end - @collision_manager.update - @game_objects.each(&:update) + def button_down(id) + if ARGV.join.include?("--savedemo") + unless @demo_last_written_index == @demo_index + @demo_last_written_index = @demo_index + @demo_file.puts("tick #{@demo_index}") + end + @demo_file.puts("down #{id}") + @demo_changed = true + end + InputMapper.keydown(id) - @skydome.update if @skydome.renderable - - @camera.update - - $window.close if $window.button_down?(Gosu::KbEscape) - $window.number_of_vertices = 0 - @delta_time = Gosu.milliseconds + @game_objects.each do |object| + object.button_down(id) if defined?(object.button_down) + end end def button_up(id) + if ARGV.join.include?("--savedemo") + unless @demo_last_written_index == @demo_index + @demo_last_written_index = @demo_index + @demo_file.puts("tick #{@demo_index}") + end + @demo_file.puts("up #{id}") + @demo_changed = true + end + InputMapper.keyup(id) + @game_objects.each do |object| object.button_up(id) if defined?(object.button_up) end diff --git a/lib/window.rb b/lib/window.rb index a77bfc0..7718f8d 100644 --- a/lib/window.rb +++ b/lib/window.rb @@ -40,6 +40,10 @@ class IMICFPS @active_state.update if @active_state end + def button_down(id) + @active_state.button_down(id) if @active_state + end + def button_up(id) @active_state.button_up(id) if @active_state end