This commit is contained in:
2020-07-19 09:42:55 -05:00
parent 4ee97cca4b
commit d72e8ccbd0
15 changed files with 91 additions and 110 deletions

View File

@@ -2,6 +2,8 @@ class IMICFPS
class CameraController class CameraController
include CommonMethods include CommonMethods
attr_accessor :mode, :camera, :entity, :distance, :origin_distance,
:constant_pitch, :mouse_sensitivity, :mouse_captured
def initialize(mode: :fpv, camera:, entity:) def initialize(mode: :fpv, camera:, entity:)
# :fpv - First Person View # :fpv - First Person View
# :tpv - Third Person View # :tpv - Third Person View
@@ -21,6 +23,10 @@ class IMICFPS
@mouse_checked = 0 @mouse_checked = 0
end end
def first_person_view?
@mode == :fpv
end
def distance_from_object def distance_from_object
@distance @distance
end end
@@ -34,12 +40,10 @@ class IMICFPS
end end
def position_camera def position_camera
if defined?(@entity.first_person_view) if first_person_view?
if @entity.first_person_view @distance = 0
@distance = 0 else
else @distance = @origin_distance
@distance = @origin_distance
end
end end
x_offset = horizontal_distance_from_object * Math.sin(@entity.orientation.y.degrees_to_radians) x_offset = horizontal_distance_from_object * Math.sin(@entity.orientation.y.degrees_to_radians)
@@ -75,13 +79,25 @@ class IMICFPS
end end
def button_down(id) def button_down(id)
case id actions = InputMapper.actions(id)
when Gosu::KB_LEFT_ALT, Gosu::KB_RIGHT_ALT
if actions.include?(:release_mouse)
@mouse_captured = false @mouse_captured = false
window.needs_cursor = true window.needs_cursor = true
when Gosu::MS_LEFT, Gosu::MS_MIDDLE, Gosu::MS_RIGHT elsif actions.include?(:capture_mouse)
@mouse_captured = true @mouse_captured = true
window.needs_cursor = false window.needs_cursor = false
elsif actions.include?(:decrease_view_distance)
@camera.max_view_distance -= 0.5
elsif actions.include?(:increase_view_distance)
@camera.max_view_distance += 0.5
elsif actions.include?(:toggle_first_person_view)
@mode = first_person_view? ? :tpv : :fpv
@entity.visible = !first_person_view?
elsif actions.include?(:turn_180)
@entity.orientation.y += 180
@entity.orientation.y %= 360.0
end end
end end

View File

@@ -30,7 +30,7 @@ class IMICFPS
@file.puts("tick #{@index}") @file.puts("tick #{@index}")
end end
@file.puts("down #{InputMapper.action(id)}") @file.puts("down #{InputMapper.actions(id)}")
@changed = true @changed = true
end end
end end
@@ -42,7 +42,7 @@ class IMICFPS
@file.puts("tick #{@index}") @file.puts("tick #{@index}")
end end
@file.puts("up #{InputMapper.action(id)}") @file.puts("up #{InputMapper.actions(id)}")
@changed = true @changed = true
end end
end end

View File

@@ -1,76 +1,19 @@
require "etc"
class IMICFPS class IMICFPS
class Player < Entity class Player < Entity
attr_accessor :speed attr_accessor :speed
attr_reader :name, :bound_model, :first_person_view attr_reader :name, :bound_model
def setup def setup
bind_model bind_model
@speed = 2.5 # meter's per second @speed = 2.5 # meter's per second
@running_speed = 5.0 # meter's per second @running_speed = 5.0 # meter's per second
@turn_speed = 50.0 @turn_speed = 50.0
@old_speed = @speed @old_speed = @speed
@mass = 72 # kg @mass = 72 # kg
@first_person_view = true
@visible = false @visible = false
@drag = 0.6 @drag = 0.6
@devisor = 500.0
@name_image = Gosu::Image.from_text("#{Etc.getlogin}", 100, font: "Consolas", align: :center)
@name_texture_id = Texture.new(image: @name_image).id
end
def draw_nameplate
_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)
glDisable(GL_LIGHTING)
glEnable(GL_COLOR_MATERIAL)
glEnable(GL_TEXTURE_2D)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND)
glBindTexture(GL_TEXTURE_2D, @name_texture_id)
glBegin(GL_TRIANGLES)
glColor3f(1.0,1.0,1.0)
# TOP LEFT
glTexCoord2f(0, 0)
glVertex3f(0-_width,_y+_height,0)
# TOP RIGHT
glTexCoord2f(1, 0)
glVertex3f(0+_width, _y+_height,0)
# BOTTOM LEFT
glTexCoord2f(0, 1)
glVertex3f(0-_width,_y,0)
# BOTTOM LEFT
glTexCoord2f(0, 1)
glVertex3f(0-_width,_y,0)
# BOTTOM RIGHT
glTexCoord2f(1, 1)
glVertex3f(0+_width, _y,0)
# TOP RIGHT
glTexCoord2f(1, 0)
glVertex3f(0+_width,_y+_height,0)
glEnd
# glDisable(GL_BLEND)
glDisable(GL_TEXTURE_2D)
glEnable(GL_LIGHTING)
glPopMatrix
end
def draw
if !@first_person_view
super
draw_nameplate
end
end end
def update def update
@@ -121,15 +64,5 @@ class IMICFPS
@velocity.y = 1.5 @velocity.y = 1.5
end end
end end
def toggle_first_person_view
@first_person_view = !@first_person_view
@visible = !@first_person_view
end
def turn_180
@orientation.y = @orientation.y + 180
@orientation.y %= 360
end
end end
end end

View File

@@ -2,7 +2,11 @@ class IMICFPS
class HUD class HUD
class RadarWidget < HUD::Widget class RadarWidget < HUD::Widget
def setup def setup
@size = 288 @min_size = 148
@max_size = 288
@target_screen_width = 1920
@size = @max_size
@border_color = Gosu::Color.new(0x88c64600) @border_color = Gosu::Color.new(0x88c64600)
@radar_color = Gosu::Color.new(0x88212121) @radar_color = Gosu::Color.new(0x88212121)
@@ -30,7 +34,10 @@ class IMICFPS
end end
def update def update
@text.text = "RADAR: X #{@player.position.x.round(1)} Y #{@player.position.y.round(1)} Z #{@player.position.z.round(1)}" @size = (window.width / @target_screen_width.to_f * @max_size).clamp(@min_size, @max_size)
@scale = (@size - Widget.padding * 2.0) / @image.width
@text.text = "X: #{@player.position.x.round(1)} Y: #{@player.position.y.round(1)} Z: #{@player.position.z.round(1)}"
@text.x = Widget.margin + @size / 2 - @text.width / 2 @text.x = Widget.margin + @size / 2 - @text.width / 2
@text.y = window.height - (Widget.margin + @size + @text.height) @text.y = window.height - (Widget.margin + @size + @text.height)
end end

View File

@@ -2,7 +2,11 @@ class IMICFPS
class HUD class HUD
class SquadWidget < HUD::Widget class SquadWidget < HUD::Widget
def setup def setup
@size = 288 # RADAR size @min_size = 148
@max_size = 288 # RADAR size
@target_screen_width = 1920
@size = @max_size
@color = Gosu::Color.new(0xff00aa00) @color = Gosu::Color.new(0xff00aa00)
@text = Text.new( @text = Text.new(
@@ -22,6 +26,8 @@ class IMICFPS
end end
def update def update
@size = (window.width / @target_screen_width.to_f * @max_size).clamp(@min_size, @max_size)
@text.x = Widget.margin + @size + Widget.padding @text.x = Widget.margin + @size + Widget.padding
@text.y = window.height - (Widget.margin + @text.height) @text.y = window.height - (Widget.margin + @text.height)
end end

View File

@@ -82,7 +82,7 @@ class IMICFPS
end end
end end
def self.action(key) def self.actions(key)
@@keymap.select do |action, value| @@keymap.select do |action, value|
if value.is_a?(Array) if value.is_a?(Array)
action if value.include?(key) action if value.include?(key)

View File

@@ -23,7 +23,7 @@ class IMICFPS
add_entity(Skydome.new(map_entity: @map_parser.skydome, manifest: Manifest.new(package: @map_parser.skydome.package, name: @map_parser.skydome.name), backface_culling: false)) add_entity(Skydome.new(map_entity: @map_parser.skydome, manifest: Manifest.new(package: @map_parser.skydome.package, name: @map_parser.skydome.name), backface_culling: false))
@map_parser.lights.each do |l| @map_parser.lights.each do |l|
add_light(Light.new(id: available_light, position: l.position, diffuse: l.diffuse, ambient: l.ambient, specular: l.specular, intensity: l.intensity)) add_light(Light.new(id: available_light, type: l.type, position: l.position, diffuse: l.diffuse, ambient: l.ambient, specular: l.specular, intensity: l.intensity))
end end
@map_parser.entities.each do |ent| @map_parser.entities.each do |ent|

View File

@@ -16,6 +16,17 @@ class IMICFPS
parse(map_file) parse(map_file)
end end
def light_type(type)
case type.downcase.strip
when "directional"
CyberarmEngine::Light::DIRECTIONAL
when "spot"
CyberarmEngine::Light::SPOT
else
CyberarmEngine::Light::POINT
end
end
def parse(file) def parse(file)
data = JSON.parse(File.read(file)) data = JSON.parse(File.read(file))
@@ -80,7 +91,7 @@ class IMICFPS
if section = data["lights"] if section = data["lights"]
section.each do |l| section.each do |l|
light = MapParser::Light.new light = MapParser::Light.new
light.type = IMICFPS::Light::POINT # TODO: fix me light.type = light_type(l["type"])
light.position = Vector.new( light.position = Vector.new(
l["position"]["x"], l["position"]["x"],
l["position"]["y"], l["position"]["y"],

View File

@@ -2,8 +2,14 @@ class IMICFPS
class TurnTableScene < Scene class TurnTableScene < Scene
def setup def setup
camera.field_of_view = 45 camera.field_of_view = 45
lights << (Light.new(id: OpenGL::GL_LIGHT1, position: Vector.new(30, 10.0, 30), diffuse: Color.new(0, 0, 0), specular: Color.new(0, 0, 0))) lights << Light.new(
lights << (Light.new(id: OpenGL::GL_LIGHT2, position: Vector.new(0, 10, 5), diffuse: Color.new(1.0, 1.0, 1.0), specular: Color.new(0, 0, 0))) id: OpenGL::GL_LIGHT1,
type: Light::DIRECTIONAL,
direction: Vector.down,
position: Vector.new(0, 10, 5),
diffuse: Color.new(1.0, 1.0, 1.0),
specular: Color.new(0, 0, 0)
)
options = { options = {
# entity: scale # entity: scale
@@ -14,7 +20,7 @@ class IMICFPS
"ttank": 0.13, "ttank": 0.13,
"alternate_tank": 0.065, "alternate_tank": 0.065,
"tree": 0.08, "tree": 0.08,
# "evergreen_tree": 0.08, "evergreen_tree": 0.08,
"power_plant": 0.025, "power_plant": 0.025,
"war_factory": 0.03, "war_factory": 0.03,
"randomish_terrain": 0.004, "randomish_terrain": 0.004,

View File

@@ -8,7 +8,7 @@ class IMICFPS
@player = @map.find_entity_by(name: "character") @player = @map.find_entity_by(name: "character")
@camera = PerspectiveCamera.new( position: @player.position.clone, aspect_ratio: window.aspect_ratio ) @camera = PerspectiveCamera.new( position: @player.position.clone, aspect_ratio: window.aspect_ratio )
@camera_controller = CameraController.new(mode: :first_person, camera: @camera, entity: @player) @camera_controller = CameraController.new(mode: :fpv, camera: @camera, entity: @player)
@director = Networking::Director.new @director = Networking::Director.new
@director.load_map(map_parser: @options[:map_parser]) @director.load_map(map_parser: @options[:map_parser])
@@ -58,7 +58,7 @@ eos
InputMapper.keys.each do |key, pressed| InputMapper.keys.each do |key, pressed|
next unless pressed next unless pressed
actions = InputMapper.action(key) actions = InputMapper.actions(key)
next unless actions next unless actions
actions.each do |action| actions.each do |action|

View File

@@ -38,7 +38,7 @@ class IMICFPS
InputMapper.keys.each do |key, pressed| InputMapper.keys.each do |key, pressed|
next unless pressed next unless pressed
actions = InputMapper.action(key) actions = InputMapper.actions(key)
next unless actions next unless actions
actions.each do |action| actions.each do |action|

View File

@@ -27,7 +27,7 @@ class IMICFPS
major, minor = gl_version.split(" ").first.split(".").map { |v| v.to_i } major, minor = gl_version.split(" ").first.split(".").map { |v| v.to_i }
unless (major == 3 && minor >= 3) || (major > 3) unless (major == 3 && minor >= 3) || (major > 3)
message = message =
"<b><c=f00>[Notice]</c></b> Your computer is reporting support for <b><c=f50>OpenGL #{major}.#{minor}</c></b>, "<b><c=a00>[Notice]</c></b> Your computer is reporting support for <b><c=f50>OpenGL #{major}.#{minor}</c></b>,
however <b><c=5f5>OpenGL 3.3 or higher is required.</c></b> however <b><c=5f5>OpenGL 3.3 or higher is required.</c></b>
Fallback <b>immediate mode renderer</b> will be used." Fallback <b>immediate mode renderer</b> will be used."
@@ -38,7 +38,7 @@ linux_mesa_message =
(Linux Only) For MESA based drivers append <b>--mesa-override</b> (Linux Only) For MESA based drivers append <b>--mesa-override</b>
as a commandline argument to override reported version." as a commandline argument to override reported version."
message += linux_mesa_message if RUBY_PLATFORM =~ /linux/ && gl_version.downcase.include?(" mesa ") message += linux_mesa_message if RUBY_PLATFORM =~ /linux/ && gl_version.downcase.include?(" mesa ")
@old_gl_warning = Gosu::Image.from_markup(message, 24, align: :center) @old_gl_warning = Gosu::Image.from_markup(message, 24, align: :center, font: "")
end end
end end

View File

@@ -46,7 +46,7 @@
} }
}, },
{ {
"type":"directional", "type":"point",
"intensity": 1, "intensity": 1,
"position": { "position": {
"x":0, "x":0,

View File

@@ -37,20 +37,22 @@ vec4 spotLight(Light light) {
vec4 calculateLighting(Light light) { vec4 calculateLighting(Light light) {
vec4 result; vec4 result;
switch(light.type) { // switch(light.type) {
case DIRECTIONAL: { // case DIRECTIONAL: {
result = directionalLight(light); // result = directionalLight(light);
} // }
case POINT: { // case SPOT: {
result = pointLight(light); // result = spotLight(light);
} // }
case SPOT: { // default: {
result = spotLight(light); // result = pointLight(light);
} // }
default: { // }
// result = vec4(1,1,1,1);
result = directionalLight(light); if (light.type == DIRECTIONAL) {
} result = directionalLight(light);
} else {
result = pointLight(light);
} }
return result; return result;

View File

@@ -1,5 +1,5 @@
struct Light { struct Light {
int type; int type;
vec3 direction; vec3 direction;
vec3 position; vec3 position;