Permalink
Browse files

started on seeker demo

  • Loading branch information...
1 parent 0f6105d commit 52af209a16544618583df24b7e026af662e2f677 @eilara committed Mar 21, 2012
View
@@ -8,5 +8,6 @@ MODULE = SDLx::Betweener PACKAGE = SDLx::Betweener
INCLUDE: src/xs/Timeline.xs
INCLUDE: src/xs/Tween.xs
+INCLUDE: src/xs/Seeker.xs
MODULE = SDLx::Betweener PACKAGE = SDLx::Betweener
View
@@ -31,7 +31,7 @@ package main;
t => (int(rand 8_000) + 1000),
to => $to,
on => $star->[0],
- ease => 'exponential_in',
+ ease => 'p2_in',
forever => 1,
);
$star->[1] = $tween;
View
@@ -0,0 +1,76 @@
+#!/usr/bin/perl
+
+package main;
+use strict;
+use warnings;
+use FindBin qw($Bin);
+use lib ("$Bin/..", "$Bin/../lib", "$Bin/../blib/arch", "$Bin/../blib/lib");
+use SDL;
+use SDL::GFX::Primitives;
+use SDL::Events;
+use SDLx::App;
+use SDLx::Text;
+use SDLx::Betweener;
+
+my $w = 640;
+my $h = 480;
+
+my $app = SDLx::App->new(title=>'Easing Functions', width=>$w, height=>$h);
+my $tweener = SDLx::Betweener->new(app => $app);
+
+my $player = [320, 200];
+my $creep = [[0, 0]];
+
+$app->add_show_handler(sub {
+ $app->draw_rect(undef, 0xFFFFFFFF);
+ my ($x, $y) = @{$creep->[0]};
+ SDL::GFX::Primitives::pixel_color($app, $x, $y, 0x000000FF);
+ $app->draw_circle([$x,$y], 32, 0xFF0000FF, 1);
+ $app->draw_circle_filled($player, 16, 0xFFFFFFFF);
+ $app->draw_circle($player, 16, 0x000000FF, 1);
+ $app->update;
+});
+
+$app->add_event_handler(sub {
+ my ($e, $app) = @_;
+ if($e->type == SDL_QUIT) {
+ $app->stop;
+ } elsif ($e->type == SDL_MOUSEMOTION) {
+ $player->[0] = $e->motion_x;
+ $player->[1] = $e->motion_y;
+ }
+ return 0;
+});
+
+my $seeker = $tweener->tween_seek(
+ on => $creep->[0],
+ speed => 200 / 1_000,
+ to => $player,
+ done => sub {
+ },
+);
+
+$seeker->start;
+
+$app->run;
+
+__END__
+
+
+$_->start(0) for @tweens;
+
+
+
+}
+
+# ------------------------------------------------------------------------------
+
+
+ push @tweens, $tweener->tween_path(
+ t => 6_000,
+ to => [$w - $radius, $y],
+ on => {position => $circle},
+ bounce => 1,
+ forever => 1,
+ ease => $ease,
+ );
View
@@ -162,6 +162,44 @@ sub tween_fade {
return $self->tween_rgba(%args);
}
+sub tween_seek {
+ my ($self, %args) = @_;
+ my $on = $args{on} || die 'No "on" given';
+ my $speed = $args{speed} || die 'No "speed" given';
+ my $proxy = $Proxy_Lookup{ref $on} || die "unknown proxy type: $on";
+
+ my ($from, $to);
+
+ # try to get 'from/to' from range
+ ($args{from}, $args{to}) = @{ $args{range} } if $args{range};
+ # must have "to" by now
+ $to = $args{to};
+ die 'No "to" given for seeker target' unless defined $to;
+ $from = $args{from};
+
+ unless (defined $from) {
+ # if we have no 'from' lets try to get it from the proxy
+ if ($proxy == DIRECT_PROXY) {
+ $from = [@$on];
+ } elsif ($proxy == METHOD_PROXY) {
+ my $method = [keys %$on]->[0];
+ $from = [values %$on]->[0]->$method;
+ } elsif ($proxy == CALLBACK_PROXY)
+ { die 'No "from" given for callback proxy of seeker target' }
+ }
+
+ $on = [%$on] if $proxy == METHOD_PROXY;
+
+ return $self->{timeline}->_tween_seek(
+ $proxy,
+ $on,
+ $speed,
+ $from,
+ $to,
+ $self->extract_completer(\%args),
+ );
+}
+
sub tween_rgba {
my ($self, %args) = @_;
my $builder = $Tween_Lookup[TWEEN_RGBA];
@@ -0,0 +1,9 @@
+package SDLx::Betweener::Seeker;
+
+use strict;
+use warnings;
+
+use SDLx::Betweener;
+
+1;
+
@@ -2,7 +2,6 @@ package SDLx::Betweener::Tween;
use strict;
use warnings;
-use SDL;
use SDLx::Betweener;
@@ -0,0 +1,3 @@
+
+#include "ISeekerTarget.h"
+
View
@@ -0,0 +1,15 @@
+
+#ifndef ISEEKERTARGET_H
+#define ISEEKERTARGET_H
+
+#include "VectorTypes.h"
+
+class ISeekerTarget {
+
+ public:
+ virtual ~ISeekerTarget() {}
+ virtual Vector2i get_target_xy() = 0;
+
+};
+
+#endif
View
@@ -0,0 +1,92 @@
+
+#include <stdlib.h>
+#include "Seeker.h"
+#include "easing.h"
+
+Seeker::Seeker(IClock *clock, ICompleter *completer, IProxy<int,2> *proxy,
+ ISeekerTarget *target, Vector2i seeker_start_xy, float speed) :
+ Ticker(clock, completer),
+ target(target),
+ proxy(proxy),
+ speed(speed),
+ last_xy(seeker_start_xy),
+ last_tick_time(0),
+ pause_start_time(0) {
+}
+
+Seeker::~Seeker() {
+ delete proxy;
+ delete target;
+}
+
+void Seeker::start(Uint32 now) {
+ Ticker::start(now);
+ last_tick_time = now;
+}
+
+void Seeker::stop() {
+ Ticker::stop();
+}
+
+void Seeker::pause(Uint32 now) {
+ Ticker::pause(now);
+ pause_start_time = now;
+}
+
+void Seeker::resume(Uint32 now) {
+ Ticker::resume(now);
+ last_tick_time += now - pause_start_time;
+ pause_start_time = 0;
+}
+
+void Seeker::on_tick(Uint32 now) {
+ Vector2i target_xy = target->get_target_xy();
+ float last_dist = distance(target_xy, last_xy);
+ if (last_dist <= 1) {
+ stop();
+ on_complete(now);
+ return;
+ }
+
+ Uint32 delta_t = now - last_tick_time;
+ float ratio = speed * ((float) delta_t) / last_dist;
+ Vector2i next_xy = last_xy + (target_xy - last_xy) * ratio;
+ proxy->update(next_xy);
+
+ float next_dist = distance(target_xy, next_xy);
+ if (next_dist <= 1) {
+ stop();
+ on_complete(now);
+ return;
+ }
+
+ Vector2i last_diff = target_xy - last_xy;
+ Vector2i next_diff = target_xy - next_xy;
+
+ int ldx = last_diff[0];
+ int ldy = last_diff[1];
+ int ndx = next_diff[0];
+ int ndy = next_diff[1];
+
+ /* we could overshoot the target, in which case dir vector changes sign */
+ if (
+ (
+ ((ldx > 0 && ndx < 0) || (ldx < 0 && ndx > 0)) &&
+ ((ldy > 0 && ndy < 0) || (ldy < 0 && ndy > 0))
+ ) ||
+ (
+ ((ldx == 0) && (ndx == 0) && (ldy*ndy < 0)) ||
+ ((ldy == 0) && (ndy == 0) && (ldx*ndx < 0))
+ )
+ ) {
+ stop();
+ on_complete(now);
+ // maybe update proxy now with target xy?
+ return;
+ }
+
+ last_xy = next_xy;
+ last_tick_time = now;
+}
+
+
View
@@ -0,0 +1,35 @@
+
+#ifndef SEEKER_H
+#define SEEKER_H
+
+#include "Types.h"
+#include "VectorTypes.h"
+#include "Vector.h"
+#include "IClock.h"
+#include "Ticker.h"
+#include "IProxy.h"
+#include "ISeekerTarget.h"
+
+class Seeker : public Ticker {
+
+ public:
+ Seeker(IClock *clock, ICompleter *completer, IProxy<int,2> *proxy, ISeekerTarget *target, Vector2i seeker_start_xy, float speed);
+ ~Seeker();
+ void start (Uint32 now);
+ void stop ();
+ void pause (Uint32 now);
+ void resume (Uint32 now);
+
+ protected:
+ void on_tick (Uint32 now);
+ private:
+ ISeekerTarget *target;
+ IProxy<int,2> *proxy;
+ float speed;
+ Vector2i last_xy;
+ Uint32 last_tick_time;
+ Uint32 pause_start_time;
+
+};
+
+#endif
@@ -0,0 +1,4 @@
+
+#include "PerlDirectSeekerTarget.h"
+
+
@@ -0,0 +1,34 @@
+
+#ifndef IPERLDIRECTSEEKERTARGET_H
+#define IPERLDIRECTSEEKERTARGET_H
+
+#include "EXTERN.h"
+#include "perl.h"
+#include "XSUB.h"
+#include "Types.h"
+#include "VectorTypes.h"
+#include "Vector.h"
+#include "ISeekerTarget.h"
+
+
+class PerlDirectSeekerTarget : public ISeekerTarget {
+
+ public:
+ PerlDirectSeekerTarget(SV* target_sv) {
+ target = (AV*) SvRV(target_sv);
+ }
+ ~PerlDirectSeekerTarget() {
+ }
+ Vector2i get_target_xy() {
+ SV** e1 = av_fetch(target, 0, 0);
+ SV** e2 = av_fetch(target, 1, 0);
+ Vector2i xy = { {(int) SvIV(*e1), (int) SvIV(*e2)} };
+ return xy;
+ }
+
+ private:
+ AV *target;
+
+};
+
+#endif
View
@@ -0,0 +1,45 @@
+
+#include "Types.h"
+#include "Seeker.h"
+#include "SDL.h"
+
+MODULE = SDLx::Betweener PACKAGE = SDLx::Betweener::Seeker
+
+#define COMPUTE_NOW() \
+ Uint32 now = items == 2? \
+ (Uint32) SvIV(ST(1)): \
+ (Uint32) SDL_GetTicks(); \
+
+void
+Seeker::start(...)
+ CODE:
+ COMPUTE_NOW()
+ THIS->start(now);
+
+void
+Seeker::stop()
+
+void
+Seeker::pause(...)
+ CODE:
+ COMPUTE_NOW()
+ THIS->pause(now);
+
+void
+Seeker::resume(...)
+ CODE:
+ COMPUTE_NOW()
+ THIS->resume(now);
+
+bool
+Seeker::is_paused()
+
+bool
+Seeker::is_active()
+
+void
+Seeker::DESTROY()
+ CODE:
+ delete THIS;
+
+
Oops, something went wrong.

0 comments on commit 52af209

Please sign in to comment.