mirror of
https://github.com/stevenhowes/CTheEscape.git
synced 2026-05-26 15:53:29 +01:00
942 lines
27 KiB
Plaintext
942 lines
27 KiB
Plaintext
#include "Graphics.h"
|
|
|
|
#define PLAYER_Y_START 100
|
|
#define PLAYER_X_SPEED 10
|
|
#define MAX_NPCS 5
|
|
#define MAX_STARS 10
|
|
#define MAX_PROJECTILES 10
|
|
|
|
//#defene PROFILE(X) lastprofile = clock(); X; printf("\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t%s %i\n", #X, (clock() - lastprofile))
|
|
#define PROFILE(X) X
|
|
|
|
enum sprite_e{player_ship, durno_ship, ship_trgt, durno_ship2, ship2_trgt, player_shipl,player_shipr,explode_start,explode_shp2,explode_shp3,explode_end,photon1,photon2,plasma1,plasma2};
|
|
char *sprites[] = {"player_ship","durno_ship","ship_trgt","durno_ship2","ship2_trgt","player_shipl","player_shipr","explode_shp1","explode_shp2","explode_shp3","explode_shp4","photon1","photon2","plasma1","plasma2"};
|
|
|
|
char hudbuffer[63];
|
|
|
|
struct EntityLocation_s {
|
|
short signed int X,Y;
|
|
};
|
|
|
|
enum npctype_e{bigdurno, littledurno,maxnpctype};
|
|
|
|
struct NPC_s {
|
|
struct EntityLocation_s location;
|
|
enum sprite_e idlesprite;
|
|
enum sprite_e sprite;
|
|
enum sprite_e weaponspritestart;
|
|
enum sprite_e weaponspriteend;
|
|
enum npctype_e npctype;
|
|
struct EntityLocation_s velocity;
|
|
int health;
|
|
struct EntityLocation_s hitbox_bl;
|
|
struct EntityLocation_s hitbox_tr;
|
|
int collideforce;
|
|
int collidable;
|
|
int explodenextframe;
|
|
int nextfire;
|
|
int fireinterval;
|
|
int firewidth;
|
|
};
|
|
|
|
struct Star_s {
|
|
struct EntityLocation_s location;
|
|
unsigned char length;
|
|
};
|
|
|
|
struct Player_s {
|
|
struct EntityLocation_s location;
|
|
enum sprite_e idlesprite;
|
|
enum sprite_e sprite;
|
|
unsigned char velocity;
|
|
int nextidlesprite;
|
|
int shields;
|
|
int nextshieldheal;
|
|
int integrity;
|
|
int remainingdistance;
|
|
struct EntityLocation_s hitbox_bl;
|
|
struct EntityLocation_s hitbox_tr;
|
|
struct EntityLocation_s phaser1;
|
|
struct EntityLocation_s phaser2;
|
|
int targetleft;
|
|
int targetright;
|
|
short int firingleft;
|
|
short int firingright;
|
|
int phaserdamage;
|
|
};
|
|
|
|
struct Projectile_s {
|
|
struct EntityLocation_s location;
|
|
enum sprite_e sprite;
|
|
enum sprite_e spritestart;
|
|
enum sprite_e spriteend;
|
|
struct EntityLocation_s velocity;
|
|
int collidable;
|
|
int nextframe;
|
|
short int active;
|
|
int damage;
|
|
};
|
|
|
|
struct Star_s Stars[MAX_STARS];
|
|
struct NPC_s NPCS[MAX_NPCS];
|
|
struct Projectile_s Projectiles[MAX_PROJECTILES];
|
|
struct Player_s Player;
|
|
|
|
extern void game_respawn_npc(int id);
|
|
extern int tick;
|
|
extern int lasttick;
|
|
|
|
enum debugs_e{dbbase,dbhitbox,dbweapons,dbinput,dbperformance,dbnpcs,dbprojectiles,dbmax};
|
|
int debugs[dbmax];
|
|
|
|
enum colour_e{lcars_black,lcars_violet1,debugpink,stargrey,debuggreen,phaserorange1,phaserorange2};
|
|
int colours[] = {0x11111100,0xc4727200,0xcc00ff00,0x66666600,0x00ff0000,0x0053ff00,0x00d5ff00};
|
|
|
|
void game_spawn_projectile(int id, int Px, int Py, int Vx, int Vy, enum sprite_e spritestart, enum sprite_e spriteend, int damage)
|
|
{
|
|
int i;
|
|
|
|
if(id < 0)
|
|
{
|
|
for(i = 0; i < MAX_PROJECTILES; i++)
|
|
{
|
|
if(Projectiles[i].active == 0)
|
|
id = i;
|
|
}
|
|
}
|
|
|
|
// If no velocity X specified we're targetting the player
|
|
if(Vx == 0)
|
|
{
|
|
int V;
|
|
int Xdistance = abs((Player.location.X + (Player.hitbox_tr.X/2)) - Px);
|
|
int Ydistance = abs((Player.location.Y + (Player.hitbox_tr.Y/2)) - Py);
|
|
int distance = sqrt((Xdistance^2) + (Ydistance^2));
|
|
V = Vy;
|
|
Vx = Xdistance / (distance / Vy);
|
|
Vy = Ydistance / (distance / Vy);
|
|
|
|
if(Player.location.X > Px)
|
|
Vx = 0 - Vx;
|
|
}
|
|
|
|
// If it's too close to horizontal you can't dodge
|
|
if(Py < (Player.location.X + 100))
|
|
id = -1;
|
|
|
|
//If no free IDs then we go without
|
|
if(id >= 0)
|
|
{
|
|
Projectiles[id].location.X = Px;
|
|
Projectiles[id].location.Y = Py;
|
|
Projectiles[id].velocity.X = Vx;
|
|
Projectiles[id].velocity.Y = Vy;
|
|
Projectiles[id].active = 1;
|
|
Projectiles[id].sprite = spritestart;
|
|
Projectiles[id].spritestart = spritestart;
|
|
Projectiles[id].spriteend = spriteend;
|
|
Projectiles[id].nextframe = tick + 10;
|
|
Projectiles[id].damage = damage;
|
|
Projectiles[id].collidable = 1;
|
|
}
|
|
|
|
}
|
|
|
|
void game_draw_player()
|
|
{
|
|
draw_sprite(sprites[Player.sprite], Player.location.X, Player.location.Y);
|
|
|
|
if(debugs[dbhitbox])
|
|
{
|
|
graphics_colour(colours[debugpink]);
|
|
|
|
// Bounding box debug
|
|
draw_rectangle(
|
|
Player.location.X + Player.hitbox_bl.X,
|
|
Player.location.Y + Player.hitbox_bl.Y,
|
|
Player.location.X + Player.hitbox_tr.X,
|
|
Player.location.Y + Player.hitbox_tr.Y
|
|
);
|
|
}
|
|
|
|
if((Player.firingleft) && (Player.targetleft >= 0))
|
|
{
|
|
graphics_colour(colours[phaserorange1]);
|
|
draw_line(
|
|
Player.location.X + Player.phaser1.X,
|
|
Player.location.Y + Player.phaser1.Y,
|
|
NPCS[Player.targetleft].location.X + ((NPCS[Player.targetleft].hitbox_bl.X + NPCS[Player.targetleft].hitbox_tr.X)/2),
|
|
NPCS[Player.targetleft].location.Y + NPCS[Player.targetleft].hitbox_bl.Y
|
|
);
|
|
graphics_colour(colours[phaserorange2]);
|
|
draw_dotted_line(
|
|
Player.location.X + Player.phaser1.X + 1,
|
|
Player.location.Y + Player.phaser1.Y,
|
|
NPCS[Player.targetleft].location.X + ((NPCS[Player.targetleft].hitbox_bl.X + NPCS[Player.targetleft].hitbox_tr.X)/2) + 1,
|
|
NPCS[Player.targetleft].location.Y + NPCS[Player.targetleft].hitbox_bl.Y
|
|
);
|
|
draw_dotted_line(
|
|
Player.location.X + Player.phaser1.X - 1,
|
|
Player.location.Y + Player.phaser1.Y,
|
|
NPCS[Player.targetleft].location.X + ((NPCS[Player.targetleft].hitbox_bl.X + NPCS[Player.targetleft].hitbox_tr.X)/2) - 1,
|
|
NPCS[Player.targetleft].location.Y + NPCS[Player.targetleft].hitbox_bl.Y
|
|
);
|
|
}
|
|
|
|
if((Player.firingright) && (Player.targetright >= 0))
|
|
{
|
|
graphics_colour(colours[phaserorange1]);
|
|
draw_line(
|
|
Player.location.X + Player.phaser2.X,
|
|
Player.location.Y + Player.phaser2.Y,
|
|
NPCS[Player.targetright].location.X + ((NPCS[Player.targetright].hitbox_bl.X + NPCS[Player.targetright].hitbox_tr.X)/2),
|
|
NPCS[Player.targetright].location.Y + NPCS[Player.targetright].hitbox_bl.Y
|
|
);
|
|
graphics_colour(colours[phaserorange2]);
|
|
draw_dotted_line(
|
|
Player.location.X + Player.phaser2.X + 1,
|
|
Player.location.Y + Player.phaser2.Y,
|
|
NPCS[Player.targetright].location.X + ((NPCS[Player.targetright].hitbox_bl.X + NPCS[Player.targetright].hitbox_tr.X)/2) + 1,
|
|
NPCS[Player.targetright].location.Y + NPCS[Player.targetright].hitbox_bl.Y
|
|
);
|
|
draw_dotted_line(
|
|
Player.location.X + Player.phaser2.X - 1,
|
|
Player.location.Y + Player.phaser2.Y,
|
|
NPCS[Player.targetright].location.X + ((NPCS[Player.targetright].hitbox_bl.X + NPCS[Player.targetright].hitbox_tr.X)/2) - 1,
|
|
NPCS[Player.targetright].location.Y + NPCS[Player.targetright].hitbox_bl.Y
|
|
);
|
|
}
|
|
|
|
if(debugs[dbweapons])
|
|
{
|
|
graphics_colour(colours[debuggreen]);
|
|
|
|
// Draw phaser banks
|
|
draw_line(
|
|
Player.location.X + Player.phaser1.X,
|
|
Player.location.Y + Player.phaser1.Y -5,
|
|
Player.location.X + Player.phaser1.X,
|
|
Player.location.Y + Player.phaser1.Y + 5
|
|
);
|
|
draw_line(
|
|
Player.location.X + Player.phaser1.X -5,
|
|
Player.location.Y + Player.phaser1.Y,
|
|
Player.location.X + Player.phaser1.X +5,
|
|
Player.location.Y + Player.phaser1.Y
|
|
);
|
|
draw_line(
|
|
Player.location.X + Player.phaser2.X,
|
|
Player.location.Y + Player.phaser2.Y -5,
|
|
Player.location.X + Player.phaser2.X,
|
|
Player.location.Y + Player.phaser2.Y + 5
|
|
);
|
|
draw_line(
|
|
Player.location.X + Player.phaser2.X -5,
|
|
Player.location.Y + Player.phaser2.Y,
|
|
Player.location.X + Player.phaser2.X +5,
|
|
Player.location.Y + Player.phaser2.Y
|
|
);
|
|
}
|
|
}
|
|
|
|
void game_draw_npcs()
|
|
{
|
|
int i;
|
|
for(i = 0; i < MAX_NPCS; i++)
|
|
{
|
|
// Don't bother if they are off the screen
|
|
if(NPCS[i].location.Y < DISPLAY_Y)
|
|
{
|
|
draw_sprite(sprites[NPCS[i].sprite], NPCS[i].location.X, NPCS[i].location.Y);
|
|
|
|
// Next sprite up in index is the appropriate target icon
|
|
if(Player.targetleft == i)
|
|
draw_sprite(sprites[NPCS[i].sprite + 1], NPCS[i].location.X, NPCS[i].location.Y);
|
|
if(Player.targetright == i)
|
|
draw_sprite(sprites[NPCS[i].sprite + 1], NPCS[i].location.X, NPCS[i].location.Y);
|
|
|
|
if(tick > NPCS[i].explodenextframe)
|
|
{
|
|
if((NPCS[i].sprite >= explode_start) && (NPCS[i].sprite <= explode_end))
|
|
{
|
|
NPCS[i].sprite++;
|
|
if(NPCS[i].sprite > explode_end)
|
|
game_respawn_npc(i);
|
|
}
|
|
NPCS[i].explodenextframe = tick + 4;
|
|
}
|
|
|
|
if(debugs[dbhitbox])
|
|
{
|
|
graphics_colour(colours[debugpink]);
|
|
|
|
// Bounding box debug
|
|
draw_rectangle(
|
|
NPCS[i].location.X + NPCS[i].hitbox_bl.X,
|
|
NPCS[i].location.Y + NPCS[i].hitbox_bl.Y,
|
|
NPCS[i].location.X + NPCS[i].hitbox_tr.X,
|
|
NPCS[i].location.Y + NPCS[i].hitbox_tr.Y
|
|
);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void game_draw_projectiles()
|
|
{
|
|
int i;
|
|
for(i = 0; i < MAX_PROJECTILES; i++)
|
|
{
|
|
if(Projectiles[i].active == 0)
|
|
continue;
|
|
|
|
draw_sprite(sprites[Projectiles[i].sprite], Projectiles[i].location.X,Projectiles[i].location.Y);
|
|
Projectiles[i].sprite++;
|
|
if(Projectiles[i].sprite > Projectiles[i].spriteend)
|
|
Projectiles[i].sprite = Projectiles[i].spritestart;
|
|
}
|
|
}
|
|
|
|
void game_draw_stars()
|
|
{
|
|
unsigned char i;
|
|
graphics_colour(colours[stargrey]);
|
|
for(i = 0; i < MAX_STARS; i++)
|
|
{
|
|
draw_line(Stars[i].location.X,Stars[i].location.Y,Stars[i].location.X,Stars[i].location.Y+Stars[i].length);
|
|
}
|
|
}
|
|
|
|
void game_setup_player()
|
|
{
|
|
Player.location.X = DISPLAY_X/2;
|
|
Player.location.Y = PLAYER_Y_START;
|
|
Player.sprite = player_ship;
|
|
Player.idlesprite = player_ship;
|
|
Player.velocity = 100;
|
|
Player.shields = 100;
|
|
Player.integrity = 100;
|
|
Player.remainingdistance = 1500000;
|
|
Player.hitbox_bl.X = 0;
|
|
Player.hitbox_bl.Y = 0;
|
|
Player.hitbox_tr.X = 60;
|
|
Player.hitbox_tr.Y = 81;
|
|
Player.phaser1.X = 20;
|
|
Player.phaser1.Y = 75;
|
|
Player.phaser2.X = 41;
|
|
Player.phaser2.Y = 75;
|
|
Player.targetleft = -1;
|
|
Player.targetright = -1;
|
|
Player.firingleft = 0;
|
|
Player.firingright = 0;
|
|
Player.phaserdamage = 10;
|
|
}
|
|
|
|
void game_tick_stars()
|
|
{
|
|
int i;
|
|
for(i = 0; i < MAX_STARS; i++)
|
|
{
|
|
Stars[i].location.Y -= (tick - lasttick) * 4;
|
|
if((Stars[i].location.Y + Stars[i].length) <= 0)
|
|
{
|
|
Stars[i].length = 20 + (rand() % 10);
|
|
Stars[i].location.X = rand() % DISPLAY_X;
|
|
Stars[i].location.Y = DISPLAY_Y + Stars[i].length;
|
|
}
|
|
}
|
|
}
|
|
|
|
void game_setup_stars()
|
|
{
|
|
int i;
|
|
for(i = 0; i < MAX_STARS; i++)
|
|
{
|
|
Stars[i].length = 20 + (rand() % 10);
|
|
Stars[i].location.X = rand() % DISPLAY_X;
|
|
Stars[i].location.Y = rand() % DISPLAY_Y;
|
|
}
|
|
}
|
|
|
|
void game_setup_input()
|
|
{
|
|
/*
|
|
inreg.r[0] = 4;
|
|
inreg.r[1] = 1;
|
|
_kernel_swi(OS_Byte,&inreg,&outreg);
|
|
*/
|
|
}
|
|
|
|
void game_respawn_npc(int id)
|
|
{
|
|
NPCS[id].location.X = rand() % DISPLAY_X;
|
|
NPCS[id].location.Y = DISPLAY_Y + (rand() % (DISPLAY_Y/2));
|
|
if((rand() % 10) > 3)
|
|
NPCS[id].npctype = littledurno;
|
|
else
|
|
NPCS[id].npctype = bigdurno;
|
|
NPCS[id].collidable = 1;
|
|
NPCS[id].nextfire = tick + (rand() % 100);
|
|
switch(NPCS[id].npctype)
|
|
{
|
|
case bigdurno:
|
|
NPCS[id].idlesprite = durno_ship;
|
|
NPCS[id].sprite = durno_ship;
|
|
NPCS[id].velocity.X = 0;
|
|
NPCS[id].velocity.Y = (rand() % 3) + 1;
|
|
NPCS[id].health = 1000;
|
|
NPCS[id].hitbox_bl.X = 0;
|
|
NPCS[id].hitbox_bl.Y = 0;
|
|
NPCS[id].hitbox_tr.X = 48;
|
|
NPCS[id].hitbox_tr.Y = 74;
|
|
NPCS[id].collideforce = 1000;
|
|
NPCS[id].weaponspritestart = photon1;
|
|
NPCS[id].weaponspriteend = photon2;
|
|
NPCS[id].fireinterval = 200;
|
|
NPCS[id].firewidth = 400;
|
|
break;
|
|
case littledurno:
|
|
NPCS[id].idlesprite = durno_ship2;
|
|
NPCS[id].sprite = durno_ship2;
|
|
NPCS[id].velocity.X = (rand() % 1) - 2;
|
|
NPCS[id].velocity.Y = (rand() % 2) + 3;
|
|
NPCS[id].health = 300;
|
|
NPCS[id].hitbox_bl.X = 0;
|
|
NPCS[id].hitbox_bl.Y = 0;
|
|
NPCS[id].hitbox_tr.X = 38;
|
|
NPCS[id].hitbox_tr.Y = 56;
|
|
NPCS[id].collideforce = 50;
|
|
NPCS[id].weaponspritestart = plasma1;
|
|
NPCS[id].weaponspriteend = plasma2;
|
|
NPCS[id].fireinterval = 80;
|
|
NPCS[id].firewidth = 60;
|
|
break;
|
|
};
|
|
}
|
|
|
|
void game_setup_npcs()
|
|
{
|
|
int i;
|
|
for(i = 0; i < MAX_NPCS; i++)
|
|
{
|
|
game_respawn_npc(i);
|
|
NPCS[i].location.Y += 400;
|
|
}
|
|
}
|
|
|
|
void game_tick_npcs()
|
|
{
|
|
int i;
|
|
for(i = 0; i < MAX_NPCS; i++)
|
|
{
|
|
NPCS[i].location.Y -= (tick - lasttick) * NPCS[i].velocity.Y;
|
|
NPCS[i].location.X -= (tick - lasttick) * NPCS[i].velocity.X;
|
|
|
|
if(NPCS[i].npctype == littledurno)
|
|
{
|
|
if(NPCS[i].location.Y > (Player.location.Y + 500))
|
|
{
|
|
if(abs(NPCS[i].location.X - Player.location.X) > 100)
|
|
{
|
|
if(NPCS[i].location.X < Player.location.X)
|
|
NPCS[i].velocity.X = 0 - abs(NPCS[i].velocity.X);
|
|
else
|
|
NPCS[i].velocity.X = abs(NPCS[i].velocity.X);
|
|
}
|
|
}else{
|
|
if(NPCS[i].velocity.X > 0)
|
|
NPCS[i].velocity.X = 1;
|
|
else
|
|
NPCS[i].velocity.X = -1;
|
|
}
|
|
}
|
|
|
|
if(NPCS[i].location.Y + NPCS[i].hitbox_tr.Y <= 0)
|
|
game_respawn_npc(i);
|
|
|
|
if((NPCS[i].location.X + NPCS[i].hitbox_tr.X) > DISPLAY_X)
|
|
game_respawn_npc(i);
|
|
|
|
if((NPCS[i].location.X + NPCS[i].hitbox_bl.X) < 0)
|
|
game_respawn_npc(i);
|
|
|
|
if(tick > NPCS[i].nextfire)
|
|
{
|
|
// Dont fire if off screen
|
|
if((NPCS[i].location.Y < DISPLAY_Y))
|
|
{
|
|
if((NPCS[i].firewidth == -1) || (abs(Player.location.X - NPCS[i].location.X) < NPCS[i].firewidth))
|
|
{
|
|
if(NPCS[i].weaponspritestart == photon1)
|
|
game_spawn_projectile(-1,NPCS[i].location.X, NPCS[i].location.Y, 0, 10, NPCS[i].weaponspritestart, NPCS[i].weaponspriteend, 60);
|
|
else
|
|
game_spawn_projectile(-1,NPCS[i].location.X, NPCS[i].location.Y, 0, 10, NPCS[i].weaponspritestart, NPCS[i].weaponspriteend, 20);
|
|
NPCS[i].nextfire = tick + NPCS[i].fireinterval;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(NPCS[i].health <= 0)
|
|
{
|
|
if(NPCS[i].sprite == NPCS[i].idlesprite)
|
|
{
|
|
NPCS[i].collidable = 0;
|
|
NPCS[i].sprite = explode_start;
|
|
NPCS[i].explodenextframe = tick + 4;
|
|
sound_play(1,-5,0,100);
|
|
sound_play(3,-15,0,1000);
|
|
sound_play(2,-10,1,100);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void game_draw_debugmenu()
|
|
{
|
|
/* int i;
|
|
if(debugs[dbbase])
|
|
{
|
|
font_colour(colours[debuggreen],colours[lcars_black],font[sys_12_8]);
|
|
draw_text("Debug List",DISPLAY_X-200,DISPLAY_Y-40,font[sys_12_8]);
|
|
font_colour(colours[debugs[dbhitbox]?debugpink:stargrey],colours[lcars_black],font[sys_12_8]);
|
|
draw_text("1: hitbox",DISPLAY_X-200,DISPLAY_Y-60,font[sys_12_8]);
|
|
font_colour(colours[debugs[dbweapons]?debugpink:stargrey],colours[lcars_black],font[sys_12_8]);
|
|
draw_text("2: weapons",DISPLAY_X-200,DISPLAY_Y-80,font[sys_12_8]);
|
|
font_colour(colours[debugs[dbinput]?debugpink:stargrey],colours[lcars_black],font[sys_12_8]);
|
|
draw_text("3: input",DISPLAY_X-200,DISPLAY_Y-100,font[sys_12_8]);
|
|
font_colour(colours[debugs[dbperformance]?debugpink:stargrey],colours[lcars_black],font[sys_12_8]);
|
|
draw_text("4: performance",DISPLAY_X-200,DISPLAY_Y-120,font[sys_12_8]);
|
|
font_colour(colours[debugs[dbnpcs]?debugpink:stargrey],colours[lcars_black],font[sys_12_8]);
|
|
draw_text("5: NPCs",DISPLAY_X-200,DISPLAY_Y-140,font[sys_12_8]);
|
|
font_colour(colours[debugs[dbprojectiles]?debugpink:stargrey],colours[lcars_black],font[sys_12_8]);
|
|
draw_text("6: Projectiles",DISPLAY_X-200,DISPLAY_Y-160,font[sys_12_8]);
|
|
}
|
|
|
|
if(debugs[dbperformance])
|
|
{
|
|
font_colour(colours[debuggreen],colours[lcars_black],font[sys_12_8]);
|
|
sprintf(hudbuffer,"CPF: %i",(tick-lasttick));
|
|
draw_text(hudbuffer,DISPLAY_X-500,DISPLAY_Y-60,font[sys_12_8]);
|
|
}
|
|
|
|
if(debugs[dbnpcs])
|
|
{
|
|
font_colour(colours[debuggreen],colours[lcars_black],font[sys_12_8]);
|
|
for(i = 0; i < MAX_NPCS; i++)
|
|
{
|
|
sprintf(hudbuffer,"NPCS[%i] %i%i,%i %i,%i %i",i,NPCS[i].health,NPCS[i].velocity.X,NPCS[i].velocity.Y,NPCS[i].location.X,NPCS[i].location.Y);
|
|
draw_text(hudbuffer,DISPLAY_X-800,DISPLAY_Y-60-(i * 20),font[sys_12_8]);
|
|
}
|
|
}
|
|
|
|
if(debugs[dbprojectiles])
|
|
{
|
|
font_colour(colours[debuggreen],colours[lcars_black],font[sys_12_8]);
|
|
for(i = 0; i < MAX_PROJECTILES; i++)
|
|
{
|
|
sprintf(hudbuffer,"Projectiles[%i] %i %i,%i %i,%i",i,Projectiles[i].active,Projectiles[i].velocity.X,Projectiles[i].velocity.Y,Projectiles[i].location.X,Projectiles[i].location.Y);
|
|
draw_text(hudbuffer,DISPLAY_X-800,DISPLAY_Y-60-(i * 20),font[sys_12_8]);
|
|
}
|
|
}*/
|
|
}
|
|
|
|
void game_tick_collider()
|
|
{
|
|
int i;
|
|
for(i = 0; i < MAX_NPCS; i++)
|
|
{
|
|
if(!NPCS[i].collidable)
|
|
continue;
|
|
// Excuse this formatting
|
|
if(
|
|
game_hitbox_collide(
|
|
(Player.location.X + Player.hitbox_bl.X),(Player.location.Y + Player.hitbox_bl.Y),
|
|
(Player.hitbox_tr.X - Player.hitbox_bl.X),(Player.hitbox_tr.Y - Player.hitbox_bl.Y),
|
|
(NPCS[i].location.X + NPCS[i].hitbox_bl.X),(NPCS[i].location.Y + NPCS[i].hitbox_bl.Y),
|
|
(NPCS[i].hitbox_tr.X - NPCS[i].hitbox_bl.X),(NPCS[i].hitbox_tr.Y - NPCS[i].hitbox_bl.Y)
|
|
)
|
|
)
|
|
{
|
|
|
|
/*if(debugs[dbhitbox])
|
|
{
|
|
font_colour(colours[debuggreen],colours[lcars_black],font[sys_12_8]);
|
|
sprintf(hudbuffer,"NPCS[%i] hits player",i,NPCS[i].location.X,NPCS[i].location.Y);
|
|
draw_text(hudbuffer,DISPLAY_X-900,DISPLAY_Y-260-(i * 20),font[sys_12_8]);
|
|
}*/
|
|
|
|
NPCS[i].health -= 300;
|
|
NPCS[i].collidable = 0;
|
|
NPCS[i].velocity.Y = NPCS[i].velocity.Y / 2;
|
|
NPCS[i].velocity.X = NPCS[i].velocity.X * 4;
|
|
|
|
Player.shields -= NPCS[i].collideforce;
|
|
if(Player.shields < 0)
|
|
{
|
|
Player.integrity += Player.shields;
|
|
Player.shields = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
for(i = 0; i < MAX_PROJECTILES; i++)
|
|
{
|
|
if(!Projectiles[i].active)
|
|
continue;
|
|
if(!Projectiles[i].collidable)
|
|
continue;
|
|
// Excuse this formatting
|
|
if(
|
|
game_hitbox_collide(
|
|
(Player.location.X + Player.hitbox_bl.X),(Player.location.Y + Player.hitbox_bl.Y),
|
|
(Player.hitbox_tr.X - Player.hitbox_bl.X),(Player.hitbox_tr.Y - Player.hitbox_bl.Y),
|
|
Projectiles[i].location.X,Projectiles[i].location.Y,
|
|
10,10
|
|
)
|
|
)
|
|
{
|
|
sound_play(2,-5, 20,1);
|
|
Projectiles[i].active = 0;
|
|
Player.shields -= Projectiles[i].damage;
|
|
if(Player.shields < 0)
|
|
{
|
|
Player.integrity += Player.shields;
|
|
Player.shields = 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void game_tick_player_targets()
|
|
{
|
|
int i;
|
|
int NoseX = Player.location.X + Player.hitbox_bl.X + (Player.hitbox_tr.X/2);
|
|
int NoseXLeft = Player.location.X + Player.hitbox_bl.X;
|
|
int NoseXRight = Player.location.X + Player.hitbox_bl.X + Player.hitbox_tr.X;
|
|
int NoseY = Player.location.Y + + Player.hitbox_bl.Y + Player.hitbox_tr.Y;
|
|
int LeftDistance = 1000;
|
|
int RightDistance = 1000;
|
|
int LeftCornerX, LeftCornerY, RightCornerX,DistanceX,DistanceY;
|
|
Player.targetleft = -1;
|
|
Player.targetright = -1;
|
|
|
|
for(i = 0; i < MAX_NPCS; i++)
|
|
{
|
|
if(!NPCS[i].collidable)
|
|
continue;
|
|
if(NPCS[i].location.Y > (DISPLAY_Y-50))
|
|
continue;
|
|
LeftCornerX = NPCS[i].location.X + NPCS[i].hitbox_bl.X;
|
|
LeftCornerY = NPCS[i].location.Y + NPCS[i].hitbox_bl.Y;
|
|
RightCornerX = NPCS[i].location.X + NPCS[i].hitbox_tr.X;
|
|
|
|
if(LeftCornerY > NoseY)
|
|
{
|
|
DistanceY = LeftCornerY - NoseY;
|
|
DistanceX = abs(NoseX - ((LeftCornerX + RightCornerX) / 2));
|
|
|
|
if((DistanceY/5) > DistanceX)
|
|
{
|
|
if((NoseXRight - ((LeftCornerX + RightCornerX) / 2)) > 0)
|
|
{
|
|
if(DistanceY < LeftDistance)
|
|
{
|
|
LeftDistance = DistanceY;
|
|
Player.targetleft = i;
|
|
}
|
|
}
|
|
if((NoseXLeft - ((LeftCornerX + RightCornerX) / 2)) < 0)
|
|
{
|
|
if(DistanceY < RightDistance)
|
|
{
|
|
RightDistance = DistanceY;
|
|
Player.targetright = i;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
void game_tick_projectiles()
|
|
{
|
|
int i;
|
|
for(i = 0; i < MAX_PROJECTILES; i++)
|
|
{
|
|
if(!Projectiles[i].active)
|
|
continue;
|
|
|
|
if(tick > Projectiles[i].nextframe)
|
|
{
|
|
if((Projectiles[i].sprite >= photon1) && (Projectiles[i].sprite <= photon2))
|
|
{
|
|
Projectiles[i].sprite++;
|
|
if(Projectiles[i].sprite > photon2)
|
|
Projectiles[i].sprite = photon1;
|
|
}
|
|
Projectiles[i].nextframe = tick + 10;
|
|
}
|
|
|
|
|
|
Projectiles[i].location.Y -= (tick - lasttick) * Projectiles[i].velocity.Y;
|
|
Projectiles[i].location.X -= (tick - lasttick) * Projectiles[i].velocity.X;
|
|
|
|
if((Projectiles[i].location.Y) <= 0)
|
|
{
|
|
Projectiles[i].active = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void game_tick_input()
|
|
{
|
|
if(debugs[dbbase])
|
|
{
|
|
// 1
|
|
if(input_readkey(17))
|
|
debugs[dbinput] = 1;
|
|
// 2
|
|
if(input_readkey(48))
|
|
debugs[dbhitbox] = 1;
|
|
// 3
|
|
if(input_readkey(49))
|
|
debugs[dbweapons] = 1;
|
|
// 4
|
|
if(input_readkey(18))
|
|
debugs[dbperformance] = 1;
|
|
// 5
|
|
if(input_readkey(19))
|
|
debugs[dbnpcs] = 1;
|
|
// 6
|
|
if(input_readkey(24))
|
|
debugs[dbprojectiles] = 1;
|
|
}
|
|
|
|
/*if(debugs[dbinput])
|
|
{
|
|
font_colour(colours[debuggreen],colours[lcars_black],font[sys_12_8]);
|
|
sprintf(hudbuffer,"Keycode: %i",input_readanykey());
|
|
draw_text(hudbuffer,DISPLAY_X-500,DISPLAY_Y-40,font[sys_12_8]);
|
|
}*/
|
|
|
|
// Q
|
|
if(input_readkey(16))
|
|
debugs[dbbase] = 1;
|
|
|
|
if(tick > Player.nextidlesprite)
|
|
Player.sprite = Player.idlesprite;
|
|
|
|
// Right arrow
|
|
if(input_readkey(121))
|
|
{
|
|
Player.location.X += PLAYER_X_SPEED * (tick - lasttick);
|
|
Player.sprite = player_shipr;
|
|
Player.nextidlesprite = tick + 15;
|
|
if((Player.location.X + Player.hitbox_tr.X) > DISPLAY_X)
|
|
{
|
|
Player.location.X = DISPLAY_X - Player.hitbox_tr.X;
|
|
}
|
|
}
|
|
|
|
// Left arrow
|
|
if(input_readkey(25))
|
|
{
|
|
Player.location.X -= PLAYER_X_SPEED * (tick - lasttick);
|
|
Player.sprite = player_shipl;
|
|
Player.nextidlesprite = tick + 15;
|
|
if((Player.location.X + Player.hitbox_bl.X) < 0)
|
|
{
|
|
Player.location.X = 0 - Player.hitbox_bl.X;
|
|
}
|
|
}
|
|
|
|
// Space
|
|
if(input_readkey(98))
|
|
{
|
|
Player.firingleft = 1;
|
|
Player.firingright = 1;
|
|
Player.nextshieldheal = tick + 100;
|
|
}else{
|
|
Player.firingleft = 0;
|
|
Player.firingright = 0;
|
|
}
|
|
}
|
|
|
|
void game_setup_audio()
|
|
{
|
|
sound_voices(4);
|
|
|
|
sound_set_voice(1,"WaveSynth-Beep");
|
|
sound_set_voice(2,"Percussion-Noise");
|
|
sound_set_voice(3,"Percussion-Soft");
|
|
sound_set_voice(4,"Percussion-Noise");
|
|
}
|
|
|
|
void game_draw_hud()
|
|
{
|
|
draw_sprite("lcars",4,DISPLAY_Y-164);
|
|
draw_sprite("pointer",141+(Player.shields*2),DISPLAY_Y - 164 + 84);
|
|
draw_sprite("pointer",141+(Player.integrity*2),DISPLAY_Y - 164 + 44);
|
|
draw_sprite("pointer",141+(Player.remainingdistance/7500),DISPLAY_Y - 164 + 4);
|
|
}
|
|
|
|
void game1_setup()
|
|
{
|
|
game_setup_input();
|
|
game_setup_audio();
|
|
game_setup_stars();
|
|
game_setup_player();
|
|
game_setup_npcs();
|
|
tick = clock();
|
|
}
|
|
|
|
void game_tick_player()
|
|
{
|
|
Player.remainingdistance -= Player.velocity * (tick - lasttick);
|
|
|
|
if(Player.shields < 100)
|
|
{
|
|
if(tick > Player.nextshieldheal)
|
|
{
|
|
Player.shields += 1;
|
|
Player.nextshieldheal = tick + 10;
|
|
}
|
|
}
|
|
|
|
if((Player.firingleft) && (Player.targetleft >= 0))
|
|
{
|
|
NPCS[Player.targetleft].health -= (tick - lasttick) * Player.phaserdamage;
|
|
}
|
|
|
|
if((Player.firingright) && (Player.targetright >= 0))
|
|
{
|
|
NPCS[Player.targetright].health -= (tick - lasttick) * Player.phaserdamage;
|
|
}
|
|
}
|
|
|
|
void game1_death()
|
|
{
|
|
int currentstart = 0;
|
|
int introframe = 0;
|
|
sound_voices(4);
|
|
|
|
sound_set_voice(1,"WaveSynth-Beep");
|
|
sound_set_voice(2,"WaveSynth-Beep");
|
|
sound_set_voice(3,"WaveSynth-Beep");
|
|
sound_set_voice(4,"WaveSynth-Beep");
|
|
sound_composition_init();
|
|
|
|
currentstart += 100;
|
|
sound_composition_element_add(currentstart,1,sound_note("D2"),150);
|
|
currentstart += 100;
|
|
sound_composition_element_add(currentstart,2,sound_note("G2"),200);
|
|
currentstart += 200;
|
|
sound_composition_element_add(currentstart,3,sound_note("B3"),75);
|
|
currentstart += 40;
|
|
sound_composition_element_add(currentstart,4,sound_note("G2"),75);
|
|
currentstart += 50;
|
|
sound_composition_element_add(currentstart,2,sound_note("B3"),200);
|
|
currentstart += 200;
|
|
sound_composition_element_add(currentstart,1,sound_note("A3"),100);
|
|
currentstart += 100;
|
|
sound_composition_element_add(currentstart,3,sound_note("G2"),150);
|
|
currentstart += 150;
|
|
sound_composition_element_add(currentstart,2,sound_note("E2"),100);
|
|
currentstart += 100;
|
|
sound_composition_element_add(currentstart,1,sound_note("D2"),150);
|
|
currentstart += 150;
|
|
sound_composition_element_add(currentstart,3,sound_note("D2"),150);
|
|
currentstart += 100;
|
|
sound_composition_element_add(currentstart,4,sound_note("G2"),150);
|
|
currentstart += 150;
|
|
sound_composition_element_add(currentstart,1,sound_note("B3"),75);
|
|
currentstart += 40;
|
|
sound_composition_element_add(currentstart,2,sound_note("G2"),75);
|
|
currentstart += 40;
|
|
sound_composition_element_add(currentstart,3,sound_note("B3"),150);
|
|
currentstart += 150;
|
|
sound_composition_element_add(currentstart,4,sound_note("A3"),130);
|
|
currentstart += 100;
|
|
sound_composition_element_add(currentstart,1,sound_note("G2"),200);
|
|
currentstart += 300;
|
|
tick = clock();
|
|
|
|
sound_composition_start(clock());
|
|
|
|
draw_sprite("spacebar",(DISPLAY_X/2)-106,50);
|
|
draw_sprite("kia",(DISPLAY_X/2)-300,500);
|
|
|
|
screen_flipbuffer();
|
|
|
|
while(sound_composition_incomplete())
|
|
{
|
|
sound_composition_tick(clock());
|
|
|
|
if(clock() > (tick + 100))
|
|
{
|
|
if(input_readkey(98))
|
|
sound_composition_stop();
|
|
}
|
|
}
|
|
}
|
|
|
|
void game1_briefing()
|
|
{
|
|
screen_clear();
|
|
|
|
draw_spritetext(
|
|
"~~~~~~~~{chief engineers log - uss archimedes - stardate 1234567890=========================}\n\n\nthe federation has begun diplomatic relations with the planet korell. their unusual position within an asteroid belt \nmeans their planet has to be protected by a deflector shield. the federation has offered to help enhance this shield. \nonce this upgrade was completed we were preparing to leave when we recieved a priority one transmission from the \narchimedes saying a fleet of fighters from the neighbouring planet of durnovaria was en route to torell. it transpires \nthat the deflector shield may also have some military value that was concealed from the federation. the durnovarians \nhave said our shuttle is now considered a military target and will be treated as such. must to get back to the archimedes \nbefore we get dragged further into the conflict between the two planets.\n\n\n~~~~~~~~{==========================================~~~~~~~~=======}"
|
|
, 50, 700);
|
|
|
|
draw_sprite("spacebar",(DISPLAY_X/2)-106,50);
|
|
|
|
tick = clock();
|
|
while(1)
|
|
{
|
|
if(clock() > (tick + 100))
|
|
{
|
|
if(input_readkey(98))
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
int game1_tick()
|
|
{
|
|
lasttick = tick;
|
|
tick = clock();
|
|
|
|
screen_flipbuffer();
|
|
screen_clear();
|
|
|
|
if(Player.integrity > 0)
|
|
{
|
|
PROFILE(game_tick_stars());
|
|
PROFILE(game_tick_input());
|
|
PROFILE(game_tick_player());
|
|
PROFILE(game_tick_npcs());
|
|
PROFILE(game_tick_collider());
|
|
PROFILE(game_tick_player_targets());
|
|
PROFILE(game_tick_npcs());
|
|
PROFILE(game_tick_projectiles());
|
|
PROFILE(game_draw_stars());
|
|
PROFILE(game_draw_player());
|
|
PROFILE(game_draw_npcs());
|
|
PROFILE(game_draw_projectiles());
|
|
|
|
PROFILE(game_draw_hud());
|
|
PROFILE(game_draw_debugmenu());
|
|
return 0;
|
|
}else{
|
|
screen_flipbuffer();
|
|
screen_clear();
|
|
game1_death();
|
|
return 1;
|
|
}
|
|
|
|
|
|
}
|