One of my first programming projects. I tried to learn C and use curses...it is quite embarrassing looking back at it now :D
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

302 lines
7.2 KiB

#include <ncurses.h>
#include <string.h>
#define MAX_PROJECTILES 2
#define MAX_ZOMBIES 1000
#define MAX_ALIVE 10000
int scrRows,scrCols;
int viewportWinRows,viewportWinCols;
int lastPressed;
WINDOW* viewportWin;
WINDOW* scoreWin;
struct Projectile{
int isAlive;
char symbol;
int curXpos;
int curYpos;
int prevYpos;
int prevXpos;
int nextYpos;
int nextXpos;
int range;
char direction;
int distanceTraveled;
};
struct Projectile projectiles[MAX_PROJECTILES];
struct Weapon{
char name[10];
int range;
int maxCapacity;
int curCapacity;
char projectileSymbol;
char symbols[8];
};
struct Entity {
char *type;
char symbol;
int curYpos, curXpos;
int nextYpos, nextXpos;
struct Weapon weapons[8];
int curWeapon;
int isAlive;
};
struct Entity player = {.type="player",.symbol='@', .curYpos=1, .curXpos=1, .nextYpos=1, .nextXpos=1 ,.isAlive=1};
struct Entity zombies[MAX_ZOMBIES];
struct Entity allEntities[MAX_ALIVE];
struct Entity zombie = {.type="zombie", .symbol='Z', .curYpos=5, .curXpos=5, .nextYpos=5, .nextXpos=5 ,.isAlive=1};
struct Weapon pistol = {.name="Pistol", .range=3, .maxCapacity=12, .curCapacity=12, .symbols="-\\|/-\\|/"};
struct Entity * collisionDetect(int objYpos, int objXpos){
int i;
for(i=1; i<MAX_ALIVE; i++){
if(allEntities[i].isAlive){
if(objYpos==allEntities[i].curYpos && objXpos==allEntities[i].curXpos){
return &allEntities[i];
}
}
}
}
void moveProjectiles(){
int i;
for(i=0; i<MAX_PROJECTILES; i++){
if(projectiles[i].isAlive){
projectiles[i].prevYpos=projectiles[i].curYpos;
projectiles[i].prevXpos=projectiles[i].curXpos;
switch(projectiles[i].direction){
case 'w':{
projectiles[i].curYpos--;
break;
}
case 'a':{
projectiles[i].curXpos--;
break;
}
case 's':{
projectiles[i].curYpos++;
break;
}
case 'd':{
projectiles[i].curXpos++;
break;
}
}
projectiles[i].distanceTraveled++;
mvwaddch(viewportWin, projectiles[i].curYpos, projectiles[i].curXpos, projectiles[i].symbol);
struct Entity * hitEntity = collisionDetect(projectiles[i].curYpos, projectiles[i].curXpos);
if(hitEntity){
if(hitEntity->type=="zombie"){
projectiles[i].isAlive=0;
hitEntity->isAlive=0;
mvwaddch(viewportWin, allEntities[i].curYpos, allEntities[i].curXpos, ' ');
}
}
if(mvwinch(viewportWin,projectiles[i].prevYpos, projectiles[i].prevXpos)==projectiles[i].symbol){
mvwaddch(viewportWin, projectiles[i].prevYpos, projectiles[i].prevXpos, ' ');
}
if(projectiles[i].distanceTraveled>=projectiles[i].range || projectiles[i].curYpos > viewportWinRows || projectiles[i].curYpos < 0 || projectiles[i].curXpos > viewportWinCols || projectiles[i].curXpos < 0){
projectiles[i].isAlive=0;
mvwaddch(viewportWin, projectiles[i].curYpos, projectiles[i].curXpos, ' ');
}
usleep(30000);
}
else{
mvwaddch(viewportWin, projectiles[i].curYpos, projectiles[i].curXpos, ' ');
}
}
}
void fireWeapon(struct Weapon *weaponRef, char *direction){
struct Projectile projectile;
if (!strcmp(weaponRef->name,"Pistol")){
projectile.range=20;
}
projectile.isAlive=1;
projectile.distanceTraveled=0;
projectile.curYpos=allEntities[0].curYpos;
projectile.curXpos=allEntities[0].curXpos;
if(direction=="up"){
projectile.range*=.4;
projectile.direction='w';
projectile.symbol=weaponRef->symbols[2];
}
if(direction=="left"){
projectile.direction='a';
projectile.symbol=weaponRef->symbols[0];
}
if(direction=="down"){
projectile.range*=.4;
projectile.direction='s';
projectile.symbol=weaponRef->symbols[6];
}
if(direction=="right"){
projectile.direction='d';
projectile.symbol=weaponRef->symbols[4];
}
int i;
for(i=0;i<MAX_PROJECTILES;i++){
if(!projectiles[i].isAlive && !projectiles[i+1].isAlive){
projectiles[i]=projectile;
allEntities[0].weapons[allEntities[0].curWeapon].curCapacity--;
break;
}
}
}
void drawScore(){
werase(scoreWin);
box(scoreWin, 0, 0);
mvwprintw(scoreWin, 1, 1, "Current Weapon: %s",allEntities[0].weapons[allEntities[0].curWeapon].name);
mvwprintw(scoreWin, 2, 1, "Ammo: %d/%d",allEntities[0].weapons[allEntities[0].curWeapon].curCapacity,allEntities[0].weapons[allEntities[0].curWeapon].maxCapacity);
wnoutrefresh(scoreWin);
}
void drawViewport(){
box(viewportWin,0,0);
int i;
for(i=0; i<MAX_ALIVE; i++){
if(allEntities[i].isAlive){
mvwaddch(viewportWin, allEntities[i].curYpos, allEntities[i].curXpos, ' ');
mvwaddch(viewportWin, allEntities[i].nextYpos, allEntities[i].nextXpos, allEntities[i].symbol);
allEntities[i].curYpos = allEntities[i].nextYpos;
allEntities[i].curXpos = allEntities[i].nextXpos; }
}
wnoutrefresh(viewportWin);
doupdate();
}
void initializeWorld() {
curs_set(0);
getmaxyx(stdscr,scrRows,scrCols);
viewportWin=newwin(scrRows-10,scrCols,0,0);
getmaxyx(viewportWin,viewportWinRows,viewportWinCols);
scoreWin=newwin(10,scrCols,scrRows-10,0);
allEntities[0]=player;
allEntities[1]=zombie;
allEntities[0].curYpos=10;
allEntities[0].curXpos=10;
zombie.curYpos=rand()%viewportWinRows;
zombie.curYpos=rand()%viewportWinCols;
}
int main() {
srand(time(NULL));
initscr();
cbreak();
keypad(stdscr, TRUE);
noecho();
initializeWorld();
nodelay(stdscr, TRUE);
int ch;
allEntities[0].weapons[0]=pistol;
allEntities[0].curWeapon=0;
while(1) {
drawScore();
drawViewport();
moveProjectiles();
doupdate();
ch = getch();
switch(ch){
case 'w':
case 'W':{
if(allEntities[0].curYpos > 1){
allEntities[0].nextYpos--;
if(allEntities[0].nextYpos < 0){
allEntities[0].nextYpos = 0;
}
}
break;
}
case 's':
case 'S':{
if(allEntities[0].curYpos < viewportWinRows - 2){
allEntities[0].nextYpos++;
if(allEntities[0].nextYpos > viewportWinRows-1){
allEntities[0].nextYpos = viewportWinRows-1;
}
}
break;
}
case 'a':
case 'A':{
if(allEntities[0].curXpos > 1){
allEntities[0].nextXpos--;
if(allEntities[0].nextXpos < 0){
allEntities[0].nextXpos = 0;
}
}
break;
}
case 'd':
case 'D':{
if(allEntities[0].curXpos < scrCols-2){
allEntities[0].nextXpos++;
if(allEntities[0].nextXpos > viewportWinCols-1){
allEntities[0].nextXpos = viewportWinCols-1;
}
}
break;
}
case KEY_UP:{
if(allEntities[0].weapons[allEntities[0].curWeapon].curCapacity>0){
fireWeapon(&pistol, "up");
}
break;
}
case KEY_LEFT:{
if(allEntities[0].weapons[allEntities[0].curWeapon].curCapacity>0){
fireWeapon(&pistol, "left");
}
break;
}
case KEY_DOWN:{
if(allEntities[0].weapons[allEntities[0].curWeapon].curCapacity>0){
fireWeapon(&pistol, "down");
}
break;
}
case KEY_RIGHT:{
if(allEntities[0].weapons[allEntities[0].curWeapon].curCapacity>0){
fireWeapon(&pistol, "right");
}
break;
}
default:
if (ch != ERR) {lastPressed=ch;};
break;
}
struct Entity * hitEntity = collisionDetect(allEntities[0].curYpos, allEntities[0].curXpos);
if(hitEntity){
if(hitEntity->type=="zombie"){
mvwprintw(viewportWin,1,1,"TEST");
allEntities[0].isAlive=0;
hitEntity->isAlive=0;
mvwaddch(viewportWin, allEntities[0].curYpos, allEntities[0].curXpos, ' ');
}
}
}
return 0;
}