diff options
| author | Tom Black <[email protected]> | 2016-10-09 15:35:13 -0400 |
|---|---|---|
| committer | Tom Black <[email protected]> | 2016-10-09 15:35:13 -0400 |
| commit | 922d47027ead7cec732e086880a3a8127c0b8cf6 (patch) | |
| tree | 0e6e9a251e69fdb4936bd9c18df7b66c9172a78c | |
| parent | 31aebd27ec78e6b751d69d2fb360187270b1be00 (diff) | |
| download | ruby2d-922d47027ead7cec732e086880a3a8127c0b8cf6.tar.gz ruby2d-922d47027ead7cec732e086880a3a8127c0b8cf6.zip | |
Add sprites
Also namespace `type_id` definitions
| -rw-r--r-- | ext/ruby2d/ruby2d.c | 65 | ||||
| -rw-r--r-- | lib/ruby2d.rb | 1 | ||||
| -rw-r--r-- | lib/ruby2d/sprite.rb | 83 | ||||
| -rw-r--r-- | lib/ruby2d/text.rb | 2 | ||||
| -rw-r--r-- | spec/sprite_spec.rb | 11 | ||||
| m--------- | tests/media | 0 | ||||
| -rw-r--r-- | tests/testcard.rb | 12 |
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 |
