mirror of
https://github.com/cyberarm/i-mic-fps.git
synced 2025-12-15 23:52:35 +00:00
Compare commits
25 Commits
deferred_s
...
v0.1.0
| Author | SHA1 | Date | |
|---|---|---|---|
| 95fc6272b8 | |||
| d3603947cc | |||
| 029d9b1951 | |||
| 6520051938 | |||
| 8d956131d1 | |||
| 7f16efe0a4 | |||
| c92ea9ec73 | |||
| c9ba1ab94a | |||
| 2000f601d8 | |||
| a078645b94 | |||
| c1eb02a106 | |||
| a3b4c6e651 | |||
| fd3785cdcd | |||
| 06fb2c0e43 | |||
| d524c21332 | |||
| 85dd90b2f4 | |||
| 1629cf4605 | |||
| f3c3a1047f | |||
| face4b092a | |||
| 75185425b6 | |||
| bb21de2e2a | |||
| c53d42166b | |||
| c05009a000 | |||
| 9593d341bf | |||
| 27de5667be |
5
Gemfile
5
Gemfile
@@ -1,8 +1,13 @@
|
||||
source "https://rubygems.org"
|
||||
gem "rake"
|
||||
gem "opengl-bindings", require: "opengl"
|
||||
gem "cyberarm_engine", git: "https://github.com/cyberarm/cyberarm_engine"
|
||||
gem "nokogiri", ">= 1.11.0.rc1"
|
||||
gem "async-websocket"
|
||||
|
||||
group(:packaging) do
|
||||
gem "releasy", github: "gosu/releasy"
|
||||
gem "ocra"
|
||||
gem "rubyzip"
|
||||
gem "excon"
|
||||
end
|
||||
|
||||
68
Gemfile.lock
68
Gemfile.lock
@@ -1,32 +1,84 @@
|
||||
GIT
|
||||
remote: https://github.com/cyberarm/cyberarm_engine
|
||||
revision: d8551c7428da98bb7da76c138e5fbde50ef0137f
|
||||
revision: 0850336e55891f1f10dcb10e3b4b42e5f7379b33
|
||||
specs:
|
||||
cyberarm_engine (0.13.1)
|
||||
cyberarm_engine (0.14.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
|
||||
remote: https://rubygems.org/
|
||||
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-x64-mingw32)
|
||||
mini_portile2 (2.4.0)
|
||||
nokogiri (1.11.0.rc1)
|
||||
mini_portile2 (~> 2.4.0)
|
||||
nokogiri (1.11.0.rc1-x64-mingw32)
|
||||
mini_portile2 (~> 2.4.0)
|
||||
gosu_more_drawables (0.3.0)
|
||||
mini_portile2 (2.5.0)
|
||||
nio4r (2.5.2)
|
||||
nokogiri (1.11.0.rc2)
|
||||
mini_portile2 (~> 2.5.0)
|
||||
nokogiri (1.11.0.rc2-x64-mingw32)
|
||||
ocra (1.3.11)
|
||||
opengl-bindings (1.6.9)
|
||||
opengl-bindings (1.6.10)
|
||||
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
|
||||
ruby
|
||||
x64-mingw32
|
||||
|
||||
DEPENDENCIES
|
||||
async-websocket
|
||||
cyberarm_engine!
|
||||
excon
|
||||
nokogiri (>= 1.11.0.rc1)
|
||||
ocra
|
||||
opengl-bindings
|
||||
rake
|
||||
releasy!
|
||||
rubyzip
|
||||
|
||||
BUNDLED WITH
|
||||
2.1.4
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# I-MIC FPS
|
||||
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/))
|
||||
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/))
|
||||
|
||||

|
||||
|
||||
## 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.)
|
||||
|
||||
12
Rakefile
12
Rakefile
@@ -1,10 +1,16 @@
|
||||
require "json"
|
||||
require "tmpdir"
|
||||
require "fileutils"
|
||||
|
||||
require "zip"
|
||||
require "excon"
|
||||
require "releasy"
|
||||
require 'bundler/setup' # Releasy requires that your application uses bundler.
|
||||
require_relative "lib/version"
|
||||
|
||||
Releasy::Project.new do
|
||||
name "I-MIC FPS"
|
||||
version "#{IMICFPS::VERSION}"
|
||||
name IMICFPS::NAME
|
||||
version IMICFPS::VERSION
|
||||
|
||||
executable "i-mic-fps.rb"
|
||||
files ["lib/**/*.*", "assets/**/*.*", "blends/**/*.*", "shaders/**/*.*", "static/**/*.*", "maps/**/*.*", "data/**/*.*"]
|
||||
@@ -12,7 +18,7 @@ Releasy::Project.new do
|
||||
verbose
|
||||
|
||||
add_build :windows_folder do
|
||||
# icon "assets/icon.ico"
|
||||
icon "static/icon.ico"
|
||||
executable_type :console # Assuming you don't want it to run with a console window.
|
||||
add_package :exe # Windows self-extracting archive.
|
||||
end
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
require "gosu"
|
||||
require_relative "lib/objects/text"
|
||||
begin
|
||||
require_relative "../cyberarm_engine/lib/cyberarm_engine"
|
||||
rescue LoadError
|
||||
require "cyberarm_engine"
|
||||
end
|
||||
|
||||
class Window < Gosu::Window
|
||||
def initialize
|
||||
@@ -9,8 +12,8 @@ class Window < Gosu::Window
|
||||
@slope = 250
|
||||
@color_step = 10
|
||||
@base_color = Gosu::Color.rgb(255, 127, 0)
|
||||
@title = Text.new("I-MIC FPS", color: Gosu::Color.rgb(255,127,0), size: 100, x: 0, y: 15, alignment: :center)
|
||||
@singleplayer = Text.new("Singleplayer", color: Gosu::Color.rgb(0,127,127), size: 50, x: 0, y: 150, alignment: :center)
|
||||
@title = CyberarmEngine::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)
|
||||
end
|
||||
|
||||
def draw
|
||||
|
||||
3
assets/base/editor/manifest.yaml
Normal file
3
assets/base/editor/manifest.yaml
Normal file
@@ -0,0 +1,3 @@
|
||||
name: "editor"
|
||||
model: "editor.obj"
|
||||
collision: "mesh"
|
||||
32
assets/base/editor/model/editor.mtl
Normal file
32
assets/base/editor/model/editor.mtl
Normal file
@@ -0,0 +1,32 @@
|
||||
# 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
|
||||
4703
assets/base/editor/model/editor.obj
Normal file
4703
assets/base/editor/model/editor.obj
Normal file
File diff suppressed because it is too large
Load Diff
BIN
blends/editor.blend
Normal file
BIN
blends/editor.blend
Normal file
Binary file not shown.
BIN
blends/editor.blend1
Normal file
BIN
blends/editor.blend1
Normal file
Binary file not shown.
9
i-mic-fps-server.rb
Normal file
9
i-mic-fps-server.rb
Normal file
@@ -0,0 +1,9 @@
|
||||
IMICFPS_SERVER_MODE = true
|
||||
require_relative "i-mic-fps"
|
||||
|
||||
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|
|
||||
puts "Ticked: #{dt}"
|
||||
end
|
||||
|
||||
director.run.join
|
||||
67
i-mic-fps.rb
67
i-mic-fps.rb
@@ -3,10 +3,13 @@ require "yaml"
|
||||
require "json"
|
||||
require "abbrev"
|
||||
require "time"
|
||||
require "socket"
|
||||
require "tmpdir"
|
||||
|
||||
require "opengl"
|
||||
require "glu"
|
||||
require "nokogiri"
|
||||
require "async/websocket"
|
||||
|
||||
begin
|
||||
require_relative "../cyberarm_engine/lib/cyberarm_engine"
|
||||
@@ -56,12 +59,21 @@ require_relative "lib/ui/console"
|
||||
require_relative "lib/ui/menus/main_menu"
|
||||
require_relative "lib/ui/menus/settings_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/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/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/publisher"
|
||||
require_relative "lib/event"
|
||||
@@ -106,22 +118,53 @@ require_relative "lib/scenes/turn_table"
|
||||
require_relative "lib/crosshair"
|
||||
require_relative "lib/demo"
|
||||
|
||||
require_relative "lib/networking/director"
|
||||
require_relative "lib/networking/packet_handler"
|
||||
require_relative "lib/networking/client"
|
||||
require_relative "lib/networking/server"
|
||||
require_relative "lib/networking/connection"
|
||||
|
||||
require_relative "lib/networking/backends/memory_server"
|
||||
require_relative "lib/networking/backends/memory_connection"
|
||||
|
||||
require_relative "lib/overlay"
|
||||
require_relative "lib/window"
|
||||
|
||||
require_relative "lib/tools/asset_viewer"
|
||||
require_relative "lib/tools/map_editor"
|
||||
|
||||
if ARGV.join.include?("--profile")
|
||||
begin
|
||||
require "ruby-prof"
|
||||
RubyProf.start
|
||||
IMICFPS::Window.new.show
|
||||
result = RubyProf.stop
|
||||
printer = RubyProf::MultiPrinter.new(result)
|
||||
printer.print(path: ".", profile: "profile", min_percent: 2)
|
||||
rescue LoadError
|
||||
puts "ruby-prof not installed!"
|
||||
# Don't launch game if IMICFPS_SERVER_MODE is defined
|
||||
# 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
|
||||
require "ruby-prof"
|
||||
RubyProf.start
|
||||
IMICFPS::Window.new.show
|
||||
result = RubyProf.stop
|
||||
printer = RubyProf::MultiPrinter.new(result)
|
||||
printer.print(path: ".", profile: "profile", min_percent: 2)
|
||||
rescue LoadError
|
||||
puts "ruby-prof not installed!"
|
||||
end
|
||||
else
|
||||
IMICFPS::Window.new.show
|
||||
end
|
||||
else
|
||||
IMICFPS::Window.new.show
|
||||
end
|
||||
puts prevent_launch?[1]
|
||||
end
|
||||
@@ -39,8 +39,53 @@ class IMICFPS
|
||||
def draw_quad(*args)
|
||||
window.draw_quad(*args)
|
||||
end
|
||||
def fill(color = Gosu::Color::WHITE)
|
||||
draw_rect(0, 0, window.width, window.height, color)
|
||||
def fill(color = Gosu::Color::WHITE, z = 0)
|
||||
draw_rect(0, 0, window.width, window.height, color, z)
|
||||
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
|
||||
|
||||
def gl_error?
|
||||
|
||||
23
lib/hud.rb
Normal file
23
lib/hud.rb
Normal file
@@ -0,0 +1,23 @@
|
||||
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
|
||||
25
lib/hud/widget.rb
Normal file
25
lib/hud/widget.rb
Normal file
@@ -0,0 +1,25 @@
|
||||
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
|
||||
29
lib/hud/widgets/ammo.rb
Normal file
29
lib/hud/widgets/ammo.rb
Normal file
@@ -0,0 +1,29 @@
|
||||
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
|
||||
48
lib/hud/widgets/health.rb
Normal file
48
lib/hud/widgets/health.rb
Normal file
@@ -0,0 +1,48 @@
|
||||
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
|
||||
28
lib/hud/widgets/radar.rb
Normal file
28
lib/hud/widgets/radar.rb
Normal file
@@ -0,0 +1,28 @@
|
||||
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
|
||||
@@ -0,0 +1,26 @@
|
||||
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
|
||||
11
lib/map.rb
11
lib/map.rb
@@ -14,7 +14,6 @@ class IMICFPS
|
||||
@lights = []
|
||||
|
||||
@collision_manager = CollisionManager.new(map: self)
|
||||
@renderer = window.renderer
|
||||
Publisher.new
|
||||
end
|
||||
|
||||
@@ -33,8 +32,11 @@ class IMICFPS
|
||||
|
||||
add_entity(Player.new(spawnpoint: @map_parser.spawnpoints.sample, manifest: Manifest.new(package: "base", name: "character")))
|
||||
|
||||
# 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)))
|
||||
# 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
|
||||
|
||||
def data
|
||||
@@ -51,7 +53,7 @@ class IMICFPS
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) # clear the screen and the depth buffer
|
||||
gl_error?
|
||||
|
||||
@renderer.draw(camera, @lights, @entities)
|
||||
window.renderer.draw(camera, @lights, @entities)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -59,7 +61,6 @@ class IMICFPS
|
||||
@collision_manager.update
|
||||
|
||||
@entities.each(&:update)
|
||||
# @lights.each(&:update)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
6
lib/networking/backends/memory_connection.rb
Normal file
6
lib/networking/backends/memory_connection.rb
Normal file
@@ -0,0 +1,6 @@
|
||||
class IMICFPS
|
||||
module Networking
|
||||
class MemoryConnection < Connection
|
||||
end
|
||||
end
|
||||
end
|
||||
6
lib/networking/backends/memory_server.rb
Normal file
6
lib/networking/backends/memory_server.rb
Normal file
@@ -0,0 +1,6 @@
|
||||
class IMICFPS
|
||||
module Networking
|
||||
class MemoryServer < Server
|
||||
end
|
||||
end
|
||||
end
|
||||
18
lib/networking/client.rb
Normal file
18
lib/networking/client.rb
Normal file
@@ -0,0 +1,18 @@
|
||||
class IMICFPS
|
||||
module Networking
|
||||
class Client
|
||||
def initialize(socket:)
|
||||
@socket = socket
|
||||
end
|
||||
|
||||
def read
|
||||
end
|
||||
|
||||
def write
|
||||
end
|
||||
|
||||
def close
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
17
lib/networking/connection.rb
Normal file
17
lib/networking/connection.rb
Normal file
@@ -0,0 +1,17 @@
|
||||
class IMICFPS
|
||||
module Networking
|
||||
class Connection
|
||||
def initialize(hostname:, port:)
|
||||
end
|
||||
|
||||
def connect
|
||||
end
|
||||
|
||||
def update
|
||||
end
|
||||
|
||||
def close
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
61
lib/networking/director.rb
Normal file
61
lib/networking/director.rb
Normal file
@@ -0,0 +1,61 @@
|
||||
class IMICFPS
|
||||
module Networking
|
||||
class Director
|
||||
attr_reader :mode, :hostname, :port, :tick_rate, :storage
|
||||
def initialize(mode:, hostname:, port:, interface:, state: nil, tick_rate: 2)
|
||||
@mode = mode
|
||||
@hostname = hostname
|
||||
@port = port
|
||||
@state = state
|
||||
@tick_rate = (1000.0 / tick_rate) / 1000.0
|
||||
|
||||
case @mode
|
||||
when :server
|
||||
@server = interface.new(hostname: @hostname, port: @port)
|
||||
when :connection
|
||||
@connection = interface.new(hostname: @hostname, port: @port)
|
||||
when :memory
|
||||
@server = interface[:server].new(hostname: @hostname, port: @port)
|
||||
@connection = interface[:connection].new(hostname: @hostname, port: @port)
|
||||
else
|
||||
raise ArgumentError, "Expected mode to be :server, :connection, or :memory, not #{mode.inspect}"
|
||||
end
|
||||
|
||||
@last_tick_time = milliseconds
|
||||
@directing = true
|
||||
@storage = {}
|
||||
end
|
||||
|
||||
def run
|
||||
Thread.start do |thread|
|
||||
while(@directing)
|
||||
dt = milliseconds - @last_tick_time
|
||||
|
||||
tick(dt)
|
||||
|
||||
@server.update if @server
|
||||
@connection.update if @connection
|
||||
|
||||
@last_tick_time = milliseconds
|
||||
sleep(@tick_rate)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def tick(dt)
|
||||
end
|
||||
|
||||
def shutdown
|
||||
@directing = false
|
||||
|
||||
@clients.each(&:close)
|
||||
@server.update if @server
|
||||
@connection.update if @connection
|
||||
end
|
||||
|
||||
def milliseconds
|
||||
Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
11
lib/networking/events.rb
Normal file
11
lib/networking/events.rb
Normal file
@@ -0,0 +1,11 @@
|
||||
class IMICFPS
|
||||
module Networking
|
||||
module Events
|
||||
def on_connect(client)
|
||||
end
|
||||
|
||||
def on_disconnect(client)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
18
lib/networking/packet.rb
Normal file
18
lib/networking/packet.rb
Normal file
@@ -0,0 +1,18 @@
|
||||
class IMICFPS
|
||||
module Networking
|
||||
class Packet
|
||||
def initialize(type:, payload:)
|
||||
end
|
||||
|
||||
def self.encode(packet)
|
||||
"#{packet.type}|#{packet.payload}"
|
||||
end
|
||||
|
||||
def self.decode(string)
|
||||
split = string.split("|")
|
||||
|
||||
Packet.new(split.first, split.last)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
6
lib/networking/packet_handler.rb
Normal file
6
lib/networking/packet_handler.rb
Normal file
@@ -0,0 +1,6 @@
|
||||
class IMICFPS
|
||||
module Networking
|
||||
class PacketHandler
|
||||
end
|
||||
end
|
||||
end
|
||||
29
lib/networking/server.rb
Normal file
29
lib/networking/server.rb
Normal file
@@ -0,0 +1,29 @@
|
||||
class IMICFPS
|
||||
module Networking
|
||||
MAX_CLIENTS = 32
|
||||
|
||||
class Server
|
||||
attr_reader :hostname, :port, :max_clients, :clients
|
||||
def initialize(hostname:, port:, max_clients: MAX_CLIENTS)
|
||||
@hostname = hostname
|
||||
@port = port
|
||||
@max_clients = max_clients
|
||||
|
||||
@clients = []
|
||||
@socket = nil
|
||||
end
|
||||
|
||||
def bind
|
||||
end
|
||||
|
||||
def broadcast(packet)
|
||||
end
|
||||
|
||||
def update
|
||||
end
|
||||
|
||||
def close
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
59
lib/overlay.rb
Normal file
59
lib/overlay.rb
Normal file
@@ -0,0 +1,59 @@
|
||||
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
|
||||
@@ -16,7 +16,7 @@ class IMICFPS
|
||||
end
|
||||
|
||||
def render(camera, lights, entities)
|
||||
if Shader.available?("default") && Shader.available?("render_screen")
|
||||
if window.config.get(:debug_options, :use_shaders) && Shader.available?("default") && Shader.available?("render_screen")
|
||||
@g_buffer.bind_for_writing
|
||||
gl_error?
|
||||
|
||||
@@ -155,6 +155,7 @@ class IMICFPS
|
||||
end
|
||||
|
||||
if window.config.get(:debug_options, :wireframe)
|
||||
glLineWidth(2)
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)
|
||||
Shader.active_shader.uniform_boolean("disableLighting", true)
|
||||
|
||||
@@ -163,6 +164,7 @@ class IMICFPS
|
||||
|
||||
Shader.active_shader.uniform_boolean("disableLighting", false)
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)
|
||||
glLineWidth(1)
|
||||
end
|
||||
|
||||
glDrawArrays(GL_TRIANGLES, 0, model.faces.count * 3)
|
||||
|
||||
53
lib/states/game_states/boot.rb
Normal file
53
lib/states/game_states/boot.rb
Normal file
@@ -0,0 +1,53 @@
|
||||
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
|
||||
49
lib/states/game_states/close.rb
Normal file
49
lib/states/game_states/close.rb
Normal file
@@ -0,0 +1,49 @@
|
||||
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
|
||||
@@ -9,10 +9,12 @@ class IMICFPS
|
||||
@player = @map.find_entity_by(name: "character")
|
||||
@camera = Camera.new(position: @player.position.clone)
|
||||
@camera.attach_to(@player)
|
||||
@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
|
||||
@hud = HUD.new(@player)
|
||||
|
||||
@text = Text.new("Pending...", x: 10, y: 10, z: 1, size: 18, font: "DejaVu Sans", shadow_color: Gosu::Color::BLACK)
|
||||
@text = Text.new("Pending...", x: 10, y: 22, z: 1, size: 18, font: "DejaVu Sans", shadow_color: Gosu::Color::BLACK)
|
||||
|
||||
if ARGV.join.include?("--playdemo")
|
||||
@demo = Demo.new(camera: @camera, player: @player, demo: "./demo.dat", mode: :play) if File.exist?("./demo.dat")
|
||||
@@ -26,6 +28,7 @@ class IMICFPS
|
||||
@map.render(@camera)
|
||||
|
||||
@crosshair.draw
|
||||
@hud.draw
|
||||
@text.draw
|
||||
end
|
||||
|
||||
@@ -37,20 +40,18 @@ class IMICFPS
|
||||
@map.update
|
||||
|
||||
control_player
|
||||
@hud.update
|
||||
|
||||
@camera.update
|
||||
@director.tick(window.dt)
|
||||
|
||||
if window.config.get(:debug_options, :stats)
|
||||
@text.text = update_text
|
||||
elsif window.config.get(:options, :fps)
|
||||
@text.text = "FPS: #{Gosu.fps}"
|
||||
else
|
||||
@text.text = ""
|
||||
end
|
||||
|
||||
@demo.update if @demo
|
||||
|
||||
window.number_of_vertices = 0
|
||||
end
|
||||
|
||||
def update_text
|
||||
@@ -66,10 +67,6 @@ Camera Field Of View: #{@camera.field_of_view}
|
||||
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}
|
||||
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
|
||||
end
|
||||
|
||||
|
||||
@@ -2,9 +2,15 @@ class IMICFPS
|
||||
class LoadingState < Menu
|
||||
def setup
|
||||
window.needs_cursor = false
|
||||
@map_parser = MapParser.new(map_file: @options[:map_file])
|
||||
if @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 "I-MIC FPS"
|
||||
title IMICFPS::NAME
|
||||
@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)
|
||||
@state = Text.new("Preparing...", y: window.height/2-40, size: 40, alignment: :center)
|
||||
@@ -28,7 +34,8 @@ class IMICFPS
|
||||
@completed_for_ms = 0
|
||||
@lock = false
|
||||
|
||||
@base_color = Gosu::Color.rgb(0, 180, 180)
|
||||
@primary_color = Gosu::Color.rgba(0, 180, 180, 200)
|
||||
@accent_color = Gosu::Color.rgba(0, 90, 90, 200)
|
||||
end
|
||||
|
||||
def draw
|
||||
@@ -109,9 +116,9 @@ class IMICFPS
|
||||
progress = (@asset_index.to_f/@assets.count)*window.width/2
|
||||
height = 100
|
||||
|
||||
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(@base_color.red - 50, @base_color.green - 50, @base_color.blue - 50)#Gosu::Color.rgb(0,127,127)
|
||||
color_two = Gosu::Color.rgb(@base_color.red + 50, @base_color.green + 50, @base_color.blue + 50)#Gosu::Color.rgb(64, 127, 255)
|
||||
dark_color= Gosu::Color.rgb(@primary_color.red - 100, @primary_color.green - 100, @primary_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_two = Gosu::Color.rgb(@primary_color.red + 50, @primary_color.green + 50, @primary_color.blue + 50)#Gosu::Color.rgb(64, 127, 255)
|
||||
|
||||
draw_rect(x, y-2, x + window.width/4, height+4, dark_color)
|
||||
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
class IMICFPS
|
||||
class AssetViewerTool
|
||||
class MainMenu < CyberarmEngine::GuiState
|
||||
class MainMenu < Menu
|
||||
def setup
|
||||
window.needs_cursor = true
|
||||
|
||||
label "#{IMICFPS::NAME}", text_size: 50
|
||||
label "Asset Viewer", text_size: 28
|
||||
|
||||
@manifests = []
|
||||
Dir.glob(GAME_ROOT_PATH + "/assets/**/manifest.yaml").each do |manifest|
|
||||
begin
|
||||
@@ -18,14 +15,23 @@ class IMICFPS
|
||||
|
||||
@manifests.sort_by! { |m| m.name.downcase }
|
||||
|
||||
button "Back", margin_bottom: 25 do
|
||||
pop_state
|
||||
end
|
||||
label "#{IMICFPS::NAME}", text_size: 100, color: Gosu::Color::BLACK
|
||||
label "Asset Viewer", text_size: 50
|
||||
|
||||
flow(margin: 10) do
|
||||
@manifests.each do |manifest|
|
||||
button manifest.name do
|
||||
push_state(TurnTable, manifest: manifest)
|
||||
flow(width: 1.0, height: 1.0) do
|
||||
stack(width: 0.25, height: 1.0) do
|
||||
button "Back", margin_bottom: 25 do
|
||||
pop_state
|
||||
end
|
||||
end
|
||||
|
||||
stack(width: 0.5, height: 1.0) do
|
||||
flow(width: 1.0, height: 1.0) do
|
||||
@manifests.each do |manifest|
|
||||
button manifest.name do
|
||||
push_state(TurnTable, manifest: manifest)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -31,7 +31,6 @@ class IMICFPS
|
||||
@lights << @light
|
||||
|
||||
@camera = Camera.new(position: Vector.new(0, 1.5, 5), orientation: Vector.forward)
|
||||
@renderer = Renderer.new
|
||||
|
||||
label @manifest.name, text_size: 50
|
||||
label @manifest.model
|
||||
@@ -55,7 +54,7 @@ class IMICFPS
|
||||
)
|
||||
|
||||
Gosu.gl do
|
||||
@renderer.draw(@camera, [@light], @map.entities)
|
||||
window.renderer.draw(@camera, [@light], @map.entities)
|
||||
end
|
||||
|
||||
@crosshair.draw
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
require_relative "map_editor/lib/main_menu"
|
||||
require_relative "map_editor/lib/main_menu"
|
||||
require_relative "map_editor/lib/editor"
|
||||
59
lib/tools/map_editor/lib/editor.rb
Normal file
59
lib/tools/map_editor/lib/editor.rb
Normal file
@@ -0,0 +1,59 @@
|
||||
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
|
||||
@@ -1,6 +1,6 @@
|
||||
class IMICFPS
|
||||
class MapEditorTool
|
||||
class MainMenu < CyberarmEngine::GuiState
|
||||
class MainMenu < Menu
|
||||
def setup
|
||||
window.needs_cursor = true
|
||||
|
||||
@@ -29,7 +29,7 @@ class IMICFPS
|
||||
flow(margin: 10) do
|
||||
@maps.each do |map|
|
||||
button map.metadata.name do
|
||||
# push_state(TurnTable, manifest: manifest)
|
||||
push_state(LoadingState, map_parser: map, forward: Editor)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,12 +1,23 @@
|
||||
class IMICFPS
|
||||
class Menu < IMICFPS::GameState
|
||||
class Menu < IMICFPS::GuiState
|
||||
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)
|
||||
@elements = []
|
||||
@size = 50
|
||||
@slope = 250
|
||||
@color_step = 10
|
||||
@base_color = Gosu::Color.rgb(255, 127, 0)
|
||||
@background_alpha = 200
|
||||
@bar_size = BAR_SIZE
|
||||
@bar_slope = BAR_SLOPE
|
||||
@bar_color_step = BAR_COLOR_STEP
|
||||
@bar_alpha = BAR_ALPHA
|
||||
@primary_color = PRIMARY_COLOR
|
||||
@accent_color = ACCENT_COLOR
|
||||
window.needs_cursor = true
|
||||
|
||||
@__version_text = CyberarmEngine::Text.new("<b>#{IMICFPS::NAME}</b> v#{IMICFPS::VERSION} (#{IMICFPS::RELEASE_NAME})")
|
||||
@@ -15,7 +26,7 @@ class IMICFPS
|
||||
super(*args)
|
||||
end
|
||||
|
||||
def title(text, color = @base_color)
|
||||
def title(text, color = Gosu::Color::BLACK)
|
||||
@elements << Text.new(text, color: color, size: 100, x: 0, y: 15)
|
||||
@_title = @elements.last
|
||||
end
|
||||
@@ -31,7 +42,7 @@ class IMICFPS
|
||||
end
|
||||
|
||||
def draw
|
||||
draw_background
|
||||
menu_background(@primary_color, @accent_color, @bar_color_step, @bar_alpha, @bar_size, @bar_slope)
|
||||
draw_menu_box
|
||||
draw_menu
|
||||
|
||||
@@ -44,34 +55,15 @@ class IMICFPS
|
||||
|
||||
window.scene.draw
|
||||
end
|
||||
end
|
||||
|
||||
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
|
||||
super
|
||||
end
|
||||
|
||||
def draw_menu_box
|
||||
draw_rect(
|
||||
window.width/4, 0,
|
||||
window.width/2, window.height,
|
||||
Gosu::Color.rgba(0, 0, 0, 150),
|
||||
window.width / 4, 0,
|
||||
window.width / 2, window.height,
|
||||
Gosu::Color.new(0x11ffffff),
|
||||
)
|
||||
end
|
||||
|
||||
@@ -83,7 +75,7 @@ class IMICFPS
|
||||
|
||||
def update
|
||||
@elements.each do |e|
|
||||
e.x = window.width / 2 - e.width / 2
|
||||
e.x = (window.width / 2 - e.width / 2).round
|
||||
e.update
|
||||
end
|
||||
|
||||
@@ -91,20 +83,12 @@ class IMICFPS
|
||||
window.scene.update(window.dt)
|
||||
end
|
||||
|
||||
super
|
||||
|
||||
@__version_text.x = window.width - (@__version_text.width + 10)
|
||||
@__version_text.y = window.height - (@__version_text.height + 10)
|
||||
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)
|
||||
if id == Gosu::MsLeft
|
||||
@elements.each do |e|
|
||||
@@ -114,6 +98,8 @@ class IMICFPS
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
super
|
||||
end
|
||||
|
||||
def mouse_over?(object)
|
||||
@@ -126,19 +112,17 @@ class IMICFPS
|
||||
def initialize(text, host, block)
|
||||
@text, @host, @block = text, host, block
|
||||
@color = @text.color
|
||||
@hover_color = Gosu::Color.rgb(64, 127, 255)
|
||||
@hover_color = Gosu::Color.rgb(64, 128, 255)
|
||||
@text.shadow_color= Gosu::Color::BLACK
|
||||
@text.shadow_size = 2
|
||||
@text.shadow_alpha = 100
|
||||
end
|
||||
|
||||
def update
|
||||
if @host.mouse_over?(self)
|
||||
@text.color = @hover_color
|
||||
@text.shadow_color= Gosu::Color::BLACK
|
||||
@text.shadow_size = 3
|
||||
else
|
||||
@text.color = @color
|
||||
@text.shadow_color = nil
|
||||
@text.shadow_size = 1
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
class IMICFPS
|
||||
class ExtrasMenu < Menu
|
||||
def setup
|
||||
title "I-MIC FPS"
|
||||
title IMICFPS::NAME
|
||||
subtitle "Extras"
|
||||
|
||||
link "Asset Viewer" do
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
class IMICFPS
|
||||
class GamePauseMenu < Menu
|
||||
def setup
|
||||
@background_alpha = 50
|
||||
title "I-MIC FPS"
|
||||
@bar_alpha = 50
|
||||
title IMICFPS::NAME
|
||||
subtitle "Paused"
|
||||
|
||||
link "Resume" do
|
||||
@@ -13,7 +13,7 @@ class IMICFPS
|
||||
push_state(SettingsMenu)
|
||||
end
|
||||
|
||||
link "Quit" do
|
||||
link "Leave" do
|
||||
push_state(MainMenu)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
class IMICFPS
|
||||
class LevelSelectMenu < Menu
|
||||
def setup
|
||||
title "I-MIC FPS"
|
||||
title IMICFPS::NAME
|
||||
subtitle "Choose a Map"
|
||||
|
||||
Dir.glob(GAME_ROOT_PATH + "/maps/*.json").map { |file| [file, MapParser.new(map_file: file)]}.each do |file, map|
|
||||
|
||||
@@ -1,13 +1,17 @@
|
||||
class IMICFPS
|
||||
class MainMenu < Menu
|
||||
def setup
|
||||
title "I-MIC FPS"
|
||||
title IMICFPS::NAME
|
||||
|
||||
link "Single Player" do
|
||||
push_state(LevelSelectMenu)
|
||||
# push_state(LoadingState.new(forward: Game, map_file: GAME_ROOT_PATH + "/maps/test_map.json"))
|
||||
end
|
||||
|
||||
link "Multiplayer" do
|
||||
push_state(MultiplayerMenu)
|
||||
end
|
||||
|
||||
link "Settings" do
|
||||
push_state(SettingsMenu)
|
||||
end
|
||||
@@ -16,7 +20,7 @@ class IMICFPS
|
||||
push_state(ExtrasMenu)
|
||||
end
|
||||
|
||||
link "Exit" do
|
||||
link "Exit Game" do
|
||||
window.close
|
||||
end
|
||||
|
||||
|
||||
14
lib/ui/menus/multiplayer_menu.rb
Normal file
14
lib/ui/menus/multiplayer_menu.rb
Normal file
@@ -0,0 +1,14 @@
|
||||
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
|
||||
@@ -1,14 +1,208 @@
|
||||
class IMICFPS
|
||||
class SettingsMenu < Menu
|
||||
include CommonMethods
|
||||
|
||||
def setup
|
||||
title "I-MIC FPS"
|
||||
subtitle "Settings"
|
||||
@categories = [
|
||||
"Display",
|
||||
"Graphics",
|
||||
"Audio",
|
||||
"Controls",
|
||||
"Multiplayer"
|
||||
]
|
||||
@pages = {}
|
||||
@current_page = nil
|
||||
|
||||
link "\"There is no spoon.\""
|
||||
label "Settings", text_size: 100, color: Gosu::Color::BLACK
|
||||
|
||||
link "Back" do
|
||||
pop_state
|
||||
flow(width: 1.0, height: 1.0) 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
|
||||
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
|
||||
@@ -1,5 +1,5 @@
|
||||
class IMICFPS
|
||||
class Window < CyberarmEngine::Engine
|
||||
class Window < CyberarmEngine::Window
|
||||
attr_accessor :number_of_vertices, :needs_cursor
|
||||
attr_reader :renderer, :scene, :config
|
||||
|
||||
@@ -26,6 +26,7 @@ class IMICFPS
|
||||
@renderer = Renderer.new
|
||||
@renderer.preload_default_shaders
|
||||
@scene = TurnTableScene.new
|
||||
@overlay = Overlay.new
|
||||
|
||||
@canvas_size = Vector.new(self.width, self.height)
|
||||
|
||||
@@ -33,7 +34,7 @@ class IMICFPS
|
||||
@config.save!
|
||||
end
|
||||
|
||||
push_state(MainMenu)
|
||||
push_state(Boot)
|
||||
|
||||
@delta_time = Gosu.milliseconds
|
||||
end
|
||||
@@ -46,6 +47,7 @@ class IMICFPS
|
||||
super
|
||||
|
||||
@console.draw if @show_console
|
||||
@overlay.draw
|
||||
draw_cursor if needs_cursor
|
||||
|
||||
_canvas_size = Vector.new(self.width, self.height)
|
||||
@@ -65,9 +67,16 @@ class IMICFPS
|
||||
super
|
||||
|
||||
@console.update if @show_console
|
||||
@overlay.update
|
||||
|
||||
@number_of_vertices = 0
|
||||
@delta_time = Gosu.milliseconds
|
||||
end
|
||||
|
||||
def close
|
||||
push_state(Close)
|
||||
end
|
||||
|
||||
def button_down(id)
|
||||
if @show_console
|
||||
@console.button_down(id)
|
||||
|
||||
BIN
pixel_test.png
BIN
pixel_test.png
Binary file not shown.
|
Before Width: | Height: | Size: 162 B |
166
rakelib/release.rake
Normal file
166
rakelib/release.rake
Normal file
@@ -0,0 +1,166 @@
|
||||
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
|
||||
BIN
screenshots/screenshot-game.png
Normal file
BIN
screenshots/screenshot-game.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 377 KiB |
BIN
screenshots/screenshot-main-menu.png
Normal file
BIN
screenshots/screenshot-main-menu.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 113 KiB |
BIN
static/icon.ico
Normal file
BIN
static/icon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 19 KiB |
BIN
static/logo.png
Normal file
BIN
static/logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 7.7 KiB |
128
svg/logo.svg
Normal file
128
svg/logo.svg
Normal file
@@ -0,0 +1,128 @@
|
||||
<?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>
|
||||
|
After Width: | Height: | Size: 6.0 KiB |
Reference in New Issue
Block a user