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.

This commit is contained in:
2019-02-17 20:06:48 -06:00
parent 5a97d292c0
commit 8d83901237
4 changed files with 133 additions and 28 deletions

View File

@@ -1,6 +1,15 @@
class IMICFPS class IMICFPS
class InputMapper class InputMapper
@@keymap = {} @@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) def self.get(category, action)
key = @@keymap.dig(category, action) key = @@keymap.dig(category, action)
@@ -23,10 +32,10 @@ class IMICFPS
if keys.is_a?(Array) if keys.is_a?(Array)
keys.detect do |key| keys.detect do |key|
Gosu.button_down?(key) @@keys[key]
end end
else else
Gosu.button_down?(keys) @@keys[keys]
end end
end end

View File

@@ -6,21 +6,22 @@ class IMICFPS
attr_accessor :x,:y,:z, :field_of_view, :pitch, :yaw, :roll, :mouse_sensitivity attr_accessor :x,:y,:z, :field_of_view, :pitch, :yaw, :roll, :mouse_sensitivity
attr_reader :game_object, :broken_mouse_centering 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 @x,@y,@z = x,y,z
@render_pitch = 20.0 @pitch = 0.0
@pitch = 20.0
@yaw = 0.0 @yaw = 0.0
@roll = 0.0 @roll = 0.0
@field_of_view = fov @field_of_view = fov
@view_distance = distance @view_distance = view_distance
@constant_pitch = 20.0
@game_object = nil @game_object = nil
@distance = 5 @distance = 4
@origin_distance = @distance
self.mouse_x, self.mouse_y = $window.width/2, $window.height/2 self.mouse_x, self.mouse_y = $window.width/2, $window.height/2
@true_mouse = Point.new($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_captured = true
@mouse_checked = 0 @mouse_checked = 0
@@ -49,11 +50,11 @@ class IMICFPS
end end
def horizontal_distance_from_object def horizontal_distance_from_object
distance_from_object * Math.cos(@pitch) distance_from_object * Math.cos(@constant_pitch)
end end
def vertical_distance_from_object def vertical_distance_from_object
distance_from_object * Math.sin(@pitch) distance_from_object * Math.sin(@constant_pitch)
end end
def position_camera def position_camera
@@ -61,7 +62,7 @@ class IMICFPS
if @game_object.first_person_view if @game_object.first_person_view
@distance = 0 @distance = 0
else else
@distance = 5 @distance = @origin_distance
end end
end end
@@ -72,7 +73,8 @@ class IMICFPS
@y = @game_object.y + 2 @y = @game_object.y + 2
@z = @game_object.z - z_offset @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 end
def draw 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 # 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) gluPerspective(@field_of_view, $window.width / $window.height, 0.1, @view_distance)
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST) glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST)
glRotatef(@render_pitch,1,0,0) glRotatef(@pitch,1,0,0)
glRotatef(@yaw,0,1,0) glRotatef(@yaw,0,1,0)
glTranslatef(-@x, -@y, -@z) glTranslatef(-@x, -@y, -@z)
glMatrixMode(GL_MODELVIEW) # The modelview matrix is where object information is stored. glMatrixMode(GL_MODELVIEW) # The modelview matrix is where object information is stored.
@@ -101,14 +103,14 @@ class IMICFPS
if @mouse_captured if @mouse_captured
position_camera if @game_object position_camera if @game_object
@yaw-=Float(@true_mouse.x-self.mouse_x)/(@mouse_sensitivity*@field_of_view)*70 unless @game_object delta = Float(@true_mouse.x-self.mouse_x)/(@mouse_sensitivity*@field_of_view)*70
@game_object.y_rotation+=Float(@true_mouse.x-self.mouse_x)/(@mouse_sensitivity*@field_of_view)*70 if @game_object @yaw -= delta
@render_pitch-=Float(@true_mouse.y-self.mouse_y)/(@mouse_sensitivity*@field_of_view)*70 #unless @game_object
@yaw %= 360.0 @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) @pitch = @pitch.clamp(-90.0, 90.0)
@game_object.y_rotation += delta if @game_object
free_move unless @game_object free_move unless @game_object
self.mouse_x = $window.width/2 if self.mouse_x <= 1 || $window.mouse_x >= $window.width-1 self.mouse_x = $window.width/2 if self.mouse_x <= 1 || $window.mouse_x >= $window.width-1

View File

@@ -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) Tree.new(x: rand(@terrain.width)-(@terrain.width/2.0), z: rand(@terrain.depth)-(@terrain.depth/2.0), terrain: @terrain, game_state: self)
end 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) @player = Player.new(x: 1, y: 0, z: -1, terrain: @terrain, game_state: self)
@camera = Camera.new(x: 0, y: -2, z: 1) @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: 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) 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 end
def glError? def glError?
@@ -67,6 +83,65 @@ class IMICFPS
def update def update
@last_frame_time = Gosu.milliseconds @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 begin
string = <<-eos string = <<-eos
OpenGL Vendor: #{glGetString(GL_VENDOR)} OpenGL Vendor: #{glGetString(GL_VENDOR)}
@@ -110,20 +185,35 @@ eos
else else
@text.text = "FPS: #{Gosu.fps}" @text.text = "FPS: #{Gosu.fps}"
end end
end
@collision_manager.update def button_down(id)
@game_objects.each(&:update) 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 @game_objects.each do |object|
object.button_down(id) if defined?(object.button_down)
@camera.update end
$window.close if $window.button_down?(Gosu::KbEscape)
$window.number_of_vertices = 0
@delta_time = Gosu.milliseconds
end end
def button_up(id) 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| @game_objects.each do |object|
object.button_up(id) if defined?(object.button_up) object.button_up(id) if defined?(object.button_up)
end end

View File

@@ -40,6 +40,10 @@ class IMICFPS
@active_state.update if @active_state @active_state.update if @active_state
end end
def button_down(id)
@active_state.button_down(id) if @active_state
end
def button_up(id) def button_up(id)
@active_state.button_up(id) if @active_state @active_state.button_up(id) if @active_state
end end