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.
Files changed (62) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +23 -0
  3. data/.rspec +0 -0
  4. data/Gemfile +4 -0
  5. data/Guardfile +21 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +21 -0
  8. data/Rakefile +8 -0
  9. data/examples/audio/main.rb +40 -0
  10. data/examples/audio/run.sh +2 -0
  11. data/examples/layers_and_sorting/main.rb +62 -0
  12. data/examples/layers_and_sorting/run.sh +2 -0
  13. data/examples/physx/main.rb +114 -0
  14. data/examples/physx/run.sh +2 -0
  15. data/examples/shared/content/audio/boing.ogg +0 -0
  16. data/examples/shared/content/audio/song_1.ogg +0 -0
  17. data/examples/shared/content/gfx/character_sprite.png +0 -0
  18. data/examples/shared/content/gfx/tileset.png +0 -0
  19. data/examples/shared/content/maps/stage2.json +299 -0
  20. data/examples/sprite/main.rb +43 -0
  21. data/examples/sprite/run.sh +2 -0
  22. data/examples/sprite_animation/main.rb +45 -0
  23. data/examples/sprite_animation/run.sh +2 -0
  24. data/examples/tmx_map/main.rb +70 -0
  25. data/examples/tmx_map/run.sh +2 -0
  26. data/lib/shirokuro.rb +42 -0
  27. data/lib/shirokuro/audio/audio_manager.rb +80 -0
  28. data/lib/shirokuro/content/content_manager.rb +58 -0
  29. data/lib/shirokuro/ecs/component.rb +37 -0
  30. data/lib/shirokuro/ecs/game_object.rb +58 -0
  31. data/lib/shirokuro/ecs/game_object_manager.rb +51 -0
  32. data/lib/shirokuro/ecs/id_generator.rb +10 -0
  33. data/lib/shirokuro/math/matrix.rb +72 -0
  34. data/lib/shirokuro/math/transform.rb +16 -0
  35. data/lib/shirokuro/math/vec2.rb +38 -0
  36. data/lib/shirokuro/physics/physics.rb +22 -0
  37. data/lib/shirokuro/standard_components/animations/animation.rb +30 -0
  38. data/lib/shirokuro/standard_components/animations/animation_component.rb +28 -0
  39. data/lib/shirokuro/standard_components/cameras/camera.rb +59 -0
  40. data/lib/shirokuro/standard_components/maps/map_component.rb +10 -0
  41. data/lib/shirokuro/standard_components/physics/box_collider.rb +40 -0
  42. data/lib/shirokuro/standard_components/physics/circle_collider.rb +29 -0
  43. data/lib/shirokuro/standard_components/physics/polygon_collider.rb +35 -0
  44. data/lib/shirokuro/standard_components/physics/rigid_body.rb +57 -0
  45. data/lib/shirokuro/standard_components/rendering/animation_sprite_renderer.rb +26 -0
  46. data/lib/shirokuro/standard_components/rendering/map_renderer.rb +36 -0
  47. data/lib/shirokuro/standard_components/rendering/shape_renderer.rb +95 -0
  48. data/lib/shirokuro/standard_components/rendering/sprite_renderer.rb +21 -0
  49. data/lib/shirokuro/standard_components/tmx/tmx_map.rb +20 -0
  50. data/lib/shirokuro/standard_components/tmx/tmx_map_layer.rb +38 -0
  51. data/lib/shirokuro/standard_components/tmx/tmx_map_layer_object.rb +17 -0
  52. data/lib/shirokuro/standard_components/transformation/rotation.rb +14 -0
  53. data/lib/shirokuro/version.rb +3 -0
  54. data/shirokuro.gemspec +30 -0
  55. data/spec/shirokuro/ecs/component_spec.rb +78 -0
  56. data/spec/shirokuro/ecs/game_object_manager_spec.rb +113 -0
  57. data/spec/shirokuro/ecs/game_object_spec.rb +110 -0
  58. data/spec/shirokuro/math/matrix_spec.rb +49 -0
  59. data/spec/shirokuro/math/transform_spec.rb +28 -0
  60. data/spec/shirokuro/math/vec2_spec.rb +49 -0
  61. data/spec/spec_helper.rb +12 -0
  62. 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,2 @@
1
+ clear
2
+ bundle exec ruby main.rb
@@ -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,2 @@
1
+ clear
2
+ bundle exec ruby main.rb
@@ -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
@@ -0,0 +1,2 @@
1
+ clear
2
+ bundle exec ruby main.rb
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