diff --git a/assets/base/door/model/door.mtl b/assets/base/door/model/door.mtl new file mode 100644 index 0000000..7889ae7 --- /dev/null +++ b/assets/base/door/model/door.mtl @@ -0,0 +1,13 @@ +# Blender MTL File: 'door.blend' +# Material Count: 1 + +newmtl Material +Ns 323.999994 +Ka 1.000000 1.000000 1.000000 +Kd 0.800000 0.800000 0.800000 +Ks 0.500000 0.500000 0.500000 +Ke 0.0 0.0 0.0 +Ni 1.450000 +d 1.000000 +illum 2 +map_Kd /home/cyberarm/Code/i-mic-fps/assets/base/door/textures/door.png diff --git a/assets/base/door/model/door.obj b/assets/base/door/model/door.obj new file mode 100644 index 0000000..d354565 --- /dev/null +++ b/assets/base/door/model/door.obj @@ -0,0 +1,55 @@ +# Blender v2.80 (sub 75) OBJ File: 'door.blend' +# www.blender.org +mtllib door.mtl +o Cube +v 1.250000 2.400000 -0.125000 +v 1.250000 0.000000 -0.125000 +v 1.250000 2.400000 0.125000 +v 1.250000 0.000000 0.125000 +v 0.000000 0.000000 -0.125000 +v 0.000000 2.400000 0.125000 +v 0.000000 0.000000 0.125000 +v 0.000000 2.400000 -0.125000 +vt 0.923077 0.000000 +vt 1.000000 0.500000 +vt 0.923077 0.500000 +vt 0.923077 0.960000 +vt 0.846154 0.000000 +vt 0.000000 0.959961 +vt 0.384766 -0.000000 +vt 0.000000 0.000000 +vt 0.384615 0.960000 +vt 0.000000 0.000000 +vt 0.384615 0.000000 +vt 1.000000 1.000000 +vt 0.923077 0.500000 +vt 1.000000 0.500000 +vt 0.769231 0.960000 +vt 0.846154 0.000000 +vt 0.846154 0.960000 +vt 1.000000 0.000000 +vt 0.846154 0.960000 +vt 0.384766 0.959961 +vt 0.000000 0.960000 +vt 0.923077 1.000000 +vt 0.769231 0.000000 +vn 0.0000 -1.0000 0.0000 +vn 1.0000 0.0000 0.0000 +vn 0.0000 0.0000 -1.0000 +vn 0.0000 0.0000 1.0000 +vn 0.0000 1.0000 0.0000 +vn -1.0000 0.0000 0.0000 +usemtl Material +s off +f 2/1/1 7/2/1 5/3/1 +f 1/4/2 4/5/2 2/1/2 +f 8/6/3 2/7/3 5/8/3 +f 3/9/4 7/10/4 4/11/4 +f 8/12/5 3/13/5 1/14/5 +f 7/15/6 8/16/6 5/17/6 +f 2/1/1 4/18/1 7/2/1 +f 1/4/2 3/19/2 4/5/2 +f 8/6/3 1/20/3 2/7/3 +f 3/9/4 6/21/4 7/10/4 +f 8/12/5 6/22/5 3/13/5 +f 7/15/6 6/23/6 8/16/6 diff --git a/blends/door.blend b/blends/door.blend index d5a9b1d..74ea628 100644 Binary files a/blends/door.blend and b/blends/door.blend differ diff --git a/blends/door.blend1 b/blends/door.blend1 index d239a1d..d5a9b1d 100644 Binary files a/blends/door.blend1 and b/blends/door.blend1 differ diff --git a/lib/game_objects/camera.rb b/lib/game_objects/camera.rb index 71e2348..3bd607f 100644 --- a/lib/game_objects/camera.rb +++ b/lib/game_objects/camera.rb @@ -91,7 +91,6 @@ class IMICFPS if @entity @entity.orientation.y += delta - @entity.orientation.y %= 360 position_camera else free_move diff --git a/lib/game_objects/entities/player.rb b/lib/game_objects/entities/player.rb index acd338f..b46e11a 100644 --- a/lib/game_objects/entities/player.rb +++ b/lib/game_objects/entities/player.rb @@ -9,6 +9,7 @@ class IMICFPS def setup bind_model("base", "biped") @collision = :dynamic + @physics = true @speed = 2.5 # meter's per second @running_speed = 5.0 # meter's per second @@ -93,11 +94,6 @@ class IMICFPS # Do not handle movement if mouse is not captured return if @camera && !@camera.mouse_captured - if @_time_in_air - air_time = (Gosu.milliseconds - @_time_in_air) / 1000.0 - @velocity.y -= IMICFPS::GRAVITY * air_time * delta_time - end - super end @@ -138,25 +134,8 @@ class IMICFPS end def jump - if InputMapper.down?(:jump) && !@jumping - @jumping = true - @_time_in_air = Gosu.milliseconds - - elsif !@jumping - @falling = true - @_time_in_air ||= Gosu.milliseconds # FIXME - else - if @jumping && @velocity.y <= 0 - @falling = false - @jumping = false - end - end - - if @jumping && !@falling - if InputMapper.down?(:jump) - @velocity.y = 1.5 - @falling = true - end + if InputMapper.down?(:jump) && window.current_state.collision_manager.on_ground?(self) + @velocity.y = 1.5 end end diff --git a/lib/game_objects/entity.rb b/lib/game_objects/entity.rb index a82f195..7ce3b17 100644 --- a/lib/game_objects/entity.rb +++ b/lib/game_objects/entity.rb @@ -9,13 +9,14 @@ class IMICFPS attr_accessor :position, :orientation, :velocity attr_reader :name, :debug_color, :bounding_box, :collision, :physics, :mass, :drag, :camera - def initialize(manifest:, map_entity: nil, spawnpoint: nil, backface_culling: true, auto_manage: true) + def initialize(manifest:, map_entity: nil, spawnpoint: nil, backface_culling: false, auto_manage: true) @manifest = manifest - @position = map_entity ? map_entity.position : spawnpoint.position - @orientation = map_entity ? map_entity.orientation : spawnpoint.orientation + @position = map_entity ? map_entity.position.clone : spawnpoint.position.clone + @orientation = map_entity ? map_entity.orientation.clone : spawnpoint.orientation.clone @scale = map_entity ? map_entity.scale : 1.0 @backface_culling = backface_culling + @name = @manifest.name @bound_model = map_entity ? bind_model(map_entity.package, map_entity.model) : nil @visible = true @@ -41,7 +42,6 @@ class IMICFPS if @bound_model @bound_model.model.entity = self - @bound_model.model.objects.each { |o| o.scale = self.scale } @normalized_bounding_box = normalize_bounding_box_with_offset normalize_bounding_box @@ -62,7 +62,6 @@ 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 } @bounding_box = normalize_bounding_box_with_offset return model diff --git a/lib/managers/collision_manager.rb b/lib/managers/collision_manager.rb index 645d8cb..f0662f6 100644 --- a/lib/managers/collision_manager.rb +++ b/lib/managers/collision_manager.rb @@ -82,5 +82,29 @@ class IMICFPS return box end + + def on_ground?(entity) # TODO: Use some form of caching to speed this up + on_ground = false + @collisions.detect do |a, b| + next unless entity == a || entity == b + + vs = a + vs = b if a == entity + + broadphase = search(Ray.new(entity.position, Vector.new(0, -1, 0), entity.velocity.y.abs)) + + broadphase.detect do |ent| + ray = Ray.new(entity.position - ent.position, Vector.new(0, -1, 0)) + if ent.model.aabb_tree.search(ray).size > 0 + on_ground = true + return true + end + end + + break if on_ground + end + + return on_ground + end end end diff --git a/lib/managers/physics_manager.rb b/lib/managers/physics_manager.rb index 69d1061..367f583 100644 --- a/lib/managers/physics_manager.rb +++ b/lib/managers/physics_manager.rb @@ -15,21 +15,24 @@ class IMICFPS 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 + entity.velocity.y = other.velocity.y if other.velocity.y < entity.velocity.y && entity.velocity.y < 0 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 + + on_ground = @collision_manager.on_ground?(entity) + entity.velocity.x *= entity.drag + entity.velocity.z *= entity.drag + + if on_ground + entity.velocity.y = 0 + else + entity.velocity.y -= IMICFPS::GRAVITY * entity.delta_time if entity.physics + end end end end diff --git a/maps/test_map.json b/maps/test_map.json index b45785b..19f5a92 100644 --- a/maps/test_map.json +++ b/maps/test_map.json @@ -26,7 +26,7 @@ "model":"tree", "position": { "x":0, - "y":1, + "y":0.6, "z":0 }, "orientation": { @@ -36,6 +36,134 @@ }, "scale": 1.0, "scripts": [] + }, + { + "package":"base", + "model":"tree", + "position": { + "x":16.7, + "y":1.1, + "z":-7.27 + }, + "orientation": { + "x": 0, + "y": 37.0, + "z": 0 + }, + "scale": 0.9, + "scripts": [] + }, + { + "package":"base", + "model":"tree", + "position": { + "x":-21.2121, + "y":0.06, + "z":6.06061 + }, + "orientation": { + "x": 0, + "y": 64.0, + "z": 0 + }, + "scale": 0.25, + "scripts": [] + }, + { + "package":"base", + "model":"power_plant", + "position": { + "x":37.8788, + "y":0.343869, + "z":-6.06061 + }, + "orientation": { + "x": 0, + "y": 0, + "z": 0 + }, + "scale": 1, + "scripts": [] + }, + { + "package":"base", + "model":"purchase_terminal", + "position": { + "x":37.8788, + "y":1.843869, + "z":-6.06061 + }, + "orientation": { + "x": 0, + "y": 0, + "z": 0 + }, + "scale": 1, + "scripts": [] + }, + { + "package":"base", + "model":"information_panel", + "position": { + "x":37.8788, + "y":0.343869, + "z":-6.06061 + }, + "orientation": { + "x": 0, + "y": 0, + "z": 0 + }, + "scale": 1, + "scripts": [] + }, + { + "package":"base", + "model":"door", + "position": { + "x":37.8788, + "y":0.343869, + "z":-12.06061 + }, + "orientation": { + "x": 0, + "y": 0, + "z": 0 + }, + "scale": 1, + "scripts": [] + }, + { + "package":"base", + "model":"door", + "position": { + "x":37.8788, + "y":0.343869, + "z":-12.06061 + }, + "orientation": { + "x": 0, + "y": 180, + "z": 0 + }, + "scale": 1, + "scripts": [] + }, + { + "package":"base", + "model":"war_factory", + "position": { + "x":39.3939, + "y":0.499657, + "z":9.69697 + }, + "orientation": { + "x": 0, + "y": 0, + "z": 0 + }, + "scale": 1, + "scripts": [] } ], @@ -43,26 +171,26 @@ { "team":0, "position": { - "x": 0, - "y": 1, - "z": 0 + "x": 37.8788, + "y": 0.343869, + "z": -2.06061 }, "orientation": { "x": 0, - "y": 0, + "y": 180, "z": 0 } }, { "team":1, "position": { - "x": 0, - "y": 1, - "z": 0 + "x": 37.8788, + "y": 0.343869, + "z": -4.06061 }, "orientation": { "x": 0, - "y": 0, + "y": 180, "z": 0 } }