From b091a489af8984a31f8a110f022df24ac005593b Mon Sep 17 00:00:00 2001 From: Cyberarm Date: Fri, 27 Sep 2019 14:30:23 -0500 Subject: [PATCH] Removed entity management from Game, refactored Map to MapLoader and added Map to manage world --- .../base/power_plant/scripts/power_plant.rb | 8 +- .../base/war_factory/scripts/war_factory.rb | 8 +- i-mic-fps.rb | 3 +- lib/event.rb | 6 +- lib/event_handlers/entity_moved.rb | 2 +- lib/event_handlers/input.rb | 2 +- lib/game_objects/entity.rb | 2 +- lib/game_objects/light.rb | 13 +- lib/managers/collision_manager.rb | 10 +- lib/managers/entity_manager.rb | 10 +- lib/managers/light_manager.rb | 6 + lib/managers/physics_manager.rb | 2 +- lib/map.rb | 177 ++++++------------ lib/map_loader.rb | 138 ++++++++++++++ lib/renderer/bounding_box_renderer.rb | 6 +- lib/renderer/renderer.rb | 8 +- lib/scripting.rb | 4 + lib/states/game_state.rb | 9 - lib/states/game_states/game.rb | 71 ++----- lib/states/game_states/loading_state.rb | 14 +- 20 files changed, 260 insertions(+), 239 deletions(-) create mode 100644 lib/map_loader.rb diff --git a/assets/base/power_plant/scripts/power_plant.rb b/assets/base/power_plant/scripts/power_plant.rb index 1f76ca5..4df26d2 100644 --- a/assets/base/power_plant/scripts/power_plant.rb +++ b/assets/base/power_plant/scripts/power_plant.rb @@ -1,8 +1,8 @@ component(:building) on.create do |event| - event.map.insert_entity("base", "purchase_terminal", event.entity.position + Vector.new(-1.5, 1.5, -4.52), Vector.new(0, 20, 0), data: {team: nil}) - event.map.insert_entity("base", "information_panel", event.entity.position + Vector.new(3, 0, 1), Vector.new(0, -90, 0)) - event.map.insert_entity("base", "door", event.entity.position + Vector.new(0, 0, 6), Vector.new(0, 0, 0)) - event.map.insert_entity("base", "door", event.entity.position + Vector.new(0, 0, 6), Vector.new(0, 180, 0)) + map.insert_entity("base", "purchase_terminal", event.entity.position + Vector.new(-1.5, 1.5, -4.52), Vector.new(0, 20, 0), data: {team: nil}) + map.insert_entity("base", "information_panel", event.entity.position + Vector.new(3, 0, 1), Vector.new(0, -90, 0)) + map.insert_entity("base", "door", event.entity.position + Vector.new(0, 0, 6), Vector.new(0, 0, 0)) + map.insert_entity("base", "door", event.entity.position + Vector.new(0, 0, 6), Vector.new(0, 180, 0)) end \ No newline at end of file diff --git a/assets/base/war_factory/scripts/war_factory.rb b/assets/base/war_factory/scripts/war_factory.rb index cf58934..6f19ed4 100644 --- a/assets/base/war_factory/scripts/war_factory.rb +++ b/assets/base/war_factory/scripts/war_factory.rb @@ -1,8 +1,8 @@ component(:building) on.create do |event| - event.map.insert_entity("base", "purchase_terminal", event.entity.position + Vector.new(6, 1.5, 3), Vector.new(0, -90, 0), data: {team: nil}) - event.map.insert_entity("base", "information_panel", event.entity.position + Vector.new(0.5, 0, 3), Vector.new(0, 90, 0)) - event.map.insert_entity("base", "door", event.entity.position + Vector.new(3.3, 0, 6), Vector.new(0, 0, 0)) - event.map.insert_entity("base", "door", event.entity.position + Vector.new(3.3, 0, 6), Vector.new(0, 180, 0)) + map.insert_entity("base", "purchase_terminal", event.entity.position + Vector.new(6, 1.5, 3), Vector.new(0, -90, 0), data: {team: nil}) + map.insert_entity("base", "information_panel", event.entity.position + Vector.new(0.5, 0, 3), Vector.new(0, 90, 0)) + map.insert_entity("base", "door", event.entity.position + Vector.new(3.3, 0, 6), Vector.new(0, 0, 0)) + map.insert_entity("base", "door", event.entity.position + Vector.new(3.3, 0, 6), Vector.new(0, 180, 0)) end \ No newline at end of file diff --git a/i-mic-fps.rb b/i-mic-fps.rb index 97fa7b4..4d0c904 100644 --- a/i-mic-fps.rb +++ b/i-mic-fps.rb @@ -85,8 +85,9 @@ require_relative "lib/wavefront/parser" require_relative "lib/wavefront/object" require_relative "lib/wavefront/material" -require_relative "lib/map" +require_relative "lib/map_loader" require_relative "lib/manifest" +require_relative "lib/map" require_relative "lib/window" diff --git a/lib/event.rb b/lib/event.rb index 5cf2eed..76873a6 100644 --- a/lib/event.rb +++ b/lib/event.rb @@ -1,9 +1,9 @@ class IMICFPS class EventHandler class Event - attr_reader :entity, :context, :map, :player - def initialize(entity:, context: nil, map: $window.current_state, player: nil) - @entity, @context, @map, @player = entity, context, map, player + attr_reader :entity, :context + def initialize(entity:, context: nil) + @entity, @context = entity, context end end end diff --git a/lib/event_handlers/entity_moved.rb b/lib/event_handlers/entity_moved.rb index 2853770..50928d9 100644 --- a/lib/event_handlers/entity_moved.rb +++ b/lib/event_handlers/entity_moved.rb @@ -6,7 +6,7 @@ class IMICFPS end def handle(subscriber, context, *args) - event = EventHandler::Event.new(entity: context) + event = EventHandler::Event.new(entity: args.first.first) subscriber.trigger(event) end diff --git a/lib/event_handlers/input.rb b/lib/event_handlers/input.rb index 68735ec..6c1743a 100644 --- a/lib/event_handlers/input.rb +++ b/lib/event_handlers/input.rb @@ -9,7 +9,7 @@ class IMICFPS action = subscriber.args.flatten.first key = args.flatten.first - event = EventHandler::Event.new(entity: subscriber.entity, context: context, player: context) + event = EventHandler::Event.new(entity: subscriber.entity, context: context) if action.is_a?(Numeric) && action == key subscriber.trigger(event) diff --git a/lib/game_objects/entity.rb b/lib/game_objects/entity.rb index c06732c..fadcf3e 100644 --- a/lib/game_objects/entity.rb +++ b/lib/game_objects/entity.rb @@ -103,7 +103,7 @@ class IMICFPS model.update unless at_same_position? - Publisher.instance.publish(:entity_moved, self, self) + Publisher.instance.publish(:entity_moved, nil, self) @bounding_box = normalize_bounding_box_with_offset if model end diff --git a/lib/game_objects/light.rb b/lib/game_objects/light.rb index a8b366a..14ea9e9 100644 --- a/lib/game_objects/light.rb +++ b/lib/game_objects/light.rb @@ -2,27 +2,18 @@ class IMICFPS class Light attr_reader :ambient, :diffuse, :specular, :position, :light_id attr_accessor :x, :y, :z, :intensity - def initialize(x:,y:,z:, game_state:, + def initialize(id:, x:,y:,z:, ambient: Vector.new(0.5, 0.5, 0.5, 1), diffuse: Vector.new(1, 0.5, 0, 1), specular: Vector.new(0.2, 0.2, 0.2, 1), position: Vector.new(x, y, z, 0), intensity: 1) + @light_id = id @x,@y,@z = x,y,z - @game_state = game_state @intensity = intensity self.ambient = ambient self.diffuse = diffuse self.specular = specular self.position = position - @light_id = available_light - - @game_state.add_light(self) - end - - def available_light - raise "Using to many lights, #{@game_state.light_count}/#{LightManager::MAX_LIGHTS}" if @game_state.light_count > LightManager::MAX_LIGHTS - puts "OpenGL::GL_LIGHT#{@game_state.light_count}" if $debug.get(:stats) - @light_id = Object.const_get "OpenGL::GL_LIGHT#{@game_state.light_count}" end def ambient=(color) diff --git a/lib/managers/collision_manager.rb b/lib/managers/collision_manager.rb index a14effd..58dc43d 100644 --- a/lib/managers/collision_manager.rb +++ b/lib/managers/collision_manager.rb @@ -1,8 +1,8 @@ class IMICFPS class CollisionManager - attr_reader :game_state, :collisions - def initialize(game_state:) - @game_state = game_state + attr_reader :map, :collisions + def initialize(map:) + @map = map @collisions = {} @aabb_tree = AABBTree.new @@ -14,7 +14,7 @@ class IMICFPS end def update - @game_state.entities.each do |entity| + @map.entities.each do |entity| next unless entity.is_a?(Entity) next unless node = @aabb_tree.objects[entity] @@ -42,7 +42,7 @@ class IMICFPS @collisions.clear broadphase = {} - @game_state.entities.each do |entity| + @map.entities.each do |entity| next unless entity.collidable? next if entity.collision == :static # Only dynamic entities can be resolved diff --git a/lib/managers/entity_manager.rb b/lib/managers/entity_manager.rb index 2c61b88..aefbbe4 100644 --- a/lib/managers/entity_manager.rb +++ b/lib/managers/entity_manager.rb @@ -2,12 +2,12 @@ class IMICFPS module EntityManager # Get included into GameState context def add_entity(entity) @collision_manager.add(entity)# Add every entity to collision manager - @publisher.publish(:create, self, entity) + Publisher.instance.publish(:create, nil, entity) @entities << entity end def insert_entity(package, name, position, orientation, data = {}) - ent = Map::Entity.new(package, name, position, orientation, Vector.new(1,1,1)) + ent = MapLoader::Entity.new(package, name, position, orientation, Vector.new(1,1,1)) add_entity(IMICFPS::Entity.new(map_entity: ent, manifest: Manifest.new(package: package, name: name))) end @@ -15,11 +15,15 @@ class IMICFPS @entities.detect {|entity| entity == entity} end + def find_entity_by(name:) + @entities.detect { |entity| entity.name == name} + end + def remove_entity(entity) ent = @entities.detect {|entity| entity == entity} if ent @collision_manager.remove(entity) - @publisher.publish(:destroy, self, entity) + @publisher.publish(:destroy, nil, entity) @entities.delete(ent) end end diff --git a/lib/managers/light_manager.rb b/lib/managers/light_manager.rb index 477f9fd..15e9745 100644 --- a/lib/managers/light_manager.rb +++ b/lib/managers/light_manager.rb @@ -20,5 +20,11 @@ class IMICFPS def clear_lights @lights.clear end + + def available_light + raise "Using to many lights, #{light_count}/#{LightManager::MAX_LIGHTS}" if light_count > LightManager::MAX_LIGHTS + puts "OpenGL::GL_LIGHT#{light_count}" if $debug.get(:stats) + Object.const_get "OpenGL::GL_LIGHT#{light_count}" + end end end diff --git a/lib/managers/physics_manager.rb b/lib/managers/physics_manager.rb index 367f583..ada9330 100644 --- a/lib/managers/physics_manager.rb +++ b/lib/managers/physics_manager.rb @@ -19,7 +19,7 @@ class IMICFPS end def simulate - @collision_manager.game_state.entities.each do |entity| + @collision_manager.map.entities.each do |entity| 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 diff --git a/lib/map.rb b/lib/map.rb index a356093..7036cea 100644 --- a/lib/map.rb +++ b/lib/map.rb @@ -1,138 +1,73 @@ class IMICFPS class Map - attr_reader :metadata, :terrain, :skydome, :entities, :spawnpoints - attr_reader :assets, :missing_assets - def initialize(map_file:) - @metadata = Map::MetaData.new - @terrain = Map::Entity.new - @skydome = Map::Entity.new - @entities = [] - @spawnpoints = [] + include EntityManager + include LightManager - @assets = [] - @missing_assets = [] + attr_reader :gravity + def initialize(map_loader:, gravity: IMICFPS::GRAVITY) + @map_loader = map_loader + @gravity = gravity - parse(map_file) + @entities = [] + @lights = [] + + @collision_manager = CollisionManager.new(map: self) + @renderer = Renderer.new(map: self) + Publisher.new end - def parse(file) - data = JSON.parse(File.read(file)) + def setup + add_entity(Terrain.new(map_entity: @map_loader.terrain, manifest: Manifest.new(package: @map_loader.terrain.package, name: @map_loader.terrain.name))) - if section = data["metadata"] - @metadata.name = section["name"] - @metadata.gamemode = section["gamemode"] - @metadata.authors = section["authors"] - @metadata.datetime = Time.parse(section["datetime"]) - @metadata.thumbnail = section["thumbnail"] # TODO: convert thumbnail to Image - @metadata.description = section["description"] - else - raise "Map metadata is missing!" + add_entity(Skydome.new(map_entity: @map_loader.skydome, manifest: Manifest.new(package: @map_loader.skydome.package, name: @map_loader.skydome.name), backface_culling: false)) + + @map_loader.entities.each do |ent| + add_entity(Entity.new(map_entity: ent, manifest: Manifest.new(package: ent.package, name: ent.name))) end - if section = data["terrain"] - @terrain.package = section["package"] - @terrain.name = section["name"] - @terrain.position = Vector.new - @terrain.orientation = Vector.new - if section["scale"] - if section["scale"].is_a?(Hash) - @terrain.scale = Vector.new( - section["scale"]["x"], - section["scale"]["y"], - section["scale"]["z"] - ) - else - scale = Float(section["scale"]) - @terrain.scale = Vector.new(scale, scale, scale) - end - else - @terrain.scale = Vector.new(1, 1, 1) - end - @terrain.water_level = section["water_level"] - else - raise "Map terrain data is missing!" - end + add_entity(Player.new(spawnpoint: @map_loader.spawnpoints.sample, manifest: Manifest.new(package: "base", name: "biped"))) - if section = data["skydome"] - @skydome.package = section["package"] - @skydome.name = section["name"] - @skydome.position = Vector.new - @skydome.orientation = Vector.new - if section["scale"] - if section["scale"].is_a?(Hash) - @skydome.scale = Vector.new( - section["scale"]["x"], - section["scale"]["y"], - section["scale"]["z"] - ) - else - scale = Float(section["scale"]) - @skydome.scale = Vector.new(scale, scale, scale) - end - else - @skydome.scale = Vector.new(1, 1, 1) - end - else - raise "Map skydome data is missing!" - end + # TODO: Load lights from MapLoader + add_light(Light.new(id: available_light, x: 3, y: -6, z: 6)) + add_light(Light.new(id: available_light, x: 0, y: 100, z: 0, diffuse: Color.new(1.0, 0.5, 0.1))) + end - if section = data["entities"] - section.each do |ent| - entity = Map::Entity.new - entity.package = ent["package"] - entity.name = ent["name"] - entity.position = Vector.new( - ent["position"]["x"], - ent["position"]["y"], - ent["position"]["z"] - ) - entity.orientation = Vector.new( - ent["orientation"]["x"], - ent["orientation"]["y"], - ent["orientation"]["z"] - ) - if ent["scale"].is_a?(Hash) - entity.scale = Vector.new( - ent["scale"]["x"], - ent["scale"]["y"], - ent["scale"]["z"] - ) - else - scale = Float(ent["scale"]) - entity.scale = Vector.new(scale, scale, scale) - end - entity.scripts = ent["scripts"] + def data + @map_loader + end - @entities << entity - end - else - raise "Map has no entities!" - end - - if section = data["spawnpoints"] - section.each do |point| - spawnpoint = SpawnPoint.new - spawnpoint.team = point["team"] - spawnpoint.position = Vector.new( - point["position"]["x"], - point["position"]["y"], - point["position"]["z"] - ) - spawnpoint.orientation = Vector.new( - point["orientation"]["x"], - point["orientation"]["y"], - point["orientation"]["z"] - ) - - @spawnpoints << spawnpoint - end - else - raise "Map has no spawnpoints!" + def glError? + e = glGetError() + if e != GL_NO_ERROR + $stderr.puts "OpenGL error in: #{gluErrorString(e)} (#{e})\n" + exit end end - MetaData = Struct.new(:name, :gamemode, :authors, :datetime, :thumbnail, :description) - Entity = Struct.new(:package, :name, :position, :orientation, :scale, :water_level, :scripts) - SpawnPoint = Struct.new(:team, :position, :orientation) + def render(camera) + glError? + + Gosu.gl do + glError? + glClearColor(0,0.2,0.5,1) # skyish blue + glError? + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) # clear the screen and the depth buffer + glError? + + @lights.each(&:draw) + + camera.draw + glEnable(GL_DEPTH_TEST) + + @renderer.draw + end + end + + def update + @collision_manager.update + + @entities.each(&:update) + # @lights.each(&:update) + end end end \ No newline at end of file diff --git a/lib/map_loader.rb b/lib/map_loader.rb new file mode 100644 index 0000000..1e2cb6b --- /dev/null +++ b/lib/map_loader.rb @@ -0,0 +1,138 @@ +class IMICFPS + class MapLoader + attr_reader :metadata, :terrain, :skydome, :entities, :spawnpoints + attr_reader :assets, :missing_assets + def initialize(map_file:) + @metadata = MapLoader::MetaData.new + @terrain = MapLoader::Entity.new + @skydome = MapLoader::Entity.new + @entities = [] + @spawnpoints = [] + + @assets = [] + @missing_assets = [] + + parse(map_file) + end + + def parse(file) + data = JSON.parse(File.read(file)) + + if section = data["metadata"] + @metadata.name = section["name"] + @metadata.gamemode = section["gamemode"] + @metadata.authors = section["authors"] + @metadata.datetime = Time.parse(section["datetime"]) + @metadata.thumbnail = section["thumbnail"] # TODO: convert thumbnail to Image + @metadata.description = section["description"] + else + raise "Map metadata is missing!" + end + + if section = data["terrain"] + @terrain.package = section["package"] + @terrain.name = section["name"] + @terrain.position = Vector.new + @terrain.orientation = Vector.new + if section["scale"] + if section["scale"].is_a?(Hash) + @terrain.scale = Vector.new( + section["scale"]["x"], + section["scale"]["y"], + section["scale"]["z"] + ) + else + scale = Float(section["scale"]) + @terrain.scale = Vector.new(scale, scale, scale) + end + else + @terrain.scale = Vector.new(1, 1, 1) + end + @terrain.water_level = section["water_level"] + else + raise "Map terrain data is missing!" + end + + if section = data["skydome"] + @skydome.package = section["package"] + @skydome.name = section["name"] + @skydome.position = Vector.new + @skydome.orientation = Vector.new + if section["scale"] + if section["scale"].is_a?(Hash) + @skydome.scale = Vector.new( + section["scale"]["x"], + section["scale"]["y"], + section["scale"]["z"] + ) + else + scale = Float(section["scale"]) + @skydome.scale = Vector.new(scale, scale, scale) + end + else + @skydome.scale = Vector.new(1, 1, 1) + end + else + raise "Map skydome data is missing!" + end + + if section = data["entities"] + section.each do |ent| + entity = MapLoader::Entity.new + entity.package = ent["package"] + entity.name = ent["name"] + entity.position = Vector.new( + ent["position"]["x"], + ent["position"]["y"], + ent["position"]["z"] + ) + entity.orientation = Vector.new( + ent["orientation"]["x"], + ent["orientation"]["y"], + ent["orientation"]["z"] + ) + if ent["scale"].is_a?(Hash) + entity.scale = Vector.new( + ent["scale"]["x"], + ent["scale"]["y"], + ent["scale"]["z"] + ) + else + scale = Float(ent["scale"]) + entity.scale = Vector.new(scale, scale, scale) + end + entity.scripts = ent["scripts"] + + @entities << entity + end + else + raise "Map has no entities!" + end + + if section = data["spawnpoints"] + section.each do |point| + spawnpoint = SpawnPoint.new + spawnpoint.team = point["team"] + spawnpoint.position = Vector.new( + point["position"]["x"], + point["position"]["y"], + point["position"]["z"] + ) + spawnpoint.orientation = Vector.new( + point["orientation"]["x"], + point["orientation"]["y"], + point["orientation"]["z"] + ) + + @spawnpoints << spawnpoint + end + else + raise "Map has no spawnpoints!" + end + end + + MetaData = Struct.new(:name, :gamemode, :authors, :datetime, :thumbnail, :description) + Entity = Struct.new(:package, :name, :position, :orientation, :scale, :water_level, :scripts) + SpawnPoint = Struct.new(:team, :position, :orientation) + end +end \ No newline at end of file diff --git a/lib/renderer/bounding_box_renderer.rb b/lib/renderer/bounding_box_renderer.rb index 31d80c2..ca6a030 100644 --- a/lib/renderer/bounding_box_renderer.rb +++ b/lib/renderer/bounding_box_renderer.rb @@ -1,8 +1,8 @@ class IMICFPS class BoundingBoxRenderer attr_reader :bounding_boxes, :vertex_count - def initialize(game_state:) - @game_state = game_state + def initialize(map:) + @map = map @bounding_boxes = {} @vertex_count = 0 @@ -205,7 +205,7 @@ class IMICFPS glPopMatrix - found = @game_state.entities.detect { |o| o == bounding_box[:object] } + found = @map.entities.detect { |o| o == bounding_box[:object] } unless found @vertex_count -= @bounding_boxes[key][:vertices_size] diff --git a/lib/renderer/renderer.rb b/lib/renderer/renderer.rb index 2e19d0c..87c490f 100644 --- a/lib/renderer/renderer.rb +++ b/lib/renderer/renderer.rb @@ -4,15 +4,15 @@ class IMICFPS attr_reader :opengl_renderer, :bounding_box_renderer - def initialize(game_state:) - @game_state = game_state + def initialize(map:) + @map = map - @bounding_box_renderer = BoundingBoxRenderer.new(game_state: game_state) + @bounding_box_renderer = BoundingBoxRenderer.new(map: map) @opengl_renderer = OpenGLRenderer.new end def draw - @game_state.entities.each do |object| + @map.entities.each do |object| if object.visible && object.renderable # Render bounding boxes before transformation is applied @bounding_box_renderer.create_bounding_box(object, object.model.bounding_box, object.debug_color, object.object_id) if $debug.get(:boundingboxes) diff --git a/lib/scripting.rb b/lib/scripting.rb index de7d6ba..fb286d3 100644 --- a/lib/scripting.rb +++ b/lib/scripting.rb @@ -8,5 +8,9 @@ class IMICFPS def component(name) Component.get(name) end + + def map + $window.current_state.map + end end end \ No newline at end of file diff --git a/lib/states/game_state.rb b/lib/states/game_state.rb index 91e1556..913e284 100644 --- a/lib/states/game_state.rb +++ b/lib/states/game_state.rb @@ -1,16 +1,7 @@ class IMICFPS class GameState < CyberarmEngine::GameState include CommonMethods - include EntityManager - include LightManager attr_reader :options - def initialize(options = {}) - @delta_time = Gosu.milliseconds - @entities = [] - @lights = [] - - super - end end end \ No newline at end of file diff --git a/lib/states/game_states/game.rb b/lib/states/game_states/game.rb index c24b120..661eaef 100644 --- a/lib/states/game_states/game.rb +++ b/lib/states/game_states/game.rb @@ -1,25 +1,12 @@ class IMICFPS class Game < GameState - attr_reader :collision_manager, :delta_time + attr_reader :map def setup - @collision_manager = CollisionManager.new(game_state: self) - @renderer = Renderer.new(game_state: self) - @publisher = Publisher.new + @map = Map.new(map_loader: @options[:map_loader]) + @map.setup - @map = @options[:map] - add_entity(Terrain.new(map_entity: @map.terrain, manifest: Manifest.new(package: @map.terrain.package, name: @map.terrain.name))) - - @draw_skydome = true - @skydome = Skydome.new(map_entity: @map.skydome, manifest: Manifest.new(package: @map.skydome.package, name: @map.skydome.name), backface_culling: false) - add_entity(@skydome) - - @map.entities.each do |ent| - add_entity(Entity.new(map_entity: ent, manifest: Manifest.new(package: ent.package, name: ent.name))) - end - - @player = Player.new(spawnpoint: @map.spawnpoints.sample, manifest: Manifest.new(package: "base", name: "biped")) - add_entity(@player) + @player = @map.find_entity_by(name: "biped") @camera = Camera.new(position: @player.position.clone) @camera.attach_to(@player) @@ -29,9 +16,6 @@ class IMICFPS @text = Text.new("Pending...", x: 10, y: 10, z: 1, size: 18, font: "DejaVu Sans", shadow_color: Gosu::Color::BLACK) - 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.exist?("./demo.dat") ? File.read("./demo.dat").lines : "" @demo_index= 0 @@ -49,33 +33,8 @@ class IMICFPS end end - def glError? - e = glGetError() - if e != GL_NO_ERROR - $stderr.puts "OpenGL error in: #{gluErrorString(e)} (#{e})\n" - exit - end - end - def draw - glError? - - gl do - glError? - glClearColor(0,0.2,0.5,1) # skyish blue - glError? - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) # clear the screen and the depth buffer - glError? - - @lights.each(&:draw) - - @camera.draw - @renderer.opengl_renderer.draw_object(@skydome) if @skydome.renderable - glEnable(GL_DEPTH_TEST) - - @renderer.draw - end - + @map.render(@camera) # Draw crosshair draw_rect(window.width/2-@crosshair_size, (window.height/2-@crosshair_size)-@crosshair_thickness/2, @crosshair_size*2, @crosshair_thickness, @crosshair_color, 0, :default) draw_rect((window.width/2)-@crosshair_thickness/2, window.height/2-(@crosshair_size*2), @crosshair_thickness, @crosshair_size*2, @crosshair_color, 0, :default) @@ -86,15 +45,12 @@ class IMICFPS def update update_text - @publisher.publish(:tick, Gosu.milliseconds - window.delta_time) + Publisher.instance.publish(:tick, Gosu.milliseconds - window.delta_time) - @collision_manager.update - @entities.each(&:update) + @map.update control_player - @skydome.update if @skydome.renderable - @camera.update if $debug.get(:stats) @@ -105,9 +61,6 @@ class IMICFPS @text.text = "" end - @draw_skydome = $debug.get(:skydome) - @skydome.renderable = @draw_skydome - if ARGV.join.include?("--playdemo") if @demo_data[@demo_index]&.start_with?("tick") if @demo_tick == @demo_data[@demo_index].split(" ").last.to_i @@ -178,8 +131,6 @@ Last Frame: #{Gosu.milliseconds - window.delta_time}ms (#{Gosu.fps} fps) Vertices: #{formatted_number(window.number_of_vertices)} Faces: #{formatted_number(window.number_of_vertices/3)} - -Draw Skydome: #{@draw_skydome} eos end @@ -204,9 +155,9 @@ eos @demo_changed = true end InputMapper.keydown(id) - @publisher.publish(:button_down, nil, id) + Publisher.instance.publish(:button_down, nil, id) - @entities.each do |entity| + @map.entities.each do |entity| entity.button_down(id) if defined?(entity.button_down) end end @@ -221,9 +172,9 @@ eos @demo_changed = true end InputMapper.keyup(id) - @publisher.publish(:button_up, nil, id) + Publisher.instance.publish(:button_up, nil, id) - @entities.each do |entity| + @map.entities.each do |entity| entity.button_up(id) if defined?(entity.button_up) end diff --git a/lib/states/game_states/loading_state.rb b/lib/states/game_states/loading_state.rb index 8f00736..af7226f 100644 --- a/lib/states/game_states/loading_state.rb +++ b/lib/states/game_states/loading_state.rb @@ -1,11 +1,11 @@ class IMICFPS class LoadingState < Menu def setup - @map = Map.new(map_file: @options[:map_file]) + @map_loader = MapLoader.new(map_file: @options[:map_file]) title "I-MIC FPS" - @subheading = Text.new("Loading Map: #{@map.metadata.name}", y: 100, size: 50, alignment: :center) - @description = Text.new("Map created by: #{@map.metadata.authors.join(", ")}\n#{@map.metadata.description}", y: 180, size: 24, alignment: :center) + @subheading = Text.new("Loading Map: #{@map_loader.metadata.name}", y: 100, size: 50, alignment: :center) + @description = Text.new("Map created by: #{@map_loader.metadata.authors.join(", ")}\n#{@map_loader.metadata.description}", y: 180, size: 24, alignment: :center) @state = Text.new("Preparing...", y: window.height/2-40, size: 40, alignment: :center) @percentage = Text.new("0%", y: window.height - 100 + 25, size: 50, alignment: :center) @@ -14,9 +14,9 @@ class IMICFPS @asset_index = 0 # add_asset(:shader, nil, "default") - add_asset(:model, @map.terrain.package, @map.terrain.name) - add_asset(:model, @map.skydome.package, @map.skydome.name) - @map.entities.each do |entity| + add_asset(:model, @map_loader.terrain.package, @map_loader.terrain.name) + add_asset(:model, @map_loader.skydome.package, @map_loader.skydome.name) + @map_loader.entities.each do |entity| add_asset(:model, entity.package, entity.name) end @@ -66,7 +66,7 @@ class IMICFPS unless @asset_index < @assets.count if @act && Gosu.milliseconds-@completed_for_ms > 250 - push_state(@options[:forward], map: @map) + push_state(@options[:forward], map_loader: @map_loader) else @act = true @completed_for_ms = Gosu.milliseconds unless @lock