Skip to content

Commit

Permalink
Merge pull request #39 from jorgegv/rename_sprite_to_enemy
Browse files Browse the repository at this point in the history
Rename sprite to enemy
  • Loading branch information
jorgegv committed Apr 24, 2021
2 parents 372ce81 + 2469852 commit 9117c84
Show file tree
Hide file tree
Showing 17 changed files with 279 additions and 228 deletions.
9 changes: 5 additions & 4 deletions doc/DATAGEN.md
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ BEGIN_SCREEN
DECORATION NAME=Stairs ROW=16 COL=10
HOTZONE NAME=Stairs ROW=17 COL=11 WIDTH=1 HEIGHT=2 ACTIVE=1
SPRITE NAME=Ghost01 MOVEMENT=LINEAR XMIN=8 YMIN=8 XMAX=233 YMAX=8 INITX=70 INITY=8 DX=2 DY=0 SPEED_DELAY=1 ANIMATION_DELAY=25 BOUNCE=1
ENEMY NAME=Ghost1 SPRITE=Ghost01 MOVEMENT=LINEAR XMIN=8 YMIN=8 XMAX=233 YMAX=8 INITX=70 INITY=8 DX=2 DY=0 SPEED_DELAY=1 ANIMATION_DELAY=25 BOUNCE=1
HERO STARTUP_XPOS=20 STARTUP_YPOS=20
Expand Down Expand Up @@ -283,9 +283,10 @@ this element (=obstacle) but s/he must move around. Arguments:
* `NAME`: the Btile that will be used to draw the item
* `ROW`,`COL`: top left position of the item, in char cell coordinates
* `ITEM_INDEX`: item index in the game inventory (0-15)
* `SPRITE`: defines an enemy on the screen (this element should probably be
named ENEMY, I know, the name is a bit misleading :-( ). Arguments:
* `NAME`: the name of the sprite to be used for this enemy
* `ENEMY`: defines an enemy on the screen. Arguments:
* `NAME`: a name for this enemy. It is _not_ needed that it matches the
sprite name
* `SPRITE`: the name of the sprite to be used for this enemy
* `MOVEMENT`: how the enemy moves. For the moment, this can be only
`LINEAR`, and the following arguments refer to this movement type.
* `XMIN`,`YMIN`,`XMAX`,`YMAX`: bounds for the enemy movement, in pixel
Expand Down
1 change: 1 addition & 0 deletions engine/include/rage1/bullet.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <stdint.h>
#include <games/sp1.h>

#include "rage1/types.h"
#include "rage1/sprite.h"

struct bullet_movement_data_s {
Expand Down
61 changes: 61 additions & 0 deletions engine/include/rage1/enemy.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
////////////////////////////////////////////////////////////////////////////////
//
// RAGE1 - Retro Adventure Game Engine, release 1
// (c) Copyright 2020 Jorge Gonzalez Villalonga <jorgegv@daikon.es>
//
// This code is published under a GNU GPL license version 3 or later. See
// LICENSE file in the distribution for details.
//
////////////////////////////////////////////////////////////////////////////////

#ifndef _ENEMY_H
#define _ENEMY_H

#include "rage1/sprite.h"
#include "rage1/types.h"

#define ENEMY_MOVE_LINEAR 0x00
struct enemy_movement_data_s {
uint8_t type; // LINEAR, etc.
uint8_t delay; // dx,dy are added every 'delay' calls
uint8_t delay_counter; // current movement delay counter
union { // this union must be the last struct component
struct {
uint8_t xmin,xmax; // enemy moves bouncing in a rectangle
uint8_t ymin,ymax; // (xmin,ymin)-(xmax,ymax)
int8_t dx,dy; // current position increments
uint8_t initx,inity; // reset positions
int8_t initdx,initdy; // reset increments
} linear;
} data;
};

struct enemy_info_s {
struct sp1_ss *sprite; // ptr to SP1 sprite struct
uint8_t width,height; // dimensions in pixels ( rows,cols * 8 )
struct sprite_animation_data_s animation; // sprite animation data
struct position_data_s position; // enemy position data
struct enemy_movement_data_s movement; // enemy movement data
uint16_t flags; // flags
};

// enemy flags macros and definitions
#define GET_ENEMY_FLAG(s,f) ( (s).flags & (f) )
#define SET_ENEMY_FLAG(s,f) ( (s).flags |= (f) )
#define RESET_ENEMY_FLAG(s,f) ( (s).flags &= ~(f) )

#define F_ENEMY_ACTIVE 0x0001
#define F_ENEMY_BOUNCE 0x0002

#define IS_ENEMY_ACTIVE(s) (GET_ENEMY_FLAG((s),F_ENEMY_ACTIVE))
#define ENEMY_MUST_BOUNCE(s) (GET_ENEMY_FLAG((s),F_ENEMY_BOUNCE))

// sets all enemies in a enemy set to initial positions and frames
void enemy_reset_position_all( uint8_t num_enemies, struct enemy_info_s *enemies );

// animates and moves all enemies in a enemy set according to their rules
void enemy_animate_and_move_all( uint8_t num_enemies, struct enemy_info_s *enemies );

void enemy_move_offscreen_all( uint8_t num_enemies, struct enemy_info_s *enemies );

#endif // _ENEMY_H
2 changes: 2 additions & 0 deletions engine/include/rage1/hero.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include <stdint.h>
#include <string.h>

#include "rage1/types.h"
#include "rage1/sprite.h"
#include "rage1/controller.h"

Expand Down Expand Up @@ -83,5 +84,6 @@ void hero_update_lives_display(void);
void hero_draw(void);
void hero_set_position_x( struct hero_info_s *h, uint8_t x);
void hero_set_position_y( struct hero_info_s *h, uint8_t y);
void hero_move_offscreen(void);

#endif // _HERO_H
7 changes: 4 additions & 3 deletions engine/include/rage1/map.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "rage1/inventory.h"
#include "rage1/hotzone.h"
#include "rage1/flow.h"
#include "rage1/enemy.h"

// Screen functions and definitions
// A screen has a set of btiles , a set of sprites and some hero data
Expand All @@ -33,9 +34,9 @@ struct map_screen_s {
struct btile_pos_s *btiles_pos;
} btile_data;
struct {
uint8_t num_sprites;
struct sprite_info_s *sprites;
} sprite_data;
uint8_t num_enemies;
struct enemy_info_s *enemies;
} enemy_data;
struct {
uint8_t startup_x,startup_y;
} hero_data;
Expand Down
54 changes: 4 additions & 50 deletions engine/include/rage1/sprite.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,11 @@
//
////////////////////////////////////////////////////////////////////////////////

#ifndef _SPRITES_H
#define _SPRITES_H
#ifndef _SPRITE_H
#define _SPRITE_H

#include <stdint.h>

#include "rage1/map.h"
#include "rage1/util.h"
#include "rage1/types.h"
#include <games/sp1.h>

// structs for storing a single sprite's data on a screen
struct sprite_animation_data_s {
Expand All @@ -26,51 +23,8 @@ struct sprite_animation_data_s {
uint8_t delay_counter; // current frame delay counter
};

#define SPRITE_MOVE_LINEAR 0x00
struct sprite_movement_data_s {
uint8_t type; // LINEAR, etc.
uint8_t delay; // dx,dy are added every 'delay' calls
uint8_t delay_counter; // current movement delay counter
union { // this union must be the last struct component
struct {
uint8_t xmin,xmax; // sprite moves bouncing in a rectangle
uint8_t ymin,ymax; // (xmin,ymin)-(xmax,ymax)
int8_t dx,dy; // current position increments
uint8_t initx,inity; // reset positions
int8_t initdx,initdy; // reset increments
} linear;
} data;
};

struct sprite_info_s {
struct sp1_ss *sprite; // ptr to SP1 sprite struct
uint8_t width,height; // dimensions in pixels ( rows,cols * 8 )
struct sprite_animation_data_s animation; // sprite animation data
struct position_data_s position; // sprite position data
struct sprite_movement_data_s movement; // sprite movement data
uint16_t flags; // flags
};

// sprite flags macros and definitions
#define GET_SPRITE_FLAG(s,f) ( (s).flags & (f) )
#define SET_SPRITE_FLAG(s,f) ( (s).flags |= (f) )
#define RESET_SPRITE_FLAG(s,f) ( (s).flags &= ~(f) )

#define F_SPRITE_ACTIVE 0x0001
#define F_SPRITE_BOUNCE 0x0002

#define IS_SPRITE_ACTIVE(s) (GET_SPRITE_FLAG((s),F_SPRITE_ACTIVE))
#define SPRITE_MUST_BOUNCE(s) (GET_SPRITE_FLAG((s),F_SPRITE_BOUNCE))

// sets all sprites in a sprite set to initial positions and frames
void sprite_reset_position_all( uint8_t num_sprites, struct sprite_info_s *sprites );

// animates and moves all sprites in a sprite set according to their rules
void sprite_animate_and_move_all( uint8_t num_sprites, struct sprite_info_s *sprites );

// move sprite off screen
void sprite_move_offscreen( struct sp1_ss *s );
void sprite_move_offscreen_all( uint8_t num_sprites, struct sprite_info_s *sprites );

// callback function and static params to set a sprite attributes
struct attr_param_s {
Expand All @@ -81,4 +35,4 @@ struct attr_param_s {
extern struct attr_param_s sprite_attr_param;
void sprite_set_cell_attributes( uint16_t count, struct sp1_cs *c );

#endif // _SPRITES_H
#endif // _SPRITE_H
25 changes: 13 additions & 12 deletions engine/src/collision.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "rage1/bullet.h"
#include "rage1/screen.h"
#include "rage1/beeper.h"
#include "rage1/enemy.h"

#define COLLISION_TOLERANCE 2

Expand All @@ -27,21 +28,21 @@ uint8_t collision_check( struct position_data_s *a,struct position_data_s *b ) {
}

void collision_check_hero_with_sprites(void) {
static struct position_data_s *hero_pos,*sprite_pos;
static struct sprite_info_s *s;
static struct position_data_s *hero_pos,*enemy_pos;
static struct enemy_info_s *s;
static uint8_t i;
struct map_screen_s *sc;

hero_pos = &game_state.hero.position;
sc = &map[game_state.current_screen];

i = sc->sprite_data.num_sprites;
i = sc->enemy_data.num_enemies;
while ( i-- ) {
s = &sc->sprite_data.sprites[ i ];
s = &sc->enemy_data.enemies[ i ];

if ( IS_SPRITE_ACTIVE( *s ) ) {
sprite_pos = &s->position;
if ( collision_check( hero_pos, sprite_pos ) ) {
if ( IS_ENEMY_ACTIVE( *s ) ) {
enemy_pos = &s->position;
if ( collision_check( hero_pos, enemy_pos ) ) {
SET_LOOP_FLAG( F_LOOP_HERO_HIT );
return;
}
Expand All @@ -51,7 +52,7 @@ void collision_check_hero_with_sprites(void) {

void collision_check_bullets_with_sprites( void ) {
static struct bullet_state_data_s *b;
static struct sprite_info_s *s;
static struct enemy_info_s *s;
static uint8_t si,bi;
struct map_screen_s *sc;

Expand All @@ -61,16 +62,16 @@ void collision_check_bullets_with_sprites( void ) {
while ( bi-- ) {
b = &game_state.bullet.bullets[ bi ];
if ( IS_BULLET_ACTIVE( *b ) ) {
si = sc->sprite_data.num_sprites;
si = sc->enemy_data.num_enemies;
while ( si-- ) {
s = &sc->sprite_data.sprites[ si ];
if ( IS_SPRITE_ACTIVE( *s ) ) {
s = &sc->enemy_data.enemies[ si ];
if ( IS_ENEMY_ACTIVE( *s ) ) {
if ( collision_check( &b->position, &s->position ) ) {
// set bullet inactive and move away
RESET_BULLET_FLAG( *b, F_BULLET_ACTIVE );
sprite_move_offscreen( b->sprite );
// set sprite inactive and move away
RESET_SPRITE_FLAG( *s, F_SPRITE_ACTIVE );
RESET_ENEMY_FLAG( *s, F_ENEMY_ACTIVE );
sprite_move_offscreen( s->sprite );
// TO DO: increment score, etc.
if ( ! --game_state.enemies_alive )
Expand Down
118 changes: 118 additions & 0 deletions engine/src/enemy.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
////////////////////////////////////////////////////////////////////////////////
//
// RAGE1 - Retro Adventure Game Engine, release 1
// (c) Copyright 2020 Jorge Gonzalez Villalonga <jorgegv@daikon.es>
//
// This code is published under a GNU GPL license version 3 or later. See
// LICENSE file in the distribution for details.
//
////////////////////////////////////////////////////////////////////////////////

#include "rage1/game_state.h"
#include "rage1/sprite.h"
#include "rage1/enemy.h"
#include "rage1/screen.h"
#include "rage1/map.h"
#include "rage1/debug.h"
#include "rage1/util.h"

#include "game_data.h"

void enemy_reset_position_all( uint8_t num_enemies, struct enemy_info_s *enemies ) {
static struct enemy_info_s *s;
static uint8_t n;

n = num_enemies;
while( n-- ) {
s = &enemies[n]; // eficiency matters ;-)
if ( ! IS_ENEMY_ACTIVE(*s) ) // skip if not active
continue;

// reset enemy state to initial values - update xmax and ymax also
s->animation.current_frame = s->animation.delay_counter = 0;
s->position.x = s->movement.data.linear.initx;
s->position.y = s->movement.data.linear.inity;
s->movement.data.linear.dx = s->movement.data.linear.initdx;
s->movement.data.linear.dy = s->movement.data.linear.initdy;

// adjust xmax, ymax and move enemy to initial position
s->position.xmax = s->position.x + s->width - 1;
s->position.ymax = s->position.y + s->height - 1;
sp1_MoveSprPix( s->sprite, &game_area, s->animation.frames[0], s->position.x, s->position.y );
}
}

void enemy_animate_and_move_all( uint8_t num_enemies, struct enemy_info_s *enemies ) {
static struct enemy_info_s *s;
static struct sprite_animation_data_s *anim;
static struct position_data_s *pos;
static struct enemy_movement_data_s *move;
static uint8_t n;

n = num_enemies;
while( n-- ) {
s = &enemies[n]; // efficiency matters ;-)
if ( ! IS_ENEMY_ACTIVE(*s) ) // skip if not active
continue;

// animate sprite
anim = &s->animation;
if ( ++anim->delay_counter == anim->delay ) {
anim->delay_counter = 0;
if ( ++anim->current_frame == anim->num_frames ) {
anim->current_frame = 0;
}
}

// set new sprite position according to movement rules
pos = &s->position;
move = &s->movement;
switch ( move->type ) {
case ENEMY_MOVE_LINEAR:
if ( ++move->delay_counter == move->delay ) {
move->delay_counter = 0;
pos->x += move->data.linear.dx;
if (
( pos->x >= move->data.linear.xmax ) ||
( pos->x <= move->data.linear.xmin ) ||
( ENEMY_MUST_BOUNCE(*s) && (
( TILE_TYPE_AT( PIXEL_TO_CELL_COORD( pos->y ), PIXEL_TO_CELL_COORD( pos->x + s->width ) ) == TT_OBSTACLE ) ||
( TILE_TYPE_AT( PIXEL_TO_CELL_COORD( pos->y ), PIXEL_TO_CELL_COORD( pos->x - 1 ) ) == TT_OBSTACLE ) ||
( TILE_TYPE_AT( PIXEL_TO_CELL_COORD( pos->y + s->height - 1), PIXEL_TO_CELL_COORD( pos->x + s->width ) ) == TT_OBSTACLE ) ||
( TILE_TYPE_AT( PIXEL_TO_CELL_COORD( pos->y + s->height - 1), PIXEL_TO_CELL_COORD( pos->x - 1 ) ) == TT_OBSTACLE )
) )
) { // then
move->data.linear.dx = -move->data.linear.dx;
}
pos->y += move->data.linear.dy;
if (
( pos->y >= move->data.linear.ymax ) ||
( pos->y <= move->data.linear.ymin ) ||
( ENEMY_MUST_BOUNCE(*s) && (
( TILE_TYPE_AT( PIXEL_TO_CELL_COORD( pos->y + s->height ), PIXEL_TO_CELL_COORD( pos->x ) ) == TT_OBSTACLE ) ||
( TILE_TYPE_AT( PIXEL_TO_CELL_COORD( pos->y - 1 ), PIXEL_TO_CELL_COORD( pos->x ) ) == TT_OBSTACLE ) ||
( TILE_TYPE_AT( PIXEL_TO_CELL_COORD( pos->y + s->height ), PIXEL_TO_CELL_COORD( pos->x + s->width - 1) ) == TT_OBSTACLE ) ||
( TILE_TYPE_AT( PIXEL_TO_CELL_COORD( pos->y - 1), PIXEL_TO_CELL_COORD( pos->x + s->width - 1 ) ) == TT_OBSTACLE )
) )
) { // then
move->data.linear.dy = -move->data.linear.dy;
}
}
break;
default:
break;
}

// adjust xmax, ymax and move sprite to new position
pos->xmax = pos->x + s->width - 1;
pos->ymax = pos->y + s->height - 1;
sp1_MoveSprPix( s->sprite, &game_area, anim->frames[anim->current_frame], pos->x, pos->y );
}
}

void enemy_move_offscreen_all( uint8_t num_enemies, struct enemy_info_s *enemies ) {
static uint8_t i;
i = num_enemies;
while ( i-- ) sprite_move_offscreen( enemies[i].sprite );
}

0 comments on commit 9117c84

Please sign in to comment.