how about the attachment?
gcc -o jump-slide-penguin jump-slide-penguin.c `pkg-config --cflags
--libs elementary`
edje_cc jump-slide-penguin.edc
./jump-slide-penguin
pretend there are nice graphics! ;-)
On Sat, Oct 2, 2010 at 11:15 PM, Gustavo Sverzut Barbieri
<barbi...@profusion.mobi> wrote:
> Hey,
>
> Today I took some time to have coding fun and based on [1] I did the
> code for a simplistic clone of [2]. It has around 600 lines of C plus
> 615 of edje (just rectangles so far), and is an endless game play as
> it constructs the levels on the fly based on some constraints.
>
> It handles touch screen or keyboard controls and shows a simple status
> (level, elapsed time and score).
>
> The game is super simple, with 2 actions: jump and slide. The goal is
> to avoid obstacles and get as many coins as possible. Be aware that
> you have regular coins, extra bonus coins and fake coins that will
> subtract you points. You die when you hit an obstacle or when you run
> out of points due fake coins.
>
> The coins and obstacles are dynamically created based on EDJ:
> tile/<type>/<name> (type = regular/jump/slide) and coin/<type>/<name>
> (type = regular/extra/fake). You can add as many different entries as
> you wish, it will help the game play be more interesting.
>
> At this lines-of-code count it do serve as a good tutorial, but it
> would be better to have some graphics to make it more interesting.
> I'll do it later tomorrow if nobody send me any fancy drawings before
> it.
>
> Later extension points could be:
> - sounds (libcanbera is a nice way to get them)
> - save highest scores
> - double jump with stuff that needs it (coins or bigger obstacles)
> - segment the type of coins and obstacles, adding a level prefix to
> them and thus allowing new stuff for new levels
> - send elapsed time + level to background so we can change time of
> the day (nigh/day) and even weather (winter,summer), making it more
> fun.
>
> Anyone interested in turning this into a tutorial, wiki or something like
> that?
>
> [1] http://trac.enlightenment.org/e/wiki/KISS-DemosAndGames
> [2] http://itunes.apple.com/br/app/dash-dash-pengy-ex/id375723113?mt=8
>
> --
> Gustavo Sverzut Barbieri
> http://profusion.mobi embedded systems
> --------------------------------------
> MSN: barbi...@gmail.com
> Skype: gsbarbieri
> Mobile: +55 (19) 9225-2202
>
--
Gustavo Sverzut Barbieri
http://profusion.mobi embedded systems
--------------------------------------
MSN: barbi...@gmail.com
Skype: gsbarbieri
Mobile: +55 (19) 9225-2202
#include <Elementary.h>
#ifndef ELM_LIB_QUICKLAUNCH
static Evas *evas;
static Evas_Object *win, *bg, *player, *controls, *controls_edje;
static int tile_size, coin_size, win_w, win_h;
static Eina_List *coins = NULL;
static Eina_List *tiles = NULL;
static double tiles_off_x = 0; /* double to account sub-pixel */
/* is player in its default state? if not, the distance */
static Eina_Bool player_default = EINA_TRUE;
static double player_default_off = 0;
typedef enum {COIN_REGULAR, COIN_EXTRA, COIN_FAKE} coin_type;
static struct coin_desc {
const char *name;
coin_type type;
} *coin_descs = NULL;
static unsigned coin_descs_count = 0; /* how many coins in coin_descs */
static unsigned coin_desc_last = 0; /* the last used coin_descs index */
static unsigned coin_last_regulars = 0; /* how many regular coins in the last sequence */
static double coin_tile_regular_variations[] = {
0.0, 0.0, 0.0, 0.0, 0.1, 0.2, 0.5, 0.8, 1.0, 1.2, 1.3, 1.3, 1.2, 1.0, 0.8, 0.5, 0.2, 0.1
};
static int coin_tile_regular_variations_idx = 0;
static const size_t coin_tile_regular_variations_count = sizeof(coin_tile_regular_variations)/sizeof(coin_tile_regular_variations[0]);
/* tiles and their type, loaded from edje matching "tile/<type>/<name>" */
typedef enum {TILE_REGULAR, TILE_JUMP, TILE_SLIDE} tile_type;
static struct tile_desc {
const char *name;
tile_type type;
} *tile_descs = NULL;
static unsigned tile_descs_count = 0; /* how many tiles in tile_descs */
static unsigned tile_desc_last = 0; /* the last used tile_descs index */
static unsigned tile_last_regulars = 0; /* how many regular tiles in the last sequence */
static double speed_level_boost = 1.05;
static const double speed_initial = 90.0; /* pixels per second, incremented by speed_level_boost */
static double speed = 90;
static double start_time, last_time;
static unsigned level = 0;
static const double level_time = 30.0; /* duration for each level */
static long long score = 0;
static Ecore_Animator *update_anim = NULL;
static void _restart(void);
static void
_die(void)
{
printf("died with score: %lld\n", score);
ecore_animator_del(update_anim);
update_anim = NULL;
edje_object_signal_emit(controls_edje, "died", "");
}
static void
_jump(void)
{
edje_object_signal_emit(player, "animate,jump", "");
player_default = EINA_FALSE;
player_default_off = 0.0;
}
static void
_slide(void)
{
edje_object_signal_emit(player, "animate,slide", "");
player_default = EINA_FALSE;
player_default_off = 0.0;
}
static void
_ed_jump(void *data, Evas_Object *ed, const char *emission, const char *source)
{
_jump();
}
static void
_ed_slide(void *data, Evas_Object *ed, const char *emission, const char *source)
{
_slide();
}
static void
_ed_restart(void *data, Evas_Object *ed, const char *emission, const char *source)
{
_restart();
}
static void
_key(void *data, Evas *e, Evas_Object *o, void *event_info)
{
Evas_Event_Key_Down *ev = event_info;
if (strcmp(ev->keyname, "Up") == 0)
_jump();
else if (strcmp(ev->keyname, "Down") == 0)
_slide();
}
static Evas_Object *
_tile_add_internal(const struct tile_desc *desc, Evas_Coord x)
{
Evas_Object *t = edje_object_add(evas);
edje_object_file_set(t, "jump-slide-penguin.edj", desc->name);
evas_object_move(t, x, 0);
evas_object_resize(t, tile_size, win_h);
evas_object_show(t);
evas_object_layer_set(t, ELM_OBJECT_LAYER_DEFAULT);
evas_object_data_set(t, "desc", desc);
tiles = eina_list_append(tiles, t);
return t;
}
static Evas_Object *
_tile_add(Evas_Coord x)
{
unsigned int i = (tile_desc_last + rand()) % tile_descs_count;
Eina_Bool needs_regular;
if (i == tile_desc_last)
i = (tile_desc_last + 1) % tile_descs_count;
needs_regular = tile_descs[tile_desc_last].type != TILE_REGULAR;
/* the first levels requires a minimum of regular tiles between obstacles */
if ((!needs_regular) && (level < 20))
{
if (tile_last_regulars < (20 - level))
needs_regular = EINA_TRUE;
}
if (needs_regular)
{
/* search next regular tile */
while (tile_descs[i].type != TILE_REGULAR)
i = (i + 1) % tile_descs_count;
}
/* account regulars in a sequence */
if (tile_descs[i].type == TILE_REGULAR) tile_last_regulars++;
else tile_last_regulars = 0;
tile_desc_last = i;
return _tile_add_internal(tile_descs + i, x);
}
static Evas_Object *
_coin_add_internal(const struct coin_desc *desc, Evas_Coord x, Evas_Coord y)
{
Evas_Object *t = edje_object_add(evas);
edje_object_file_set(t, "jump-slide-penguin.edj", desc->name);
evas_object_move(t, x, y);
evas_object_resize(t, coin_size, coin_size);
evas_object_show(t);
evas_object_layer_set(t, ELM_OBJECT_LAYER_DEFAULT + 1);
evas_object_data_set(t, "desc", desc);
coins = eina_list_append(coins, t);
return t;
}
static Evas_Object *
_coin_add(Evas_Coord x, Evas_Coord y, Eina_Bool needs_regular)
{
unsigned int i = (coin_desc_last + rand()) % coin_descs_count;
if (i == coin_desc_last)
i = (coin_desc_last + 1) % coin_descs_count;
if (!needs_regular)
needs_regular = coin_descs[coin_desc_last].type != COIN_REGULAR;
/* the first levels requires a minimum of regular coins between obstacles */
if ((!needs_regular) && (level < 20))
{
if (coin_last_regulars < (20 - level))
needs_regular = EINA_TRUE;
}
if (needs_regular)
{
/* search next regular coin */
while (coin_descs[i].type != COIN_REGULAR)
i = (i + 1) % coin_descs_count;
}
/* account regulars in a sequence */
if (coin_descs[i].type == COIN_REGULAR) coin_last_regulars++;
else coin_last_regulars = 0;
coin_desc_last = i;
return _coin_add_internal(coin_descs + i, x, y);
}
static void
_tiles_and_coins_load(void)
{
Eina_List *lst, *l;
struct tile_desc *tile_itr;
struct coin_desc *coin_itr;
const char *s;
unsigned int count;
lst = edje_file_collection_list("jump-slide-penguin.edj");
count = eina_list_count(lst);
/* pre allocate as if all entries were of the expected type */
tile_itr = tile_descs = malloc(sizeof(struct tile_desc) * count);
coin_itr = coin_descs = malloc(sizeof(struct coin_desc) * count);
EINA_LIST_FOREACH(lst, l, s)
{
if (strncmp(s, "tile/", sizeof("tile/") - 1) == 0)
{
const char *t = s + sizeof("tile/") - 1;
if (strncmp(t, "regular/", sizeof("regular/") - 1) == 0)
tile_itr->type = TILE_REGULAR;
else if (strncmp(t, "jump/", sizeof("jump/") - 1) == 0)
tile_itr->type = TILE_JUMP;
else if (strncmp(t, "slide/", sizeof("slide/") - 1) == 0)
tile_itr->type = TILE_SLIDE;
else
{
EINA_LOG_ERR("unknown tile type: %s", t);
continue;
}
tile_itr->name = eina_stringshare_add(s);
tile_itr++;
tile_descs_count++;
}
else if (strncmp(s, "coin/", sizeof("coin/") -1 ) == 0)
{
const char *t = s + sizeof("coin/") - 1;
if (strncmp(t, "regular/", sizeof("regular/") - 1) == 0)
coin_itr->type = COIN_REGULAR;
else if (strncmp(t, "extra/", sizeof("extra/") - 1) == 0)
coin_itr->type = COIN_EXTRA;
else if (strncmp(t, "fake/", sizeof("fake/") - 1) == 0)
coin_itr->type = COIN_FAKE;
else
{
EINA_LOG_ERR("unknown coin type: %s", t);
continue;
}
coin_itr->name = eina_stringshare_add(s);
coin_itr++;
coin_descs_count++;
}
}
edje_file_collection_list_free(lst);
/* give back over-allocated memory */
tile_descs = realloc(tile_descs, sizeof(struct tile_desc) * tile_descs_count);
coin_descs = realloc(coin_descs, sizeof(struct coin_desc) * coin_descs_count);
}
static void
_update_elapsed_time(void)
{
unsigned int elapsed = last_time - start_time;
char buf[16];
if (elapsed < 60)
snprintf(buf, sizeof(buf), "%02d", elapsed);
else if (elapsed < 3600)
snprintf(buf, sizeof(buf), "%02d:%02d", elapsed / 60, elapsed % 60);
else
snprintf(buf, sizeof(buf), "%d:%02d:%02d",
elapsed / 3600, (elapsed / 60) % 60, elapsed % 60);
edje_object_part_text_set(controls_edje, "elapsed", buf);
}
static void
_update_score(void)
{
char buf[64];
snprintf(buf, sizeof(buf), "%lld", score);
edje_object_part_text_set(controls_edje, "score", buf);
}
static void
_change_level(void)
{
char buf[16];
level++;
speed *= speed_level_boost;
snprintf(buf, sizeof(buf), "%d", level);
edje_object_part_text_set(controls_edje, "level", buf);
}
static void
_create_coins(void)
{
Evas_Object *last_tile, *last_coin;
Evas_Coord cx, cy;
Evas_Coord tx, ox, oy, ow, oh, ph;
const struct tile_desc *tile_desc;
Eina_Bool use_variations;
last_tile = eina_list_last(tiles)->data;
last_coin = coins ? eina_list_last(coins)->data : NULL;
tile_desc = evas_object_data_get(last_tile, "desc");
evas_object_geometry_get(last_tile, &tx, NULL, NULL, NULL);
edje_object_part_geometry_get(last_tile, "obstacle", &ox, &oy, &ow, &oh);
ox += tx;
if (!last_coin)
cx = ox;
else
{
evas_object_geometry_get(last_coin, &cx, &cy, NULL, NULL);
if (cx + coin_size > ox + ow) return;
cx += coin_size;
}
if (tile_desc->type != TILE_REGULAR)
{
coin_tile_regular_variations_idx = 0;
use_variations = EINA_FALSE;
}
else
{
if (coin_tile_regular_variations_idx == 0)
use_variations = (rand() % 2) == 0; /* use variations occasionally */
else
use_variations = EINA_TRUE; /* already using... */
edje_object_part_geometry_get(player, "area", NULL, NULL, NULL, &ph);
}
for (; cx < ox + ow; cx += coin_size)
{
if (use_variations)
{
unsigned int i = ((coin_tile_regular_variations_idx + 1) %
coin_tile_regular_variations_count);
coin_tile_regular_variations_idx = i;
cy = oy - coin_size - ph * coin_tile_regular_variations[i];
}
else
{
if (oy == 0) cy = oh;
else cy = oy - coin_size;
}
_coin_add(cx, cy, tile_desc->type != TILE_REGULAR);
}
}
static Eina_Bool
_update(void *data)
{
Eina_List *l, *coins_deleted = NULL;
Evas_Object *o;
Evas_Coord x, offx;
Evas_Coord px, py, pw, ph, tx;
double now = ecore_loop_time_get();
double dx = (speed * (now - last_time));
/* don't do any work if we did not change a full pixel */
if ((int)tiles_off_x == (int)(tiles_off_x + dx)) return EINA_TRUE;
last_time = now;
edje_object_part_geometry_get(player, "area", &px, &py, &pw, &ph);
/* check if we need to revert player to its default state */
if (!player_default)
{
player_default_off += dx;
if (player_default_off > tile_size + 2 * pw)
{
edje_object_signal_emit(player, "animate,default", "");
player_default = EINA_TRUE;
}
}
/* we'll move of dx, if it's more than one tile, pop the first tile
* and append a new one until we're done.
*/
tiles_off_x -= dx;
while (tiles_off_x < -tile_size)
{
tiles_off_x += tile_size;
evas_object_del(tiles->data);
tiles = eina_list_remove_list(tiles, tiles);
_tile_add(x);
}
/* update tiles to their updated position, checking obstacle collisions */
x = tiles_off_x;
evas_object_geometry_get(tiles->data, &tx, NULL, NULL, NULL);
offx = x - tx;
EINA_LIST_FOREACH(tiles, l, o)
{
evas_object_move(o, x, 0);
if (eina_spans_intersect(px, pw, x, tile_size))
{
Evas_Coord ox, oy, ow, oh;
edje_object_part_geometry_get(o, "obstacle", &ox, &oy, &ow, &oh);
ox += x;
if (eina_spans_intersect(px, pw, ox, ow) &&
eina_spans_intersect(py, ph, oy, oh))
{
_die();
}
}
x += tile_size;
}
/* update coins to their updated position, checking target hits.
* delete is not done immediately as we're walking the list.
*/
EINA_LIST_FOREACH(coins, l, o)
{
Evas_Coord y;
evas_object_geometry_get(o, &x, &y, NULL, NULL);
x += offx;
if (x < -coin_size)
{
coins_deleted = eina_list_append(coins_deleted, l);
continue;
}
evas_object_move(o, x, y);
if (eina_spans_intersect(px, pw, x, coin_size))
{
Evas_Coord tx, ty, tw, th;
edje_object_part_geometry_get(o, "target", &tx, &ty, &tw, &th);
tx += x;
ty += y;
if (eina_spans_intersect(px, pw, tx, tw) &&
eina_spans_intersect(py, ph, ty, th))
{
const char *s = edje_object_data_get(o, "points");
if (s) score += atoi(s);
if (score < 0) _die();
coins_deleted = eina_list_append(coins_deleted, l);
}
}
}
EINA_LIST_FREE(coins_deleted, l)
{
evas_object_del(l->data);
coins = eina_list_remove_list(coins, l);
}
_create_coins();
if (last_time - start_time > level * level_time)
_change_level();
_update_elapsed_time();
_update_score();
return EINA_TRUE;
}
static int
_edje_data_int_get(const Evas_Object *ed, const char *key, int defval)
{
const char *s = edje_object_data_get(ed, key);
if (s) return atoi(s);
else return defval;
}
static void
_restart(void)
{
Evas_Object *o;
const struct tile_desc *d, *d_end;
Evas_Coord w;
EINA_LIST_FREE(tiles, o) evas_object_del(o);
EINA_LIST_FREE(coins, o) evas_object_del(o);
start_time = ecore_loop_time_get();
last_time = start_time;
speed = speed_initial;
level = 0;
score = 0;
tiles_off_x = 0.0;
tile_last_regulars = 0;
tile_desc_last = 0;
coin_last_regulars = 0;
coin_desc_last = 0;
coin_tile_regular_variations_idx = 0;
player_default = EINA_TRUE;
player_default_off = 0;
edje_object_signal_emit(player, "set,default", "");
d = tile_descs;
d_end = d + tile_descs_count;
for (;d < d_end; d++)
if (d->type == TILE_REGULAR)
break;
if (d == d_end)
{
EINA_LOG_CRIT("no regular tiles?! theme is bogus!");
return;
}
for (w = 0; w < win_w + tile_size; w += tile_size)
_tile_add_internal(d, w);
if (!update_anim) update_anim = ecore_animator_add(_update, NULL);
edje_object_signal_emit(controls_edje, "start", "");
}
EAPI int
elm_main(int argc, char **argv)
{
Evas_Object *ed;
srand(time(NULL) + getpid());
elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED);
win = elm_win_add(NULL, "jump-slide-penguin", ELM_WIN_BASIC);
elm_win_title_set(win, "Jump & Slide Penguin!");
elm_win_autodel_set(win, 1);
evas = evas_object_evas_get(win);
bg = elm_layout_add(win);
elm_layout_file_set(bg, "jump-slide-penguin.edj", "background");
evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(bg, EVAS_HINT_FILL, EVAS_HINT_FILL);
evas_object_layer_set(bg, ELM_OBJECT_LAYER_BACKGROUND);
evas_object_show(bg);
elm_win_resize_object_add(win, bg);
ed = elm_layout_edje_get(bg);
tile_size = _edje_data_int_get(ed, "tile_size", 80);
coin_size = _edje_data_int_get(ed, "coin_size", 20);
edje_object_size_min_get(ed, &win_w, &win_h);
edje_object_size_min_restricted_calc(ed, &win_w, &win_h, win_w, win_h);
evas_object_size_hint_min_set(win, win_w, win_h);
evas_object_resize(win, win_w, win_h);
player = edje_object_add(evas);
edje_object_file_set(player, "jump-slide-penguin.edj", "player");
evas_object_size_hint_weight_set(player, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(player, EVAS_HINT_FILL, EVAS_HINT_FILL);
evas_object_layer_set(player, ELM_OBJECT_LAYER_DEFAULT + 2);
evas_object_show(player);
elm_win_resize_object_add(win, player);
controls = elm_layout_add(win);
elm_layout_file_set(controls, "jump-slide-penguin.edj", "controls");
evas_object_size_hint_weight_set(controls, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(controls, EVAS_HINT_FILL, EVAS_HINT_FILL);
evas_object_layer_set(controls, ELM_OBJECT_LAYER_CURSOR);
evas_object_show(controls);
elm_win_resize_object_add(win, controls);
controls_edje = ed = elm_layout_edje_get(controls);
edje_object_signal_callback_add(ed, "jump", "", _ed_jump, NULL);
edje_object_signal_callback_add(ed, "slide", "", _ed_slide, NULL);
edje_object_signal_callback_add(ed, "restart", "", _ed_restart, NULL);
evas_object_focus_set(controls, EINA_TRUE);
evas_object_event_callback_add(controls, EVAS_CALLBACK_KEY_DOWN, _key, NULL);
_tiles_and_coins_load();
_restart();
evas_object_show(win);
elm_run();
elm_shutdown();
return 0;
}
#endif
ELM_MAIN()
collections {
group { name: "background";
min: 800 480;
max: 800 480;
data.item: "tile_size" "80";
data.item: "coin_size" "20";
parts {
part { name: "bg";
type: RECT;
mouse_events: 0;
description { state: "default" 0.0;
color: 255 255 255 255;
min: 800 480;
}
}
}
}
group { name: "controls";
parts {
part { name: "level-label";
type: TEXT;
mouse_events: 0;
effect: SOFT_OUTLINE;
description {
state: "default" 0.0;
color: 255 255 0 255;
color3: 0 0 0 255;
fixed: 1 1;
align: 0.0 0.0;
rel1 {
relative: 0.0 0.0;
offset: 10 10;
}
rel2 {
relative: 0.0 0.0;
offset: 20 20;
}
text {
font: "Sans:style=Bold";
size: 14;
text: "Level:";
min: 1 1;
}
}
}
part { name: "level";
type: TEXT;
mouse_events: 0;
effect: SOFT_OUTLINE;
description {
state: "default" 0.0;
color: 255 255 0 255;
color3: 0 0 0 255;
fixed: 1 1;
align: 0.0 0.0;
rel1 {
relative: 1.0 0.0;
offset: 3 10;
to_x: "level-label";
}
rel2 {
relative: 1.0 0.0;
offset: 20 20;
to_x: "level-label";
}
text {
font: "Sans:style=Bold";
size: 14;
text: "0";
min: 1 1;
}
}
}
part { name: "elapsed";
type: TEXT;
mouse_events: 0;
effect: SOFT_OUTLINE;
description {
state: "default" 0.0;
color: 255 255 0 255;
color3: 0 0 0 255;
fixed: 1 1;
align: 0.5 0.0;
rel1 {
relative: 0.5 0.0;
offset: -10 10;
}
rel2 {
relative: 0.5 0.0;
offset: 9 20;
}
text {
font: "Sans:style=Bold";
size: 14;
text: "00";
min: 1 1;
}
}
}
part { name: "score";
type: TEXT;
mouse_events: 0;
effect: SOFT_OUTLINE;
description {
state: "default" 0.0;
color: 255 255 0 255;
color3: 0 0 0 255;
fixed: 1 1;
align: 1.0 0.0;
rel1 {
relative: 1 0.0;
offset: -20 10;
}
rel2 {
relative: 1 0.0;
offset: -9 20;
}
text {
font: "Sans:style=Bold";
size: 14;
text: "0";
min: 1 1;
}
}
}
part { name: "jump";
type: RECT;
description { state: "default" 0.0;
color: 255 0 0 255;
rel1 {
relative: 0.0 1.0;
offset: 0 -100;
}
rel2 {
relative: 0.0 1.0;
offset: 100 -1;
}
}
}
part { name: "slide";
type: RECT;
description { state: "default" 0.0;
color: 255 0 255 255;
rel1 {
relative: 1.0 1.0;
offset: -100 -100;
}
rel2 {
relative: 1.0 1.0;
offset: -1 -1;
}
}
}
part { name: "died-clipper";
type: RECT;
description { state: "default" 0.0;
color: 255 255 255 0;
visible: 0;
}
description { state: "visible" 0.0;
color: 255 255 255 255;
visible: 1;
}
}
part { name: "died-bg";
type: RECT;
clip_to: "died-clipper";
mouse_events: 0;
description { state: "default" 0.0;
color: 32 32 32 128;
}
}
part { name: "restart";
type: RECT;
clip_to: "died-clipper";
description { state: "default" 0.0;
color: 255 0 0 255;
rel1 {
relative: 0.0 0.0;
offset: -10 -10;
to: "restart-label";
}
rel2 {
relative: 1.0 1.0;
offset: 9 9;
to: "restart-label";
}
}
}
part {
name: "restart-label";
type: TEXT;
clip_to: "died-clipper";
effect: SOFT_OUTLINE;
mouse_events: 0;
description {
state: "default" 0.0;
color: 255 255 255 255;
color3: 0 0 0 255;
fixed: 1 1;
rel1 {
relative: 0.5 0.5;
offset: 0 0;
}
rel2 {
relative: 0.5 0.5;
offset: -1 -1;
}
text {
font: "Sans:style=Bold";
size: 32;
text: "RESTART!";
min: 1 1;
}
}
}
programs {
program {
signal: "mouse,clicked,*";
source: "jump";
action: SIGNAL_EMIT "jump" "";
}
program {
signal: "mouse,clicked,*";
source: "slide";
action: SIGNAL_EMIT "slide" "";
}
program {
signal: "mouse,clicked,*";
source: "restart";
action: SIGNAL_EMIT "restart" "";
}
program {
signal: "died";
action: STATE_SET "visible" 0.0;
target: "died-clipper";
}
program {
signal: "start";
action: STATE_SET "default" 0.0;
target: "died-clipper";
}
}
}
}
group { name: "player";
parts {
part { name: "area";
type: RECT;
mouse_events: 0;
description { state: "default" 0.0;
color: 0 0 0 255;
align: 0.5 0.0;
rel1 {
relative: 0.5 1.0;
offset: -20 -340;
}
rel2 {
relative: 0.5 1.0;
offset: 19 -301;
}
}
description { state: "jump" 0.0;
inherit: "default" 0.0;
rel1 {
relative: 0.5 1.0;
offset: -20 -380;
}
rel2 {
relative: 0.5 1.0;
offset: 19 -341;
}
}
description { state: "slide" 0.0;
inherit: "default" 0.0;
rel1 {
relative: 0.5 1.0;
offset: -20 -320;
}
rel2 {
relative: 0.5 1.0;
offset: 19 -301;
}
}
}
programs {
program {
signal: "animate,jump";
action: STATE_SET "jump" 0.0;
transition: ACCELERATE 0.2;
target: "area";
after: "animate,jump,2";
}
program { name: "animate,jump,2";
action: SIGNAL_EMIT "animate,jump,end" "";
}
program {
signal: "animate,slide";
action: STATE_SET "slide" 0.0;
transition: ACCELERATE 0.2;
target: "area";
after: "animate,slide,2";
}
program { name: "animate,slide,2";
action: SIGNAL_EMIT "animate,slide,end" "";
}
program {
signal: "animate,default";
action: STATE_SET "default" 0.0;
transition: DECELERATE 0.2;
target: "area";
after: "animate,default,2";
}
program { name: "animate,default,2";
action: SIGNAL_EMIT "animate,default,end" "";
}
program {
signal: "set,default";
action: STATE_SET "default" 0.0;
target: "area";
}
}
}
}
group { name: "tile/regular/0";
parts {
part { name: "obstacle";
type: RECT;
mouse_events: 0;
description { state: "obstacle" 0.0;
color: 128 128 128 255;
rel1 {
relative: 0.0 1.0;
offset: 0 -300;
}
}
}
}
}
group { name: "tile/regular/1";
parts {
part { name: "obstacle";
type: RECT;
mouse_events: 0;
description { state: "default" 0.0;
color: 200 200 200 255;
rel1 {
relative: 0.0 1.0;
offset: 0 -300;
}
}
}
}
}
group { name: "tile/regular/2";
parts {
part { name: "obstacle";
type: RECT;
mouse_events: 0;
description { state: "default" 0.0;
color: 96 96 96 255;
rel1 {
relative: 0.0 1.0;
offset: 0 -300;
}
}
}
}
}
group { name: "tile/jump/0";
parts {
part { name: "obstacle";
type: RECT;
mouse_events: 0;
description { state: "default" 0.0;
color: 128 0 0 255;
rel1 {
relative: 0.0 1.0;
offset: 0 -340;
}
}
}
}
}
group { name: "tile/jump/1";
parts {
part { name: "obstacle";
type: RECT;
mouse_events: 0;
description { state: "default" 0.0;
color: 255 0 0 255;
rel1 {
relative: 0.0 1.0;
offset: 0 -340;
}
}
}
}
}
group { name: "tile/slide/0";
parts {
part { name: "obstacle";
type: RECT;
mouse_events: 0;
description { state: "default" 0.0;
color: 0 128 0 255;
rel2 {
relative: 1.0 1.0;
offset: -1 -330;
}
}
}
part { name: "ground";
type: RECT;
mouse_events: 0;
description { state: "obstacle" 0.0;
color: 128 128 128 255;
rel1 {
relative: 0.0 1.0;
offset: 0 -300;
}
}
}
}
}
group { name: "tile/slide/1";
parts {
part { name: "obstacle";
type: RECT;
mouse_events: 0;
description { state: "default" 0.0;
color: 0 255 0 255;
rel2 {
relative: 1.0 1.0;
offset: -1 -330;
}
}
}
part { name: "ground";
type: RECT;
mouse_events: 0;
description { state: "obstacle" 0.0;
color: 128 128 128 255;
rel1 {
relative: 0.0 1.0;
offset: 0 -300;
}
}
}
}
}
group { name: "coin/regular/0";
data.item: "points" "1";
parts {
part { name: "target";
type: RECT;
mouse_events: 0;
description { state: "default" 0.0;
color: 255 255 0 255;
rel1 {
relative: 0.5 0.5;
offset: -5 -5;
}
rel2 {
relative: 0.5 0.5;
offset: 4 4;
}
}
}
}
}
group { name: "coin/regular/1";
data.item: "points" "1";
parts {
part { name: "target";
type: RECT;
mouse_events: 0;
description { state: "default" 0.0;
color: 255 200 0 255;
rel1 {
relative: 0.5 0.5;
offset: -5 -5;
}
rel2 {
relative: 0.5 0.5;
offset: 4 4;
}
}
}
}
}
group { name: "coin/regular/2";
data.item: "points" "1";
parts {
part { name: "target";
type: RECT;
mouse_events: 0;
description { state: "default" 0.0;
color: 200 255 0 255;
rel1 {
relative: 0.5 0.5;
offset: -5 -5;
}
rel2 {
relative: 0.5 0.5;
offset: 4 4;
}
}
}
}
}
group { name: "coin/extra/0";
data.item: "points" "50";
parts {
part { name: "target";
type: RECT;
mouse_events: 0;
description { state: "default" 0.0;
color: 255 200 0 255;
rel1 {
relative: 0.5 0.5;
offset: -2 -2;
}
rel2 {
relative: 0.5 0.5;
offset: 2 2;
}
}
description { state: "pulse" 0.0;
color: 255 200 128 255;
rel1 {
relative: 0.5 0.5;
offset: -5 -5;
}
rel2 {
relative: 0.5 0.5;
offset: 4 4;
}
}
}
programs {
program {
signal: "show";
after: "pulse1";
}
program {
name: "pulse1";
action: STATE_SET "pulse" 0.0;
transition: LINEAR 0.1;
target: "target";
after: "pulse2";
}
program {
name: "pulse2";
action: STATE_SET "default" 0.0;
transition: LINEAR 0.1;
target: "target";
after: "pulse1";
}
}
}
}
group { name: "coin/fake/0";
data.item: "points" "-5";
parts {
part { name: "target";
type: RECT;
mouse_events: 0;
description { state: "default" 0.0;
color: 32 32 32 255;
rel1 {
relative: 0.5 0.5;
offset: -3 -3;
}
rel2 {
relative: 0.5 0.5;
offset: 2 2;
}
}
}
}
}
}
------------------------------------------------------------------------------
Start uncovering the many advantages of virtual appliances
and start using them to simplify application deployment and
accelerate your shift to cloud computing.
http://p.sf.net/sfu/novell-sfdev2dev
_______________________________________________
enlightenment-devel mailing list
enlightenment-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel