soeren
15 years ago
11 changed files with 360 additions and 0 deletions
@ -0,0 +1,56 @@ |
|||
#include "common.h" |
|||
|
|||
void ball_think (ball_t *b) |
|||
{ |
|||
uint8_t new_x, new_y; |
|||
if (!b->strength) |
|||
return; |
|||
|
|||
new_x = (b->x + b->dir_x) >> 8; |
|||
new_y = (b->y + b->dir_y) >> 8; |
|||
|
|||
/* ball fell out of the field */ |
|||
if (new_y >= NUM_ROWS) |
|||
ball_die (b); |
|||
|
|||
/* bounce in x direction */ |
|||
if (check_bounce (new_x, b->y >> 8)) |
|||
{ |
|||
b->dir_x *= -1; /* invert x vector */ |
|||
|
|||
#if BOUNCE_SLOWDOWN |
|||
if (b->dir_x < 0) |
|||
{ |
|||
b->dir_x += BOUNCE_SLOWDOWN; |
|||
} else |
|||
{ |
|||
b->dir_x -= BOUNCE_SLOWDOWN; |
|||
} |
|||
#endif |
|||
} |
|||
|
|||
/* bounce in y direction */ |
|||
if (check_bounce (b->x >> 8), new_y) |
|||
{ |
|||
b->dir_y *= -1; /* invert y vector */ |
|||
|
|||
#if BOUNCE_SLOWDOWN |
|||
if (b->dir_y < 0) |
|||
{ |
|||
b->dir_y += BOUNCE_SLOWDOWN; |
|||
} else |
|||
{ |
|||
b->dir_y -= BOUNCE_SLOWDOWN; |
|||
} |
|||
#endif |
|||
} |
|||
} |
|||
|
|||
void ball_die (ball_t *in_b) |
|||
{ |
|||
in_b->strength--; |
|||
|
|||
/* respawn ball with random direction */ |
|||
if (in_b->strength) |
|||
ball_spawn (in_b, (NUM_COLS / 2) << 8, (NUM_ROWS-2) << 8, - random8(), random8(), START_LIFES); |
|||
} |
@ -0,0 +1,35 @@ |
|||
#ifndef BALL_H |
|||
#define BALL_H |
|||
|
|||
#include <stdint.h> |
|||
#include "common.h" |
|||
|
|||
|
|||
typedef struct |
|||
{ |
|||
uint16_t x; |
|||
uint16_t y; |
|||
int16_t dir_x; /* direction vector */ |
|||
int16_t dir_y; |
|||
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) |
|||
{ |
|||
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; |
|||
} |
|||
|
|||
/* @description Called once per game tick. Move the ball further along it's vector.
|
|||
*/ |
|||
void ball_think (ball_t *in_ball); |
|||
|
|||
/* @description Change the ball's moving vector according to bounce and collision type
|
|||
*/ |
|||
void ball_bounce (ball_t *in_ball, enum collision_t in_coltype); |
|||
|
|||
void ball_die (ball_t *in_b) |
|||
#endif /* BALL_H */ |
@ -0,0 +1,32 @@ |
|||
|
|||
#include "../../menu/menu.h" |
|||
|
|||
static uint8_t icon[8] PROGMEM = |
|||
{0x03, 0x03, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00}; /* our Icon */ |
|||
|
|||
|
|||
#ifdef MENU_SUPPORT |
|||
game_descriptor_t invaders_game_descriptor __attribute__((section(".game_descriptors"))) ={ |
|||
&borg_breakout, |
|||
icon, |
|||
}; |
|||
#endif |
|||
|
|||
void borg_breakout() |
|||
{ |
|||
uint8_t rungame = 1, num_balls = 1; |
|||
ball_t balls[1]; |
|||
|
|||
ball_init (balls[0]); |
|||
|
|||
/* spawn a ball in the middle bottom of the field, let it move upwards with random speed & x-direction */ |
|||
ball_spawn (balls[0], (NUM_COLS / 2) << 8, (NUM_ROWS-2) << 8, - random8(), random8(), START_LIFES); |
|||
level_init(1); |
|||
|
|||
while (rungame) |
|||
{ |
|||
ball_think(balls[0]); |
|||
playfield_draw(); |
|||
ball_draw(balls[0]); |
|||
} |
|||
} |
@ -0,0 +1,8 @@ |
|||
typedef struct |
|||
{ |
|||
uint8_t x; |
|||
uint8_t y; |
|||
uint8_t strength; |
|||
} brick_t; |
|||
|
|||
void brick_damage (brick_t *in_brick); |
@ -0,0 +1,12 @@ |
|||
#ifndef COMMON_H |
|||
#define COMMON_H |
|||
#include <stdint.h> |
|||
#include "../../config.h" |
|||
#include "../../random/prng.h" |
|||
#include "../../pixel.h" |
|||
#include "config.h" |
|||
#include "playfield.h" |
|||
#include "ball.h" |
|||
#include "score.h" |
|||
#include "level.h" |
|||
#endif /* COMMON_H */ |
@ -0,0 +1,8 @@ |
|||
/* amount of speed to slow down on bounce */ |
|||
#define BOUNCE_SLOWDOWN 1 |
|||
|
|||
/* minimum speed of the ball */ |
|||
#define BALL_MINSPEED 0x0010 |
|||
|
|||
/* initial amount of lifes */ |
|||
#define START_LIFES 3 |
@ -0,0 +1,67 @@ |
|||
#include "level.h" |
|||
|
|||
/* real level definition */ |
|||
inline void level_field (uint8_t in_x, uint8_t in_y, uint8_t in_lvl) |
|||
{ |
|||
switch (in_lvl) |
|||
{ |
|||
case 1: |
|||
/* space for the lower half of the level */ |
|||
if (in_y < (NUM_ROWS / 2)) |
|||
return sp; |
|||
|
|||
/* type 2 bricks for 1/4th of the field */ |
|||
if (in_y >= (NUM_ROWS / 4)) |
|||
return b2; |
|||
|
|||
/* fill the rest with type 1 */ |
|||
return b1; |
|||
break; |
|||
|
|||
case 3: |
|||
/* add a row of solid bricks right in the middle of the field */ |
|||
if (in_y == (NUM_ROWS / 2) && |
|||
(in_x > (NUM_COLS / 4) && in_x < (NUM_COLS - (NUM_COLS / 4))) |
|||
return bs; |
|||
|
|||
/* intentional fallthrough: the rest of level 3 is like level 2 */ |
|||
|
|||
case 2: |
|||
/* space for the lower third of the level */ |
|||
if (in_y < (NUM_ROWS / 3)) |
|||
return sp; |
|||
|
|||
/* type 3 bricks for 1/8th of the field */ |
|||
if (in_y >= (NUM_ROWS / 8)) |
|||
return b3; |
|||
|
|||
/* type 2 bricks for 1/4th of the field */ |
|||
if (in_y >= (NUM_ROWS / 4)) |
|||
return b2; |
|||
|
|||
/* fill the rest with type 1 */ |
|||
return b1; |
|||
|
|||
default: /* random level generation */ |
|||
/* space for the lower half of the level */ |
|||
if (in_y < (NUM_ROWS / 2)) |
|||
return sp; |
|||
|
|||
return random8() % 5; /* fill field with random bricks (and spaces) */ |
|||
break; |
|||
} |
|||
} |
|||
|
|||
void level_init (uint8_t in_levelnum) |
|||
{ |
|||
uint8_t x,y; |
|||
|
|||
for (x=0;x<NUM_COLS;x++) |
|||
{ |
|||
for (y=0;y<NUM_ROWS;y++) |
|||
{ |
|||
playfield_set (x,y, level_field (x, y, in_levelnum)); |
|||
} |
|||
} |
|||
} |
|||
|
@ -0,0 +1,5 @@ |
|||
#ifndef LEVEL_H |
|||
#define LEVEL_H |
|||
#include "common.h" |
|||
void level_init (uint8_t in_levelnum) |
|||
#endif /* LEVEL_H */ |
@ -0,0 +1,93 @@ |
|||
#include "common.h" |
|||
|
|||
uint8_t brick_damage (uint8_t in_x, uint8_t in_y) |
|||
{ |
|||
game_field_t newtype; |
|||
|
|||
switch (playfiled[in_x][in_y]) |
|||
{ |
|||
case brick_1: |
|||
playfield[in_x][in_y] = freespace; |
|||
break; |
|||
|
|||
case brick_2: |
|||
playfield[in_x][in_y] = brick_1; |
|||
break; |
|||
|
|||
case brick_3: |
|||
playfield[in_x][in_y] = brick_2; |
|||
break; |
|||
|
|||
default: |
|||
return; |
|||
} |
|||
score_add (1); |
|||
} |
|||
|
|||
uint8_t check_bounce (uint8_t in_x, uint8_t in_y) |
|||
{ |
|||
/* overflow check */ |
|||
if (in_x >= NUM_ROWS) |
|||
return 1; |
|||
|
|||
if (in_y >= NUM_COLS) |
|||
return 1; |
|||
|
|||
/* collisions with real objects */ |
|||
switch (playfield[in_x][in_y]) |
|||
{ |
|||
case freespace: |
|||
case ball: |
|||
return 0; |
|||
|
|||
case brick_2: |
|||
case brick_3: |
|||
case brick_1: |
|||
brick_damage (in_x, in_y); |
|||
/* intentional fallthrough */ |
|||
|
|||
case brick_solid: |
|||
case bouncer: |
|||
return 1; |
|||
} |
|||
} |
|||
|
|||
/* this is the actual draw function for a single field
|
|||
*/ |
|||
static inline void draw_single_field (game_field_t in_f) |
|||
{ |
|||
switch (in_f) |
|||
{ |
|||
case b1: |
|||
setPixel (); |
|||
return; |
|||
case rb: |
|||
case b2: |
|||
|
|||
return; |
|||
|
|||
case b3: |
|||
case bl: |
|||
case bs: |
|||
|
|||
return; |
|||
|
|||
default: /* this includes freespace */ |
|||
|
|||
return; |
|||
|
|||
} |
|||
} |
|||
|
|||
void playfield_draw () |
|||
{ |
|||
uint8_t x,y; |
|||
|
|||
for (x=0;x<NUM_ROWS;x++) |
|||
{ |
|||
for (y=0;y<NUM_COLS;y++) |
|||
{ |
|||
|
|||
} |
|||
} |
|||
} |
@ -0,0 +1,31 @@ |
|||
#include <stdint.h> |
|||
#include "ball.h" |
|||
#include "score.h" |
|||
|
|||
#ifndef PLAYFIELD_H |
|||
#define PLAYFIELD_H |
|||
|
|||
/* entries for the playing field */ |
|||
enum game_field_t |
|||
{ |
|||
sp = 0, /* space */ |
|||
b1 = 1, b2 = 2, b3 = 3, /* bricks */ |
|||
bs = 4 /* solid (unbreakable) brick */ |
|||
bl, /* ball */ |
|||
rb, /* rebound */ |
|||
}; |
|||
|
|||
|
|||
/* @description draw the current field
|
|||
*/ |
|||
void playfield_draw(); |
|||
|
|||
/* @description set a field with given property.
|
|||
*/ |
|||
void playfield_set (uint8_t in_x, uint8_t in_y, enum game_field_t in_field); |
|||
|
|||
/* @description Checks if there is an object in the way. If so, it returns 1
|
|||
*/ |
|||
uint8_t check_bounce (uint8_t in_x, uint8_t in_y); |
|||
|
|||
#endif /* PLAYFIELD_H */ |
@ -0,0 +1,13 @@ |
|||
#include <stdint.h> |
|||
|
|||
#ifndef SCORE_H |
|||
#define SCORE_H |
|||
|
|||
static uint16_t score = 0; |
|||
|
|||
void score_add(uint8_t); |
|||
score_add (uint8_t in_score) |
|||
{ |
|||
score += in_score; |
|||
} |
|||
#endif |
Loading…
Reference in new issue