shirokuro 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +23 -0
- data/.rspec +0 -0
- data/Gemfile +4 -0
- data/Guardfile +21 -0
- data/LICENSE.txt +22 -0
- data/README.md +21 -0
- data/Rakefile +8 -0
- data/examples/audio/main.rb +40 -0
- data/examples/audio/run.sh +2 -0
- data/examples/layers_and_sorting/main.rb +62 -0
- data/examples/layers_and_sorting/run.sh +2 -0
- data/examples/physx/main.rb +114 -0
- data/examples/physx/run.sh +2 -0
- data/examples/shared/content/audio/boing.ogg +0 -0
- data/examples/shared/content/audio/song_1.ogg +0 -0
- data/examples/shared/content/gfx/character_sprite.png +0 -0
- data/examples/shared/content/gfx/tileset.png +0 -0
- data/examples/shared/content/maps/stage2.json +299 -0
- data/examples/sprite/main.rb +43 -0
- data/examples/sprite/run.sh +2 -0
- data/examples/sprite_animation/main.rb +45 -0
- data/examples/sprite_animation/run.sh +2 -0
- data/examples/tmx_map/main.rb +70 -0
- data/examples/tmx_map/run.sh +2 -0
- data/lib/shirokuro.rb +42 -0
- data/lib/shirokuro/audio/audio_manager.rb +80 -0
- data/lib/shirokuro/content/content_manager.rb +58 -0
- data/lib/shirokuro/ecs/component.rb +37 -0
- data/lib/shirokuro/ecs/game_object.rb +58 -0
- data/lib/shirokuro/ecs/game_object_manager.rb +51 -0
- data/lib/shirokuro/ecs/id_generator.rb +10 -0
- data/lib/shirokuro/math/matrix.rb +72 -0
- data/lib/shirokuro/math/transform.rb +16 -0
- data/lib/shirokuro/math/vec2.rb +38 -0
- data/lib/shirokuro/physics/physics.rb +22 -0
- data/lib/shirokuro/standard_components/animations/animation.rb +30 -0
- data/lib/shirokuro/standard_components/animations/animation_component.rb +28 -0
- data/lib/shirokuro/standard_components/cameras/camera.rb +59 -0
- data/lib/shirokuro/standard_components/maps/map_component.rb +10 -0
- data/lib/shirokuro/standard_components/physics/box_collider.rb +40 -0
- data/lib/shirokuro/standard_components/physics/circle_collider.rb +29 -0
- data/lib/shirokuro/standard_components/physics/polygon_collider.rb +35 -0
- data/lib/shirokuro/standard_components/physics/rigid_body.rb +57 -0
- data/lib/shirokuro/standard_components/rendering/animation_sprite_renderer.rb +26 -0
- data/lib/shirokuro/standard_components/rendering/map_renderer.rb +36 -0
- data/lib/shirokuro/standard_components/rendering/shape_renderer.rb +95 -0
- data/lib/shirokuro/standard_components/rendering/sprite_renderer.rb +21 -0
- data/lib/shirokuro/standard_components/tmx/tmx_map.rb +20 -0
- data/lib/shirokuro/standard_components/tmx/tmx_map_layer.rb +38 -0
- data/lib/shirokuro/standard_components/tmx/tmx_map_layer_object.rb +17 -0
- data/lib/shirokuro/standard_components/transformation/rotation.rb +14 -0
- data/lib/shirokuro/version.rb +3 -0
- data/shirokuro.gemspec +30 -0
- data/spec/shirokuro/ecs/component_spec.rb +78 -0
- data/spec/shirokuro/ecs/game_object_manager_spec.rb +113 -0
- data/spec/shirokuro/ecs/game_object_spec.rb +110 -0
- data/spec/shirokuro/math/matrix_spec.rb +49 -0
- data/spec/shirokuro/math/transform_spec.rb +28 -0
- data/spec/shirokuro/math/vec2_spec.rb +49 -0
- data/spec/spec_helper.rb +12 -0
- metadata +223 -0
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'gosu'
|
2
|
+
require_relative '../../lib/shirokuro'
|
3
|
+
|
4
|
+
class Window < Gosu::Window
|
5
|
+
def initialize width, height
|
6
|
+
super(width, height, false)
|
7
|
+
self.caption = "SK Sprite Example"
|
8
|
+
|
9
|
+
@content = SK::ContentManager.new(self, "../shared/content/", true)
|
10
|
+
|
11
|
+
@manager = SK::GameObjectManager.new
|
12
|
+
|
13
|
+
sprite = @manager.create("sprite")
|
14
|
+
sprite.transform.position = SK::Vec2.new(256, 256)
|
15
|
+
sprite.transform.scale = SK::Vec2.new(1, 1) * 2.0
|
16
|
+
sprite.add_component(SK::SpriteRenderer.new(@content.load_tiles("gfx/character_sprite.png", 32, 32).first))
|
17
|
+
sprite.add_component(SK::Rotation.new(0.01))
|
18
|
+
|
19
|
+
sprite.get_component(SK::SpriteRenderer).origin.y = 1.0
|
20
|
+
|
21
|
+
@manager.start
|
22
|
+
end
|
23
|
+
|
24
|
+
def button_down(id)
|
25
|
+
case id
|
26
|
+
when Gosu::KbEscape
|
27
|
+
self.close
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def update
|
32
|
+
delta = 16.0 #fake it
|
33
|
+
|
34
|
+
@manager.update delta
|
35
|
+
end
|
36
|
+
|
37
|
+
def draw
|
38
|
+
@manager.draw self
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
window = Window.new(512, 512)
|
43
|
+
window.show
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'gosu'
|
2
|
+
require_relative '../../lib/shirokuro'
|
3
|
+
|
4
|
+
class Window < Gosu::Window
|
5
|
+
def initialize width, height
|
6
|
+
super(width, height, false)
|
7
|
+
self.caption = "SK Sprite Animation Example"
|
8
|
+
|
9
|
+
@content = SK::ContentManager.new(self, "../shared/content/", true)
|
10
|
+
|
11
|
+
@manager = SK::GameObjectManager.new
|
12
|
+
|
13
|
+
sprite = @manager.create("sprite")
|
14
|
+
sprite.transform.position = SK::Vec2.new(256, 256)
|
15
|
+
sprite.transform.scale = SK::Vec2.new(1, 1) * 6.0
|
16
|
+
|
17
|
+
sprite.add_component(SK::AnimationComponent.new({
|
18
|
+
:idle => SK::Animation.new([0, 1, 2, 3, 4], 100)
|
19
|
+
}))
|
20
|
+
sprite.add_component(SK::AnimationSpriteRenderer.new(@content.load_tiles("gfx/character_sprite.png", 32, 32)))
|
21
|
+
#sprite.add_component(SK::Rotation.new(0.01))
|
22
|
+
|
23
|
+
@manager.start
|
24
|
+
end
|
25
|
+
|
26
|
+
def button_down(id)
|
27
|
+
case id
|
28
|
+
when Gosu::KbEscape
|
29
|
+
self.close
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def update
|
34
|
+
delta = 16.0 #fake it
|
35
|
+
|
36
|
+
@manager.update delta
|
37
|
+
end
|
38
|
+
|
39
|
+
def draw
|
40
|
+
@manager.draw self
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
window = Window.new(512, 512)
|
45
|
+
window.show
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'gosu'
|
2
|
+
require_relative '../../lib/shirokuro'
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
class Window < Gosu::Window
|
6
|
+
def initialize width, height
|
7
|
+
super(width, height, false)
|
8
|
+
self.caption = "SK Sprite Animation Example"
|
9
|
+
|
10
|
+
@content = SK::ContentManager.new(self, "../shared/content/", true)
|
11
|
+
@manager = SK::GameObjectManager.new
|
12
|
+
|
13
|
+
@cam = SK::Camera.new(SK::Vec2.new(width, height))
|
14
|
+
cam = @manager.create("cam")
|
15
|
+
cam.add_component(@cam)
|
16
|
+
@cam.set_zoom(2.0)
|
17
|
+
|
18
|
+
map = @manager.create("map")
|
19
|
+
map.transform.position.x -= 256
|
20
|
+
map.transform.position.y -= 256
|
21
|
+
|
22
|
+
tmx_map = SK::TMX::Map.new(JSON.load(File.open("#{@content.content_root}maps/stage2.json").read))
|
23
|
+
map.add_component(SK::MapComponent.new(tmx_map))
|
24
|
+
map.add_component(SK::MapRenderer.new(@content.load_tiles("gfx/tileset.png", 32, 32)))
|
25
|
+
|
26
|
+
@manager.start
|
27
|
+
end
|
28
|
+
|
29
|
+
def button_down(id)
|
30
|
+
case id
|
31
|
+
when Gosu::KbEscape
|
32
|
+
self.close
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def update
|
37
|
+
dt = 16.0 #fake it
|
38
|
+
|
39
|
+
if button_down?(Gosu::KbLeft)
|
40
|
+
@cam.move_by(-1.0 * dt, 0)
|
41
|
+
end
|
42
|
+
if button_down?(Gosu::KbRight)
|
43
|
+
@cam.move_by(1.0 * dt, 0)
|
44
|
+
end
|
45
|
+
if button_down?(Gosu::KbUp)
|
46
|
+
@cam.move_by(0, -1.0 * dt)
|
47
|
+
end
|
48
|
+
if button_down?(Gosu::KbDown)
|
49
|
+
@cam.move_by(0, 1.0 * dt)
|
50
|
+
end
|
51
|
+
|
52
|
+
if button_down?(Gosu::KbW)
|
53
|
+
@cam.zoom_by(0.01)
|
54
|
+
end
|
55
|
+
if button_down?(Gosu::KbS)
|
56
|
+
@cam.zoom_by(-0.01)
|
57
|
+
end
|
58
|
+
|
59
|
+
@manager.update dt
|
60
|
+
end
|
61
|
+
|
62
|
+
def draw
|
63
|
+
@cam.view(self) do
|
64
|
+
@manager.draw self
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
window = Window.new(1024, 1024)
|
70
|
+
window.show
|
data/lib/shirokuro.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'chipmunk'
|
2
|
+
|
3
|
+
require "shirokuro/math/matrix"
|
4
|
+
require "shirokuro/math/vec2"
|
5
|
+
require "shirokuro/math/transform"
|
6
|
+
|
7
|
+
require "shirokuro/physics/physics"
|
8
|
+
|
9
|
+
require "shirokuro/version"
|
10
|
+
require "shirokuro/ecs/component"
|
11
|
+
require "shirokuro/ecs/game_object"
|
12
|
+
require "shirokuro/ecs/game_object_manager"
|
13
|
+
require "shirokuro/ecs/id_generator"
|
14
|
+
|
15
|
+
require "shirokuro/content/content_manager"
|
16
|
+
require "shirokuro/audio/audio_manager"
|
17
|
+
|
18
|
+
require "shirokuro/standard_components/cameras/camera"
|
19
|
+
|
20
|
+
require "shirokuro/standard_components/rendering/sprite_renderer"
|
21
|
+
require "shirokuro/standard_components/rendering/animation_sprite_renderer"
|
22
|
+
require "shirokuro/standard_components/rendering/map_renderer"
|
23
|
+
require "shirokuro/standard_components/rendering/shape_renderer"
|
24
|
+
|
25
|
+
require "shirokuro/standard_components/maps/map_component"
|
26
|
+
|
27
|
+
require "shirokuro/standard_components/transformation/rotation"
|
28
|
+
|
29
|
+
require "shirokuro/standard_components/animations/animation"
|
30
|
+
require "shirokuro/standard_components/animations/animation_component"
|
31
|
+
|
32
|
+
require "shirokuro/standard_components/tmx/tmx_map"
|
33
|
+
require "shirokuro/standard_components/tmx/tmx_map_layer"
|
34
|
+
require "shirokuro/standard_components/tmx/tmx_map_layer_object"
|
35
|
+
|
36
|
+
require "shirokuro/standard_components/physics/rigid_body"
|
37
|
+
require "shirokuro/standard_components/physics/box_collider"
|
38
|
+
require "shirokuro/standard_components/physics/circle_collider"
|
39
|
+
require "shirokuro/standard_components/physics/polygon_collider"
|
40
|
+
|
41
|
+
module SK
|
42
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
module SK
|
2
|
+
class AudioManager
|
3
|
+
|
4
|
+
attr_reader :sfx_volume, :music_volume
|
5
|
+
|
6
|
+
def initialize context, content_root
|
7
|
+
@sfx_volume = 1.0
|
8
|
+
@music_volume = 1.0
|
9
|
+
@context = context
|
10
|
+
@content_root = content_root.end_with?("/") ? content_root : "#{content_root}/"
|
11
|
+
@song_names = []
|
12
|
+
@sound_names = []
|
13
|
+
@songs = {}
|
14
|
+
@sound_instances = []
|
15
|
+
@sounds = {}
|
16
|
+
@file_extension = ".ogg"
|
17
|
+
end
|
18
|
+
|
19
|
+
def register_sound name
|
20
|
+
@sound_names << name
|
21
|
+
end
|
22
|
+
|
23
|
+
def register_song name
|
24
|
+
@song_names << name
|
25
|
+
end
|
26
|
+
|
27
|
+
def set_music_volume volume
|
28
|
+
@music_volume = volume
|
29
|
+
# TODO: set on playing song instances
|
30
|
+
end
|
31
|
+
|
32
|
+
def set_sfx_volume volume
|
33
|
+
@sfx_volume = volume
|
34
|
+
end
|
35
|
+
|
36
|
+
def load
|
37
|
+
@song_names.each do |song|
|
38
|
+
@songs[song] = Gosu::Song.new(@context, "#{@content_root}#{song}#{@file_extension}")
|
39
|
+
end
|
40
|
+
|
41
|
+
@sound_names.each do |sound|
|
42
|
+
@sounds[sound] = Gosu::Sample.new(@context, "#{@content_root}#{sound}#{@file_extension}")
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def play sound_name, pitch = 1.0, looping = false
|
47
|
+
@sound_instances << @sounds[sound_name].play(@sfx_volume, pitch, looping)
|
48
|
+
end
|
49
|
+
|
50
|
+
def play_pan sound_name, pan = 0, pitch = 1, looping = false
|
51
|
+
@sound_instances << @sounds[sound_name].play(pan, @sfx_volume, pitch, looping)
|
52
|
+
end
|
53
|
+
|
54
|
+
def play_song song_name, looping = true
|
55
|
+
@songs[song_name].play(looping)
|
56
|
+
end
|
57
|
+
|
58
|
+
def stop_song song_name
|
59
|
+
@songs[song_name].stop
|
60
|
+
end
|
61
|
+
|
62
|
+
def pause_song song_name
|
63
|
+
@songs[song_name].pause
|
64
|
+
end
|
65
|
+
|
66
|
+
def resume_song song_name
|
67
|
+
if @songs[song_name].paused?
|
68
|
+
@songs[song_name].play
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def get_song song_name
|
73
|
+
@songs[song_name]
|
74
|
+
end
|
75
|
+
|
76
|
+
def update dt
|
77
|
+
@sound_instances.delete_if{|s| !s.playing? }
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module SK
|
2
|
+
class ContentManager
|
3
|
+
|
4
|
+
attr_accessor :content_root
|
5
|
+
|
6
|
+
def initialize window, content_root, nearest_filtering = false
|
7
|
+
@window = window
|
8
|
+
@cache = {}
|
9
|
+
@content_root = content_root.end_with?("/") ? content_root : "#{content_root}/"
|
10
|
+
@nearest_filtering = nearest_filtering
|
11
|
+
end
|
12
|
+
|
13
|
+
def load_image(name)
|
14
|
+
asset_name = "#{@content_root}#{name}"
|
15
|
+
unless @cache[asset_name] == nil
|
16
|
+
return @cache[asset_name]
|
17
|
+
end
|
18
|
+
@cache[asset_name] = Gosu::Image.new(@window, asset_name)
|
19
|
+
|
20
|
+
if @nearest_filtering
|
21
|
+
@cache[asset_name].retro!
|
22
|
+
end
|
23
|
+
|
24
|
+
return load_image(name)
|
25
|
+
end
|
26
|
+
|
27
|
+
def load_tiles(name, tile_width, tile_height, tileable = true)
|
28
|
+
asset_name = "#{@content_root}#{name}"
|
29
|
+
unless @cache[asset_name] == nil
|
30
|
+
return @cache[asset_name]
|
31
|
+
end
|
32
|
+
@cache[asset_name] = Gosu::Image.load_tiles(@window, asset_name, tile_width, tile_height, tileable)
|
33
|
+
|
34
|
+
if @nearest_filtering
|
35
|
+
@cache[asset_name].each{ |image|
|
36
|
+
image.retro!
|
37
|
+
}
|
38
|
+
end
|
39
|
+
|
40
|
+
return load_tiles(name, tile_width, tile_height)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# TODO: Move to Gosu extensions dir
|
46
|
+
require 'opengl'
|
47
|
+
include GL
|
48
|
+
|
49
|
+
module Gosu
|
50
|
+
class Image
|
51
|
+
def retro!
|
52
|
+
glBindTexture(GL_TEXTURE_2D, self.gl_tex_info.tex_name)
|
53
|
+
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
|
54
|
+
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
|
55
|
+
self
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module SK
|
2
|
+
class Component
|
3
|
+
|
4
|
+
attr_accessor :game_object, :layer, :order_in_layer
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
@game_object = nil
|
8
|
+
@layer = 0
|
9
|
+
@order_in_layer = 0
|
10
|
+
end
|
11
|
+
|
12
|
+
def get_component type
|
13
|
+
@game_object.get_component type
|
14
|
+
end
|
15
|
+
|
16
|
+
def remove component
|
17
|
+
@game_object.remove_component component
|
18
|
+
end
|
19
|
+
|
20
|
+
def transform
|
21
|
+
@game_object.transform
|
22
|
+
end
|
23
|
+
|
24
|
+
def physics
|
25
|
+
@game_object.physics
|
26
|
+
end
|
27
|
+
|
28
|
+
def start
|
29
|
+
end
|
30
|
+
|
31
|
+
def update dt
|
32
|
+
end
|
33
|
+
|
34
|
+
def draw context
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module SK
|
2
|
+
class GameObject
|
3
|
+
|
4
|
+
attr_reader :name, :id, :children, :manager, :components
|
5
|
+
attr_accessor :parent, :transform
|
6
|
+
|
7
|
+
def initialize name, id
|
8
|
+
@name = name
|
9
|
+
@id = id
|
10
|
+
@components = []
|
11
|
+
@children = []
|
12
|
+
@parent = nil
|
13
|
+
@transform = Transform.new
|
14
|
+
@manager = nil
|
15
|
+
end
|
16
|
+
|
17
|
+
def add_component component
|
18
|
+
component.game_object = self
|
19
|
+
@components << component
|
20
|
+
end
|
21
|
+
|
22
|
+
def add_child game_object
|
23
|
+
if game_object.parent != nil
|
24
|
+
game_object.parent.remove_child game_object
|
25
|
+
end
|
26
|
+
game_object.parent = self
|
27
|
+
@children << game_object
|
28
|
+
end
|
29
|
+
|
30
|
+
def remove_child game_object
|
31
|
+
@children.delete game_object
|
32
|
+
end
|
33
|
+
|
34
|
+
def get_component type
|
35
|
+
@components.find{|x| x.is_a?(type)}
|
36
|
+
end
|
37
|
+
|
38
|
+
def get_components type
|
39
|
+
@components.collect{|x| x if x.is_a?(type)}
|
40
|
+
end
|
41
|
+
|
42
|
+
def remove_component component
|
43
|
+
@components.delete component
|
44
|
+
end
|
45
|
+
|
46
|
+
def physics
|
47
|
+
@manager.physics
|
48
|
+
end
|
49
|
+
|
50
|
+
def start
|
51
|
+
@components.each{|x| x.start }
|
52
|
+
end
|
53
|
+
|
54
|
+
def update dt
|
55
|
+
@components.each{|x| x.update dt }
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|