Agrego la colisión del pingüino contra las bolsas de café.

master
Félix Arreola Rodríguez 2018-06-04 20:19:38 -05:00
parent 4149eb480b
commit 59fb8204af
8 changed files with 549 additions and 21 deletions

View File

@ -10,7 +10,8 @@ nobase_dist_collidergamedata_DATA = \
penguin_7.col \
penguin_8.col \
penguin_9.col \
penguin_10.col
penguin_10.col \
bag_3.col
noinst_PROGRAMS = penguin-generator collider-generator
penguin_generator_SOURCES = generate-penguins.c \
@ -54,3 +55,4 @@ colliders: collider-generator penguin-generator
$(COLLIDER_GENERATOR) penguin_10.png penguin_10.col
rm penguin_1.png penguin_2.png penguin_3.png penguin_4.png penguin_5.png penguin_6.png penguin_7.png penguin_8.png penguin_9.png penguin_10.png
$(COLLIDER_GENERATOR) $(top_srcdir)/data/images/bag_3.png bag_3.col

Binary file not shown.

View File

@ -6,6 +6,8 @@ bin_PROGRAMS = bean-counters-classic
bean_counters_classic_SOURCES = beans.c \
gfx_blit_func.c gfx_blit_func.h \
path.c path.h \
collider.c collider.h \
sdl2_rect.c sdl2_rect.h \
gettext.h
if MACOSX

View File

@ -42,6 +42,7 @@
#include "path.h"
#include "gfx_blit_func.h"
#include "collider.h"
#define FPS (1000/24)
#define RANDOM(x) ((int) (x ## .0 * rand () / (RAND_MAX + 1.0)))
@ -228,6 +229,38 @@ enum {
NUM_PENGUIN_FRAMES
};
enum {
COLLIDER_BAG_3,
COLLIDER_PENGUIN_1,
COLLIDER_PENGUIN_2,
COLLIDER_PENGUIN_3,
COLLIDER_PENGUIN_4,
COLLIDER_PENGUIN_5,
COLLIDER_PENGUIN_6,
COLLIDER_PENGUIN_7,
COLLIDER_PENGUIN_8,
COLLIDER_PENGUIN_9,
COLLIDER_PENGUIN_10,
NUM_COLLIDERS
};
const char *collider_names[NUM_COLLIDERS] = {
"collider/bag_3.col",
"collider/penguin_1.col",
"collider/penguin_2.col",
"collider/penguin_3.col",
"collider/penguin_4.col",
"collider/penguin_5.col",
"collider/penguin_6.col",
"collider/penguin_7.col",
"collider/penguin_8.col",
"collider/penguin_9.col",
"collider/penguin_10.col"
};
const SDL_Color penguin_colors[18] = {
{0, 51, 102},
{51, 51, 51},
@ -262,24 +295,24 @@ const int bag_0_points[31][3] = {
{1, 479, 27},
{1, 465, 27},
{1, 456, 28},
{2, 427, 43},
{2, 413, 46},
{2, 400, 49},
{2, 387, 51},
{2, 371, 59},
{2, 355, 66},
{2, 338, 73},
{2, 322, 88},
{2, 305, 102},
{2, 288, 117},
{2, 274, 139},
{2, 259, 161},
{2, 245, 183},
{2, 234, 211},
{2, 223, 239},
{2, 212, 268},
{2, 204, 300},
{2, 196, 333},
{2, 427, 86},
{2, 413, 89},
{2, 401, 93},
{2, 388, 97},
{2, 371, 103},
{2, 355, 110},
{2, 340, 119},
{2, 322, 131},
{2, 305, 146},
{2, 290, 161},
{2, 273, 181},
{2, 259, 203},
{2, 246, 226},
{2, 233, 254},
{2, 223, 282},
{2, 214, 311},
{2, 205, 343},
{2, 196, 375},
{3, 165, 408}
};
@ -390,6 +423,7 @@ SDL_Surface * screen;
SDL_Surface * images[NUM_IMAGES];
SDL_Surface * penguin_images[NUM_PENGUIN_FRAMES];
int use_sound;
Collider *colliders[NUM_COLLIDERS];
int color_penguin = 0;
@ -535,7 +569,7 @@ int game_loop (void) {
int bags = 0;
int penguin_frame = 0;
int i, j;
int i, j, k;
int level, activator;
int bag_activity = 15;
@ -619,6 +653,12 @@ int game_loop (void) {
}
}
if (bags >= 0 && bags <= 6) {
k = COLLIDER_PENGUIN_1 + bags;
} else {
k = COLLIDER_PENGUIN_7;
}
/* Procesar las bolsas */
thisbag = first_bag;
while (thisbag != NULL) {
@ -628,7 +668,23 @@ int game_loop (void) {
j = thisbag->frame - thisbag->throw_length;
/* Calcular aquí la colisión contra el pingüino */
if (j < 0) {
/* Calcular aquí la colisión contra el pingüino */
i = collider_hittest (colliders[COLLIDER_BAG_3], thisbag->bag_points[thisbag->frame][1], thisbag->bag_points[thisbag->frame][2], colliders[k], penguinx - 120, 251);
if (i == SDL_TRUE) {
bags++;
k = COLLIDER_PENGUIN_1 + bags;
/* Reproducir el sonido de "Agarrar bolsa" */
/* Sumar score = score + (nivel * 2); */
airbone--;
delete_bag (thisbag);
thisbag = nextbag;
continue;
}
}
if (j == 0) {
/* Eliminar del airbone */
@ -736,6 +792,7 @@ void setup (void) {
int g;
char buffer_file[8192];
char *systemdata_path = get_systemdata_path ();
Collider *c;
/* Inicializar el Video SDL */
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
@ -807,6 +864,21 @@ void setup (void) {
setup_and_color_penguin ();
/* Cargar los colliders de los pingüinos */
for (g = 0; g < NUM_COLLIDERS; g++) {
sprintf (buffer_file, "%s%s", systemdata_path, collider_names[g]);
c = collider_new_from_file (buffer_file);
if (c == NULL) {
fprintf (stderr,
_("Failed to load data file:\n"
"%s\n"), buffer_file);
SDL_Quit ();
exit (1);
}
colliders[g] = c;
}
if (use_sound) {
/*for (g = 0; g < NUM_SOUNDS; g++) {
sprintf (buffer_file, "%s%s", systemdata_path, sound_names[g]);

192
src/collider.c 100644
View File

@ -0,0 +1,192 @@
/*
* collider.c
* This file is part of Bean Counters Classic
*
* Copyright (C) 2018 - Félix Arreola Rodríguez
*
* Bean Counters Classic 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.
*
* Bean Counters Classic 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 Bean Counters Classic; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
#include <SDL.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "collider.h"
#include "sdl2_rect.h"
struct _Collider {
Uint32 offset_x, offset_y;
Uint32 size_w, size_h;
Uint32 pitch;
Uint32 *pixels;
};
Uint32 collider_extract_block (Collider *c, int y, int x, int size) {
int bit_pos;
int align;
Uint32 res;
bit_pos = c->pitch * y + (x / 32);
align = 32 - (x % 32);
if (align == 32) {
res = c->pixels[bit_pos];
} else {
res = c->pixels[bit_pos] << (32 - align);
res = res | (c->pixels[bit_pos + 1] >> align);
}
if (size < 32) {
/* Quitar los bits sobrantes */
res = res ^ (res & ((1 << (32 - size)) - 1));
}
return res;
}
Collider * collider_new_from_file (const char *filename) {
int fd;
Collider *new;
Uint32 temp;
Uint32 four_int[4];
int res, g, h;
int map_size;
fd = open (filename, O_RDONLY);
if (fd < 0) {
return NULL;
}
new = (Collider *) malloc (sizeof (Collider));
if (new == NULL) goto bad_load;
/* Empezar a leer los bytes iniciales para saber cuánto reservar en pixeles */
res = read (fd, &temp, sizeof (temp));
if (res < 0) goto bad_load_and_free;
/* Versión incorrecta */
if (temp != 1) goto bad_load_and_free;
/* Consumir el byte extra de alineación de bytes */
res = read (fd, &temp, sizeof (temp));
if (res < 0) goto bad_load_and_free;
res = read (fd, four_int, 4 * sizeof (Uint32));
if (res < 4 * sizeof (Uint32)) goto bad_load_and_free;
new->offset_x = four_int[0];
new->offset_y = four_int[1];
new->size_w = four_int[2];
new->size_h = four_int[3];
if (new->size_w % 32 != 0) {
new->pitch = (new->size_w / 32) + 2;
} else {
new->pitch = (new->size_w / 32) + 1;
}
map_size = new->pitch * new->size_h;
new->pixels = (Uint32 *) malloc (sizeof (Uint32) * map_size);
if (new->pixels == NULL) goto bad_load_and_free;
memset (new->pixels, 0, sizeof (Uint32) * map_size);
for (h = 0; h < new->size_h; h++) {
for (g = 0; g < new->pitch; g++) {
res = read (fd, &temp, sizeof (Uint32));
if (res < 0) goto bad_load_and_free_pixels;
new->pixels[(h * new->pitch) + g] = temp;
}
}
close (fd);
return new;
bad_load_and_free_pixels:
free (new->pixels);
bad_load_and_free:
free (new);
bad_load:
close (fd);
return NULL;
}
int collider_hittest (Collider *a, int x1, int y1, Collider *b, int x2, int y2) {
SDL_Rect rect_left, rect_right, result;
int first = SDL_FALSE;
int g, h;
int s, x;
int offset_a_x, offset_a_y;
int offset_b_x, offset_b_y;
rect_left.x = x1 + a->offset_x; // Sumar los offsets del collider
rect_left.y = y1 + a->offset_y;
rect_left.w = a->size_w;
rect_left.h = a->size_h;
rect_right.x = x2 + b->offset_x;
rect_right.y = y2 + b->offset_y;
rect_right.w = b->size_w;
rect_right.h = b->size_h;
first = SDL_IntersectRect (&rect_left, &rect_right, &result);
if (first == SDL_FALSE) {
/* Ni siquiera cercas */
//printf ("Ni siquiera cercas de colision\n");
return 0;
}
offset_a_y = result.y - rect_left.y;
offset_a_x = result.x - rect_left.x;
offset_b_y = result.y - rect_right.y;
offset_b_x = result.x - rect_right.x;
Uint32 block_a, block_b;
for (h = result.h; h >= 0; h++) {
s = result.w;
x = 0;
while (s > 0) {
block_a = collider_extract_block (a, h + offset_a_y, x + offset_a_x, s);
block_b = collider_extract_block (b, h + offset_b_y, x + offset_b_x, s);
block_a = block_a & block_b;
if (block_a != 0) {
return 1;
}
x = x + 32;
s = s - 32;
}
}
return 0;
}

31
src/collider.h 100644
View File

@ -0,0 +1,31 @@
/*
* collider.h
* This file is part of Bean Counters Classic
*
* Copyright (C) 2018 - Félix Arreola Rodríguez
*
* Bean Counters Classic 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.
*
* Bean Counters Classic 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 Bean Counters Classic; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
#ifndef __COLLIDER_H__
#define __COLLIDER_H__
typedef struct _Collider Collider;
Collider * collider_new_from_file (const char *filename);
int collider_hittest (Collider *a, int x1, int y1, Collider *b, int x2, int y2);
#endif

188
src/sdl2_rect.c 100644
View File

@ -0,0 +1,188 @@
/*
* sdl2_rect.c
* This file is part of Find Four
*
* Copyright (C) 2017 - Félix Arreola Rodríguez
*
* Find Four 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.
*
* Find Four 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 Find Four; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
#include <SDL.h>
#include "sdl2_rect.h"
/* Funciones */
int SDL_RectEmpty(const SDL_Rect *r) {
return ((!r) || (r->w <= 0) || (r->h <= 0)) ? SDL_TRUE : SDL_FALSE;
}
int SDL_HasIntersection(const SDL_Rect * A, const SDL_Rect * B) {
int Amin, Amax, Bmin, Bmax;
if (!A) {
return SDL_FALSE;
}
if (!B) {
return SDL_FALSE;
}
/* Special cases for empty rects */
if (SDL_RectEmpty(A) || SDL_RectEmpty(B)) {
return SDL_FALSE;
}
/* Horizontal intersection */
Amin = A->x;
Amax = Amin + A->w;
Bmin = B->x;
Bmax = Bmin + B->w;
if (Bmin > Amin)
Amin = Bmin;
if (Bmax < Amax)
Amax = Bmax;
if (Amax <= Amin)
return SDL_FALSE;
/* Vertical intersection */
Amin = A->y;
Amax = Amin + A->h;
Bmin = B->y;
Bmax = Bmin + B->h;
if (Bmin > Amin)
Amin = Bmin;
if (Bmax < Amax)
Amax = Bmax;
if (Amax <= Amin)
return SDL_FALSE;
return SDL_TRUE;
}
int SDL_IntersectRect(const SDL_Rect * A, const SDL_Rect * B, SDL_Rect * result) {
int Amin, Amax, Bmin, Bmax;
if (!A) {
return SDL_FALSE;
}
if (!B) {
return SDL_FALSE;
}
if (!result) {
return SDL_FALSE;
}
/* Special cases for empty rects */
if (SDL_RectEmpty(A) || SDL_RectEmpty(B)) {
result->w = 0;
result->h = 0;
return SDL_FALSE;
}
/* Horizontal intersection */
Amin = A->x;
Amax = Amin + A->w;
Bmin = B->x;
Bmax = Bmin + B->w;
if (Bmin > Amin)
Amin = Bmin;
result->x = Amin;
if (Bmax < Amax)
Amax = Bmax;
if (Amax - Amin < 0) {
result->w = 0;
} else {
result->w = Amax - Amin;
}
/* Vertical intersection */
Amin = A->y;
Amax = Amin + A->h;
Bmin = B->y;
Bmax = Bmin + B->h;
if (Bmin > Amin)
Amin = Bmin;
result->y = Amin;
if (Bmax < Amax)
Amax = Bmax;
if (Amax - Amin < 0) {
result->h = 0;
} else {
result->h = Amax - Amin;
}
return !SDL_RectEmpty(result);
}
void SDL_UnionRect(const SDL_Rect * A, const SDL_Rect * B, SDL_Rect * result) {
int Amin, Amax, Bmin, Bmax;
if (!A) {
return;
}
if (!B) {
return;
}
if (!result) {
return;
}
/* Special cases for empty Rects */
if (SDL_RectEmpty(A)) {
if (SDL_RectEmpty(B)) {
/* A and B empty */
return;
} else {
/* A empty, B not empty */
*result = *B;
return;
}
} else {
if (SDL_RectEmpty(B)) {
/* A not empty, B empty */
*result = *A;
return;
}
}
/* Horizontal union */
Amin = A->x;
Amax = Amin + A->w;
Bmin = B->x;
Bmax = Bmin + B->w;
if (Bmin < Amin)
Amin = Bmin;
result->x = Amin;
if (Bmax > Amax)
Amax = Bmax;
result->w = Amax - Amin;
/* Vertical union */
Amin = A->y;
Amax = Amin + A->h;
Bmin = B->y;
Bmax = Bmin + B->h;
if (Bmin < Amin)
Amin = Bmin;
result->y = Amin;
if (Bmax > Amax)
Amax = Bmax;
result->h = Amax - Amin;
}

41
src/sdl2_rect.h 100644
View File

@ -0,0 +1,41 @@
/*
* sdl2_rect.h
* This file is part of Find Four
*
* Copyright (C) 2017 - Félix Arreola Rodríguez
*
* Find Four 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.
*
* Find Four 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 Find Four; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
#ifndef __SDL2_RECT_H__
#define __SDL2_RECT_H__
#include <SDL.h>
#ifndef SDL_FALSE
#define SDL_FALSE 0
#endif
#ifndef SDL_TRUE
#define SDL_TRUE -1
#endif
int SDL_RectEmpty(const SDL_Rect *r);
int SDL_HasIntersection(const SDL_Rect * A, const SDL_Rect * B);
int SDL_IntersectRect(const SDL_Rect * A, const SDL_Rect * B, SDL_Rect * result);
void SDL_UnionRect(const SDL_Rect * A, const SDL_Rect * B, SDL_Rect * result);
#endif /* __SDL2_RECT_H__ */