gnome-games r8701 - trunk/gnometris
- From: jclinton svn gnome org
- To: svn-commits-list gnome org
- Subject: gnome-games r8701 - trunk/gnometris
- Date: Tue, 10 Feb 2009 23:49:19 +0000 (UTC)
Author: jclinton
Date: Tue Feb 10 23:49:19 2009
New Revision: 8701
URL: http://svn.gnome.org/viewvc/gnome-games?rev=8701&view=rev
Log:
Massive rewrite of movement animation and performance improvements
This change reduces the number of callbacks we end up handling by a very
significant amount. The strategy for movement of pieces that are in the
FALLING state is to use a static Behaviours array that can be stopped,
adjusted by appending new knots. And the resumed. This has the huge
benefit of making it possible accelerate the piece to a very rapid pace
making sure that it never takes more than 60ms to reach the final
resting place.
Modified:
trunk/gnometris/blockops.cpp
trunk/gnometris/blockops.h
Modified: trunk/gnometris/blockops.cpp
==============================================================================
--- trunk/gnometris/blockops.cpp (original)
+++ trunk/gnometris/blockops.cpp Tue Feb 10 23:49:19 2009
@@ -27,12 +27,13 @@
#define FONT "Sans Bold"
GList *Block::destroy_actors = NULL;
-GList *Block::destroy_behaviours = NULL;
-ClutterTimeline *Block::move_block_tml = NULL;
-ClutterAlpha *Block::move_block_alpha = NULL;
+GList *Block::fall_behaviours = NULL;
+ClutterTimeline *Block::fall_tml = NULL;
+ClutterAlpha *Block::fall_alpha = NULL;
+ClutterEffectTemplate *Block::explode_tmpl = NULL;
void
-Block::animation_destroy (ClutterTimeline *tml, BlockOps *f)
+Block::explode_end (ClutterTimeline *tml, BlockOps *f)
{
ClutterActor *tmp_actor = NULL;
g_list_foreach (destroy_actors,
@@ -48,14 +49,17 @@
}
void
-Block::behaviours_destroy (ClutterTimeline *tml, gpointer *data)
+Block::fall_end (ClutterTimeline *tml, gpointer *data)
{
ClutterBehaviour *tmp_behav = NULL;
- g_list_foreach (destroy_behaviours,
- (GFunc)clutter_behaviour_remove_all,
- tmp_behav);
- g_list_free (destroy_behaviours);
- destroy_behaviours = NULL;
+ if (fall_behaviours) {
+ g_list_foreach (fall_behaviours,
+ (GFunc)clutter_behaviour_remove_all,
+ tmp_behav);
+ //FIXME unref this too when it doesn't blow up
+ }
+ g_list_free (fall_behaviours);
+ fall_behaviours = NULL;
}
Block::Block ():
@@ -63,37 +67,24 @@
actor(NULL),
x(0),
y(0),
- move_block_path(NULL)
+ fall_path(NULL)
{
- //knot_line;
-
- if (!timeline)
- timeline = clutter_timeline_new_for_duration (180);
- if (!tmpl)
- tmpl = clutter_effect_template_new (timeline, CLUTTER_ALPHA_RAMP_INC);
- if (!move_block_tml)
- move_block_tml = clutter_timeline_new_for_duration (120);
- if (!move_block_alpha)
- move_block_alpha = clutter_alpha_new_full (move_block_tml,
- CLUTTER_ALPHA_RAMP_INC,
+ if (!fall_tml)
+ fall_tml = clutter_timeline_new_for_duration (180);
+ if (!fall_alpha)
+ fall_alpha = clutter_alpha_new_full (fall_tml, CLUTTER_ALPHA_EXP_INC,
NULL, NULL);
+ if (!explode_tmpl)
+ explode_tmpl = clutter_effect_template_new (fall_tml,
+ CLUTTER_ALPHA_SINE_INC);
}
Block::~Block ()
{
if (actor)
clutter_actor_destroy (CLUTTER_ACTOR(actor));
- if (move_block_path)
- g_object_unref (move_block_path);
-}
-
-void
-Block::shift (gint cell_width, gint cell_height, gint shift_x, gint shift_y)
-{
- const ClutterKnot knot_line[] = {{x - shift_x * cell_width, y - shift_y * cell_height}, {x, y}};
- move_block_path = clutter_behaviour_path_new (move_block_alpha, knot_line, 2);
- clutter_behaviour_apply (move_block_path, actor);
- destroy_behaviours = g_list_append (destroy_behaviours, move_block_path);
+ if (fall_path)
+ g_object_unref (fall_path);
}
void
@@ -115,25 +106,32 @@
b.what = EMPTY;
color = b.color;
b.color = 0;
- if (actor) {
+/* if (actor) {
int cur_x, cur_y = 0;
g_object_get (G_OBJECT (actor), "x", &cur_x, "y", &cur_y, NULL);
clutter_actor_raise_top (actor);
- clutter_effect_fade (tmpl, actor, 0, NULL, NULL);
- clutter_effect_move (tmpl, actor,
+ clutter_effect_fade (explode_tmpl, actor, 0, NULL, NULL);
+ clutter_effect_move (explode_tmpl, actor,
cur_x + g_random_int_range(f->cell_width * -5, f->cell_width * 5),
cur_y + g_random_int_range(f->cell_height * -5, f->cell_height * 5),
NULL, NULL);
destroy_actors = g_list_append (destroy_actors, actor);
+ }*/
+ if (b.actor) {
+ const ClutterKnot knot_line[] = {{b.x, b.y}, {x, y}};
+ fall_path = clutter_behaviour_path_new (fall_alpha, knot_line, 2);
+ clutter_behaviour_apply (fall_path, b.actor);
+ fall_behaviours = g_list_append (fall_behaviours, fall_path);
}
- if (b.actor)
- clutter_effect_move (tmpl, b.actor, x, y, NULL, NULL);
actor = b.actor;
b.actor = NULL;
}
return *this;
}
+ClutterTimeline *BlockOps::long_anim_tml = NULL;
+ClutterEffectTemplate *BlockOps::effect_earthquake = NULL;
+
BlockOps::BlockOps() :
background(NULL),
foreground(NULL),
@@ -170,6 +168,16 @@
long_anim_tml = clutter_timeline_new_for_duration (600);
effect_earthquake = clutter_effect_template_new (long_anim_tml, earthquake_alpha_func);
+
+ move_block_tml = clutter_timeline_new_for_duration (60);
+ move_block_alpha = clutter_alpha_new_full (move_block_tml,
+ CLUTTER_ALPHA_RAMP_INC, NULL, NULL);
+ g_signal_connect (move_block_tml, "completed",
+ G_CALLBACK (BlockOps::move_end), this);
+
+ for (int x = 0; x < 4; ++x)
+ for (int y = 0; y < 4; ++y)
+ move_path[x][y] = clutter_behaviour_path_new (move_block_alpha, NULL, 0);
}
BlockOps::~BlockOps()
@@ -177,6 +185,13 @@
for (int i = 0; i < COLUMNS; ++i)
delete[] field[i];
+ g_object_unref (effect_earthquake);
+ g_object_unref (long_anim_tml);
+
+ if (move_path)
+ g_object_unref (move_path);
+
+
delete[] field;
}
@@ -351,8 +366,8 @@
int cur_x, cur_y = 0;
g_object_get (G_OBJECT (field[x][l].actor), "x", &cur_x, "y", &cur_y, NULL);
clutter_actor_raise_top (field[x][l].actor);
- clutter_effect_fade (tmpl, field[x][l].actor, 0, NULL, NULL);
- clutter_effect_move (tmpl, field[x][l].actor,
+ clutter_effect_fade (Block::explode_tmpl, field[x][l].actor, 0, NULL, NULL);
+ clutter_effect_move (Block::explode_tmpl, field[x][l].actor,
cur_x + g_random_int_range(-60, 60),
cur_y + g_random_int_range(-60, 60),
NULL, NULL);
@@ -404,9 +419,11 @@
if (numFullLines > 0)
{
- g_signal_connect (timeline, "completed",
- G_CALLBACK (Block::animation_destroy), this);
- clutter_timeline_start (timeline);
+ g_signal_connect (Block::fall_tml, "completed",
+ G_CALLBACK (Block::fall_end), (gpointer) NULL);
+ g_signal_connect (Block::fall_tml, "completed",
+ G_CALLBACK (Block::explode_end), this);
+ clutter_timeline_start (Block::fall_tml);
quake_ratio = ((float) numCascades) / (float) LINES;
}
@@ -492,6 +509,7 @@
field[i][j].createActor (playingField,
renderer->getCacheCellById (color));
} else {
+ //FIXME jclinton these seem redundant
if (field[i][j].actor) {
clutter_actor_destroy (CLUTTER_ACTOR(field[i][j].actor));
field[i][j].actor = NULL;
@@ -503,6 +521,16 @@
}
void
+BlockOps::move_end (ClutterTimeline *tml, BlockOps *f)
+{
+ for (int x = 0; x < 4; ++x)
+ for (int y = 0; y < 4; ++y) {
+ clutter_behaviour_remove_all (f->move_path[x][y]);
+ clutter_behaviour_path_clear ((ClutterBehaviourPath *) f->move_path[x][y]);
+ }
+}
+
+void
BlockOps::updateBlockInField ()
{
int shift_x = posx - posx_old;
@@ -510,7 +538,7 @@
if (shift_x == 0 && shift_y == 0)
return;
- ClutterActor *blocks_tmp[4][4] = {{0, }};
+ ClutterActor *blocks_actor[4][4] = {{0, }};
for (int x = 0; x < 4; ++x) {
for (int y = 0; y < 4; ++y) {
@@ -518,7 +546,7 @@
int i = posx - 2 + x;
int j = y + posy;
- blocks_tmp[x][y] = field[i-shift_x][j-shift_y].actor;
+ blocks_actor[x][y] = field[i-shift_x][j-shift_y].actor;
field[i-shift_x][j-shift_y].what = EMPTY;
field[i-shift_x][j-shift_y].color = 0;
field[i-shift_x][j-shift_y].actor = NULL;
@@ -533,14 +561,20 @@
field[i][j].what = FALLING;
field[i][j].color = color;
- field[i][j].actor = blocks_tmp[x][y];
- field[i][j].shift (cell_width, cell_height, shift_x, shift_y);
+ field[i][j].actor = blocks_actor[x][y];
+ if (field[i][j].actor) {
+ int cur_x, cur_y = 0;
+ g_object_get (G_OBJECT (field[i][j].actor), "x", &cur_x, "y", &cur_y, NULL);
+ const ClutterKnot knot_line[] = {{cur_x, cur_y}, {field[i][j].x, field[i][j].y}};
+ clutter_behaviour_remove_all (move_path[x][y]);
+ clutter_behaviour_path_clear ((ClutterBehaviourPath *) move_path[x][y]);
+ clutter_behaviour_path_append_knots ((ClutterBehaviourPath *) move_path[x][y], &knot_line[0], &knot_line[1], NULL);
+ clutter_behaviour_apply (move_path[x][y], field[i][j].actor);
+ }
}
}
}
- clutter_timeline_start (Block::move_block_tml);
- g_signal_connect (Block::move_block_tml, "completed",
- G_CALLBACK (Block::behaviours_destroy), (gpointer) NULL);
+ clutter_timeline_start (move_block_tml);
posx_old = posx;
posy_old = posy;
}
@@ -561,6 +595,8 @@
{
field->width = allocation->width;
field->height = allocation->height;
+ if (field->width == 0 || field->height == 0)
+ return FALSE;
field->cell_width = field->width/COLUMNS;
field->cell_height = field->height/LINES;
field->rescaleField();
Modified: trunk/gnometris/blockops.h
==============================================================================
--- trunk/gnometris/blockops.h (original)
+++ trunk/gnometris/blockops.h Tue Feb 10 23:49:19 2009
@@ -27,10 +27,6 @@
#include <clutter/clutter.h>
-//FIXME dtor these somewhere...?
-static ClutterTimeline *timeline = NULL;
-static ClutterEffectTemplate *tmpl = NULL;
-
enum SlotType {
EMPTY,
FALLING,
@@ -50,19 +46,19 @@
int x;
int y;
-
- static ClutterTimeline *move_block_tml;
- static ClutterAlpha *move_block_alpha;
- ClutterBehaviour *move_block_path;
- void shift (gint cell_width, gint cell_height, gint shift_x, gint shift_y);
+ static ClutterTimeline *fall_tml;
+ static ClutterAlpha *fall_alpha;
+ ClutterBehaviour *fall_path;
+ static ClutterEffectTemplate *explode_tmpl;
void createActor (ClutterActor *chamber, ClutterActor *texture_source);
void associateActor (ClutterActor *chamber, ClutterActor *other_actor);
static GList *destroy_actors;
- static GList *destroy_behaviours;
- static void animation_destroy (ClutterTimeline *timeline, BlockOps *f);
- static void behaviours_destroy (ClutterTimeline *timeline, gpointer *data);
+ static GList *fall_behaviours;
+ static void explode_end (ClutterTimeline *timeline, BlockOps *f);
+ static void move_end (ClutterTimeline *timeline, gpointer *data);
+ static void fall_end (ClutterTimeline *timeline, gpointer *data);
};
class BlockOps {
@@ -140,18 +136,22 @@
ClutterActor *playingField;
static guint32 earthquake_alpha_func (ClutterAlpha *alpha, gpointer data);
- ClutterTimeline *long_anim_tml;
- ClutterEffectTemplate *effect_earthquake;
+ static ClutterTimeline *long_anim_tml;
+ static ClutterEffectTemplate *effect_earthquake;
float quake_ratio;
int center_anchor_x;
int center_anchor_y;
- static gboolean configure (GtkWidget * widget, GdkEventConfigure * event,
- BlockOps * field);
- static gboolean resize (GtkWidget * widget, GtkAllocation * event,
- BlockOps * field);
+ ClutterTimeline *move_block_tml;
+ ClutterAlpha *move_block_alpha;
+ ClutterBehaviour *move_path[4][4];
+
+ static void move_end (ClutterTimeline *tml, BlockOps *f);
+
+ static gboolean resize(GtkWidget *widget, GtkAllocation *event,
+ BlockOps *field);
};
#endif //__blockops_h__
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]