diff --git a/lib/managers/collision_manager.rb b/lib/managers/collision_manager.rb index 351e8b1..3d8388b 100644 --- a/lib/managers/collision_manager.rb +++ b/lib/managers/collision_manager.rb @@ -28,7 +28,7 @@ class IMICFPS @physics_manager.update 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 @@ -57,12 +57,12 @@ class IMICFPS # aabb vs aabb next unless entity.bounding_box.intersect?(ent.bounding_box) # entity model aabb tree vs ent model aabb tree - # ent_tree_search = ent.model.aabb_tree.search(localize_entity_bounding_box(entity, ent), true) - # next if ent_tree_search.size == 0 + ent_tree_search = ent.model.aabb_tree.search(localize_entity_bounding_box(entity, ent), true) + next if ent_tree_search.size == 0 # 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 end diff --git a/lib/managers/physics_manager.rb b/lib/managers/physics_manager.rb index 8c15081..69d1061 100644 --- a/lib/managers/physics_manager.rb +++ b/lib/managers/physics_manager.rb @@ -10,9 +10,27 @@ class IMICFPS resolve(entity, other) end end + + simulate end 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 \ No newline at end of file diff --git a/lib/objects/entities/player.rb b/lib/objects/entities/player.rb index b580eff..ca0ad52 100644 --- a/lib/objects/entities/player.rb +++ b/lib/objects/entities/player.rb @@ -14,7 +14,6 @@ class IMICFPS @running_speed = 6.8 # meter's per second @old_speed = @speed @mass = 72 # kg - @floor = 0 @first_person_view = true @devisor = 500.0 @@ -37,8 +36,8 @@ class IMICFPS end 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 glPushMatrix glRotatef(180, 0, 1, 0) @@ -90,74 +89,74 @@ class IMICFPS def update relative_speed = @speed if InputMapper.down?(:sprint) - relative_speed = (@running_speed)*(delta_time) + relative_speed = (@running_speed) * (delta_time) else - relative_speed = @speed*(delta_time) + relative_speed = @speed * (delta_time) end - relative_y_rotation = @rotation.y*-1 + relative_y_rotation = @rotation.y * -1 if InputMapper.down?(:forward) - @position.z+=Math.cos(relative_y_rotation * Math::PI / 180)*relative_speed - @position.x-=Math.sin(relative_y_rotation * Math::PI / 180)*relative_speed + @velocity.z += Math.cos(relative_y_rotation * Math::PI / 180) * relative_speed + @velocity.x -= Math.sin(relative_y_rotation * Math::PI / 180) * relative_speed end if InputMapper.down?(:backward) - @position.z-=Math.cos(relative_y_rotation * Math::PI / 180)*relative_speed - @position.x+=Math.sin(relative_y_rotation * Math::PI / 180)*relative_speed + @velocity.z -= Math.cos(relative_y_rotation * Math::PI / 180) * relative_speed + @velocity.x += Math.sin(relative_y_rotation * Math::PI / 180) * relative_speed end if InputMapper.down?(:strife_left) - @position.z+=Math.sin(relative_y_rotation * Math::PI / 180)*relative_speed - @position.x+=Math.cos(relative_y_rotation * Math::PI / 180)*relative_speed + @velocity.z += Math.sin(relative_y_rotation * Math::PI / 180) * relative_speed + @velocity.x += Math.cos(relative_y_rotation * Math::PI / 180) * relative_speed end if InputMapper.down?(:strife_right) - @position.z-=Math.sin(relative_y_rotation * Math::PI / 180)*relative_speed - @position.x-=Math.cos(relative_y_rotation * Math::PI / 180)*relative_speed + @velocity.z -= Math.sin(relative_y_rotation * Math::PI / 180) * relative_speed + @velocity.x -= Math.cos(relative_y_rotation * Math::PI / 180) * relative_speed end if InputMapper.down?(:turn_left) - @rotation.y+=(relative_speed*1000)*delta_time + @rotation.y += (relative_speed * 1000) * delta_time end if InputMapper.down?(:turn_right) - @rotation.y-=(relative_speed*1000)*delta_time + @rotation.y -= (relative_speed * 1000) * delta_time end if @_time_in_air - air_time = ((Gosu.milliseconds-@_time_in_air)/1000.0) - @velocity.y-=(IMICFPS::GRAVITY*air_time)*delta_time + air_time = (Gosu.milliseconds - @_time_in_air) / 1000.0 + @velocity.y -= IMICFPS::GRAVITY * air_time * delta_time end if InputMapper.down?(:jump) && !@jumping @jumping = true @_time_in_air = Gosu.milliseconds - elsif !@jumping && @position.y > @floor + + elsif !@jumping @falling = true @_time_in_air ||= Gosu.milliseconds # FIXME else - if @jumping - if @position.y <= @floor - @falling = false; @jumping = false; @velocity.y = 0; @position.y = @floor - end + if @jumping && @velocity.y <= 0 + @falling = false + @jumping = false end end + if @jumping && !@falling if InputMapper.down?(:jump) - @velocity.y = 1.5 + @velocity.y += 1.5 @falling = true 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 end - def button_up(id) + def button_down(id) if InputMapper.is?(:toggle_first_person_view, id) @first_person_view = !@first_person_view @visible = !@first_person_view puts "First Person? #{@first_person_view}" + elsif InputMapper.is?(:turn_180, id) - @rotation.y = @rotation.y+180 + @rotation.y = @rotation.y + 180 @rotation.y %= 360 end end diff --git a/lib/objects/entities/terrain.rb b/lib/objects/entities/terrain.rb index 4331d26..53a2b2c 100644 --- a/lib/objects/entities/terrain.rb +++ b/lib/objects/entities/terrain.rb @@ -1,8 +1,8 @@ class IMICFPS class Terrain < Entity def setup - #bind_model("base", "randomish_terrain") - bind_model("base", "river_terrain") + # bind_model("base", "randomish_terrain") + bind_model("base", "river_terrain") end end end diff --git a/lib/objects/entity.rb b/lib/objects/entity.rb index 6f8f01c..c779106 100644 --- a/lib/objects/entity.rb +++ b/lib/objects/entity.rb @@ -6,9 +6,11 @@ class IMICFPS include OpenGL include GLU include CommonMethods + attr_accessor :scale, :visible, :renderable, :backface_culling 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) @position = Vector.new(x, y, z) @scale = scale @@ -18,11 +20,15 @@ class IMICFPS @renderable = true @rotation = Vector.new(0, 0, 0) @velocity = Vector.new(0, 0, 0) + @drag = 0.94 @debug_color = Color.new(0.0, 1.0, 0.0) @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 @mass = 100 # kg @@ -33,7 +39,7 @@ class IMICFPS if @bound_model @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 box = normalize_bounding_box @@ -52,7 +58,7 @@ class IMICFPS raise "model isn't a model!" unless model.is_a?(ModelLoader) @bound_model = model @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 # box = normalize_bounding_box @@ -91,10 +97,6 @@ class IMICFPS @position == @last_position 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 @bound_model.model.bounding_box.normalize_with_offset(self) end