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,57 @@
|
|
1
|
+
module SK
|
2
|
+
class RigidBody < Component
|
3
|
+
|
4
|
+
attr_accessor :mass, :inertia, :static, :fixed_rotation
|
5
|
+
attr_reader :body
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@mass = 1.0
|
9
|
+
@inertia = 1.0
|
10
|
+
@static = false
|
11
|
+
@fixed_rotation = false
|
12
|
+
end
|
13
|
+
|
14
|
+
def start
|
15
|
+
if @static
|
16
|
+
@body = CP::Body.new_static()
|
17
|
+
else
|
18
|
+
@body = CP::Body.new(@mass, @inertia)
|
19
|
+
physics.space.add_body(@body)
|
20
|
+
end
|
21
|
+
teleport(transform.position.x, transform.position.y)
|
22
|
+
end
|
23
|
+
|
24
|
+
def teleport x, y
|
25
|
+
@body.p.x = x
|
26
|
+
@body.p.y = y
|
27
|
+
transform.position.x = x
|
28
|
+
transform.position.y = y
|
29
|
+
end
|
30
|
+
|
31
|
+
def set_rotation rotation
|
32
|
+
transform.rotation = rotation
|
33
|
+
@body.t = rotation
|
34
|
+
end
|
35
|
+
|
36
|
+
def add_force force
|
37
|
+
@body.apply_force(force, CP::Vec2.new(0, 0))
|
38
|
+
end
|
39
|
+
|
40
|
+
def add_impulse impulse
|
41
|
+
@body.apply_impulse(impulse, CP::Vec2.new(0, 0))
|
42
|
+
end
|
43
|
+
|
44
|
+
def add_torque torque
|
45
|
+
@body.t += torque
|
46
|
+
end
|
47
|
+
|
48
|
+
def update dt
|
49
|
+
if @fixed_rotation
|
50
|
+
@body.a = 0.0
|
51
|
+
end
|
52
|
+
transform.position.x = @body.p.x
|
53
|
+
transform.position.y = @body.p.y
|
54
|
+
transform.rotation = @body.a
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module SK
|
2
|
+
class AnimationSpriteRenderer < Component
|
3
|
+
|
4
|
+
attr_accessor :origin, :images
|
5
|
+
|
6
|
+
def initialize images
|
7
|
+
@images = images
|
8
|
+
@origin = Vec2.new(0.5, 0.5)
|
9
|
+
end
|
10
|
+
|
11
|
+
def start
|
12
|
+
@animations = get_component(AnimationComponent)
|
13
|
+
end
|
14
|
+
|
15
|
+
def draw context
|
16
|
+
@images[@animations.frame].draw_rot(
|
17
|
+
transform.position.x, transform.position.y, 0,
|
18
|
+
transform.rotation.radians_to_degrees,
|
19
|
+
@origin.x, @origin.y,
|
20
|
+
transform.scale.x, transform.scale.y,
|
21
|
+
Gosu::Color::WHITE
|
22
|
+
)
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module SK
|
2
|
+
class MapRenderer < Component
|
3
|
+
|
4
|
+
attr_accessor :images
|
5
|
+
|
6
|
+
def initialize images
|
7
|
+
@images = images
|
8
|
+
end
|
9
|
+
|
10
|
+
def start
|
11
|
+
@map = get_component(MapComponent)
|
12
|
+
if @map == nil
|
13
|
+
raise "MapComponent required for MapRenderer"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def draw context
|
18
|
+
map = @map.map
|
19
|
+
|
20
|
+
map.layers.each do |layer|
|
21
|
+
if layer.type == "tilelayer" && layer.visible
|
22
|
+
layer.width.times do |col|
|
23
|
+
layer.height.times do |row|
|
24
|
+
cell = layer.get(col, row)
|
25
|
+
if cell > -1
|
26
|
+
@images[cell].draw(
|
27
|
+
transform.position.x + (map.tile_width * col),
|
28
|
+
transform.position.y + (map.tile_height * row), 0, 1, 1, layer.color)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
module SK
|
2
|
+
class ShapeRenderer < Component
|
3
|
+
def initialize
|
4
|
+
end
|
5
|
+
|
6
|
+
def draw context
|
7
|
+
rigid_body = get_component(RigidBody)
|
8
|
+
color = rigid_body.static ? Gosu::Color::BLUE : Gosu::Color::GREEN
|
9
|
+
|
10
|
+
collider = get_component(BoxCollider)
|
11
|
+
|
12
|
+
unless collider == nil
|
13
|
+
half_width = collider.width / 2.0
|
14
|
+
half_height = collider.height / 2.0
|
15
|
+
|
16
|
+
context.translate(transform.position.x, transform.position.y) do
|
17
|
+
context.rotate(transform.rotation.radians_to_degrees) do
|
18
|
+
# top
|
19
|
+
context.draw_line(
|
20
|
+
-half_width, -half_height, color,
|
21
|
+
half_width, -half_height, color,
|
22
|
+
)
|
23
|
+
# bottom
|
24
|
+
context.draw_line(
|
25
|
+
-half_width, half_height, color,
|
26
|
+
half_width, half_height, color,
|
27
|
+
)
|
28
|
+
# left
|
29
|
+
context.draw_line(
|
30
|
+
-half_width, -half_height, color,
|
31
|
+
-half_width, half_height, color,
|
32
|
+
)
|
33
|
+
# right
|
34
|
+
context.draw_line(
|
35
|
+
half_width, -half_height, color,
|
36
|
+
half_width, half_height, color,
|
37
|
+
)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
collider = get_component(CircleCollider)
|
43
|
+
|
44
|
+
unless collider == nil
|
45
|
+
radius = collider.radius
|
46
|
+
|
47
|
+
context.translate(transform.position.x, transform.position.y) do
|
48
|
+
context.rotate(transform.rotation.radians_to_degrees) do
|
49
|
+
# line
|
50
|
+
context.draw_line(
|
51
|
+
0, 0, color,
|
52
|
+
0, radius, color
|
53
|
+
)
|
54
|
+
x = Math::cos(0) * radius
|
55
|
+
y = Math::sin(0) * radius
|
56
|
+
(0..360).each do |i|
|
57
|
+
if i.even? # only draw half of them
|
58
|
+
_x = Math::cos(i.degrees_to_radians) * radius
|
59
|
+
_y = Math::sin(i.degrees_to_radians) * radius
|
60
|
+
context.draw_line(
|
61
|
+
x, y, color,
|
62
|
+
_x, _y, color
|
63
|
+
)
|
64
|
+
x = _x
|
65
|
+
y = _y
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
collider = get_component(PolygonCollider)
|
73
|
+
|
74
|
+
unless collider == nil
|
75
|
+
context.translate(transform.position.x, transform.position.y) do
|
76
|
+
context.rotate(transform.rotation.radians_to_degrees) do
|
77
|
+
(collider.vertices.size).times do |i|
|
78
|
+
p = collider.vertices[i]
|
79
|
+
if i == collider.vertices.size - 1
|
80
|
+
p_next = collider.vertices[0]
|
81
|
+
else
|
82
|
+
p_next = collider.vertices[i + 1]
|
83
|
+
end
|
84
|
+
|
85
|
+
context.draw_line(
|
86
|
+
p.x, p.y, color,
|
87
|
+
p_next.x, p_next.y, color
|
88
|
+
)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module SK
|
2
|
+
class SpriteRenderer < Component
|
3
|
+
|
4
|
+
attr_accessor :origin, :image
|
5
|
+
|
6
|
+
def initialize image
|
7
|
+
@image = image
|
8
|
+
@origin = Vec2.new(0.5, 0.5)
|
9
|
+
end
|
10
|
+
|
11
|
+
def draw context
|
12
|
+
@image.draw_rot(
|
13
|
+
transform.position.x, transform.position.y, 0,
|
14
|
+
transform.rotation.radians_to_degrees,
|
15
|
+
@origin.x, @origin.y,
|
16
|
+
transform.scale.x, transform.scale.y,
|
17
|
+
Gosu::Color::WHITE
|
18
|
+
)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module SK
|
2
|
+
module TMX
|
3
|
+
class Map
|
4
|
+
|
5
|
+
attr_accessor :width, :height, :tile_width, :tile_height, :layers
|
6
|
+
|
7
|
+
def initialize json
|
8
|
+
@width = json["width"]
|
9
|
+
@height = json["height"]
|
10
|
+
@tile_width = json["tilewidth"]
|
11
|
+
@tile_height = json["tileheight"]
|
12
|
+
|
13
|
+
@layers = []
|
14
|
+
json["layers"].each{ |layer|
|
15
|
+
@layers << MapLayer.new(layer)
|
16
|
+
}
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module SK
|
2
|
+
module TMX
|
3
|
+
class MapLayer
|
4
|
+
|
5
|
+
attr_accessor :properties, :width, :height, :data, :visible, :objects, :type, :color
|
6
|
+
|
7
|
+
def initialize json
|
8
|
+
@name = json["name"]
|
9
|
+
@opacity = json["opacity"].to_f
|
10
|
+
@visible = json["visible"]
|
11
|
+
@data = json["data"]
|
12
|
+
@width = json["width"].to_i
|
13
|
+
@height = json["height"].to_i
|
14
|
+
@properties = json["properties"]
|
15
|
+
@type = json["type"]
|
16
|
+
@objects = []
|
17
|
+
|
18
|
+
if json["objects"]
|
19
|
+
json["objects"].each do |obj|
|
20
|
+
@objects << MapLayerObject.new(obj)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
@color = Gosu::Color.new(255, 255 * @opacity, 255 * @opacity, 255 * @opacity)
|
24
|
+
end
|
25
|
+
|
26
|
+
def is_collision_layer?
|
27
|
+
if @properties != nil && @properties["collision"] == "true"
|
28
|
+
return true
|
29
|
+
end
|
30
|
+
false
|
31
|
+
end
|
32
|
+
|
33
|
+
def get(col, row)
|
34
|
+
@data[col + row * @width] - 1
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module SK
|
2
|
+
module TMX
|
3
|
+
class MapLayerObject
|
4
|
+
|
5
|
+
attr_accessor :x, :y, :width, :height, :rotation, :type
|
6
|
+
|
7
|
+
def initialize json
|
8
|
+
@x = json["x"].to_f
|
9
|
+
@y = json["y"].to_f
|
10
|
+
@width = json["width"].to_f
|
11
|
+
@height = json["height"].to_f
|
12
|
+
@rotation = json["rotation"].to_f
|
13
|
+
@type = json["type"]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/shirokuro.gemspec
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'shirokuro/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "shirokuro"
|
8
|
+
spec.version = SK::VERSION
|
9
|
+
spec.authors = ["erikskogl"]
|
10
|
+
spec.email = ["erikskoglund88@gmail.com"]
|
11
|
+
spec.summary = "Gosu helper lib"
|
12
|
+
spec.description = "Gosu helper lib"
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_dependency "gosu"
|
22
|
+
spec.add_dependency "chipmunk"
|
23
|
+
spec.add_dependency "ruby-opengl"
|
24
|
+
|
25
|
+
spec.add_development_dependency "bundler", "~> 1.6"
|
26
|
+
spec.add_development_dependency "rake"
|
27
|
+
spec.add_development_dependency "rspec"
|
28
|
+
spec.add_development_dependency "guard"
|
29
|
+
spec.add_development_dependency "guard-rspec"
|
30
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class ConcreteComponent < SK::Component
|
4
|
+
end
|
5
|
+
class ConcreteComponent2 < SK::Component
|
6
|
+
end
|
7
|
+
|
8
|
+
describe SK::Component do
|
9
|
+
|
10
|
+
it "can be instantiated without arguments" do
|
11
|
+
expect(SK::Component.new).to_not be_nil
|
12
|
+
end
|
13
|
+
|
14
|
+
it "is initialized with a nil game_object" do
|
15
|
+
expect(SK::Component.new.game_object).to be_nil
|
16
|
+
end
|
17
|
+
|
18
|
+
it "can be updated" do
|
19
|
+
expect(SK::Component.new).to respond_to(:update)
|
20
|
+
end
|
21
|
+
|
22
|
+
it "can be started" do
|
23
|
+
expect(SK::Component.new).to respond_to(:start)
|
24
|
+
end
|
25
|
+
|
26
|
+
it "can be updated and takes one parameter" do
|
27
|
+
expect(SK::Component.new).to respond_to(:update).with(1).argument
|
28
|
+
end
|
29
|
+
|
30
|
+
it "can be drawn using a context" do
|
31
|
+
expect(SK::Component.new).to respond_to(:draw).with(1).argument
|
32
|
+
end
|
33
|
+
|
34
|
+
it "can not be drawn without context" do
|
35
|
+
expect(SK::Component.new).to_not respond_to(:draw).with(0).arguments
|
36
|
+
end
|
37
|
+
|
38
|
+
it "can get a transform" do
|
39
|
+
component = SK::Component.new()
|
40
|
+
game_object = SK::GameObject.new("name", 0)
|
41
|
+
game_object.add_component component
|
42
|
+
|
43
|
+
expect(component.transform).to be(game_object.transform)
|
44
|
+
end
|
45
|
+
|
46
|
+
it "can remove itself from the game_object" do
|
47
|
+
component = SK::Component.new
|
48
|
+
game_object = SK::GameObject.new "name", 0
|
49
|
+
game_object.add_component component
|
50
|
+
component.remove(component)
|
51
|
+
expect(game_object.instance_variable_get(:@components).size).to be(0)
|
52
|
+
end
|
53
|
+
|
54
|
+
it "is assigned the game_object when added to one" do
|
55
|
+
component = SK::Component.new
|
56
|
+
game_object = SK::GameObject.new "name", 0
|
57
|
+
game_object.add_component component
|
58
|
+
expect(component.game_object).to be(game_object)
|
59
|
+
end
|
60
|
+
|
61
|
+
it "can get other components by type" do
|
62
|
+
game_object = SK::GameObject.new "name", 0
|
63
|
+
component = ConcreteComponent.new
|
64
|
+
component_2 = ConcreteComponent2.new
|
65
|
+
game_object.add_component component
|
66
|
+
game_object.add_component component_2
|
67
|
+
|
68
|
+
expect(component.get_component(ConcreteComponent2)).to be(component_2)
|
69
|
+
end
|
70
|
+
|
71
|
+
it "returns nil if getting component that does not exist" do
|
72
|
+
game_object = SK::GameObject.new "name", 0
|
73
|
+
component = ConcreteComponent.new
|
74
|
+
game_object.add_component component
|
75
|
+
|
76
|
+
expect(component.get_component(ConcreteComponent2)).to be(nil)
|
77
|
+
end
|
78
|
+
end
|