GitLab repository storage has been migrated to hashed layout. Please contact Infrastructure team if you notice any issues with repositories or hooks.

Commit 9a99a80f authored by Yves Combe's avatar Yves Combe

new board crane by Marc BRUN.

parent 08ddffc9
2006-01-01 Yves Combe <yves@ycombe.net>
new board crane by Marc BRUN.
NOT added in potfile yet.
* boards/Makefile.am:
* boards/boardicons/crane.png:
* boards/crane.xml.in:
* boards/crane/arrow_b.png:
* boards/crane/arrow_l.png:
* boards/crane/arrow_r.png:
* boards/crane/arrow_u.png:
* boards/crane/bulb.png:
* boards/crane/crane-bg.png:
* boards/crane/letter-a.png:
* boards/crane/letter-b.png:
* boards/crane/letter-c.png:
* boards/crane/rectangle1.png:
* boards/crane/rectangle2.png:
* boards/crane/selected.png:
* boards/crane/square1.png:
* boards/crane/square2.png:
* boards/crane/triangle1.png:
* boards/crane/triangle2.png:
* boards/crane/tux.png:
* boards/crane/water_drop1.png:
* boards/crane/water_drop2.png:
* boards/crane/water_spot1.png:
* boards/crane/water_spot2.png:
* po/Makefile.in.in:
* src/boards/Makefile.am:
* src/boards/crane.c: (pause_board), (start_board), (end_board),
(set_level), (is_our_board), (crane_next_level),
(crane_destroy_all_items), (crane_create_item), (bonus),
(finished), (game_won), (item_event), (arrow_event), (draw_arrow),
(draw_redhands), (draw_frame), (place_item), (smooth_move),
(is_allowed_move), (get_item_index), (shuffle_list), (select_item):
2005-12-19 Bruno coudoin <bruno.coudoin@free.fr>
- Patch by Patrick GOLDBRONN pgoldbronn on free.fr
......
......@@ -30,6 +30,7 @@ xml_in_files = \
clickgame.xml.in \
clockgame.xml.in \
colors.xml.in \
crane.xml.in \
colors_group.xml.in \
computer.xml.in \
connect4.xml.in \
......
<?xml version="1.0" encoding="UTF-8"?>
<GCompris>
<Board
name="crane"
type="crane"
section="/boards"
icon="boardicons/crane.png"
difficulty="0"
mode="normal"
author="Marc BRUN"
boarddir="">
<_title>Build the same</_title>
<_description>Copy the model</_description>
<_prerequisite>Mouse manipulation</_prerequisite>
<_goal>Motor-coordination</_goal>
<_manual>
Move the item from the bottom left frame to have them positioned the same as in the top right model.
</_manual>
<_credit></_credit>
</Board>
</GCompris>
......@@ -11,6 +11,11 @@
#
# - Modified by jacob berkman <jacob@ximian.com> to install
# Makefile.in.in and po2tbl.sed.in for use with glib-gettextize
#
# - Modified by Rodney Dawes <dobey@novell.com> for use with intltool
#
# We have the following line for use by intltoolize:
# INTLTOOL_MAKEFILE
GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
PACKAGE = @PACKAGE@
......@@ -27,13 +32,13 @@ VPATH = @srcdir@
prefix = @prefix@
exec_prefix = @exec_prefix@
datadir = @datadir@
datarootdir = @datarootdir@
libdir = @libdir@
localedir = $(libdir)/locale
gnulocaledir = $(datadir)/locale
gettextsrcdir = $(datadir)/glib-2.0/gettext/po
subdir = po
install_sh = @install_sh@
mkdir_p = @mkdir_p@
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
INSTALL = @INSTALL@
......@@ -61,7 +66,8 @@ SOURCES =
POFILES = @POFILES@
GMOFILES = @GMOFILES@
DISTFILES = ChangeLog Makefile.in.in POTFILES.in \
$(POFILES) $(GMOFILES) $(SOURCES)
$(POFILES) $(SOURCES)
EXTRA_DISTFILES = POTFILES.skip Makevars LINGUAS
POTFILES = \
......@@ -77,7 +83,7 @@ INSTOBJEXT = @INSTOBJEXT@
.po.pox:
$(MAKE) $(GETTEXT_PACKAGE).pot
$(MSGMERGE) $< $(top_builddir)/po/$(GETTEXT_PACKAGE).pot -o $*pox
$(MSGMERGE) $< $(GETTEXT_PACKAGE).pot -o $*.pox
.po.mo:
$(MSGFMT) -o $@ $<
......@@ -174,7 +180,7 @@ uninstall:
rm -f $(DESTDIR)$(gettextsrcdir)/Makefile.in.in; \
fi
check: all
check: all $(GETTEXT_PACKAGE).pot
dvi info tags TAGS ID:
......@@ -186,16 +192,21 @@ mostlyclean:
clean: mostlyclean
distclean: clean
rm -f Makefile Makefile.in POTFILES *.mo *.msg *.cat *.cat.m
rm -f Makefile Makefile.in POTFILES
rm -f *.mo *.msg *.cat *.cat.m $(GMOFILES)
maintainer-clean: distclean
@echo "This command is intended for maintainers to use;"
@echo "it deletes files that may require special tools to rebuild."
rm -f $(GMOFILES)
rm -f Makefile.in.in
distdir = ../$(GETTEXT_PACKAGE)-$(VERSION)/$(subdir)
dist distdir: $(DISTFILES) $(GETTEXT_PACKAGE).pot
dist distdir: $(DISTFILES)
dists="$(DISTFILES)"; \
extra_dists="$(EXTRA_DISTFILES)"; \
for file in $$extra_dists; do \
test -f $$file && dists="$$dists $$file"; \
done; \
for file in $$dists; do \
ln $(srcdir)/$$file $(distdir) 2> /dev/null \
|| cp -p $(srcdir)/$$file $(distdir); \
......@@ -232,17 +243,13 @@ update-po: Makefile
# and Intltool tags (enclosed in square brackets), and appending a full
# relative path to them
POTFILES: POTFILES.in
( if test 'x$(srcdir)' != 'x.'; then \
posrcprefix='$(top_srcdir)/'; \
else \
posrcprefix="../"; \
fi; \
( posrcprefix='$(top_srcdir)/'; \
rm -f $@-t $@ \
&& (sed -e '/^#/d' \
-e "s/^\[.*\] +//" \
-e '/^[ ]*$$/d' \
-e "s@.*@ $$posrcprefix& \\\\@" < $(srcdir)/$@.in \
| sed -e '$$s/\\$$//') > $@-t \
&& (sed -e '/^#/d' \
-e 's/^[[].*] *//' \
-e '/^[ ]*$$/d' \
-e "s@^@ $$posrcprefix@" $(srcdir)/$@.in \
| sed -e '$$!s/$$/ \\/') > $@-t \
&& chmod a-w $@-t \
&& mv $@-t $@ )
......
......@@ -36,6 +36,7 @@ lib_LTLIBRARIES = \
libclickgame.la \
libclockgame.la \
libcolors.la \
libcrane.la \
liberase.la \
libenumerate.la \
libfifteen.la \
......@@ -87,6 +88,10 @@ libawele_la_LDFLAGS = -module -avoid-version
libawele_la_LIBADD = $(top_builddir)/src/gcompris/libgcompris-1.la
libawele_la_SOURCES = awele.c awele_alphaBeta.c awele_utils.c
libcrane_la_LDFLAGS = -module -avoid-version
libcrane_la_LIBADD = $(top_builddir)/src/gcompris/libgcompris-1.la
libcrane_la_SOURCES = crane.c
libmenu_la_LDFLAGS = -module -avoid-version
libmenu_la_LIBADD = $(top_builddir)/src/gcompris/libgcompris-1.la
libmenu_la_SOURCES = menu.c
......
/* gcompris - crane.c
*
* Copyright (C) 2005 Marc BRUN
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <ctype.h>
#include <math.h>
#include <assert.h>
#include <string.h>
#include <unistd.h>
#include "gcompris/gcompris.h"
// Define
#define SOUNDLISTFILE PACKAGE
#define CRANE_BUTTON_WIDTH 20
#define CRANE_BUTTON_HEIGHT 50
#define CRANE_BUTTON_SPACE 20 // Space between a pair (left/right or up/down)
#define CRANE_BUTTON_LEFT_X 200
#define CRANE_BUTTON_LEFT_Y 72
#define CRANE_BUTTON_RIGHT_X (CRANE_BUTTON_LEFT_X + CRANE_BUTTON_HEIGHT + CRANE_BUTTON_SPACE)
#define CRANE_BUTTON_RIGHT_Y CRANE_BUTTON_LEFT_Y
#define CRANE_BUTTON_UP_X 408
#define CRANE_BUTTON_UP_Y 200
#define CRANE_BUTTON_DOWN_X CRANE_BUTTON_UP_X
#define CRANE_BUTTON_DOWN_Y (CRANE_BUTTON_UP_Y + CRANE_BUTTON_HEIGHT + CRANE_BUTTON_SPACE)
#define CRANE_FRAME_X 38
#define CRANE_FRAME_Y 168
#define CRANE_FRAME_COLUMN 6
#define CRANE_FRAME_LINE 5
#define CRANE_FRAME_CELL 52
#define CRANE_FRAME_BORDER 6
#define CRANE_FRAME_IMAGE_SIZE 40
#define CRANE_FRAME_MODEL_X 460
#define CRANE_FRAME_MODEL_Y 107
#define RIGHT 0
#define LEFT 1
#define UP 2
#define DOWN 3
#define MAX_LEVEL 6 // Don't raise this number except if putting more values in pixmap[] array, in place_item function
#define NB_ELEMENT (2 * MAX_LEVEL) + 2
// Types
// Structure describes the objects of the frames
typedef struct {
GdkPixbuf *pixmap;
double x;
double y;
double h;
double w;
} crane_object;
// Structure decribes a movement
typedef struct {
int x; // x movement
int y; // y movement
int nb; // how much of x/y movement (to give a smooth effect) ?
} move_object;
// Global variables
static GcomprisBoard *gcomprisBoard = NULL;
static gboolean board_paused = TRUE;
static GnomeCanvasGroup *boardRootItem = NULL;
static GnomeCanvasItem *selected_item = NULL;
static GnomeCanvasItem *red_hands = NULL;
static gint timer_id = 0;
static gint nb_move = 0;
static gboolean moving = FALSE;
static move_object my_move;
static int list_answer[CRANE_FRAME_LINE * CRANE_FRAME_COLUMN];
static int list_game[CRANE_FRAME_LINE * CRANE_FRAME_COLUMN];
// gcompris functions
static void start_board (GcomprisBoard *agcomprisBoard);
static void pause_board (gboolean pause);
static void end_board (void);
static gboolean is_our_board (GcomprisBoard *gcomprisBoard);
static void set_level (guint level);
static int gamewon;
static void game_won(void);
static GnomeCanvasItem *crane_create_item();
static void crane_destroy_all_items(void);
static void crane_next_level(void);
// crane functions
static gint item_event(GnomeCanvasItem *item, GdkEvent *event, gpointer data);
static gint arrow_event(GnomeCanvasItem *item, GdkEvent *event, gpointer data);
static guint smooth_move(move_object *);
static int is_allowed_move (double, double, int);
static void shuffle_list(int list[], int);
static void select_item(GnomeCanvasItem *, int);
static int get_item_index (double, double);
static void draw_arrow(void);
static void draw_frame(int, int);
static void draw_redhands(void);
static void place_item(int, int, int);
/* Description of this plugin */
static BoardPlugin menu_bp =
{
NULL,
NULL,
"Duplicate the top right model.",
"Select item in the bottom left frame and move them with the crane's arrows.",
"Marc BRUN",
NULL,
NULL,
NULL,
NULL,
start_board,
pause_board,
end_board,
is_our_board,
NULL,
NULL,
set_level,
NULL,
NULL,
NULL,
NULL
};
/*
* Main entry point mandatory for each Gcompris's game
* ---------------------------------------------------
*
*/
GET_BPLUGIN_INFO(crane)
static void pause_board (gboolean pause)
{
if (gcomprisBoard == NULL)
return;
if (timer_id) {
gtk_timeout_remove (timer_id);
timer_id = 0;
}
/* the game is won */
if (gamewon == TRUE && pause == FALSE)
game_won();
board_paused = pause;
}
static void start_board (GcomprisBoard *agcomprisBoard)
{
if (agcomprisBoard != NULL) {
gcomprisBoard = agcomprisBoard;
gcomprisBoard->level = 1;
gcomprisBoard->maxlevel = MAX_LEVEL;
gcomprisBoard->sublevel = 1;
gcomprisBoard->number_of_sublevel = 1; /* Go to next level after this number of 'play' */
gcompris_bar_set(GCOMPRIS_BAR_LEVEL);
crane_next_level();
gamewon = FALSE;
pause_board(FALSE);
}
}
static void end_board () {
if (timer_id) {
gtk_timeout_remove (timer_id);
timer_id = 0;
}
if (gcomprisBoard != NULL) {
pause_board(TRUE);
crane_destroy_all_items();
}
gcomprisBoard = NULL;
}
/* ======================================= */
static void set_level (guint level) {
if (gcomprisBoard != NULL) {
gcomprisBoard->level = level;
gcomprisBoard->sublevel = 1;
crane_next_level();
}
}
/* ======================================= */
static gboolean is_our_board (GcomprisBoard *gcomprisBoard) {
if (gcomprisBoard) {
if (g_strcasecmp(gcomprisBoard->type, "crane") == 0) {
/* Set the plugin entry */
gcomprisBoard->plugin = &menu_bp;
return TRUE;
}
}
return FALSE;
}
/*-------------------------------------------------------------------------------*/
/*-------------------------------------------------------------------------------*/
/* set initial values for the next level */
static void crane_next_level() {
gcompris_set_background(gnome_canvas_root(gcomprisBoard->canvas), "crane/crane-bg.png");
gcompris_bar_set_level(gcomprisBoard);
crane_destroy_all_items();
gamewon = FALSE;
/* Try the next level */
crane_create_item();
}
/* ==================================== */
/* Destroy all the items */
static void crane_destroy_all_items()
{
if (timer_id) {
gtk_timeout_remove (timer_id);
timer_id = 0;
}
if(boardRootItem != NULL)
gtk_object_destroy (GTK_OBJECT(boardRootItem));
boardRootItem = NULL;
}
/* ==================================== */
static GnomeCanvasItem *crane_create_item()
{
int i;
int nb_element;
boardRootItem = GNOME_CANVAS_GROUP(gnome_canvas_item_new (gnome_canvas_root(gcomprisBoard->canvas),
gnome_canvas_group_get_type (),
"x", (double) 0,
"y", (double) 0,
NULL));
// The four arrows on the crane
draw_arrow();
// The leading frames on both model (answer) and boardgame, only for first levels
if (gcomprisBoard->level < 5) {
draw_frame(CRANE_FRAME_X, CRANE_FRAME_Y); // Boardgame
draw_frame(CRANE_FRAME_MODEL_X, CRANE_FRAME_MODEL_Y); // Model
}
// The red corners (hands) that show the selected item
draw_redhands();
nb_element = gcomprisBoard->level * 2 + 2;
// Answer frame => the unmovable items of the model
for (i = 0 ; i < nb_element ; i++) list_answer[i] = i;
for ( ; i < CRANE_FRAME_LINE * CRANE_FRAME_COLUMN ; i ++) list_answer[i] = -1;
shuffle_list(list_answer, CRANE_FRAME_LINE * CRANE_FRAME_COLUMN);
place_item(CRANE_FRAME_MODEL_X, CRANE_FRAME_MODEL_Y, 0);
// Game frame => the playable items
for (i = 0 ; i < nb_element ; i++) list_game[i] = i;
for ( ; i < CRANE_FRAME_LINE * CRANE_FRAME_COLUMN ; i ++) list_game[i] = -1;
shuffle_list(list_game, CRANE_FRAME_LINE * CRANE_FRAME_COLUMN);
place_item(CRANE_FRAME_X, CRANE_FRAME_Y, 1);
return NULL;
}
// Display an happy face for end of level
static void bonus() {
gcompris_display_bonus(gamewon, BONUS_SMILEY);
gcompris_play_ogg ("bonus", NULL);
timer_id = 0;
}
// Display a 'end of game' animation
static void finished() {
board_finished(BOARD_FINISHED_RANDOM);
timer_id = 0;
}
// One more level completed
static void game_won() {
gcomprisBoard->sublevel++;
if (gcomprisBoard->sublevel>gcomprisBoard->number_of_sublevel) {
/* Try the next level */
gcomprisBoard->sublevel = 1;
gcomprisBoard->level++;
if (gcomprisBoard->level>gcomprisBoard->maxlevel) { // all levels completed : the current board is finished
timer_id = g_timeout_add (2000, (GtkFunction) finished, NULL);
return;
}
}
crane_next_level();
}
// Event on item
static gint item_event(GnomeCanvasItem *item, GdkEvent *event, gpointer data) {
if(board_paused)
return FALSE;
if (event->type == GDK_MOTION_NOTIFY) // Mouse moved
return FALSE;
// Select item if left click on it
if (event->type == GDK_BUTTON_PRESS && event->button.button == 1)
select_item(item, TRUE);
return FALSE;
}
// Event on arrow
static gint arrow_event(GnomeCanvasItem *item, GdkEvent *event, gpointer data) {
int success;
double x,y;
double dx1, dy1, dx2, dy2;
int direction;
int i;
int index, new_index;
if (board_paused)
return FALSE;
if (moving) // An object is already moving
return FALSE;
if (gamewon)
return FALSE;
if (event->type == GDK_MOTION_NOTIFY) // Mouse moved
return FALSE;
if (selected_item == NULL)
return FALSE;
// Left click on an arrow move the selected item
if (event->type == GDK_BUTTON_PRESS && event->button.button == 1) {
x = event->button.x;
y = event->button.y;
gnome_canvas_item_get_bounds(selected_item, &dx1, &dy1, &dx2, &dy2);
if (x < CRANE_BUTTON_RIGHT_X) {
direction = LEFT;
my_move.x = -1;
my_move.y = 0;
} else if (x < (CRANE_BUTTON_RIGHT_X + CRANE_BUTTON_HEIGHT)) {
direction = RIGHT;
my_move.x = 1;
my_move.y = 0;
} else if (y < CRANE_BUTTON_DOWN_Y) {
direction = UP;
my_move.x = 0;
my_move.y = -1;
} else if (y < (CRANE_BUTTON_DOWN_Y + CRANE_BUTTON_HEIGHT)) {
direction= DOWN;
my_move.x = 0;
my_move.y = 1;
} else {
printf("Clic location error : %g %g\n", x, y);
return FALSE;
}
// Check if the move doesn't go out of the frame
if (is_allowed_move(dx1, dy1, direction)) {
index = get_item_index(dx1, dy1);
new_index = index + my_move.x + (my_move.y * CRANE_FRAME_COLUMN);
// Check if no object is already here
if (list_game[new_index] == -1) {
// Do a smooth move
my_move.nb = 52;
timer_id = g_timeout_add(10, (GtkFunction) smooth_move, &my_move);
list_game[new_index] = list_game[index];
list_game[index] = -1;
}
}
}
// Check if the level is won
success = 1;
for (i = 0 ; i < CRANE_FRAME_LINE * CRANE_FRAME_COLUMN ; i++) {
if (list_answer[i] != list_game[i]) success = 0;
}
if (success) {
gamewon = TRUE;
timer_id = g_timeout_add (1200, (GtkFunction) bonus, NULL);
}
return FALSE;
}
// Draw the four arrows on the crane
static void draw_arrow() {
GnomeCanvasItem *item_arrow = NULL;
int i;
crane_object arrow[4];
arrow[0].pixmap = gcompris_load_pixmap("crane/arrow_b.png");
arrow[0].x = CRANE_BUTTON_DOWN_X; arrow[0].y = CRANE_BUTTON_DOWN_Y; arrow[0].w = CRANE_BUTTON_WIDTH; arrow[0].h = CRANE_BUTTON_HEIGHT;
arrow[1].pixmap = gcompris_load_pixmap("crane/arrow_u.png");
arrow[1].x = CRANE_BUTTON_UP_X; arrow[1].y = CRANE_BUTTON_UP_Y; arrow[1].w = CRANE_BUTTON_WIDTH; arrow[1].h = CRANE_BUTTON_HEIGHT;
arrow[2].pixmap = gcompris_load_pixmap("crane/arrow_l.png");
arrow[2].x = CRANE_BUTTON_LEFT_X; arrow[2].y = CRANE_BUTTON_LEFT_Y; arrow[2].w = CRANE_BUTTON_HEIGHT; arrow[2].h = CRANE_BUTTON_WIDTH;
arrow[3].pixmap = gcompris_load_pixmap("crane/arrow_r.png");
arrow[3].x = CRANE_BUTTON_RIGHT_X; arrow[3].y = CRANE_BUTTON_RIGHT_Y; arrow[3].w = CRANE_BUTTON_HEIGHT; arrow[3].h = CRANE_BUTTON_WIDTH;
for (i = 0 ; i < 4 ; i++) {
item_arrow = gnome_canvas_item_new (boardRootItem,
gnome_canvas_pixbuf_get_type(),
"pixbuf", arrow[i].pixmap,
"x", arrow[i].x,
"y", arrow[i].y,
"width", arrow[i].w,
"height", arrow[i].h,
"width_set", TRUE,