diff --git a/programs/games/heliothryx/game/rsgamelogic.c b/programs/games/heliothryx/game/rsgamelogic.c new file mode 100644 index 0000000000..36b2bcb0b0 --- /dev/null +++ b/programs/games/heliothryx/game/rsgamelogic.c @@ -0,0 +1,419 @@ +#include "rsgamelogic.h" + +#include "rsgametext.h" + +#include "rsgamemenu.h" + +#include "rsgamedraw.h" + +#include "rskos.h" + +#include "rsgentex.h" +#include "rssoundgen.h" +#include "rsnoise.h" + +#include "rs/rsplatform.h" + + +#ifdef RS_USE_C_LIBS // linux version + #include + #include + #include + + #include "rs/rskeyboard.h" +#endif + + + + +int next_rock_timer = 0; + +void next_stage_now() { + game.stage_timer = 0; + game.stage++; +}; + +void next_stage_after(int t) { + if (game.stage_timer > t) { + next_stage_now(); + }; +}; + +void next_stage_after_sec(int t) { + next_stage_after(t*25); +}; + + + + +int check_collision(int obj1, int obj2) { + // obj1 must be bullet + // obj2 can be anything + + if ( game.objs[obj1].obj_type == OBJ_BULLET ) { + + if ( ( abs(game.objs[obj1].y - game.objs[obj2].y) < ( 4 + game.objs[obj2].radius ) ) + && ( abs( (game.objs[obj1].x - 8) - game.objs[obj2].x) < ( 8 + game.objs[obj2].radius ) ) ){ + return 1; + }; + + }; + + return 0; + +}; + +int check_collision_with_player(int obj1) { + + const int player_radius = 3; + + int obj_radius = game.objs[obj1].radius; +// if (game.objs[obj1].obj_type == OBJ_RED_BULLET) { +// obj_radius = 3; +// }; + +// if ( game.objs[obj1].obj_type == OBJ_RED_BULLET ) { + + if ( ( abs(game.objs[obj1].y - game.player_y) < ( obj_radius + player_radius ) ) + && ( abs( (game.objs[obj1].x ) - game.player_x) < ( obj_radius + 4 + player_radius ) ) ){ + return 1; + }; + +// }; + + return 0; + +}; + +void player_hit() { + + game.health--; + + + if (game.health < 1) { + game.status = STATUS_MENU; + menu_open( MENU_GAME_OVER ); + }; + +}; + + +void GameProcess() { + + if (game.status == STATUS_PLAYING) { + + // shoot + + if ( ( (game.shoot_keypressed) || (is_key_pressed(RS_ATTACK_KEY_MASK)) ) && (game.ammo>0) ) { + + game.shoot_delay ++; + + if (game.shoot_delay > GAME_SHOOT_PERIOD) { + +// if (game.ammo > 0) { + + game.shoot_restore_delay = 0; + game.ammo--; + soundbuf_play(&game.sound_test1); + game_obj_add( game_obj( OBJ_BULLET, 0, 0, 0, game.player_x+5, game.player_y, 0, 0.0) ); + +// }; + + game.shoot_delay -= GAME_SHOOT_PERIOD; + game.shoot_keypressed = 0; + + }; + } + else { + + if (game.ammo < GAME_AMMO_MAX) { + game.shoot_restore_delay++; + + if (game.shoot_restore_delay > GAME_SHOOT_PERIOD * 2) { + + game.shoot_delay++; + + if (game.shoot_delay > GAME_SHOOT_PERIOD) { + game.ammo++; + game.shoot_delay -= GAME_SHOOT_PERIOD; + }; + + }; + + }; + + }; + + + + + int speed = 4; + int bullet_speed = 11; + int red_bullet_speed = 8; + int rock_speed = 6; + + game.player_x += speed * ( is_key_pressed(RS_ARROW_RIGHT_MASK) - is_key_pressed(RS_ARROW_LEFT_MASK) ); + game.player_y += speed * ( is_key_pressed(RS_ARROW_DOWN_MASK) - is_key_pressed(RS_ARROW_UP_MASK) ); + + game.player_x = rs_clamp_i(game.player_x, 5, GAME_WIDTH-25); + game.player_y = rs_clamp_i(game.player_y, 5, GAME_HEIGHT - 25); + + game.tz += 1; + + + + + + + game.stage_timer++; + + if (game.stage == 0) { + + // level start + + next_stage_after_sec(3); + + } + + else if (game.stage == 1) { + +// game.stage = 4; + + // rocks + next_rock_timer--; + if (next_rock_timer < 1) { + next_rock_timer = 9 + rs_rand()%16; + //game_obj_add( game_obj( ((rs_rand() % 512) > 256) ? OBJ_ROCK : OBJ_MINIROCK, 0, rs_rand() % ROCKS_COUNT , 32, GAME_WIDTH + 100, 30 + rs_rand()%(GAME_HEIGHT-60), 0, 0.0 ) ); + game_obj_add( game_obj( OBJ_ROCK, OBJ_FLAG_ENEMY, rs_rand() % ROCKS_COUNT , game.tex_rocks[0].w/2, GAME_WIDTH + 50, 30 + rs_rand()%(GAME_HEIGHT-90), 0, 0.0 ) ); + }; + + next_stage_after_sec(12); + + } + + if (game.stage == 2) { + + next_stage_after_sec(4); + + } + + else if (game.stage == 3) { + + // rocks + next_rock_timer--; + if (next_rock_timer < 1) { + next_rock_timer = 10 + rs_rand()%16; + //game_obj_add( game_obj( ((rs_rand() % 512) > 256) ? OBJ_ROCK : OBJ_MINIROCK, 0, rs_rand() % ROCKS_COUNT , 32, GAME_WIDTH + 100, 30 + rs_rand()%(GAME_HEIGHT-60), 0, 0.0 ) ); + game_obj_add( game_obj( OBJ_MINIROCK, OBJ_FLAG_ENEMY, rs_rand() % ROCKS_COUNT , game.tex_minirocks[0].w/2, GAME_WIDTH + 50, 30 + rs_rand()%(GAME_HEIGHT-90), 0, 0.0 ) ); + }; + + next_stage_after_sec(16); + + } + + else if (game.stage == 4) { + + next_stage_after_sec(4); + + } + + else if (game.stage == 5) { + + // rocks + next_rock_timer--; + if (next_rock_timer < 1) { + next_rock_timer = 5; + //game_obj_add( game_obj( ((rs_rand() % 512) > 256) ? OBJ_ROCK : OBJ_MINIROCK, 0, rs_rand() % ROCKS_COUNT , 32, GAME_WIDTH + 100, 30 + rs_rand()%(GAME_HEIGHT-60), 0, 0.0 ) ); + game_obj_add( game_obj( OBJ_MINIROCK, OBJ_FLAG_ENEMY | OBJ_FLAG_SIN, rs_rand() % ROCKS_COUNT , game.tex_minirocks[0].w/2, GAME_WIDTH + 50, GAME_HEIGHT/8, 0, 0.0 ) ); + }; + + next_stage_after_sec(6); + + } + + else if (game.stage == 6) { + + // mix rocks + next_rock_timer--; + if (next_rock_timer < 1) { + next_rock_timer = 9 + rs_rand()%12; + //game_obj_add( game_obj( ((rs_rand() % 512) > 256) ? OBJ_ROCK : OBJ_MINIROCK, 0, rs_rand() % ROCKS_COUNT , 32, GAME_WIDTH + 100, 30 + rs_rand()%(GAME_HEIGHT-60), 0, 0.0 ) ); + game_obj_add( game_obj( rs_rand()%1024 < 768 ? OBJ_MINIROCK : OBJ_ROCK, OBJ_FLAG_ENEMY, rs_rand() % ROCKS_COUNT , + rs_rand()%1024 < 768 ? game.tex_minirocks[0].w/2 : game.tex_rocks[0].w/2, GAME_WIDTH + 100, 30 + rs_rand()%(GAME_HEIGHT-90), 0, 0.0 ) ); + }; + + next_stage_after_sec(10); + + } + + else if (game.stage == 7) { + + + if (game.stage_timer > 3*25) { + next_stage_now(); + + game_obj_add( game_obj( OBJ_TURRET, OBJ_FLAG_ENEMY | OBJ_FLAG_BOSS, 60, game.tex_rocks[0].w/2, GAME_WIDTH+60, GAME_HEIGHT/2, 0, 0.0 ) ); + + }; + + } + + else if (game.stage == 8) { + + if ( IS_BIT_SET(game.flags, GAME_FLAG_BOSS_DESTROYED) ) { + next_stage_now(); + }; + + } + + else if (game.stage == 9) { + next_stage_after_sec(2); + } + else if (game.stage == 10) { + + game.status = STATUS_MENU; + menu_open( MENU_LEVEL_PASSED ); + + level_passed_score_str[1] = '0' + (game.score / 100) % 10; + level_passed_score_str[2] = '0' + (game.score / 10) % 10; + level_passed_score_str[3] = '0' + (game.score / 1) % 10; + + }; + + + + + + int i, j; + game_obj_t *obj; + + for (i = 0; i < game.objs_count; i++) { + + obj = &(game.objs[i]); + + if (obj->obj_type == OBJ_BULLET) { + + obj->x += bullet_speed; + if (obj->x > GAME_WIDTH) { + // destroy object + game_obj_remove(i); + i--; + continue; + }; + + for (j = 0; j < game.objs_count; j++) { + if (IS_BIT_SET(game.objs[j].flags, OBJ_FLAG_ENEMY)) { + if (check_collision(i, j)) { + if (IS_BIT_SET( game.objs[j].flags, OBJ_FLAG_BOSS)) { + game.objs[j].tag--; + if (game.objs[j].tag < 1) { + BIT_SET( game.objs[j].flags, OBJ_FLAG_DESTROYED ); + BIT_SET( game.flags, GAME_FLAG_BOSS_DESTROYED ); + game.score += 50; + }; + } + else { + BIT_SET( game.objs[j].flags, OBJ_FLAG_DESTROYED ); + game.score += game.objs[j].obj_type == OBJ_ROCK ? 2 : 3; + }; + game_obj_remove(i); + i--; + break; // continue parent loop + }; + }; + }; + + } + + else if (obj->obj_type == OBJ_RED_BULLET) { + + obj->x -= red_bullet_speed; + if (obj->x < 4) { + // destroy object + game_obj_remove(i); + i--; + continue; + }; + + if (check_collision_with_player(i)) { + player_hit(); + game_obj_remove(i); + i--; + continue; + }; + + } + + else if (obj->obj_type == OBJ_EXPLOSION) { + + obj->t++; + if (obj->t >= EXPLOSIONS_COUNT) { + game_obj_remove(i); + i--; + continue; + }; + + } + else if ( (obj->obj_type == OBJ_ROCK) || (obj->obj_type == OBJ_MINIROCK) ) { + + obj->x -= rock_speed; + if (obj->x < - obj->radius * 2) { + game_obj_remove(i); + i--; + continue; + }; + + if ( IS_BIT_SET(obj->flags, OBJ_FLAG_SIN) ) { + obj->f += 0.2; + obj->y += 7.0 * sin(obj->f); + }; + + if ( check_collision_with_player(i) ) { + player_hit(); + game_obj_remove(i); + i--; + continue; + }; + + } + else if ( obj->obj_type == OBJ_TURRET ) { + + if (obj->x > GAME_WIDTH*3/4) { + obj->x -= 2; + } + else { + obj->f += 0.03; + obj->y = GAME_HEIGHT * ( 0.5 + 0.3*sin(obj->f) ); + }; + + obj->t--; + if (obj->t < 1) { + game_obj_add( game_obj( OBJ_RED_BULLET, 0, 0, 3, obj->x - 30, obj->y, 0, 0) ); + obj->t = 10 + rs_rand() % 20; + }; + + }; + + }; + + + + for (i = 0; i < game.objs_count; i++) { + if ( IS_BIT_SET( game.objs[i].flags, OBJ_FLAG_DESTROYED ) ) { + game_obj_add( game_obj( OBJ_EXPLOSION, 0, 0, EXPLOSION_RADIUS, game.objs[i].x, game.objs[i].y, 0, 0.0 ) ); + game_obj_remove(i); + i--; + + }; + }; + + + + }; + + game_draw(); + +} + + + diff --git a/programs/games/heliothryx/game/rsgamelogic.h b/programs/games/heliothryx/game/rsgamelogic.h new file mode 100644 index 0000000000..3f85a856bc --- /dev/null +++ b/programs/games/heliothryx/game/rsgamelogic.h @@ -0,0 +1,26 @@ +#ifndef RSGAMELOGIC_H_INCLUDED +#define RSGAMELOGIC_H_INCLUDED + +/* + + Heliothryx + Game by Roman Shuvalov + +*/ + +#ifndef RS_LINUX + #ifndef RS_WIN32 + #ifndef RS_KOS + #error Please specify platform + #endif + #endif +#endif + + +#include "rsgame.h" + + +void GameProcess(); + + +#endif // RSGAME_H_INCLUDED