PhysicsManager now has a job, CollisionManager enabled, using Player velocity instead of position for movement controls, added Entity drag, added spaces

This commit is contained in:
2019-08-09 08:27:34 -05:00
parent 3b662090fc
commit f84b680de5
5 changed files with 61 additions and 42 deletions

View File

@@ -28,7 +28,7 @@ class IMICFPS
@physics_manager.update @physics_manager.update
collisions.each do |ent, list| collisions.each do |ent, list|
# puts "#{ent.class} -> [#{list.map{|e| e.class}.join(', ')}] (#{Gosu.milliseconds})" # puts "#{ent.class} -> [#{list.map { |e| e.class }.join(', ')}] (#{Gosu.milliseconds})"
end end
end end
@@ -57,12 +57,12 @@ class IMICFPS
# aabb vs aabb # aabb vs aabb
next unless entity.bounding_box.intersect?(ent.bounding_box) next unless entity.bounding_box.intersect?(ent.bounding_box)
# entity model aabb tree vs ent model aabb tree # entity model aabb tree vs ent model aabb tree
# ent_tree_search = ent.model.aabb_tree.search(localize_entity_bounding_box(entity, ent), true) ent_tree_search = ent.model.aabb_tree.search(localize_entity_bounding_box(entity, ent), true)
# next if ent_tree_search.size == 0 next if ent_tree_search.size == 0
# puts "#{ent.class} -> #{ent_tree_search.size} (#{Gosu.milliseconds})" # puts "#{ent.class} -> #{ent_tree_search.size} (#{Gosu.milliseconds})"
# entity.position.y = ent_tree_search.first.object.vertices.first.y if entity.is_a?(Player) && ent.is_a?(Terrain) entity.position.y = ent_tree_search.first.object.vertices.first.y if entity.is_a?(Player) && ent.is_a?(Terrain)
@collisions[entity] = _collisions @collisions[entity] = _collisions
end end

View File

@@ -10,9 +10,27 @@ class IMICFPS
resolve(entity, other) resolve(entity, other)
end end
end end
simulate
end end
def resolve(entity, other) def resolve(entity, other)
if other.is_a?(Terrain)
entity.velocity.y = 0 if entity.velocity.y < 0
else
entity.velocity.y = other.velocity.y if other.velocity.y < entity.velocity.y && entity.velocity.y < 0
end
end
def simulate
@collision_manager.game_state.entities.each do |entity|
entity.velocity.x *= entity.drag
entity.velocity.z *= entity.drag
entity.position.x += entity.velocity.x * entity.delta_time
entity.position.y += entity.velocity.y * entity.delta_time
entity.position.z += entity.velocity.z * entity.delta_time
end
end end
end end
end end

View File

@@ -14,7 +14,6 @@ class IMICFPS
@running_speed = 6.8 # meter's per second @running_speed = 6.8 # meter's per second
@old_speed = @speed @old_speed = @speed
@mass = 72 # kg @mass = 72 # kg
@floor = 0
@first_person_view = true @first_person_view = true
@devisor = 500.0 @devisor = 500.0
@@ -37,8 +36,8 @@ class IMICFPS
end end
def draw_nameplate def draw_nameplate
_height = (@name_image.height/@devisor) _width = (@name_image.width / @devisor) / 2
_width = (@name_image.width/@devisor)/2 _height = (@name_image.height / @devisor)
_y = 2#normalize_bounding_box(model.bounding_box).max_y+0.05 _y = 2#normalize_bounding_box(model.bounding_box).max_y+0.05
glPushMatrix glPushMatrix
glRotatef(180, 0, 1, 0) glRotatef(180, 0, 1, 0)
@@ -90,74 +89,74 @@ class IMICFPS
def update def update
relative_speed = @speed relative_speed = @speed
if InputMapper.down?(:sprint) if InputMapper.down?(:sprint)
relative_speed = (@running_speed)*(delta_time) relative_speed = (@running_speed) * (delta_time)
else else
relative_speed = @speed*(delta_time) relative_speed = @speed * (delta_time)
end end
relative_y_rotation = @rotation.y*-1 relative_y_rotation = @rotation.y * -1
if InputMapper.down?(:forward) if InputMapper.down?(:forward)
@position.z+=Math.cos(relative_y_rotation * Math::PI / 180)*relative_speed @velocity.z += Math.cos(relative_y_rotation * Math::PI / 180) * relative_speed
@position.x-=Math.sin(relative_y_rotation * Math::PI / 180)*relative_speed @velocity.x -= Math.sin(relative_y_rotation * Math::PI / 180) * relative_speed
end end
if InputMapper.down?(:backward) if InputMapper.down?(:backward)
@position.z-=Math.cos(relative_y_rotation * Math::PI / 180)*relative_speed @velocity.z -= Math.cos(relative_y_rotation * Math::PI / 180) * relative_speed
@position.x+=Math.sin(relative_y_rotation * Math::PI / 180)*relative_speed @velocity.x += Math.sin(relative_y_rotation * Math::PI / 180) * relative_speed
end end
if InputMapper.down?(:strife_left) if InputMapper.down?(:strife_left)
@position.z+=Math.sin(relative_y_rotation * Math::PI / 180)*relative_speed @velocity.z += Math.sin(relative_y_rotation * Math::PI / 180) * relative_speed
@position.x+=Math.cos(relative_y_rotation * Math::PI / 180)*relative_speed @velocity.x += Math.cos(relative_y_rotation * Math::PI / 180) * relative_speed
end end
if InputMapper.down?(:strife_right) if InputMapper.down?(:strife_right)
@position.z-=Math.sin(relative_y_rotation * Math::PI / 180)*relative_speed @velocity.z -= Math.sin(relative_y_rotation * Math::PI / 180) * relative_speed
@position.x-=Math.cos(relative_y_rotation * Math::PI / 180)*relative_speed @velocity.x -= Math.cos(relative_y_rotation * Math::PI / 180) * relative_speed
end end
if InputMapper.down?(:turn_left) if InputMapper.down?(:turn_left)
@rotation.y+=(relative_speed*1000)*delta_time @rotation.y += (relative_speed * 1000) * delta_time
end end
if InputMapper.down?(:turn_right) if InputMapper.down?(:turn_right)
@rotation.y-=(relative_speed*1000)*delta_time @rotation.y -= (relative_speed * 1000) * delta_time
end end
if @_time_in_air if @_time_in_air
air_time = ((Gosu.milliseconds-@_time_in_air)/1000.0) air_time = (Gosu.milliseconds - @_time_in_air) / 1000.0
@velocity.y-=(IMICFPS::GRAVITY*air_time)*delta_time @velocity.y -= IMICFPS::GRAVITY * air_time * delta_time
end end
if InputMapper.down?(:jump) && !@jumping if InputMapper.down?(:jump) && !@jumping
@jumping = true @jumping = true
@_time_in_air = Gosu.milliseconds @_time_in_air = Gosu.milliseconds
elsif !@jumping && @position.y > @floor
elsif !@jumping
@falling = true @falling = true
@_time_in_air ||= Gosu.milliseconds # FIXME @_time_in_air ||= Gosu.milliseconds # FIXME
else else
if @jumping if @jumping && @velocity.y <= 0
if @position.y <= @floor @falling = false
@falling = false; @jumping = false; @velocity.y = 0; @position.y = @floor @jumping = false
end
end end
end end
if @jumping && !@falling if @jumping && !@falling
if InputMapper.down?(:jump) if InputMapper.down?(:jump)
@velocity.y = 1.5 @velocity.y += 1.5
@falling = true @falling = true
end end
end end
@position.y+=@velocity.y*delta_time if @position.y >= @floor # TEMP fix to prevent falling forever, collision/physics managers should fix this in time.
super super
end end
def button_up(id) def button_down(id)
if InputMapper.is?(:toggle_first_person_view, id) if InputMapper.is?(:toggle_first_person_view, id)
@first_person_view = !@first_person_view @first_person_view = !@first_person_view
@visible = !@first_person_view @visible = !@first_person_view
puts "First Person? #{@first_person_view}" puts "First Person? #{@first_person_view}"
elsif InputMapper.is?(:turn_180, id) elsif InputMapper.is?(:turn_180, id)
@rotation.y = @rotation.y+180 @rotation.y = @rotation.y + 180
@rotation.y %= 360 @rotation.y %= 360
end end
end end

View File

@@ -1,8 +1,8 @@
class IMICFPS class IMICFPS
class Terrain < Entity class Terrain < Entity
def setup def setup
#bind_model("base", "randomish_terrain") # bind_model("base", "randomish_terrain")
bind_model("base", "river_terrain") bind_model("base", "river_terrain")
end end
end end
end end

View File

@@ -6,9 +6,11 @@ class IMICFPS
include OpenGL include OpenGL
include GLU include GLU
include CommonMethods include CommonMethods
attr_accessor :scale, :visible, :renderable, :backface_culling attr_accessor :scale, :visible, :renderable, :backface_culling
attr_accessor :position, :rotation, :velocity attr_accessor :position, :rotation, :velocity
attr_reader :model, :name, :debug_color, :bounding_box, :collision attr_reader :model, :name, :debug_color, :bounding_box, :collision, :physics, :mass, :drag
def initialize(x: 0, y: 0, z: 0, bound_model: nil, scale: MODEL_METER_SCALE, backface_culling: true, auto_manage: true, manifest_file: nil) def initialize(x: 0, y: 0, z: 0, bound_model: nil, scale: MODEL_METER_SCALE, backface_culling: true, auto_manage: true, manifest_file: nil)
@position = Vector.new(x, y, z) @position = Vector.new(x, y, z)
@scale = scale @scale = scale
@@ -18,11 +20,15 @@ class IMICFPS
@renderable = true @renderable = true
@rotation = Vector.new(0, 0, 0) @rotation = Vector.new(0, 0, 0)
@velocity = Vector.new(0, 0, 0) @velocity = Vector.new(0, 0, 0)
@drag = 0.94
@debug_color = Color.new(0.0, 1.0, 0.0) @debug_color = Color.new(0.0, 1.0, 0.0)
@collidable = [:static, :dynamic] @collidable = [:static, :dynamic]
@collision = :static # :dynamic => moves in response, :static => does not move ever, :none => no collision check, entities can pass through # :dynamic => moves in response,
# :static => does not move ever,
# :none => no collision check, entities can pass through
@collision = :static
@physics = false # Entity affected by gravity and what not @physics = false # Entity affected by gravity and what not
@mass = 100 # kg @mass = 100 # kg
@@ -33,7 +39,7 @@ class IMICFPS
if @bound_model if @bound_model
@bound_model.model.entity = self @bound_model.model.entity = self
@bound_model.model.objects.each {|o| o.scale = self.scale} @bound_model.model.objects.each { |o| o.scale = self.scale }
@normalized_bounding_box = normalize_bounding_box_with_offset @normalized_bounding_box = normalize_bounding_box_with_offset
box = normalize_bounding_box box = normalize_bounding_box
@@ -52,7 +58,7 @@ class IMICFPS
raise "model isn't a model!" unless model.is_a?(ModelLoader) raise "model isn't a model!" unless model.is_a?(ModelLoader)
@bound_model = model @bound_model = model
@bound_model.model.entity = self @bound_model.model.entity = self
@bound_model.model.objects.each {|o| o.scale = self.scale} @bound_model.model.objects.each { |o| o.scale = self.scale }
@bounding_box = normalize_bounding_box_with_offset @bounding_box = normalize_bounding_box_with_offset
# box = normalize_bounding_box # box = normalize_bounding_box
@@ -91,10 +97,6 @@ class IMICFPS
@position == @last_position @position == @last_position
end end
def distance(vertex, other)
return Math.sqrt((vertex.x-other.x)**2 + (vertex.y-other.y)**2 + (vertex.z-other.z)**2)
end
def normalize_bounding_box_with_offset def normalize_bounding_box_with_offset
@bound_model.model.bounding_box.normalize_with_offset(self) @bound_model.model.bounding_box.normalize_with_offset(self)
end end