Jo Engine Forum

Sega Saturn Development => General Jo Engine Help => Topic started by: SaturnTeam on June 26, 2018, 11:32:58 pm

Title: Trouble trying to set explosions in shooter game
Post by: SaturnTeam on June 26, 2018, 11:32:58 pm
I have been trying to figure out how to tie in an explosion that is linked to an enemy ship being destroyed by the laser. I have been working on it for a while, looking through the code sections in the shooter demo. It's obvious where the enemy ships come in and the detection of whether an enemy ship has been hit and deleted, but I can't figure out how to input an explosion image to replace the enemy ship just vanishing into thin air. The closest I got was with adding an inline void and trying to tie it in with enemies being destroyed. It made it through the compiler, but nothing happened. I'm wondering if I need to create a header file for the enemy ship. I don't know if anyone can give me a hint. I know that Johannes considered this, because he left an explosion image in the directory.
Title: Re: Trouble trying to set explosions in shooter game
Post by: ponut64 on June 27, 2018, 12:29:28 am
It's a pretty basic thing with code in C.
Create a struct for a ship.
Code: [Select]
typedef struct {

} ship;
Have it include the relevant sprites for a ship, including the destroyed sprite.
Have it also include states, like if the ship is destroyed or not.
From that bool, you can set it to display either the ship sprite or the explosion sprite.

Then, you can use something like
Code: [Select]
Sint32 curtime = jo_get_ticks();
whenever the condition for exploding the ship is called, and...
Code: [Select]
if(explodeShip != true){
//Display the normal ship sprite.
} else if(explodeShip == true){
//Display the explode sprite.
if(curtime > 99){
//Display an empty sprite.
}
}
Title: Re: Trouble trying to set explosions in shooter game
Post by: SaturnTeam on June 27, 2018, 01:32:27 am
Okay. Thanks. I'll work on this another day. I'm out of time, today.
Title: Re: Trouble trying to set explosions in shooter game
Post by: SaturnTeam on June 28, 2018, 12:27:55 am
Okay, I spent most of the day trying to implement this, but I'm stuck, again. I want to share the pieces of code I do have.

Here is the header file:
Code: [Select]
#ifndef __ENEMY_H__
# define __ENEMY_H__

# define ENEMY_TILE_COUNT    (4)
/*
typedef enum
{
//    NONE,
}                       e_ship;
*/

typedef struct
{
    int                 anim_id;
//    int                 x;
//    int                 y;
//    int                 speed;
//    t_ship_horiz_move   move;
    char                is_alive;
    char                is_dead;
//    char                is_moving_horizontaly;
//    char                reverse_animation;
//    int                 shield_pos_x;
//    int                 shield_pos_y;
//    int                 shield_angle;
//    int                 score;
}                       e_ship;

#endif /* !__ENEMY_H__ */

I copied that from the ship header file, and changed it, but I'm not clear on changing the struct elements.

Here is code from the main C file. There are numerous mistakes, and obviously I left out the standard code:
Code: [Select]
#include "enemy.h"

static e_ship       enemy;
static int          enemy_sprite_id;
static int          enemy_dead_sprite_id;

inline bool         draw_enemy_dead(jo_node *node)
{
    jo_sprite_draw3D(enemy_dead_sprite_id, node->data.coord.x, node->data.coord.y, 520);
    node->data.coord.y += 2;
    if (jo_list_any(&enemies_list, check_if_laser_hit_enemy, node))
        get_enemy.anim_id();
}
inline void         start_enemy_animation(char check_if_laser_hit_enemy)
{
        jo_start_sprite_anim(enemy.anim_id);
enemy.anim_id = jo_create_sprite_anim(enemy_sprite_id, 4, 2);
}
void                init_game(void)
{
    jo_tile     enemy_tileset[ENEMY_TILE_COUNT] =
    {
        {0, 0, 40, 40},
        {40, 0, 40, 40},
        {80, 0, 40, 40},
        {120, 0, 40, 40},
    };
    enemy_dead_sprite_id = jo_sprite_add_tga_tileset(JO_ROOT_DIR, "ENEMY.TGA", JO_COLOR_Blue, enemy_tileset, ENEMY_TILE_COUNT);
    enemy_sprite_id = jo_sprite_add_tga(JO_ROOT_DIR, "EN.TGA", JO_COLOR_Blue);
    enemy.anim_id = jo_create_sprite_anim(enemy_dead_sprite_id, ENEMY_TILE_COUNT, 4);
}

The explosion animation is 4 tiles, from left to right. I didn't get to the curtime part, because I am having trouble setting up the code before that. I saw how the animation is handled in the sprite animation demo, but this is different with it being a whole game. The demo is just a changing sprite without outside interaction.
Title: Re: Trouble trying to set explosions in shooter game
Post by: XL2 on June 28, 2018, 01:51:53 am
If it can make it easier, don't worry about the animation functions and just add a status parameter and a timer.
Something like

void renderShip(ship_t * ship)
{
if (ship->status & alive)
    Display(shipID);
else
{
if (Ship->timer ++ < max_anim_frames)
    Display(shipID + Ship->timer);
else
    Ship->timer=max_anim_frames;

}
}
Title: Re: Trouble trying to set explosions in shooter game
Post by: SaturnTeam on June 28, 2018, 02:08:48 am
Okay. Thanks. I'll integrate this idea and keep working on this tomorrow.
Title: Re: Trouble trying to set explosions in shooter game
Post by: SaturnTeam on July 01, 2018, 01:17:02 am
Okay, this is what I have after a few days. This is kind of a mess. I'll include the warnings/errors under the code.

Code: [Select]
#ifndef __ENEMY_H__
# define __ENEMY_H__

# define ENEMY_TILE_COUNT    (4)
/*
typedef enum
{
    NONE,
}                       e_ship;
*/

typedef struct
{
    int                   anim_id;
    char                  alive;
    char                  status;
    char                  max_anim_frames;
    char                  timer;
//    int                 x;
//    int                 y;
//    int                 speed;
//    t_ship_horiz_move   move;
      char                first_dead_sprite_id;
//    char                is_moving_horizontaly;
//    char                reverse_animation;
//    int                 shield_pos_x;
//    int                 shield_pos_y;
//    int                 shield_angle;
//    int                 score;
}                       e_ship;

#endif /* !__ENEMY_H__ */

I'm still not clear on what char items should be included in the structure and the implementation connection with the main file.

Code: [Select]
#include "enemy.h"

static e_ship    enemy;
static int          enemy_sprite_id;
static int          enemy_dead_sprite_id;

inline bool         explodeEnemy(jo_node *node)
{
        Sint32 curtime = jo_get_ticks();
        if(explodeEnemy != true)
        {
            jo_sprite_draw3D(enemy_sprite_id, node->data.coord.x, node->data.coord.y, 520);
        }
        else if(explodeEnemy == true)
        {
            jo_sprite_draw3D(enemy_dead_sprite_id, node->data.coord.x, node->data.coord.y, 520);
        }
        if(curtime > 99)
        {
            jo_sprite_draw3D(enemy_sprite_id, node->data.coord.x, node->data.coord.y, 520);
        }
}

inline void         renderEnemy(e_ship * enemy, char alive, char status, char max_anim_frames, char timer, jo_node *node)
{
    if (enemy->status & alive)
        Display(enemy);
    else if (enemy->timer ++ < max_anim_frames)
        Display(enemy + enemy->timer);
    else
        enemy->timer=max_anim_frames;
}

inline void         start_enemy_animation(e_ship enemy, char first_dead_sprite_id)
{
    jo_start_sprite_anim(enemy.anim_id);
//    enemy.reverse_animation = reverse_animation;
enemy.anim_id = jo_create_sprite_anim(first_dead_sprite_id, 4, 2);
}

void                init_game(void)
{
    jo_tile     enemy_tileset[ENEMY_TILE_COUNT] =
    {
        {0, 0, 40, 40},
        {40, 0, 40, 40},
        {80, 0, 40, 40},
        {120, 0, 40, 40},
    };

enemy_dead_sprite_id = jo_sprite_add_tga_tileset(JO_ROOT_DIR, "ENEMY.TGA", JO_COLOR_Blue, enemy_tileset, ENEMY_TILE_COUNT);
enemy_sprite_id = jo_sprite_add_tga(JO_ROOT_DIR, "EN.TGA", JO_COLOR_Blue);
enemy.anim_id = jo_create_sprite_anim(enemy_dead_sprite_id, ENEMY_TILE_COUNT, 4);

The compiler warns me that my early mention of static e_ship enemy shadows the global declaration. With the if explode enemy is true, the warning is about the comparison between pointer and integer. At the end of the explode section, it warns that there is no return statement in function returning non-void. There is a warning/error about using the term "display," because it doesn't know where this comes from and doesn't seem to be embedded in the engine. In the renderEnemy section, the status, timer, and node go unused. I realize that these are just mentioned, but not implemented. I don't know enough about it to do this. It also warns that at the end of the explodeEnemy section, "control reaches end of non-void function." I'm wondering if there is an easier way to implement an explosion, but I haven't figured it out yet.
Title: Re: Trouble trying to set explosions in shooter game
Post by: ponut64 on July 01, 2018, 01:42:42 am
A "static" variable becomes read-only. You can generally avoid using this.
I would guess the compiler is complaining about redefinition of e_ship because the type is not static but your variable is. Plus, you should put the following line in the .h file.
Code: [Select]
extern e_ship enemy;
You use extern to notify another document (especially ones compiled separately) that this variable exists, though you do not define the variable's contents with extern.

I generally avoid using "char" variables, if you can remember the state with integers, you should use integers (S or U int 8/16/32, depending on how much bit depth you need and whether or not you need negative values)

If your function code is not meant to return data to a variable, its return type should be "void".
Code: [Select]
inline bool         explodeEnemy(jo_node *node);
just becomes
void explodeEnemy(jo_node *node);
You generally see a lot of programmers use bool as a function return type so the function can return TRUE or FALSE depending on successful or unsuccessful execution of the intended result. You haven't written in those conditions; you don't need to.

"Display" is in fact undefined in the SGL and SBL libraries; you need to define what "Display" means in terms of SGL or SBL.
Do you mean debug information? If so you would be looking at "jo_printf" or "slPrintFX".




Also, programming is gonna take a long time. Welcome to the club.
Title: Re: Trouble trying to set explosions in shooter game
Post by: SaturnTeam on July 01, 2018, 02:27:39 am
Okay. That's good information. I appreciate the help. I will soldier on!
Title: Re: Trouble trying to set explosions in shooter game
Post by: XL2 on July 01, 2018, 07:08:40 am
In fact, a static variable will have 2 different behaviours depending on how you declare it.
Within a function, it will remain in memory in that function for all the program's life. Try to avoid that.
A global static variable is one that you can only see within one c file.
It's useful if you need variables for some functions but you don't want them to become available for the whole program.
Try to avoid global variables and use local variables and pointers as much as possible.
Also, a bool is 32 bits with SGL, so you waste 31 bits.
A better way is to use bitmasks.
Like say your enum says alive = 1<<17;
Then
ship->status |= alive;  //sets the ship to alive
ship->status &= ~alive; //sets the ship to dead

To check if the ship is alive :
If (ship->status & alive) //same as == true
If ((ship->status & alive)==0) //same as == false

You could then use status for 31 others true/false flags in the same maner.
Title: Re: Trouble trying to set explosions in shooter game
Post by: SaturnTeam on July 01, 2018, 07:13:58 am
Okay. Thanks for the tips on variables. I'll start back on this tomorrow.