1 Commits

Author SHA1 Message Date
c18309614f Stubbed out files for networking 2020-03-26 14:25:55 -05:00
48 changed files with 134 additions and 5930 deletions

View File

@@ -1,13 +1,9 @@
source "https://rubygems.org" source "https://rubygems.org"
gem "rake"
gem "opengl-bindings", require: "opengl" gem "opengl-bindings", require: "opengl"
gem "cyberarm_engine", git: "https://github.com/cyberarm/cyberarm_engine" gem "cyberarm_engine", git: "https://github.com/cyberarm/cyberarm_engine"
gem "nokogiri", ">= 1.11.0.rc1" gem "nokogiri", ">= 1.11.0.rc1"
gem "async-websocket" gem "async-websocket"
group(:packaging) do group(:packaging) do
gem "releasy", github: "gosu/releasy"
gem "ocra" gem "ocra"
gem "rubyzip"
gem "excon"
end end

View File

@@ -1,84 +1,32 @@
GIT GIT
remote: https://github.com/cyberarm/cyberarm_engine remote: https://github.com/cyberarm/cyberarm_engine
revision: 0850336e55891f1f10dcb10e3b4b42e5f7379b33 revision: d8551c7428da98bb7da76c138e5fbde50ef0137f
specs: specs:
cyberarm_engine (0.14.0) cyberarm_engine (0.13.1)
gosu (~> 0.15.0) gosu (~> 0.15.0)
gosu_more_drawables (~> 0.3)
GIT
remote: https://github.com/gosu/releasy.git
revision: e8a24c079c4930c6ddbab17fc444027ba41491ca
specs:
releasy (0.2.3)
bundler (>= 1.2.1)
cri (~> 2.1.0)
ocra (~> 1.3.0)
rake (>= 0.9.2.2)
GEM GEM
remote: https://rubygems.org/ remote: https://rubygems.org/
specs: specs:
async (1.26.0)
console (~> 1.0)
nio4r (~> 2.3)
timers (~> 4.1)
async-http (0.52.2)
async (~> 1.25)
async-io (~> 1.28)
async-pool (~> 0.2)
protocol-http (~> 0.19.0)
protocol-http1 (~> 0.13.0)
protocol-http2 (~> 0.14.0)
async-io (1.29.0)
async (~> 1.14)
async-pool (0.3.1)
async (~> 1.25)
async-websocket (0.14.0)
async-http (~> 0.51)
async-io (~> 1.23)
protocol-websocket (~> 0.7.0)
console (1.8.2)
cri (2.1.0)
excon (0.73.0)
gosu (0.15.1) gosu (0.15.1)
gosu (0.15.1-x64-mingw32) gosu (0.15.1-x64-mingw32)
gosu_more_drawables (0.3.0) mini_portile2 (2.4.0)
mini_portile2 (2.5.0) nokogiri (1.11.0.rc1)
nio4r (2.5.2) mini_portile2 (~> 2.4.0)
nokogiri (1.11.0.rc2) nokogiri (1.11.0.rc1-x64-mingw32)
mini_portile2 (~> 2.5.0) mini_portile2 (~> 2.4.0)
nokogiri (1.11.0.rc2-x64-mingw32)
ocra (1.3.11) ocra (1.3.11)
opengl-bindings (1.6.10) opengl-bindings (1.6.9)
protocol-hpack (1.4.2)
protocol-http (0.19.0)
protocol-http1 (0.13.0)
protocol-http (~> 0.19)
protocol-http2 (0.14.0)
protocol-hpack (~> 1.4)
protocol-http (~> 0.18)
protocol-websocket (0.7.4)
protocol-http (~> 0.2)
protocol-http1 (~> 0.2)
rake (13.0.1)
rubyzip (2.3.0)
timers (4.3.0)
PLATFORMS PLATFORMS
ruby ruby
x64-mingw32 x64-mingw32
DEPENDENCIES DEPENDENCIES
async-websocket
cyberarm_engine! cyberarm_engine!
excon
nokogiri (>= 1.11.0.rc1) nokogiri (>= 1.11.0.rc1)
ocra ocra
opengl-bindings opengl-bindings
rake
releasy!
rubyzip
BUNDLED WITH BUNDLED WITH
2.1.4 2.1.4

View File

@@ -1,7 +1,5 @@
# I-MIC FPS # I-MIC FPS
Creating a multiplayer first-person-shooter in pure Ruby; Using C extensions only for Rendering, Sound, and Input. ([Gosu](https://libgosu.org) and [opengl-bindings](https://github.com/vaiorabbit/ruby-opengl/)) An endeavor to create a multiplayer first-person-shooter in pure Ruby; Using C extensions only for Rendering, Sound, and Input. ([Gosu](https://libgosu.org) and [opengl-bindings](https://github.com/vaiorabbit/ruby-opengl/))
![](https://raw.githubusercontent.com/cyberarm/i-mic-fps/master/screenshots/screenshot-game.png)
## Using ## Using
Requires a Ruby runtime that supports the gosu and opengl-bindings C-extensions (truffleruby 1.0.0-rc12 did not work when tested. Rubinus was not tested.) Requires a Ruby runtime that supports the gosu and opengl-bindings C-extensions (truffleruby 1.0.0-rc12 did not work when tested. Rubinus was not tested.)

View File

@@ -1,16 +1,10 @@
require "json"
require "tmpdir"
require "fileutils"
require "zip"
require "excon"
require "releasy" require "releasy"
require 'bundler/setup' # Releasy requires that your application uses bundler. require 'bundler/setup' # Releasy requires that your application uses bundler.
require_relative "lib/version" require_relative "lib/version"
Releasy::Project.new do Releasy::Project.new do
name IMICFPS::NAME name "I-MIC FPS"
version IMICFPS::VERSION version "#{IMICFPS::VERSION}"
executable "i-mic-fps.rb" executable "i-mic-fps.rb"
files ["lib/**/*.*", "assets/**/*.*", "blends/**/*.*", "shaders/**/*.*", "static/**/*.*", "maps/**/*.*", "data/**/*.*"] files ["lib/**/*.*", "assets/**/*.*", "blends/**/*.*", "shaders/**/*.*", "static/**/*.*", "maps/**/*.*", "data/**/*.*"]
@@ -18,7 +12,7 @@ Releasy::Project.new do
verbose verbose
add_build :windows_folder do add_build :windows_folder do
icon "static/icon.ico" # icon "assets/icon.ico"
executable_type :console # Assuming you don't want it to run with a console window. executable_type :console # Assuming you don't want it to run with a console window.
add_package :exe # Windows self-extracting archive. add_package :exe # Windows self-extracting archive.
end end

View File

@@ -1,8 +1,5 @@
begin require "gosu"
require_relative "../cyberarm_engine/lib/cyberarm_engine" require_relative "lib/objects/text"
rescue LoadError
require "cyberarm_engine"
end
class Window < Gosu::Window class Window < Gosu::Window
def initialize def initialize
@@ -12,8 +9,8 @@ class Window < Gosu::Window
@slope = 250 @slope = 250
@color_step = 10 @color_step = 10
@base_color = Gosu::Color.rgb(255, 127, 0) @base_color = Gosu::Color.rgb(255, 127, 0)
@title = CyberarmEngine::Text.new("I-MIC FPS", color: Gosu::Color.rgb(255,127,0), size: 100, x: 0, y: 15, alignment: :center) @title = Text.new("I-MIC FPS", color: Gosu::Color.rgb(255,127,0), size: 100, x: 0, y: 15, alignment: :center)
@singleplayer = CyberarmEngine::Text.new("Singleplayer", color: Gosu::Color.rgb(0,127,127), size: 50, x: 0, y: 150, alignment: :center) @singleplayer = Text.new("Singleplayer", color: Gosu::Color.rgb(0,127,127), size: 50, x: 0, y: 150, alignment: :center)
end end
def draw def draw

View File

@@ -1,3 +0,0 @@
name: "editor"
model: "editor.obj"
collision: "mesh"

View File

@@ -1,32 +0,0 @@
# Blender MTL File: 'editor.blend'
# Material Count: 3
newmtl body
Ns 225.000000
Ka 1.000000 1.000000 1.000000
Kd 0.011935 0.113782 0.401969
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.450000
d 1.000000
illum 2
newmtl energy
Ns 225.000000
Ka 1.000000 1.000000 1.000000
Kd 0.000000 0.653036 0.800000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.450000
d 1.000000
illum 2
newmtl eye
Ns 225.000000
Ka 1.000000 1.000000 1.000000
Kd 0.710554 0.177754 0.000000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.450000
d 1.000000
illum 2

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

View File

@@ -1,5 +1,12 @@
IMICFPS_SERVER_MODE = true require "async/websocket"
require_relative "i-mic-fps"
require_relative "lib/networking/director"
require_relative "lib/networking/packet_handler"
require_relative "lib/networking/server"
require_relative "lib/networking/client"
require_relative "lib/networking/backends/memory_server"
require_relative "lib/networking/backends/memory_connection"
director = IMICFPS::Networking::Director.new(mode: :server, hostname: "0.0.0.0", port: 56789, interface: IMICFPS::Networking::MemoryServer) director = IMICFPS::Networking::Director.new(mode: :server, hostname: "0.0.0.0", port: 56789, interface: IMICFPS::Networking::MemoryServer)
director.define_singleton_method(:tick) do |dt| director.define_singleton_method(:tick) do |dt|

View File

@@ -3,13 +3,10 @@ require "yaml"
require "json" require "json"
require "abbrev" require "abbrev"
require "time" require "time"
require "socket"
require "tmpdir"
require "opengl" require "opengl"
require "glu" require "glu"
require "nokogiri" require "nokogiri"
require "async/websocket"
begin begin
require_relative "../cyberarm_engine/lib/cyberarm_engine" require_relative "../cyberarm_engine/lib/cyberarm_engine"
@@ -59,21 +56,12 @@ require_relative "lib/ui/console"
require_relative "lib/ui/menus/main_menu" require_relative "lib/ui/menus/main_menu"
require_relative "lib/ui/menus/settings_menu" require_relative "lib/ui/menus/settings_menu"
require_relative "lib/ui/menus/extras_menu" require_relative "lib/ui/menus/extras_menu"
require_relative "lib/ui/menus/multiplayer_menu"
require_relative "lib/ui/menus/level_select_menu" require_relative "lib/ui/menus/level_select_menu"
require_relative "lib/ui/menus/game_pause_menu" require_relative "lib/ui/menus/game_pause_menu"
require_relative "lib/states/game_states/boot"
require_relative "lib/states/game_states/close"
require_relative "lib/states/game_states/game" require_relative "lib/states/game_states/game"
require_relative "lib/states/game_states/loading_state" require_relative "lib/states/game_states/loading_state"
require_relative "lib/hud"
require_relative "lib/hud/widget"
require_relative "lib/hud/widgets/ammo"
require_relative "lib/hud/widgets/radar"
require_relative "lib/hud/widgets/health"
require_relative "lib/subscription" require_relative "lib/subscription"
require_relative "lib/publisher" require_relative "lib/publisher"
require_relative "lib/event" require_relative "lib/event"
@@ -127,31 +115,12 @@ require_relative "lib/networking/connection"
require_relative "lib/networking/backends/memory_server" require_relative "lib/networking/backends/memory_server"
require_relative "lib/networking/backends/memory_connection" require_relative "lib/networking/backends/memory_connection"
require_relative "lib/overlay"
require_relative "lib/window" require_relative "lib/window"
require_relative "lib/tools/asset_viewer" require_relative "lib/tools/asset_viewer"
require_relative "lib/tools/map_editor" require_relative "lib/tools/map_editor"
# Don't launch game if IMICFPS_SERVER_MODE is defined if ARGV.join.include?("--profile")
# or if game is being packaged
def prevent_launch?
packaging_lockfile = File.expand_path("i-mic-fps-packaging.lock", Dir.tmpdir)
m = "Game client not launched"
return [true, "#{m}: Server is running"] if defined?(IMICFPS_SERVER_MODE) && IMICFPS_SERVER_MODE
return [true, "#{m}: Packaging is running"] if defined?(Ocra)
if File.exist?(packaging_lockfile) && File.read(packaging_lockfile).strip == IMICFPS::VERSION
return [true, "#{m}: Packaging lockfile is present (#{packaging_lockfile})"]
end
return [false, ""]
end
unless prevent_launch?[0]
if ARGV.join.include?("--profile")
begin begin
require "ruby-prof" require "ruby-prof"
RubyProf.start RubyProf.start
@@ -162,9 +131,6 @@ unless prevent_launch?[0]
rescue LoadError rescue LoadError
puts "ruby-prof not installed!" puts "ruby-prof not installed!"
end end
else
IMICFPS::Window.new.show
end
else else
puts prevent_launch?[1] IMICFPS::Window.new.show
end end

View File

@@ -39,53 +39,8 @@ class IMICFPS
def draw_quad(*args) def draw_quad(*args)
window.draw_quad(*args) window.draw_quad(*args)
end end
def fill(color = Gosu::Color::WHITE, z = 0) def fill(color = Gosu::Color::WHITE)
draw_rect(0, 0, window.width, window.height, color, z) draw_rect(0, 0, window.width, window.height, color)
end
def fill_quad(x1, y1, x2, y2, x3, y3, x4, y4, color = Gosu::Color::WHITE, z = 0, mode = :default)
draw_quad(
x1,y1, color,
x2,y2, color,
x3,y3, color,
x4,y4, color,
z, mode
)
end
def menu_background(primary_color, accent_color, color_step, transparency, bar_size, slope)
((Gosu.screen_height + slope) / bar_size).times do |i|
color = Gosu::Color.rgba(
primary_color.red - i * color_step,
primary_color.green - i * color_step,
primary_color.blue - i * color_step,
transparency
)
fill_quad(
0, i * bar_size,
0, slope + (i * bar_size),
window.width / 2, (-slope) + (i * bar_size),
window.width / 2, i * bar_size,
color,
-2
)
fill_quad(
window.width, i * bar_size,
window.width, slope + (i * bar_size),
window.width / 2, (-slope) + (i * bar_size),
window.width / 2, i * bar_size,
color,
-2
)
end
Gosu.draw_quad(
0, 0, primary_color,
window.width, 0, primary_color,
window.width, window.height, accent_color,
0, window.height, accent_color,
-2
)
end end
def gl_error? def gl_error?

View File

@@ -1,23 +0,0 @@
class IMICFPS
class HUD
def initialize(player)
@ammo = AmmoWidget.new({ player: player })
@radar = RadarWidget.new({ player: player })
@health = HealthWidget.new({ player: player })
@hud_elements = [
@ammo,
@radar,
@health,
]
end
def draw
@hud_elements.each(&:draw)
end
def update
@hud_elements.each(&:update)
end
end
end

View File

@@ -1,25 +0,0 @@
class IMICFPS
class HUD
class Widget
include CommonMethods
attr_reader :options
def initialize(options = {})
@options = options
@player = options[:player]
@margin = 10
setup
end
def setup
end
def draw
end
def update
end
end
end
end

View File

@@ -1,29 +0,0 @@
class IMICFPS
class HUD
class AmmoWidget < HUD::Widget
def setup
@text = Text.new("")
@background = Gosu::Color.new(0x88222222)
end
def draw
Gosu.draw_rect(
@text.x - @margin, @text.y - @margin,
@text.width + @margin * 2, @text.height + @margin * 2,
@background
)
@text.draw
end
def update
if (Gosu.milliseconds / 1000.0) % 1.0 >= 0.9
random = "#{rand(0..999)}".rjust(3, "0")
@text.text = "Pistol\nAMMO: #{random}"
end
@text.x = window.width - (@margin * 2 + @text.width)
@text.y = window.height - (@margin * 2 + @text.height)
end
end
end
end

View File

@@ -1,48 +0,0 @@
class IMICFPS
class HUD
class HealthWidget < HUD::Widget
def setup
@spacer = 0
@text = Text.new("")
@width = 512
@height = 24
@slant = 32
@color = Gosu::Color.rgba(100, 100, 200, 128)
@shield = Gosu::Color.rgba(200, 100, 50, 200)
@health = 0.0
end
def draw
@text.draw
fill_quad(
window.width / 2 - @width / 2, @spacer, # TOP LEFT
window.width / 2 + @width / 2, @spacer, # TOP RIGHT
window.width / 2 + @width / 2 - @slant, @spacer + @height, # BOTTOM RIGHT
window.width / 2 - @width / 2 + @slant, @spacer + @height, # BOTTOM LEFT
@color
)
# Current Health
fill_quad(
window.width / 2 - @width / 2, @spacer, # TOP LEFT
(window.width / 2 - @width / 2) + @width * @health, @spacer, # TOP RIGHT
(window.width / 2 - @width / 2) + @width * @health - @slant, @spacer + @height, # BOTTOM RIGHT
window.width / 2 - @width / 2 + @slant, @spacer + @height, # BOTTOM LEFT
@shield
)
end
def update
percentage = "#{(@health * 100).round}".rjust(3, "0")
@text.text = "[Health #{percentage}%]"
@text.x = window.width / 2 - @text.width / 2
@text.y = @spacer + @height / 2 - @text.height / 2
@health += 0.1 * window.dt
@health = 0 if @health > 1.0
end
end
end
end

View File

@@ -1,28 +0,0 @@
class IMICFPS
class HUD
class RadarWidget < HUD::Widget
def setup
@size = 256
@color = Gosu::Color.new(0x88222222)
@text = Text.new("RADAR")
end
def draw
Gosu.draw_rect(
@margin, window.height - (@size + @margin),
@size, @size,
@color
)
@text.draw
end
def update
@text.text = "RADAR: X #{@player.position.x.round(1)} Y #{@player.position.z.round(1)}"
@text.x = @margin + @size / 2 - @text.width / 2
@text.y = window.height - (@margin + @size)
end
end
end
end

View File

@@ -1,26 +0,0 @@
class IMICFPS
class NetworkManager
MULTICAST_ADDRESS = "224.0.0.1"
MULTICAST_PORT = 30_000
REMOTE_GAMEHUB = "i-mic.rubyclan.org"
REMOTE_GAMEHUB_PORT = 98765
DEFAULT_SERVER_HOST = "0.0.0.0"
DEFAULT_SERVER_PORT = 56789
DEFAULT_SERVER_QUERY_PORT = 28900
def initialize
end
# https://github.com/jpignata/blog/blob/master/articles/multicast-in-ruby.md
def broadcast_lan_lobby
socket = UDPSocket.open
socket.setsockopt(:IPPROTO_IP, :IP_MULTICAST_TTL, 1)
socket.send("IMICFPS_LAN_LOBBY", 0, MULTICAST_ADDRESS, MULTICAST_PORT)
socket.close
end
def handle_lan_multicast
end
end
end

View File

@@ -14,6 +14,7 @@ class IMICFPS
@lights = [] @lights = []
@collision_manager = CollisionManager.new(map: self) @collision_manager = CollisionManager.new(map: self)
@renderer = window.renderer
Publisher.new Publisher.new
end end
@@ -31,12 +32,6 @@ class IMICFPS
end end
add_entity(Player.new(spawnpoint: @map_parser.spawnpoints.sample, manifest: Manifest.new(package: "base", name: "character"))) add_entity(Player.new(spawnpoint: @map_parser.spawnpoints.sample, manifest: Manifest.new(package: "base", name: "character")))
# Default lights if non are defined
if @map_parser.lights.size == 0
add_light(Light.new(id: available_light, position: Vector.new(30, 10.0, 30)))
add_light(Light.new(id: available_light, position: Vector.new(0, 100, 0), diffuse: Color.new(1.0, 0.5, 0.1)))
end
end end
def data def data
@@ -53,7 +48,7 @@ class IMICFPS
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) # clear the screen and the depth buffer glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) # clear the screen and the depth buffer
gl_error? gl_error?
window.renderer.draw(camera, @lights, @entities) @renderer.draw(camera, @lights, @entities)
end end
end end

View File

@@ -7,9 +7,6 @@ class IMICFPS
def connect def connect
end end
def update
end
def close def close
end end
end end

View File

@@ -19,9 +19,6 @@ class IMICFPS
def broadcast(packet) def broadcast(packet)
end end
def update
end
def close def close
end end
end end

View File

@@ -1,59 +0,0 @@
class IMICFPS
class Overlay
include CommonMethods
Slot = Struct.new(:value, :width)
def initialize
@text = CyberarmEngine::Text.new("", x: 3, y: 3, shadow_color: Gosu::Color::BLACK)
@slots = []
@space_width = @text.textobject.text_width(" ")
end
def draw
return if @text.text.empty?
width = @text.width + 8
Gosu.draw_rect(0, 0, width, (@text.height + 4), Gosu::Color.rgba(0, 0, 0, 100))
Gosu.draw_rect(2, 2, width - 4, (@text.height + 4) - 4, Gosu::Color.rgba(100, 100, 100, 100))
@text.draw
end
def update
rebuild_slots
end
def rebuild_slots
@slots.clear
if window.config.get(:options, :fps)
create_slot "FPS: #{Gosu.fps}"
create_slot "Frame time: #{Gosu.milliseconds - window.delta_time}ms" if window.config.get(:debug_options, :stats)
end
if window.config.get(:debug_options, :stats)
create_slot "Vertices: #{formatted_number(window.number_of_vertices)}"
create_slot "Faces: #{formatted_number(window.number_of_vertices / 3)}"
end
if window.config.get(:debug_options, :boundingboxes)
create_slot "Boundingboxes: #{window.config.get(:debug_options, :boundingboxes) ? 'On' : 'Off'}"
end
if window.config.get(:debug_options, :wireframe)
create_slot "Wireframes: #{window.config.get(:debug_options, :wireframe) ? 'On' : 'Off'}"
end
@text.text = ""
@slots.each_with_index do |slot, i|
@text.text += "#{slot.value} <c=ff000000>•</c> " unless i == @slots.size - 1
@text.text += "#{slot.value}" if i == @slots.size - 1
end
end
def create_slot(string)
@slots << Slot.new(string, @text.textobject.text_width(string))
end
end
end

View File

@@ -16,7 +16,7 @@ class IMICFPS
end end
def render(camera, lights, entities) def render(camera, lights, entities)
if window.config.get(:debug_options, :use_shaders) && Shader.available?("default") && Shader.available?("render_screen") if Shader.available?("default") && Shader.available?("render_screen")
@g_buffer.bind_for_writing @g_buffer.bind_for_writing
gl_error? gl_error?
@@ -155,7 +155,6 @@ class IMICFPS
end end
if window.config.get(:debug_options, :wireframe) if window.config.get(:debug_options, :wireframe)
glLineWidth(2)
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE) glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)
Shader.active_shader.uniform_boolean("disableLighting", true) Shader.active_shader.uniform_boolean("disableLighting", true)
@@ -164,7 +163,6 @@ class IMICFPS
Shader.active_shader.uniform_boolean("disableLighting", false) Shader.active_shader.uniform_boolean("disableLighting", false)
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL) glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)
glLineWidth(1)
end end
glDrawArrays(GL_TRIANGLES, 0, model.faces.count * 3) glDrawArrays(GL_TRIANGLES, 0, model.faces.count * 3)

View File

@@ -1,53 +0,0 @@
class IMICFPS
class Boot < GameState
def setup
@title = Text.new(IMICFPS::NAME, size: 100, z: 0, color: Gosu::Color.new(0xff000000), shadow: false, font: "Droid Serif")
@logo = get_image(IMICFPS::GAME_ROOT_PATH + "/static/logo.png")
@start_time = Gosu.milliseconds
@time_to_live = 3_000
window.needs_cursor = false
end
def draw
fraction_left = ((Gosu.milliseconds - @start_time) / (@time_to_live - 200).to_f)
menu_background(Menu::PRIMARY_COLOR, Menu::ACCENT_COLOR, Menu::BAR_COLOR_STEP, Menu::BAR_ALPHA, Menu::BAR_SIZE, Menu::BAR_SLOPE)
if fraction_left <= 1.0
Gosu.draw_circle(
window.width / 2,
window.height / 2,
@logo.width / 2, 128, Gosu::Color.new(0x11ffffff)
)
Gosu.draw_arc(
window.width / 2,
window.height / 2,
@logo.width / 2, fraction_left.clamp(0.0, 1.0), 128, 8, Gosu::Color.new(0x33ff8800)
)
@logo.draw(window.width / 2 - @logo.width / 2, window.height / 2 - @logo.height / 2, 0)
@title.draw
end
end
def update
@title.x = window.width / 2 - @title.width / 2
@title.y = 0
push_state(MainMenu) if Gosu.milliseconds - @start_time >= @time_to_live
end
def button_up(id)
if id == Gosu::KbEscape or
(id >= Gosu::GP_LEFT and id >= Gosu::GP_BUTTON_15) or
id == Gosu::MsLeft
push_state(MainMenu)
end
end
end
end

View File

@@ -1,49 +0,0 @@
class IMICFPS
class Close < GameState
def setup
@slope = Menu::BAR_SLOPE
@logo = get_image(IMICFPS::GAME_ROOT_PATH + "/static/logo.png")
@start_time = Gosu.milliseconds
@time_to_live = 3_000
window.needs_cursor = false
end
def draw
fraction_left = 1 - ((Gosu.milliseconds - @start_time) / (@time_to_live - 200).to_f)
menu_background(Menu::PRIMARY_COLOR, Menu::ACCENT_COLOR, Menu::BAR_COLOR_STEP, Menu::BAR_ALPHA, Menu::BAR_SIZE, @slope.round)
Gosu.draw_circle(
window.width / 2,
window.height / 2,
@logo.width / 2, 128, Gosu::Color.new(0x11ffffff)
)
Gosu.draw_arc(
window.width / 2,
window.height / 2,
@logo.width / 2, fraction_left.clamp(0.0, 1.0), 128, 8, Gosu::Color.new(0x33ff8800)
)
@logo.draw(window.width / 2 - @logo.width / 2, window.height / 2 - @logo.height / 2, 0)
fill(Gosu::Color.rgba(0,0,0, 255 * (1.1 - fraction_left)))
end
def update
window.close! if Gosu.milliseconds - @start_time >= @time_to_live
@slope -= 25 * window.dt
end
def button_up(id)
if id == Gosu::KbEscape or
(id >= Gosu::GP_LEFT and id >= Gosu::GP_BUTTON_15) or
id == Gosu::MsLeft
window.close!
end
end
end
end

View File

@@ -12,9 +12,8 @@ class IMICFPS
@director = Networking::Director.new(mode: :memory, hostname: "i-mic.rubyclan.org", port: 56789, interface: { server: Networking::MemoryServer, connection: Networking::MemoryConnection }, state: self) @director = Networking::Director.new(mode: :memory, hostname: "i-mic.rubyclan.org", port: 56789, interface: { server: Networking::MemoryServer, connection: Networking::MemoryConnection }, state: self)
@crosshair = Crosshair.new @crosshair = Crosshair.new
@hud = HUD.new(@player)
@text = Text.new("Pending...", x: 10, y: 22, z: 1, size: 18, font: "DejaVu Sans", shadow_color: Gosu::Color::BLACK) @text = Text.new("Pending...", x: 10, y: 10, z: 1, size: 18, font: "DejaVu Sans", shadow_color: Gosu::Color::BLACK)
if ARGV.join.include?("--playdemo") if ARGV.join.include?("--playdemo")
@demo = Demo.new(camera: @camera, player: @player, demo: "./demo.dat", mode: :play) if File.exist?("./demo.dat") @demo = Demo.new(camera: @camera, player: @player, demo: "./demo.dat", mode: :play) if File.exist?("./demo.dat")
@@ -28,7 +27,6 @@ class IMICFPS
@map.render(@camera) @map.render(@camera)
@crosshair.draw @crosshair.draw
@hud.draw
@text.draw @text.draw
end end
@@ -40,18 +38,21 @@ class IMICFPS
@map.update @map.update
control_player control_player
@hud.update
@camera.update @camera.update
@director.tick(window.dt) @director.tick(window.dt)
if window.config.get(:debug_options, :stats) if window.config.get(:debug_options, :stats)
@text.text = update_text @text.text = update_text
elsif window.config.get(:options, :fps)
@text.text = "FPS: #{Gosu.fps}"
else else
@text.text = "" @text.text = ""
end end
@demo.update if @demo @demo.update if @demo
window.number_of_vertices = 0
end end
def update_text def update_text
@@ -67,6 +68,10 @@ Camera Field Of View: #{@camera.field_of_view}
Camera Mouse Sesitivity: #{@camera.mouse_sensitivity} Camera Mouse Sesitivity: #{@camera.mouse_sensitivity}
#{if @camera.entity then "Actor X: #{@camera.entity.position.x.round(2)} Y: #{@camera.entity.position.y.round(2)} Z: #{@camera.entity.position.z.round(2)}";end} #{if @camera.entity then "Actor X: #{@camera.entity.position.x.round(2)} Y: #{@camera.entity.position.y.round(2)} Z: #{@camera.entity.position.z.round(2)}";end}
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)}
eos eos
end end

View File

@@ -2,15 +2,9 @@ class IMICFPS
class LoadingState < Menu class LoadingState < Menu
def setup def setup
window.needs_cursor = false window.needs_cursor = false
if @options[:map_file]
@map_parser = MapParser.new(map_file: @options[:map_file]) @map_parser = MapParser.new(map_file: @options[:map_file])
elsif @options[:map_parser]
@map_parser = @options[:map_parser]
else
raise "Unable to load map, missing :map_file or :map_parser"
end
title IMICFPS::NAME title "I-MIC FPS"
@subheading = Text.new("Loading Map: #{@map_parser.metadata.name}", y: 100, size: 50, alignment: :center) @subheading = Text.new("Loading Map: #{@map_parser.metadata.name}", y: 100, size: 50, alignment: :center)
@description = Text.new("Map created by: #{@map_parser.metadata.authors.join(", ")}\n#{@map_parser.metadata.description}", y: 180, size: 24, alignment: :center) @description = Text.new("Map created by: #{@map_parser.metadata.authors.join(", ")}\n#{@map_parser.metadata.description}", y: 180, size: 24, alignment: :center)
@state = Text.new("Preparing...", y: window.height/2-40, size: 40, alignment: :center) @state = Text.new("Preparing...", y: window.height/2-40, size: 40, alignment: :center)
@@ -34,8 +28,7 @@ class IMICFPS
@completed_for_ms = 0 @completed_for_ms = 0
@lock = false @lock = false
@primary_color = Gosu::Color.rgba(0, 180, 180, 200) @base_color = Gosu::Color.rgb(0, 180, 180)
@accent_color = Gosu::Color.rgba(0, 90, 90, 200)
end end
def draw def draw
@@ -116,9 +109,9 @@ class IMICFPS
progress = (@asset_index.to_f/@assets.count)*window.width/2 progress = (@asset_index.to_f/@assets.count)*window.width/2
height = 100 height = 100
dark_color= Gosu::Color.rgb(@primary_color.red - 100, @primary_color.green - 100, @primary_color.blue - 100)#Gosu::Color.rgb(64, 127, 255) dark_color= Gosu::Color.rgb(@base_color.red - 100, @base_color.green - 100, @base_color.blue - 100)#Gosu::Color.rgb(64, 127, 255)
color = Gosu::Color.rgb(@primary_color.red - 50, @primary_color.green - 50, @primary_color.blue - 50)#Gosu::Color.rgb(0,127,127) color = Gosu::Color.rgb(@base_color.red - 50, @base_color.green - 50, @base_color.blue - 50)#Gosu::Color.rgb(0,127,127)
color_two = Gosu::Color.rgb(@primary_color.red + 50, @primary_color.green + 50, @primary_color.blue + 50)#Gosu::Color.rgb(64, 127, 255) color_two = Gosu::Color.rgb(@base_color.red + 50, @base_color.green + 50, @base_color.blue + 50)#Gosu::Color.rgb(64, 127, 255)
draw_rect(x, y-2, x + window.width/4, height+4, dark_color) draw_rect(x, y-2, x + window.width/4, height+4, dark_color)

View File

@@ -1,9 +1,12 @@
class IMICFPS class IMICFPS
class AssetViewerTool class AssetViewerTool
class MainMenu < Menu class MainMenu < CyberarmEngine::GuiState
def setup def setup
window.needs_cursor = true window.needs_cursor = true
label "#{IMICFPS::NAME}", text_size: 50
label "Asset Viewer", text_size: 28
@manifests = [] @manifests = []
Dir.glob(GAME_ROOT_PATH + "/assets/**/manifest.yaml").each do |manifest| Dir.glob(GAME_ROOT_PATH + "/assets/**/manifest.yaml").each do |manifest|
begin begin
@@ -15,18 +18,11 @@ class IMICFPS
@manifests.sort_by! { |m| m.name.downcase } @manifests.sort_by! { |m| m.name.downcase }
label "#{IMICFPS::NAME}", text_size: 100, color: Gosu::Color::BLACK
label "Asset Viewer", text_size: 50
flow(width: 1.0, height: 1.0) do
stack(width: 0.25, height: 1.0) do
button "Back", margin_bottom: 25 do button "Back", margin_bottom: 25 do
pop_state pop_state
end end
end
stack(width: 0.5, height: 1.0) do flow(margin: 10) do
flow(width: 1.0, height: 1.0) do
@manifests.each do |manifest| @manifests.each do |manifest|
button manifest.name do button manifest.name do
push_state(TurnTable, manifest: manifest) push_state(TurnTable, manifest: manifest)
@@ -34,8 +30,6 @@ class IMICFPS
end end
end end
end end
end
end
def update def update
super super

View File

@@ -31,6 +31,7 @@ class IMICFPS
@lights << @light @lights << @light
@camera = Camera.new(position: Vector.new(0, 1.5, 5), orientation: Vector.forward) @camera = Camera.new(position: Vector.new(0, 1.5, 5), orientation: Vector.forward)
@renderer = Renderer.new
label @manifest.name, text_size: 50 label @manifest.name, text_size: 50
label @manifest.model label @manifest.model
@@ -54,7 +55,7 @@ class IMICFPS
) )
Gosu.gl do Gosu.gl do
window.renderer.draw(@camera, [@light], @map.entities) @renderer.draw(@camera, [@light], @map.entities)
end end
@crosshair.draw @crosshair.draw

View File

@@ -1,2 +1 @@
require_relative "map_editor/lib/main_menu" require_relative "map_editor/lib/main_menu"
require_relative "map_editor/lib/editor"

View File

@@ -1,59 +0,0 @@
class IMICFPS
class MapEditorTool
class Editor < CyberarmEngine::GuiState
attr_reader :map
def setup
# TODO: Move everything required for a playable game map
# in to a Scene or Scene3D container object
# and refactor Game to use it.
Publisher.new
@map = Map.new( map_parser: @options[:map_parser] )
@camera = Camera.new( position: Vector.new )
@crosshair = Crosshair.new
@map.setup
end
def draw
super
@map.render(@camera)
@crosshair.draw
end
def update
super
Publisher.instance.publish(:tick, Gosu.milliseconds - window.delta_time)
@map.update
@camera.update
end
def button_down(id)
if id == Gosu::KB_ESCAPE
# TODO: Use Editor specific menu
push_state(GamePauseMenu)
return
end
InputMapper.keydown(id)
Publisher.instance.publish(:button_down, nil, id)
@map.entities.each do |entity|
entity.button_down(id) if defined?(entity.button_down)
end
end
def button_up(id)
InputMapper.keyup(id)
Publisher.instance.publish(:button_up, nil, id)
@map.entities.each do |entity|
entity.button_up(id) if defined?(entity.button_up)
end
@camera.button_up(id)
end
end
end
end

View File

@@ -1,6 +1,6 @@
class IMICFPS class IMICFPS
class MapEditorTool class MapEditorTool
class MainMenu < Menu class MainMenu < CyberarmEngine::GuiState
def setup def setup
window.needs_cursor = true window.needs_cursor = true
@@ -29,7 +29,7 @@ class IMICFPS
flow(margin: 10) do flow(margin: 10) do
@maps.each do |map| @maps.each do |map|
button map.metadata.name do button map.metadata.name do
push_state(LoadingState, map_parser: map, forward: Editor) # push_state(TurnTable, manifest: manifest)
end end
end end
end end

View File

@@ -1,23 +1,12 @@
class IMICFPS class IMICFPS
class Menu < IMICFPS::GuiState class Menu < IMICFPS::GameState
include CommonMethods
PRIMARY_COLOR = Gosu::Color.rgba(255, 127, 0, 200)
ACCENT_COLOR = Gosu::Color.rgba(155, 27, 0, 200)
BAR_SIZE = 50
BAR_SLOPE = 250
BAR_COLOR_STEP = 10
BAR_ALPHA = 200
def initialize(*args) def initialize(*args)
@elements = [] @elements = []
@bar_size = BAR_SIZE @size = 50
@bar_slope = BAR_SLOPE @slope = 250
@bar_color_step = BAR_COLOR_STEP @color_step = 10
@bar_alpha = BAR_ALPHA @base_color = Gosu::Color.rgb(255, 127, 0)
@primary_color = PRIMARY_COLOR @background_alpha = 200
@accent_color = ACCENT_COLOR
window.needs_cursor = true window.needs_cursor = true
@__version_text = CyberarmEngine::Text.new("<b>#{IMICFPS::NAME}</b> v#{IMICFPS::VERSION} (#{IMICFPS::RELEASE_NAME})") @__version_text = CyberarmEngine::Text.new("<b>#{IMICFPS::NAME}</b> v#{IMICFPS::VERSION} (#{IMICFPS::RELEASE_NAME})")
@@ -26,7 +15,7 @@ class IMICFPS
super(*args) super(*args)
end end
def title(text, color = Gosu::Color::BLACK) def title(text, color = @base_color)
@elements << Text.new(text, color: color, size: 100, x: 0, y: 15) @elements << Text.new(text, color: color, size: 100, x: 0, y: 15)
@_title = @elements.last @_title = @elements.last
end end
@@ -42,7 +31,7 @@ class IMICFPS
end end
def draw def draw
menu_background(@primary_color, @accent_color, @bar_color_step, @bar_alpha, @bar_size, @bar_slope) draw_background
draw_menu_box draw_menu_box
draw_menu draw_menu
@@ -55,15 +44,34 @@ class IMICFPS
window.scene.draw window.scene.draw
end end
end
super def draw_background
((Gosu.screen_height+@slope)/@size).times do |i|
fill_quad(
0, i*@size,
0, @slope+(i*@size),
window.width/2, (-@slope)+(i*@size),
window.width/2, i*@size,
Gosu::Color.rgba(@base_color.red-i*@color_step, @base_color.green-i*@color_step, @base_color.blue-i*@color_step, @background_alpha),
-2
)
fill_quad(
window.width, i*@size,
window.width, @slope+(i*@size),
window.width/2, (-@slope)+(i*@size),
window.width/2, i*@size,
Gosu::Color.rgba(@base_color.red-i*@color_step, @base_color.green-i*@color_step, @base_color.blue-i*@color_step, @background_alpha),
-2
)
end
end end
def draw_menu_box def draw_menu_box
draw_rect( draw_rect(
window.width / 4, 0, window.width/4, 0,
window.width / 2, window.height, window.width/2, window.height,
Gosu::Color.new(0x11ffffff), Gosu::Color.rgba(0, 0, 0, 150),
) )
end end
@@ -75,7 +83,7 @@ class IMICFPS
def update def update
@elements.each do |e| @elements.each do |e|
e.x = (window.width / 2 - e.width / 2).round e.x = window.width / 2 - e.width / 2
e.update e.update
end end
@@ -83,12 +91,20 @@ class IMICFPS
window.scene.update(window.dt) window.scene.update(window.dt)
end end
super
@__version_text.x = window.width - (@__version_text.width + 10) @__version_text.x = window.width - (@__version_text.width + 10)
@__version_text.y = window.height - (@__version_text.height + 10) @__version_text.y = window.height - (@__version_text.height + 10)
end end
def fill_quad(x1, y1, x2, y2, x3, y3, x4, y4, color = Gosu::Color::WHITE, z = 0, mode = :default)
draw_quad(
x1,y1, color,
x2,y2, color,
x3,y3, color,
x4,y4, color,
z, mode
)
end
def button_up(id) def button_up(id)
if id == Gosu::MsLeft if id == Gosu::MsLeft
@elements.each do |e| @elements.each do |e|
@@ -98,8 +114,6 @@ class IMICFPS
end end
end end
end end
super
end end
def mouse_over?(object) def mouse_over?(object)
@@ -112,17 +126,19 @@ class IMICFPS
def initialize(text, host, block) def initialize(text, host, block)
@text, @host, @block = text, host, block @text, @host, @block = text, host, block
@color = @text.color @color = @text.color
@hover_color = Gosu::Color.rgb(64, 128, 255) @hover_color = Gosu::Color.rgb(64, 127, 255)
@text.shadow_color= Gosu::Color::BLACK
@text.shadow_size = 2
@text.shadow_alpha = 100 @text.shadow_alpha = 100
end end
def update def update
if @host.mouse_over?(self) if @host.mouse_over?(self)
@text.color = @hover_color @text.color = @hover_color
@text.shadow_color= Gosu::Color::BLACK
@text.shadow_size = 3
else else
@text.color = @color @text.color = @color
@text.shadow_color = nil
@text.shadow_size = 1
end end
end end

View File

@@ -1,7 +1,7 @@
class IMICFPS class IMICFPS
class ExtrasMenu < Menu class ExtrasMenu < Menu
def setup def setup
title IMICFPS::NAME title "I-MIC FPS"
subtitle "Extras" subtitle "Extras"
link "Asset Viewer" do link "Asset Viewer" do

View File

@@ -1,8 +1,8 @@
class IMICFPS class IMICFPS
class GamePauseMenu < Menu class GamePauseMenu < Menu
def setup def setup
@bar_alpha = 50 @background_alpha = 50
title IMICFPS::NAME title "I-MIC FPS"
subtitle "Paused" subtitle "Paused"
link "Resume" do link "Resume" do
@@ -13,7 +13,7 @@ class IMICFPS
push_state(SettingsMenu) push_state(SettingsMenu)
end end
link "Leave" do link "Quit" do
push_state(MainMenu) push_state(MainMenu)
end end
end end

View File

@@ -1,7 +1,7 @@
class IMICFPS class IMICFPS
class LevelSelectMenu < Menu class LevelSelectMenu < Menu
def setup def setup
title IMICFPS::NAME title "I-MIC FPS"
subtitle "Choose a Map" subtitle "Choose a Map"
Dir.glob(GAME_ROOT_PATH + "/maps/*.json").map { |file| [file, MapParser.new(map_file: file)]}.each do |file, map| Dir.glob(GAME_ROOT_PATH + "/maps/*.json").map { |file| [file, MapParser.new(map_file: file)]}.each do |file, map|

View File

@@ -1,17 +1,13 @@
class IMICFPS class IMICFPS
class MainMenu < Menu class MainMenu < Menu
def setup def setup
title IMICFPS::NAME title "I-MIC FPS"
link "Single Player" do link "Single Player" do
push_state(LevelSelectMenu) push_state(LevelSelectMenu)
# push_state(LoadingState.new(forward: Game, map_file: GAME_ROOT_PATH + "/maps/test_map.json")) # push_state(LoadingState.new(forward: Game, map_file: GAME_ROOT_PATH + "/maps/test_map.json"))
end end
link "Multiplayer" do
push_state(MultiplayerMenu)
end
link "Settings" do link "Settings" do
push_state(SettingsMenu) push_state(SettingsMenu)
end end
@@ -20,7 +16,7 @@ class IMICFPS
push_state(ExtrasMenu) push_state(ExtrasMenu)
end end
link "Exit Game" do link "Exit" do
window.close window.close
end end

View File

@@ -1,14 +0,0 @@
class IMICFPS
class MultiplayerMenu < Menu
def setup
title IMICFPS::NAME
subtitle "Multiplayer"
link "Online"
link "LAN"
link "Back" do
pop_state
end
end
end
end

View File

@@ -1,208 +1,14 @@
class IMICFPS class IMICFPS
class SettingsMenu < Menu class SettingsMenu < Menu
include CommonMethods
def setup def setup
@categories = [ title "I-MIC FPS"
"Display", subtitle "Settings"
"Graphics",
"Audio",
"Controls",
"Multiplayer"
]
@pages = {}
@current_page = nil
label "Settings", text_size: 100, color: Gosu::Color::BLACK link "\"There is no spoon.\""
flow(width: 1.0, height: 1.0) do link "Back" do
stack(width: 0.25, height: 1.0) do
@categories.each do |category|
button category, width: 1.0 do
show_page(:"#{category}".downcase)
end
end
button "Back", width: 1.0, margin_top: 64 do
pop_state pop_state
end end
end end
@categories.each do |category|
stack(width: 0.5, height: 1.0) do |element|
@pages[:"#{category}".downcase] = element
element.hide
if respond_to?(:"create_page_#{category}".downcase)
self.send(:"create_page_#{category}".downcase)
end
end
end
end
show_page(:display)
end
def show_page(page)
if element = @pages.dig(page)
@current_page.hide if @current_page
@current_page = element
element.show
end
end
def create_page_display
label "Display", text_size: 50
label "Resolution"
flow do
stack do
label "Width"
label "Height"
end
stack do
edit_line "#{window.width}"
edit_line "#{window.height}"
end
end
check_box "Fullscreen", padding_top: 25, padding_bottom: 25
flow do
stack do
label "Gamma Correction"
label "Brightness"
label "Contrast"
end
stack do
slider
slider
slider
end
stack do
label "0.0"
label "0.0"
label "0.0"
end
end
end
def create_page_audio
label "Audio", text_size: 50
flow do
stack do
label "Master Volume"
label "Sound Effects"
label "Dialog"
label "Cinematic"
end
stack do
slider range: 0.0..1.0, value: 1.0
slider range: 0.0..1.0, value: 1.0
slider range: 0.0..1.0, value: 1.0
slider range: 0.0..1.0, value: 1.0
end
stack do
label "0.0"
label "0.0"
label "0.0"
label "0.0"
end
end
end
def create_page_controls
label "Controls", text_size: 50
InputMapper.keymap.each do |key, values|
flow do
label "#{key}"
[values].flatten.each do |value|
button Gosu.button_id_to_char(value)
end
end
end
end
def create_page_graphics
label "Graphics", text_size: 50
flow do
check_box "V-Sync"
label "(No Supported)"
end
flow do
label "Field of View"
slider range: 70.0..110.0
label "90.0"
end
flow do
stack do
label "Detail"
end
stack do
slider range: 1..3
end
stack do
label "High"
end
end
advanced_mode = check_box "Advanced Mode"
advanced_settings = stack do |element|
element.hide
flow do
stack do
label "Geometry Detail"
label "Shadow Detail"
label "Texture Detail"
label "Particle Detail"
label "Surface Effect Detail"
end
stack do
slider
slider
slider
slider
slider
end
stack do
label "High"
label "High"
label "High"
label "High"
label "High"
end
end
flow do
stack do
label "Lighting Mode"
edit_line ""
end
stack do
label "Texture Filtering"
edit_line ""
end
end
end
advanced_mode.subscribe(:changed) do |element, value|
advanced_settings.show if value
advanced_settings.hide unless value
end
end
def create_page_multiplayer
label "Multiplayer", text_size: 50
check_box "Show player names"
end
end end
end end

View File

@@ -1,5 +1,5 @@
class IMICFPS class IMICFPS
class Window < CyberarmEngine::Window class Window < CyberarmEngine::Engine
attr_accessor :number_of_vertices, :needs_cursor attr_accessor :number_of_vertices, :needs_cursor
attr_reader :renderer, :scene, :config attr_reader :renderer, :scene, :config
@@ -26,7 +26,6 @@ class IMICFPS
@renderer = Renderer.new @renderer = Renderer.new
@renderer.preload_default_shaders @renderer.preload_default_shaders
@scene = TurnTableScene.new @scene = TurnTableScene.new
@overlay = Overlay.new
@canvas_size = Vector.new(self.width, self.height) @canvas_size = Vector.new(self.width, self.height)
@@ -34,7 +33,7 @@ class IMICFPS
@config.save! @config.save!
end end
push_state(Boot) push_state(MainMenu)
@delta_time = Gosu.milliseconds @delta_time = Gosu.milliseconds
end end
@@ -47,7 +46,6 @@ class IMICFPS
super super
@console.draw if @show_console @console.draw if @show_console
@overlay.draw
draw_cursor if needs_cursor draw_cursor if needs_cursor
_canvas_size = Vector.new(self.width, self.height) _canvas_size = Vector.new(self.width, self.height)
@@ -67,16 +65,9 @@ class IMICFPS
super super
@console.update if @show_console @console.update if @show_console
@overlay.update
@number_of_vertices = 0
@delta_time = Gosu.milliseconds @delta_time = Gosu.milliseconds
end end
def close
push_state(Close)
end
def button_down(id) def button_down(id)
if @show_console if @show_console
@console.button_down(id) @console.button_down(id)

BIN
pixel_test.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 162 B

View File

@@ -1,166 +0,0 @@
PACKAGING_LOCKFILE = File.expand_path("i-mic-fps-packaging.lock", Dir.tmpdir)
GITHUB_API_URL = "https://api.github.com/repos/cyberarm/i-mic-fps"
USERAGENT = "cyberarm +i-mic-fps"
DEFAULT_HEADERS = {"Authorization": "token #{ENV["GITHUB_TOKEN"]}", "User-Agent": USERAGENT}
def sh_with_status(command)
outbuf = IO.popen(command, :err => [:child, :out], &:read)
status = $?
return [outbuf, status]
end
def version
IMICFPS::VERSION
end
def version_tag
"v#{version}"
end
def release_name
"#{IMICFPS::NAME.gsub(" ", "-").downcase}_#{version_tag}"
end
def clean?
sh_with_status("git diff --exit-code")[1].success?
end
def committed?
sh_with_status("git diff-index --quiet --cached HEAD")[1].success?
end
def guard_clean
clean? && committed? || abort(" There are files that need to be committed.")
end
def tag_version
sh "git tag -m \"Version #{version}\" #{version_tag}"
puts " Tagged #{version_tag}."
rescue RuntimeError
puts " Untagging #{version_tag} due to error."
sh_with_status "git tag -d #{version_tag}"
abort
end
def already_tagged?
return false unless sh_with_status("git tag")[0].split(/\n/).include?(version_tag)
abort " Tag #{version_tag} has already been created."
end
def create_lockfile
File.open(PACKAGING_LOCKFILE, "w") { |f| f.write version }
end
def remove_lockfile
File.delete(PACKAGING_LOCKFILE)
rescue Errno::ENOENT
end
def create_directory(dir)
levels = dir.split("/")
location = ""
levels.each do |level|
location +="#{level}/"
mkdir_p location unless File.exist?(location)
end
end
def build_package(path)
abort " Package folder already exists!" if File.exist?(path)
sh "rake build:windows:folder"
end
def patch_windows_package(folder)
patch = "require_relative \"i-mic-fps/i-mic-fps\""
patch_file = "#{folder}/src/i-mic-fps.rb"
File.open(patch_file, "w") { |f| f.write patch }
end
def create_archive(folder, archive)
abort " Archive already exists!" if File.exist?(archive)
Zip::File.open(archive, Zip::File::CREATE) do |zipfile|
Dir["#{folder}/**/**"].each do |file|
zipfile.add(file.sub(folder + '/', ''), file)
end
end
end
def get_release
url = "#{GITHUB_API_URL}/releases"
request = Excon.get(url, headers: DEFAULT_HEADERS)
if request.status == 200
release = JSON.parse(request.body).find { |r| r["tag_name"] == version_tag }
return release
else
abort " Getting repo releases failed! (#{request.status})"
end
end
def upload_asset(asset)
github_token = ENV["GITHUB_TOKEN"]
abort " GITHUB_TOKEN not set!" unless github_token
release = get_release
upload_url = release["upload_url"].split("{?").first + "?name=#{asset.split("/").last}"
file = File.read(asset)
headers = DEFAULT_HEADERS
headers["Content-Type"] = "application/zip"
headers["Content-Length"] = file.size
request = Excon.post(upload_url, body: file, headers: headers)
abort " Upload failed! #{request.body} (#{request.status})" unless request.status.between?(200, 201)
end
namespace "game" do
desc "Create git tag, build, and release package"
task :release do
puts "Checking for uncommited changes..."
guard_clean
puts "Checking git tag for #{version_tag}..."
already_tagged?
puts "Committing git tag #{version_tag}..."
tag_version
puts "Pushing changes..."
sh "git push origin master"
sh "git push origin master --tags"
path = File.expand_path("../pkg/#{release_name}_WIN32", __dir__)
puts "Building release package '#{release_name}', this may take a while..."
create_lockfile
build_package(path)
puts "Patching..."
patch_windows_package(path)
puts "Creating archive..."
create_archive(path, "#{path}.zip")
remove_lockfile
puts "Pushing package to github..."
upload_asset("#{path}.zip")
puts "Done."
end
desc "Remove packaging assets"
task "release:cleanup" do
path = File.expand_path("../pkg", __dir__)
if File.exist?(path)
puts "Cleaning up..."
Dir["#{path}/**"].each do |file|
puts "Removing #{file}..."
if File.directory?(file)
FileUtils.remove_entry_secure(file)
else
File.delete(file)
end
end
puts "Done."
end
end
end

Binary file not shown.

Before

Width:  |  Height:  |  Size: 377 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.7 KiB

View File

@@ -1,128 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="232"
height="232"
viewBox="0 0 61.383334 61.383334"
version="1.1"
id="svg8"
sodipodi:docname="logo.svg"
inkscape:export-filename="/home/cyberarm/Code/i-mic-fps/static/logo.png"
inkscape:export-xdpi="211.86208"
inkscape:export-ydpi="211.86208"
inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)">
<defs
id="defs2" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.4142136"
inkscape:cx="28.822764"
inkscape:cy="101.19387"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="true"
units="px"
borderlayer="true"
inkscape:showpageshadow="false"
inkscape:snap-bbox="true"
inkscape:snap-intersection-paths="true"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:window-width="1920"
inkscape:window-height="1010"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1">
<inkscape:grid
type="xygrid"
id="grid10"
empspacing="8"
originx="0"
originy="2.2411203e-09"
dotted="false" />
</sodipodi:namedview>
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-33.940008,-296.21455)">
<path
style="opacity:1;fill:#e9b96e;fill-opacity:1;stroke:#000000;stroke-width:0.52916664;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:stroke markers fill"
d="m 69.448977,318.17079 h -9.524999 l 4.7625,4.7625 z"
id="path42"
inkscape:connector-curvature="0" />
<path
style="opacity:1;fill:#8f5902;fill-opacity:1;stroke:#000000;stroke-width:0.52916664;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:stroke markers fill"
d="m 51.986478,310.23329 7.9375,7.9375 h 9.524999 l 7.9375,-7.9375 z"
id="path30"
inkscape:connector-curvature="0" />
<path
style="opacity:1;fill:#ce5c00;fill-opacity:1;stroke:#000000;stroke-width:0.52916664;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:stroke markers fill"
d="m 69.448977,318.17079 16.485815,16.48581 7.9375,-7.9375 -16.485815,-16.48581 z"
id="path47"
inkscape:connector-curvature="0" />
<path
style="opacity:1;fill:#ce5c00;fill-opacity:1;stroke:#000000;stroke-width:0.52916664;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:stroke markers fill"
d="m 64.686478,322.93329 v 32.97163 L 85.934792,334.6566 69.448977,318.17079 Z"
id="path50"
inkscape:connector-curvature="0" />
<path
style="opacity:1;fill:#f57900;fill-opacity:1;stroke:#000000;stroke-width:0.52916664;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:stroke markers fill"
d="M 59.923978,318.17079 43.438163,334.6566 64.686478,355.90492 V 322.93329 Z"
id="path45"
inkscape:connector-curvature="0" />
<path
style="opacity:1;fill:#f57900;fill-opacity:1;stroke:#000000;stroke-width:0.52916664;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:stroke markers fill"
d="m 51.986478,310.23329 -16.485815,16.48581 7.9375,7.9375 16.485815,-16.48581 z"
id="path28"
inkscape:connector-curvature="0" />
<path
style="opacity:1;fill:#f57900;fill-opacity:1;stroke:#000000;stroke-width:0.52916664;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:stroke markers fill"
d="m 64.686478,297.53329 -12.7,12.7 h 12.7 z"
id="path53"
inkscape:connector-curvature="0" />
<path
style="opacity:1;fill:#ce5c00;fill-opacity:1;stroke:#000000;stroke-width:0.52916664;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:stroke markers fill"
d="m 64.686478,297.53329 v 12.7 h 12.699999 z"
id="rect22"
inkscape:connector-curvature="0" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.58333302px;line-height:1.25;font-family:'Droid Serif';-inkscape-font-specification:'Droid Serif';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
x="99.88446"
y="329.00253"
id="text14"><tspan
sodipodi:role="line"
id="tspan12"
x="99.88446"
y="329.00253"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:'Droid Serif';-inkscape-font-specification:'Droid Serif';fill:#000000;stroke-width:0.26458332">I-MIC FPS</tspan></text>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 6.0 KiB