shirokuro 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|