From 3488109d65605e64aac8336a90df9994e10c494e Mon Sep 17 00:00:00 2001 From: soeren Date: Thu, 21 Jan 2010 13:40:40 +0000 Subject: [PATCH] improved the wurstwasser-kompensator! --- games/breakout/ball.c | 72 +++++++++++++++++++++++++++++++------- games/breakout/ball.h | 2 +- games/breakout/breakout.c | 19 +++++++--- games/breakout/common.h | 2 ++ games/breakout/level.c | 21 ++++++++++- games/breakout/level.h | 1 + games/breakout/messages.c | 20 +++++++++++ games/breakout/messages.h | 8 +++++ games/breakout/playfield.c | 23 ++++++++---- games/breakout/playfield.h | 9 +++-- games/breakout/rebound.c | 44 +++++++++++++++++++++++ games/breakout/rebound.h | 7 ++++ games/breakout/score.c | 11 ++++++ 13 files changed, 212 insertions(+), 27 deletions(-) create mode 100644 games/breakout/messages.c create mode 100644 games/breakout/messages.h create mode 100644 games/breakout/rebound.c create mode 100644 games/breakout/rebound.h create mode 100644 games/breakout/score.c diff --git a/games/breakout/ball.c b/games/breakout/ball.c index 83f6f8c..11ec087 100644 --- a/games/breakout/ball.c +++ b/games/breakout/ball.c @@ -1,20 +1,59 @@ #include "common.h" +/* modify a vecotor according to given type of bouncing */ +void bounce_rand_vector (ball_t *in_b, uint8_t in_bouncetype); +void bounce_rand_vector (ball_t *in_b, uint8_t in_bouncetype) +{ + uint8_t rval = random8(); + + switch (in_bouncetype) + { + case BOUNCE_NONE: /* don't touch the vector since nothing changed */ + return; + + case BOUNCE_BRICK: + in_b->dir_x ^= (rval & 0x07); + in_b->dir_y ^= (rval & 0x07); + break; + + case BOUNCE_REBOUND: /* the rebound is rather percise */ + in_b->dir_x ^= (rval & 0x03); + in_b->dir_y ^= (rval & 0x03); + if (JOYISRIGHT || JOYISLEFT) + { + /* a moving rebond accelerates the ball by 1/8th */ + in_b->dir_y += (in_b->dir_y / 8); + in_b->dir_x += (in_b->dir_x / 8); + } + break; + + default: /* walls */ + in_b->dir_x ^= (rval & 0x01); + in_b->dir_y ^= (rval & 0x01); + } + if (!in_b->dir_x) + in_b->dir_x = 213; + + if (!in_b->dir_y) + in_b->dir_y = 217; +} void ball_think (ball_t *b) { int8_t proj_x, proj_y, bounce; + + /* if (!b->strength) return; + */ /* projection of the new coordinates */ proj_x = (b->x + (b->dir_x)) / 256; proj_y = (b->y + (b->dir_y)) / 256; - /* ball fell out of the field */ + /* falling out of the field */ if (proj_y >= NUM_ROWS) ball_die (b); - bounce = check_bounce (proj_x, b->y / 256); if (bounce & BOUNCE_UNDEF) @@ -28,14 +67,12 @@ void ball_think (ball_t *b) if (bounce & BOUNCE_UNDEF) bounce = BOUNCE_X | BOUNCE_Y; - + bounce_rand_vector (b, bounce); /* bounce in x direction */ - if (bounce & 0x01) + if (bounce & (BOUNCE_X | BOUNCE_BRICK)) { b->dir_x *= -1; /* invert x vector */ - b->dir_x ^= random8() & 0x0F; /* randomize bouncing */ - #if BOUNCE_SLOWDOWN if (b->dir_x < 0) @@ -49,10 +86,10 @@ void ball_think (ball_t *b) } /* bounce in y direction */ - if (bounce & 0x02) + if (bounce & (BOUNCE_Y | BOUNCE_BRICK)) { b->dir_y *= -1; /* invert y vector */ - b->dir_y ^= random8() & 0x0F; + #if BOUNCE_SLOWDOWN if (b->dir_y < 0) { @@ -66,6 +103,11 @@ void ball_think (ball_t *b) b->y += b->dir_y; b->x += b->dir_x; + + if (!b->dir_x || !b->dir_y) + { + printf("Ball stopped!\n"); + } } void ball_die (ball_t *in_b) @@ -76,7 +118,7 @@ void ball_die (ball_t *in_b) if (in_b->strength) { print_ballsleft(in_b); - ball_spawn (in_b, (uint16_t) (rebound_getpos() * 256), (uint16_t) (NUM_ROWS-2) * 256, -120, 150, in_b->strength); + ball_spawn_default (in_b); } } @@ -89,16 +131,22 @@ void ball_draw (ball_t *b) setpixel (p, 3); } -void ball_spawn (ball_t *in_ball, uint16_t in_x, uint16_t in_y, int16_t in_dir_x, int16_t in_dir_y, uint8_t in_strength) +void ball_spawn (ball_t *in_ball, uint16_t in_x, uint16_t in_y, int16_t in_dir_x, int16_t in_dir_y) { in_ball->x = in_x; in_ball->y = in_y; in_ball->dir_x = in_dir_x; in_ball->dir_y = in_dir_y; - in_ball->strength = in_strength; } void ball_spawn_default (ball_t *in_b) { - ball_spawn (in_b, (uint16_t) (NUM_COLS / 2) * 256, (uint16_t) (NUM_ROWS-2) * 256, -120, 150, START_LIFES); + int16_t xdir; + + xdir = 128 + (random8() & 0x3F); + if (random8() & 0x01) + xdir *= -1; + + ball_spawn (in_b, (uint16_t) rebound_getpos() * 256, (NUM_ROWS -2) * 256, + xdir, -131); } diff --git a/games/breakout/ball.h b/games/breakout/ball.h index 07d41d2..3d4d1c8 100644 --- a/games/breakout/ball.h +++ b/games/breakout/ball.h @@ -14,7 +14,7 @@ typedef struct uint8_t strength; } ball_t; -void ball_spawn (ball_t *in_ball, uint16_t in_x, uint16_t in_y, int16_t in_dir_x, int16_t in_dir_y, uint8_t in_strength); +void ball_spawn (ball_t *in_ball, uint16_t in_x, uint16_t in_y, int16_t in_dir_x, int16_t in_dir_y); /* @description Called once per game tick. Move the ball further along it's vector. */ diff --git a/games/breakout/breakout.c b/games/breakout/breakout.c index ac928ca..5d75fe0 100644 --- a/games/breakout/breakout.c +++ b/games/breakout/breakout.c @@ -4,7 +4,7 @@ void borg_breakout(); #ifdef MENU_SUPPORT //static uint8_t breakout_icon[8] PROGMEM = {0x03, 0x03, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00}; /* our Icon */ -static uint8_t breakout_icon[8] PROGMEM = {0x18, 0x18, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00}; /* our Icon */ +static uint8_t breakout_icon[8] PROGMEM = {0x00, 0x18, 0x18, 0x00, 0x00, 0xff, 0xff, 0x00}; /* our Icon */ game_descriptor_t breakout_game_descriptor __attribute__((section(".game_descriptors"))) = { @@ -15,12 +15,13 @@ game_descriptor_t breakout_game_descriptor __attribute__((section(".game_descrip void borg_breakout() { - uint8_t rungame = 1, num_balls = 1; + uint8_t rungame = 1, num_balls = 1, level = 0; ball_t balls[1]; /* spawn a ball in the middle bottom of the field, let it move upwards with random speed & direction */ - ball_spawn (&balls[0], (uint16_t) (NUM_COLS / 2) * 256, (uint16_t) (NUM_ROWS-2) * 256, -120, 150, START_LIFES); - level_init(0); + ball_spawn_default(&(balls[0])); + balls[0].strength = START_LIFES; + level_init(level); rebound_init(); while (23) @@ -35,5 +36,15 @@ void borg_breakout() print_score(); break; } + + if (!level_getscorediff()) + { + printf("lvl done\n"); + level++; + /* respawn ball at rebound position */ + ball_spawn_default (&(balls[0])); + balls[0].strength++; + level_init(level); + } } } diff --git a/games/breakout/common.h b/games/breakout/common.h index 97bbf52..cc29b06 100644 --- a/games/breakout/common.h +++ b/games/breakout/common.h @@ -19,4 +19,6 @@ #include "level.h" #include "rebound.h" #include "messages.h" + +#define MAX(a,b) (a > b) ? a : b #endif /* COMMON_H */ diff --git a/games/breakout/level.c b/games/breakout/level.c index d2ba4aa..c9e0696 100644 --- a/games/breakout/level.c +++ b/games/breakout/level.c @@ -1,11 +1,19 @@ #include "level.h" +static uint16_t maxscore; + /* real level definition */ enum game_field_t level_field (uint8_t in_x, uint8_t in_y, uint8_t in_lvl); enum game_field_t level_field (uint8_t in_x, uint8_t in_y, uint8_t in_lvl) { switch (in_lvl) { + case 0: + /* space for the lower half of the level */ + if (in_y > (NUM_ROWS / 3)) + return sp; + + return b1; /* b1-blocks for the rest */ case 1: /* space for the lower half of the level */ if (in_y > (NUM_ROWS / 2)) @@ -56,13 +64,24 @@ enum game_field_t level_field (uint8_t in_x, uint8_t in_y, uint8_t in_lvl) void level_init (uint8_t in_levelnum) { uint8_t x,y; + enum game_field_t tmp; + maxscore = 0; for (x=0;xstrength); + scrolltext(txt); +#endif +} + +void print_score () +{ +#ifdef SCROLLTEXT_SUPPORT + uint8_t txt[32]; + snprintf (txt, sizeof(txt), "= NUM_ROWS || in_y >= NUM_COLS) + { + return; + } playfield[in_x][in_y] = in_field; } @@ -10,8 +14,9 @@ void brick_damage (uint8_t in_x, uint8_t in_y) { enum game_field_t newtype; - if (playfield[in_x][in_y] > bs || playfield[in_x][in_y] == 0) + if (playfield[in_x][in_y] >= bs || playfield[in_x][in_y] == 0) return; + playfield[in_x][in_y] -= 1; score_add (1); } @@ -26,7 +31,11 @@ uint8_t check_bounce (int8_t in_x, int8_t in_y) if (in_y >= NUM_COLS || in_y < 0) ov |= BOUNCE_Y; - if (ov) return ov; + if (ov) + { + return ov; + } + /* collisions with real objects */ switch (playfield[abs(in_x)][abs(in_y)]) { @@ -35,20 +44,22 @@ uint8_t check_bounce (int8_t in_x, int8_t in_y) case b1: brick_damage (in_x, in_y); /* intentional fallthrough */ - case bs: - return BOUNCE_UNDEF | ov; + ov |= BOUNCE_BRICK; + break; /* bouncing on the rebound needs special care */ case rb: - return BOUNCE_Y; + ov |= BOUNCE_Y | BOUNCE_REBOUND; + break; case sp: case bl: default: - return ov; + break; } + return ov; } /* this is the actual draw function for a single field diff --git a/games/breakout/playfield.h b/games/breakout/playfield.h index b7ef992..ebb0f2b 100644 --- a/games/breakout/playfield.h +++ b/games/breakout/playfield.h @@ -2,9 +2,12 @@ #define PLAYFIELD_H #include "common.h" -#define BOUNCE_X 0x01 -#define BOUNCE_Y 0x02 -#define BOUNCE_UNDEF 0x04 +#define BOUNCE_NONE 0x00 +#define BOUNCE_X 0x01 +#define BOUNCE_Y 0x02 +#define BOUNCE_UNDEF 0x04 +#define BOUNCE_BRICK 0x08 +#define BOUNCE_REBOUND 0x10 /* entries for the playing field */ enum game_field_t diff --git a/games/breakout/rebound.c b/games/breakout/rebound.c new file mode 100644 index 0000000..0b4e8c1 --- /dev/null +++ b/games/breakout/rebound.c @@ -0,0 +1,44 @@ +#include "rebound.h" + +#include +static uint8_t rbpos; + +uint8_t rebound_getpos () +{ + return (rbpos + (REBOUND_SIZE / 2)); +} + +void rebound_init() +{ + rbpos = (NUM_ROWS / 2) - (REBOUND_SIZE / 2); + rebound_draw(); +} + +void rebound_draw () +{ + uint8_t i; + + for (i=rbpos;i