summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorTom Black <[email protected]>2016-10-09 15:35:13 -0400
committerTom Black <[email protected]>2016-10-09 15:35:13 -0400
commit922d47027ead7cec732e086880a3a8127c0b8cf6 (patch)
tree0e6e9a251e69fdb4936bd9c18df7b66c9172a78c
parent31aebd27ec78e6b751d69d2fb360187270b1be00 (diff)
downloadruby2d-922d47027ead7cec732e086880a3a8127c0b8cf6.tar.gz
ruby2d-922d47027ead7cec732e086880a3a8127c0b8cf6.zip
Add sprites
Also namespace `type_id` definitions
-rw-r--r--ext/ruby2d/ruby2d.c65
-rw-r--r--lib/ruby2d.rb1
-rw-r--r--lib/ruby2d/sprite.rb83
-rw-r--r--lib/ruby2d/text.rb2
-rw-r--r--spec/sprite_spec.rb11
m---------tests/media0
-rw-r--r--tests/testcard.rb12
7 files changed, 163 insertions, 11 deletions
diff --git a/ext/ruby2d/ruby2d.c b/ext/ruby2d/ruby2d.c
index e426f0d..784ca7c 100644
--- a/ext/ruby2d/ruby2d.c
+++ b/ext/ruby2d/ruby2d.c
@@ -2,10 +2,11 @@
#include <simple2d.h>
// @type_id values for rendering
-#define TRIANGLE 1
-#define QUAD 2
-#define IMAGE 3
-#define TEXT 4
+#define R2D_TRIANGLE 1
+#define R2D_QUAD 2
+#define R2D_IMAGE 3
+#define R2D_SPRITE 4
+#define R2D_TEXT 5
// Ruby 2D window
static VALUE self;
@@ -22,6 +23,9 @@ static VALUE c_data_klass;
struct image_data {
S2D_Image *img;
};
+struct sprite_data {
+ S2D_Sprite *spr;
+};
struct text_data {
S2D_Text *txt;
};
@@ -58,6 +62,25 @@ static VALUE init_image(char *path) {
/*
+ * Free sprite structure attached to Ruby 2D `Sprite` class
+ */
+static void free_sprite(struct sprite_data *data) {
+ S2D_FreeSprite(data->spr);
+ xfree(data);
+}
+
+
+/*
+ * Initialize sprite structure data
+ */
+static VALUE init_sprite(char *path) {
+ struct sprite_data *data = ALLOC(struct sprite_data);
+ data->spr = S2D_CreateSprite(path);
+ return Data_Wrap_Struct(c_data_klass, NULL, free_sprite, data);
+}
+
+
+/*
* Free text structure attached to Ruby 2D `Text` class
*/
static void free_text(struct text_data *data) {
@@ -145,7 +168,7 @@ static void render() {
// Switch on the object's type_id
switch(type_id) {
- case TRIANGLE: {
+ case R2D_TRIANGLE: {
VALUE c1 = rb_iv_get(el, "@c1");
VALUE c2 = rb_iv_get(el, "@c2");
VALUE c3 = rb_iv_get(el, "@c3");
@@ -175,7 +198,7 @@ static void render() {
}
break;
- case QUAD: {
+ case R2D_QUAD: {
VALUE c1 = rb_iv_get(el, "@c1");
VALUE c2 = rb_iv_get(el, "@c2");
VALUE c3 = rb_iv_get(el, "@c3");
@@ -213,10 +236,10 @@ static void render() {
}
break;
- case IMAGE: {
+ case R2D_IMAGE: {
if (rb_iv_get(el, "@data") == Qnil) {
VALUE data = init_image(RSTRING_PTR(rb_iv_get(el, "@path")));
- rb_iv_set(el, "@data", data);
+ rb_iv_set(el, "@data", data);
}
struct image_data *data;
@@ -228,7 +251,31 @@ static void render() {
}
break;
- case TEXT: {
+ case R2D_SPRITE: {
+ if (rb_iv_get(el, "@data") == Qnil) {
+ VALUE data = init_sprite(RSTRING_PTR(rb_iv_get(el, "@path")));
+ rb_iv_set(el, "@data", data);
+ }
+
+ struct sprite_data *data;
+ Data_Get_Struct(rb_iv_get(el, "@data"), struct sprite_data, data);
+
+ data->spr->x = NUM2DBL(rb_iv_get(el, "@x"));
+ data->spr->y = NUM2DBL(rb_iv_get(el, "@y"));
+
+ S2D_ClipSprite(
+ data->spr,
+ NUM2INT(rb_iv_get(el, "@clip_x")),
+ NUM2INT(rb_iv_get(el, "@clip_y")),
+ NUM2INT(rb_iv_get(el, "@clip_w")),
+ NUM2INT(rb_iv_get(el, "@clip_h"))
+ );
+
+ S2D_DrawSprite(data->spr);
+ }
+ break;
+
+ case R2D_TEXT: {
if (rb_iv_get(el, "@data") == Qnil) {
VALUE data = init_text(
RSTRING_PTR(rb_iv_get(el, "@font")),
diff --git a/lib/ruby2d.rb b/lib/ruby2d.rb
index 342e03a..4e41d22 100644
--- a/lib/ruby2d.rb
+++ b/lib/ruby2d.rb
@@ -9,6 +9,7 @@ require 'ruby2d/rectangle'
require 'ruby2d/square'
require 'ruby2d/triangle'
require 'ruby2d/image'
+require 'ruby2d/sprite'
require 'ruby2d/text'
require 'ruby2d/exceptions'
require 'ruby2d/ruby2d' # load native extension
diff --git a/lib/ruby2d/sprite.rb b/lib/ruby2d/sprite.rb
new file mode 100644
index 0000000..6e3eae4
--- /dev/null
+++ b/lib/ruby2d/sprite.rb
@@ -0,0 +1,83 @@
+# sprite.rb
+
+module Ruby2D
+ class Sprite
+
+ attr_accessor :x, :y
+
+ def initialize(x, y, path)
+
+ unless File.exists? path
+ raise Error, "Cannot find image file `#{path}`"
+ end
+
+ @type_id = 4
+ @x, @y, @path = x, y, path
+ @clip_x, @clip_y, @clip_w, @clip_h = 0, 0, 0, 0
+ @default = nil
+ @animations = {}
+ @current_animation = nil
+ @current_frame = 0
+ @current_frame_time = 0
+
+ if defined? DSL
+ Application.add(self)
+ end
+ end
+
+ def start(x, y, w, h)
+ @default = [x, y, w, h]
+ clip(x, y, w, h)
+ end
+
+ def add(animations)
+ @animations.merge!(animations)
+ end
+
+ def animate(animation)
+ if @current_animation != animation
+ @current_frame = 0
+ @current_frame_time = 0
+ @current_animation = animation
+ end
+ animate_frames(@animations[animation])
+ end
+
+ def reset
+ clip(@default[0], @default[1], @default[2], @default[3])
+ @current_animation = nil
+ end
+
+ def remove
+ if defined? DSL
+ Application.remove(self)
+ end
+ end
+
+ private
+
+ def clip(x, y, w, h)
+ @clip_x, @clip_y, @clip_w, @clip_h = x, y, w, h
+ end
+
+ def animate_frames(frames)
+ if @current_frame_time < frames[@current_frame][4]
+ clip_with_current_frame(frames)
+ @current_frame_time += 1
+ else
+ @current_frame += 1
+ if @current_frame == frames.length
+ @current_frame = 0
+ end
+ clip_with_current_frame(frames)
+ @current_frame_time = 0
+ end
+ end
+
+ def clip_with_current_frame(frames)
+ clip(frames[@current_frame][0], frames[@current_frame][1],
+ frames[@current_frame][2], frames[@current_frame][3])
+ end
+
+ end
+end
diff --git a/lib/ruby2d/text.rb b/lib/ruby2d/text.rb
index 9ba4e41..dedfa39 100644
--- a/lib/ruby2d/text.rb
+++ b/lib/ruby2d/text.rb
@@ -13,7 +13,7 @@ module Ruby2D
@font = resolve_path(font)
end
- @type_id = 4
+ @type_id = 5
@x, @y, @size = x, y, size
@text, @color = msg, c
update_color(c)
diff --git a/spec/sprite_spec.rb b/spec/sprite_spec.rb
new file mode 100644
index 0000000..42268be
--- /dev/null
+++ b/spec/sprite_spec.rb
@@ -0,0 +1,11 @@
+require 'ruby2d'
+
+RSpec.describe Ruby2D::Sprite do
+
+ describe '#new' do
+ it 'creates a new sprite' do
+ Ruby2D::Sprite.new(0, 0, "tests/media/sprite_sheet.png")
+ end
+ end
+
+end
diff --git a/tests/media b/tests/media
-Subproject 1f71d49737eee12071c637f7c936cdc31e4b0d3
+Subproject fd57d1c22c11b1cc84b160236718b7e26c438a3
diff --git a/tests/testcard.rb b/tests/testcard.rb
index c9204cc..95a6d28 100644
--- a/tests/testcard.rb
+++ b/tests/testcard.rb
@@ -141,6 +141,16 @@ t2 = Text.new(0, 325, 20) # Default message
t2.text = "Text can be changed"
fps = Text.new(0, 375, 20)
+
+# Sprites
+s1 = Sprite.new(350, 200, "media/sprite_sheet.png")
+s1.add(forwards: [
+ [ 0, 0, 50, 50, 30],
+ [ 50, 0, 50, 50, 40],
+ [100, 0, 50, 50, 50],
+ [150, 0, 50, 50, 60]
+])
+
# Pointer for mouse
pointer = Square.new(0, 0, 10, 'white')
@@ -151,7 +161,7 @@ end
update do
pointer.x = (get :mouse_x) - 5
pointer.y = (get :mouse_y) - 7
-
+ s1.animate(:forwards)
fps.text = "FPS: #{get :fps}"
end