Back to index

gcompris  8.2.2
Classes | Defines | Typedefs | Enumerations | Functions | Variables
machpuzzle.c File Reference
#include "gcompris/gcompris.h"

Go to the source code of this file.

Classes

struct  _MachItem

Defines

#define SOUNDLISTFILE   PACKAGE
#define BORDER   40
#define MIN_X1   60
#define MIN_X2   (BOARDWIDTH-MIN_X1)
#define MIN_Y1   65
#define MIN_Y2   (BOARDHEIGHT-30)

Typedefs

typedef struct _MachItem

Enumerations

enum  MachItemType {
  MACH_HORZ_WALL = 0, MACH_VERT_WALL, MACH_HOLE, MACH_DIAG_WALL,
  MACH_BASKET_BALL, MACH_FLYING_BALL
}

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 void game_won (void)
static GnomeCanvasItem * minigolf_create_item (GnomeCanvasGroup *parent)
static void minigolf_destroy_all_items (void)
static void minigolf_next_level (void)
static gint item_event (GnomeCanvasItem *item, GdkEvent *event, MachItem *machItem)
static void minigolf_move (GList *item_list)
static MachItem * create_machine_item (MachItemType machItemType, double x, double y)
static gint rectangle_in (double sx1, double sy1, double sx2, double sy2, double dx1, double dy1, double dx2, double dy2)

Variables

static GList * item_list = NULL
static GcomprisBoard * gcomprisBoard = NULL
static gboolean board_paused = TRUE
static gint move_id = 0
static double times_inc = 0.1
static double gravity = 0
static double velocity = 0.99
static int gamewon
static GnomeCanvasGroup * boardRootItem = NULL
static BoardPlugin menu_bp

Class Documentation

struct _MachItem

Definition at line 33 of file machpuzzle.c.

Class Members
double ax
double ay
double elasticity
double height
GnomeCanvasItem * item
gboolean moving
double times
MachItemType type
double vxo
double vyo
double width
double x1
double x2
double xpos
double xposo
double y1
double y2
double ypos
double yposo

Define Documentation

#define BORDER   40

Definition at line 75 of file machpuzzle.c.

#define MIN_X1   60

Definition at line 78 of file machpuzzle.c.

#define MIN_X2   (BOARDWIDTH-MIN_X1)

Definition at line 79 of file machpuzzle.c.

#define MIN_Y1   65

Definition at line 80 of file machpuzzle.c.

#define MIN_Y2   (BOARDHEIGHT-30)

Definition at line 81 of file machpuzzle.c.

#define SOUNDLISTFILE   PACKAGE

Definition at line 22 of file machpuzzle.c.


Typedef Documentation

typedef struct _MachItem

Definition at line 46 of file machpuzzle.c.


Enumeration Type Documentation

Enumerator:
MACH_HORZ_WALL 
MACH_VERT_WALL 
MACH_HOLE 
MACH_DIAG_WALL 
MACH_BASKET_BALL 
MACH_FLYING_BALL 

Definition at line 24 of file machpuzzle.c.


Function Documentation

static MachItem * create_machine_item ( MachItemType  machItemType,
double  x,
double  y 
) [static]

Definition at line 330 of file machpuzzle.c.

{
  MachItem           *machItem;
  guint                      width;
  guint                      height;

  machItem = g_new (MachItem, 1);

  machItem->type     = machItemType;

  switch (machItemType)
    {
    case MACH_HORZ_WALL:
      width = 100;
      height = 20;
      machItem->moving      = FALSE;
      machItem->times   = 0.0;

      machItem->xposo       = x;
      machItem->xpos = x;
      machItem->vxo  = 0;
      machItem->ax   = 0;

      machItem->yposo       = y;
      machItem->ypos = y;
      machItem->vyo  = 0;
      machItem->ay   = 0;

      machItem->elasticity  = 5;

      machItem->item = gnome_canvas_item_new (boardRootItem,
                                         gnome_canvas_rect_get_type (),
                                         "x1", (double) machItem->xposo,
                                         "y1", (double) machItem->yposo,
                                         "x2", (double) machItem->xposo + width,
                                         "y2", (double) machItem->yposo + height,
                                         "outline_color", "black",
                                         "fill_color_rgba", 0xFF10C0FF,
                                         "width_units", (double)1,
                                         NULL);

      gtk_signal_connect(GTK_OBJECT(machItem->item), "event",
                      (GtkSignalFunc) item_event,
                      machItem);
      break;
    case MACH_VERT_WALL:
      break;
    case MACH_DIAG_WALL:
      break;
    case MACH_HOLE:
      /* Make the hole be smaller based on the level */
      width = 110 - gcomprisBoard->level*3;
      machItem->moving      = FALSE;
      machItem->times   = 0.0;

      machItem->xposo       = x - width/2;
      machItem->xpos = x - width/2;
      machItem->vxo  = 0;
      machItem->ax   = 0;

      machItem->yposo       = y - width/2;
      machItem->ypos = y - width/2;
      machItem->vyo  = 0;
      machItem->ay   = 0;

      machItem->width       = width;
      machItem->height      = width;

      machItem->elasticity  = 3;

      machItem->item = gnome_canvas_item_new (boardRootItem,
                                         gnome_canvas_ellipse_get_type (),
                                         "x1", (double) machItem->xposo,
                                         "y1", (double) machItem->yposo,
                                         "x2", (double) machItem->xposo + width,
                                         "y2", (double) machItem->yposo + width,
                                         "outline_color_rgba", 0xEEEEEEFF,
                                         "fill_color_rgba", 0x111111FF,
                                         "width_units", (double)2,
                                         NULL);

      break;
    case MACH_BASKET_BALL:
      width = 40;
      machItem->moving      = TRUE;
      machItem->times   = 0.0;

      machItem->xposo       = x;
      machItem->xpos = x;
      machItem->vxo  = 0;
      machItem->ax   = 0;

      machItem->yposo       = y;
      machItem->ypos = y;
      machItem->vyo  = 0;
      machItem->ay   = gravity;

      machItem->width       = width;
      machItem->height      = width;

      machItem->elasticity  = 4;

      machItem->item = gnome_canvas_item_new (boardRootItem,
                                         gnome_canvas_ellipse_get_type (),
                                         "x1", (double) machItem->xposo,
                                         "y1", (double) machItem->yposo,
                                         "x2", (double) machItem->xposo + width,
                                         "y2", (double) machItem->yposo + width,
                                         "outline_color", "black",
                                         "fill_color", "white",
                                         "width_units", (double)1,
                                         NULL);

      gtk_signal_connect(GTK_OBJECT(machItem->item), "event",
                      (GtkSignalFunc) item_event,
                      machItem);

      break;
    case MACH_FLYING_BALL:
      width = 40;
      machItem->moving      = TRUE;
      machItem->times   = 0.0;

      machItem->xposo       = x;
      machItem->xpos = x;
      machItem->vxo  = 10;
      machItem->ax   = 0;

      machItem->yposo       = y;
      machItem->ypos = y;
      machItem->vyo  = -5;
      machItem->ay   = -0.5;

      machItem->width       = width;
      machItem->height      = width;

      machItem->elasticity  = 1;

      machItem->item = gnome_canvas_item_new (boardRootItem,
                                         gnome_canvas_ellipse_get_type (),
                                         "x1", (double) machItem->xposo,
                                         "y1", (double) machItem->yposo,
                                         "x2", (double) machItem->xposo + width,
                                         "y2", (double) machItem->yposo + width * 1.5,
                                         "outline_color", "black",
                                         "fill_color_rgba", 0xE03000FF,
                                         "width_units", (double)1,
                                         NULL);

      gtk_signal_connect(GTK_OBJECT(machItem->item), "event",
                      (GtkSignalFunc) item_event,
                      machItem);
      break;
    }

  gtk_object_set_data(GTK_OBJECT(machItem->item),"mach",(gpointer)machItem);

  item_list = g_list_append (item_list, machItem);

  return machItem;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void end_board ( void  ) [static]

Definition at line 154 of file machpuzzle.c.

Here is the call graph for this function:

static void game_won ( void  ) [static]

Definition at line 252 of file machpuzzle.c.

{
  gcomprisBoard->sublevel++;

  if(gcomprisBoard->sublevel>gcomprisBoard->number_of_sublevel) {
    /* Try the next level */
    gcomprisBoard->sublevel=1;
    gcomprisBoard->level++;
    if(gcomprisBoard->level>gcomprisBoard->maxlevel) { // the current board is finished : bail out
      gc_bonus_end_display(BOARD_FINISHED_RANDOM);
      return;
    }
    gc_sound_play_ogg ("sounds/bonus.ogg", NULL);
  }
  minigolf_next_level();
}

Here is the call graph for this function:

Here is the caller graph for this function:

static gboolean is_our_board ( GcomprisBoard *  gcomprisBoard) [static]

Definition at line 176 of file machpuzzle.c.

{
  if (gcomprisBoard)
    {
      if(g_strcasecmp(gcomprisBoard->type, "machpuzzle")==0)
       {
         /* Set the plugin entry */
         gcomprisBoard->plugin=&menu_bp;

         return TRUE;
       }
    }
  return FALSE;
}
static gint item_event ( GnomeCanvasItem *  item,
GdkEvent *  event,
MachItem *  machItem 
) [static]

Definition at line 271 of file machpuzzle.c.

{
  double item_x, item_y;
  double x1, y1, x2, y2;
  double width;
  item_x = event->button.x;
  item_y = event->button.y;
  gnome_canvas_item_w2i(item->parent, &item_x, &item_y);
  gnome_canvas_item_get_bounds    (item,
                               &x1,
                               &y1,
                               &x2,
                               &y2);

  if(board_paused)
    return FALSE;

   switch (event->type)
     {

     case GDK_BUTTON_PRESS:
       width = x2-x1;

       //       machItem->vyo   = (y1 - machItem->ypos) * machItem->elasticity;
       machItem->times = 0;
       machItem->yposo = machItem->ypos;
       machItem->xposo = machItem->xpos;

       machItem->vyo = ((item_y-y1)<width/2?(width/2-(item_y-y1))*20:-1*(width/2-(y2-item_y))*20);
       machItem->vxo = ((item_x-x1)<width/2?(width/2-(item_x-x1))*20:-1*(width/2-(x2-item_x))*20);
       break;

     default:
       break;
     }


   return FALSE;
}

Here is the caller graph for this function:

static GnomeCanvasItem * minigolf_create_item ( GnomeCanvasGroup *  parent) [static]

Definition at line 234 of file machpuzzle.c.

{

  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));

  create_machine_item(MACH_HOLE, 730.0, 260.0);
  create_machine_item(MACH_BASKET_BALL, (double)RAND(60, 150), (double)RAND(60, 400));


  return NULL;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void minigolf_destroy_all_items ( void  ) [static]

Definition at line 212 of file machpuzzle.c.

{
  if(boardRootItem!=NULL)
    gtk_object_destroy (GTK_OBJECT(boardRootItem));

  if (move_id) {
    gtk_timeout_remove (move_id);
    move_id = 0;
  }

  boardRootItem = NULL;

  if(item_list)
  {
      int i;
      for( i=0; i< g_list_length(item_list); i++)
          g_free(g_list_nth_data(item_list,i));
      g_list_free(item_list);
  }
  item_list = NULL;
}

Here is the caller graph for this function:

static void minigolf_move ( GList *  item_list) [static]

Definition at line 518 of file machpuzzle.c.

{
  double              x1, y1, x2, y2;
  MachItem           *machItem;
  GnomeCanvasItem    *item;
  guint                      i;
  gboolean            collision = FALSE;
  double               xpos, ypos;

  for(i=0; i<g_list_length(item_list); i++)
    {
      gint j;

      machItem = g_list_nth_data(item_list, i);

      //      dump_machItem(machItem);
      item = machItem->item;

      if(machItem->moving)
       {

         gnome_canvas_item_get_bounds(item, &x1, &y1, &x2, &y2);

         machItem->times += times_inc;

         /* Collision detection */
         for(j=0; j<g_list_length(item_list); j++)
           {
             MachItem             *collMachItem;

             collMachItem = g_list_nth_data(item_list, j);

             //printf("Checking coll detec item %d\n", j);

             if(collMachItem != machItem) {

              if(rectangle_in(x1, y1, x2, y2,
                            collMachItem->xpos,
                            collMachItem->ypos,
                            collMachItem->xpos + collMachItem->width,
                            collMachItem->ypos + collMachItem->height))
                {
                  //printf("!!! Collision detected with:\n");
                  //dump_machItem(collMachItem);
                  collision = TRUE;

                  gamewon = TRUE;
                  minigolf_destroy_all_items();
                  gc_bonus_display(gamewon, BONUS_SMILEY);
                  return;
                }
             }
           }

         ypos=machItem->yposo
           + (machItem->vyo*machItem->times)
           + (.5*machItem->ay * (machItem->times*machItem->times));

         /* Simulate going slower */
         if(ABS(machItem->ypos-ypos)>0.3) {
           machItem->vyo = machItem->vyo * velocity;
         } else {
           machItem->yposo = ypos;
           machItem->vyo = 0;
         }

         xpos=machItem->xposo
           + (machItem->vxo*machItem->times)
           + (.5*machItem->ax * (machItem->times*machItem->times));

         /* Simulate going slower */
         if(ABS(machItem->xpos-xpos)>0.3) {
           machItem->vxo = machItem->vxo * velocity;
         } else {
           machItem->xposo = xpos;
           machItem->vxo = 0;
         }

         machItem->xpos=xpos;
         machItem->ypos=ypos;

         /* v = u + at */
         machItem->vxo += (machItem->ax * machItem->times);
         machItem->vyo += (machItem->ay * machItem->times);

         if(machItem->ypos >= MIN_Y2 - machItem->height -1)
           machItem->ypos = MIN_Y2 - machItem->height;

         if(machItem->ypos < MIN_Y1)
           machItem->ypos = MIN_Y1;

         if(machItem->xpos < MIN_X1)
           machItem->xpos = MIN_X1;

         if(machItem->xpos > MIN_X2)
           machItem->xpos = MIN_X2;


         gc_item_absolute_move(item, machItem->xpos, machItem->ypos);

         if((machItem->ypos>=MIN_Y2-machItem->height-BORDER && (y1 - machItem->ypos)<=0) || collision == TRUE)
           {
             machItem->vyo   = machItem->vyo * -0.5;
             machItem->vxo   = machItem->vxo * 0.5;
             machItem->times = 0;
             machItem->yposo = machItem->ypos;
             machItem->xposo = machItem->xpos;

             /* Floor touch */
             //machItem->vxo *= 0.9;
           }

         if((y1<=MIN_Y1 && (y1 - machItem->ypos)>=0) || collision == TRUE)
           {
             machItem->vyo   = machItem->vyo * -0.5;
             machItem->vxo   = machItem->vxo * 0.5;
             machItem->times=0;
             machItem->yposo=machItem->ypos;
             machItem->xposo=machItem->xpos;
           }

         //     if(x1<=5 && (x1 - machItem->xpos)>0 || collision == TRUE)
         if((x1<=MIN_X1 && machItem->vxo<0) || collision == TRUE)
           {
             machItem->vyo   = machItem->vyo * 0.5;
             machItem->vxo   = machItem->vxo * -0.5;
             machItem->times=0;
             machItem->yposo=machItem->ypos;
             machItem->xposo=machItem->xpos;
           }

         if((x2>=MIN_X2 && machItem->vxo>0) || collision == TRUE)
           {
             machItem->vyo = 0.5 * machItem->vyo;
             machItem->vxo = machItem->vxo * -0.5;
             machItem->times=0;
             machItem->yposo=machItem->ypos;
             machItem->xposo=machItem->xpos;
           }

       }

    }

}

Here is the call graph for this function:

Here is the caller graph for this function:

static void minigolf_next_level ( void  ) [static]

Definition at line 194 of file machpuzzle.c.

{

  gc_set_background(gnome_canvas_root(gcomprisBoard->canvas),"images/foot_background.png");

  gc_bar_set_level(gcomprisBoard);

  minigolf_destroy_all_items();
  gamewon = FALSE;

  /* Try the next level */
  minigolf_create_item(gnome_canvas_root(gcomprisBoard->canvas));

  move_id = gtk_timeout_add (40, (GtkFunction) minigolf_move, item_list);

}

Here is the call graph for this function:

Here is the caller graph for this function:

static void pause_board ( gboolean  pause) [static]

Definition at line 120 of file machpuzzle.c.

{
  if(gcomprisBoard==NULL)
    return;

  if(gamewon == TRUE && pause == FALSE) /* the game is won */
    {
      game_won();
    }

  board_paused = pause;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static gint rectangle_in ( double  sx1,
double  sy1,
double  sx2,
double  sy2,
double  dx1,
double  dy1,
double  dx2,
double  dy2 
) [static]

Definition at line 496 of file machpuzzle.c.

{
  guint corner_in = 0;
  //  printf("rectangle_in %10f %10f %10f %10f\n             %10f %10f %10f %10f\n", sx1,sy1,sx2,sy2,dx1,dy1,dx2,dy2);

  if(sx1>dx1 && sx1<dx2 && sy1>dy1 && sy1<dy2)
    corner_in++;

  if(sx2>dx1 && sx2<dx2 && sy2>dy1 && sy2<dy2)
    corner_in++;

  if(sx2>dx1 && sx2<dx2 && sy1>dy1 && sy1<dy2)
    corner_in++;

  if(sx1>dx1 && sx1<dx2 && sy2>dy1 && sy2<dy2)
    corner_in++;

  return (corner_in>=3 ? TRUE : FALSE);
}

Here is the caller graph for this function:

static void set_level ( guint  level) [static]

Definition at line 165 of file machpuzzle.c.

{

  if(gcomprisBoard!=NULL)
    {
      gcomprisBoard->level=level;
      gcomprisBoard->sublevel=1;
      minigolf_next_level();
    }
}

Here is the call graph for this function:

static void start_board ( GcomprisBoard *  agcomprisBoard) [static]

Definition at line 135 of file machpuzzle.c.

{

  if(agcomprisBoard!=NULL)
    {
      gcomprisBoard=agcomprisBoard;
      gcomprisBoard->level=1;
      gcomprisBoard->maxlevel=6;
      gcomprisBoard->sublevel=1;
      gcomprisBoard->number_of_sublevel=1; /* Go to next level after this number of 'play' */
      gc_bar_set(GC_BAR_LEVEL);

      minigolf_next_level();

      gamewon = FALSE;
      pause_board(FALSE);
    }
}

Here is the call graph for this function:


Variable Documentation

gboolean board_paused = TRUE [static]

Definition at line 51 of file machpuzzle.c.

GnomeCanvasGroup* boardRootItem = NULL [static]

Definition at line 64 of file machpuzzle.c.

int gamewon [static]

Definition at line 61 of file machpuzzle.c.

GcomprisBoard* gcomprisBoard = NULL [static]

Definition at line 50 of file machpuzzle.c.

double gravity = 0 [static]

Definition at line 54 of file machpuzzle.c.

GList* item_list = NULL [static]

Definition at line 48 of file machpuzzle.c.

BoardPlugin menu_bp [static]
Initial value:
  {
    NULL,
    NULL,
    N_("Move the mouse"),
    "football",
    "Bruno Coudoin <bruno.coudoin@free.fr>",
    NULL,
    NULL,
    NULL,
    NULL,
    start_board,
    pause_board,
    end_board,
    is_our_board,
    NULL,
    NULL,
    set_level,
    NULL,
    NULL,
    NULL,
    NULL
  }

Definition at line 84 of file machpuzzle.c.

gint move_id = 0 [static]

Definition at line 52 of file machpuzzle.c.

double times_inc = 0.1 [static]

Definition at line 53 of file machpuzzle.c.

double velocity = 0.99 [static]

Definition at line 55 of file machpuzzle.c.