#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <vector>
#include <fstream>
#include <sstream>
#include "mylib.h"
#include "Character.h"
#include "Bullet.h"
#include "Object.h"
#include "Enemy.h"
using namespace std;
volatile int flag = 0;
void timer()
{
flag = 1;
}
END_OF_FUNCTION(timer)
void check_keyboard(Character *character, vector<Bullet> &bullet)
{
if(key[KEY_RIGHT])
{
character->setSpriteN(0);
//If key_right pressed and not flying, move right
if(!character->getFlying())
character->setSpeedX(7);
//test-=5;
}
else if(key[KEY_LEFT])
{
character->setSpriteN(1);
//If key_left pressed and not flying, move left
if(!character->getFlying())
character->setSpeedX(-7);
}
else
{
//Else do not move
if(!character->getJumping())
character->setSpeedX(0);
}
if(key[KEY_UP])
{
//If key_up pressed and not flying, jump
if(!character->getFlying())
{
character->setSpeedY(-15);
character->setFlying(true);
character->setJumping(true);
}
}
if(key[KEY_SPACE])
{
//If key_space pressed, fire
//if(bullet.size()<5)
{
if(character->CanFire() | character->getAuto()) //Only if allowed
{
int speed=20;
float x = character->getX() + character->getW();
if(character->getSpriteN()==1)
{
x = character->getX();
speed=-20;
}
bullet.push_back(*new Bullet((int)x, character->getY()+((int)(character->getH()/2.4)), speed, 1));
character->AllowFire(false);
}
}
}
else character->AllowFire(true);
}
void move_bullet(vector<Bullet> &bullet, Bullet *bull, int index)
{
if(bull->getY() <0)
{
//If it goes beyond the top border, destroy it
bullet.erase(bullet.begin()+index);
}
else if(bull->getY() >600)
{
//If it goes beyond the bottom border, destroy it
bullet.erase(bullet.begin()+index);
}
}
void draw_screen(BITMAP* buf, BITMAP* back, Character *character, vector<Object> &object, vector<Enemy> &enemy,
vector<Bullet> &bullet,int tx, int *temp)
{
//Draw background
draw_sprite(buf,back,*temp,0);
if(*temp<0)
draw_sprite(buf,back,*temp+back->w,0);
else if(*temp>0)
draw_sprite(buf,back,*temp-back->w,0);
if(abs(*temp)>=back->w)
*temp=0;
//Draw bullets
for(unsigned int i=0; i<bullet.size(); i++)
{
draw_sprite(buf, bullet[i].getSprite(), (int)bullet[i].getX(), (int)bullet[i].getY());
}
//Draw enemies
for(unsigned int i=0; i<enemy.size(); i++)
{
//Draw only enemies in the screen
if(enemy[i].onScreen())
{
draw_sprite(buf, enemy[i].getSprite(), (int)enemy[i].getX(), (int)enemy[i].getY());
drawLife(buf, &enemy[i]);
}
}
//Draw objects
for(unsigned int i=0; i<object.size(); i++)
{
//Draw only objects in the screen
if(object[i].onScreen())
{
blit(object[i].getSprite(),buf,0,0, (int)object[i].getX(), (int)object[i].getY(),object[i].getW(),object[i].getH());
}
}
draw_sprite(buf, character->getSprite(), (int)character->getX(), (int)character->getY());
drawLife(buf, character);
draw_sprite(screen,buf,0,0);
clear_to_color(buf,makecol(255,255,255));
}
void initLevel(int n, vector<Object> &obj, vector<Enemy> &ene, string *back)
{
stringstream lfname;
ifstream sti;
int on, x, y, w;
string path;
BITMAP *tb, *tb2;
//Get level file name
lfname<<"levels/level";
lfname<<n;
lfname<<".txt";
//Open level file
sti.open(lfname.str().c_str(),ios::in);
if(!sti.is_open())
{
allegro_message("Cannot open level file!\n");
allegro_exit();
exit(-1);
}
//**********************
// Load background
//**********************
sti>>*back;
//**********************
// Load enemies
//**********************
tb = load_bitmap("images/sprite2.bmp",default_palette);
tb2 = load_bitmap("images/sprite2b.bmp",default_palette);
if((!tb) | (!tb2))
error_load_bitmap();
//Get the number of enemies
sti>>on;
for(int i=0; i<on; i++)
{
sti>>x;
sti>>y;
sti>>w; //Load life
ene.push_back(*(new Enemy(tb)));
ene[i].loadSprite(tb2);
ene[i].setX(x);
ene[i].setY(y);
ene[i].setLife(w);
}
//**********************
// Load objects
//**********************
//Get the number of objects
sti>>on;
//Load objects from level file
for(int i=0; i<on; i++)
{
sti>>x;
sti>>y;
sti>>w;
sti>>path;
if(path!="-")
{
tb = load_bitmap(path.c_str(),default_palette);
if((!tb))
error_load_bitmap();
}
obj.push_back(*(new Object(tb)));
obj[i].setX(x);
obj[i].setY(y);
obj[i].setW(w);
}
sti.close();
//**********************
// Load bullets
//**********************
Bullet::bsprite.push_back(load_bitmap("images/bullet1.bmp",default_palette));
}
int main()
{
allegro_init();
install_keyboard();
set_color_depth(32);
set_gfx_mode(GFX_AUTODETECT,800,600,0,0);
int flag10=0;
int absx=0, dx;
Character *cha=NULL;
vector<Enemy> ene;
vector<Bullet> bul;
vector<Object> obj;
BITMAP *back=NULL;
BITMAP *buf;
string path;
//**********************
// Load hero
//**********************
//TODO: check if loaded well
cha=new Character(load_bitmap("images/sprite0.bmp",default_palette));
cha->loadSprite(load_bitmap("images/sprite0b.bmp",default_palette));
cha->setSpriteN(0);
cha->setX(350);
//Initialize level
initLevel(1,obj,ene, &path);
back = load_bitmap(path.c_str(),default_palette);
if(!back)
error_load_bitmap();
//Create the buffer
buf = create_bitmap(800,600);
//Create the timer
LOCK_VARIABLE(flag);
LOCK_FUNCTION(timer);
install_int(timer,30);
//Load init message
BITMAP *title = load_bitmap("images/title.bmp",default_palette);
if(!title)
error_load_bitmap();
//Show init message
draw_sprite(screen, title ,0,0);
textout_centre_ex(screen, font, "Press any key to play...",
SCREEN_W / 2, 500,
makecol(0, 255, 0), makecol(0, 0, 0));
while(!keypressed()){}
//Play game
while(!key[KEY_ESC])
{
rest(10);
if(flag)
{
dx = cha->getX();
flag = 0;
flag10++;
if(cha->getDead())
{
//If character is dead, game over
title = load_bitmap("images/gameover.bmp",default_palette);
if(!title)
error_load_bitmap();
clear_to_color(buf,makecol(0,0,0));
draw_sprite(buf,title,0,0);
textout_centre_ex(buf, font, "Press esc to quit...",
SCREEN_W / 2, 500,
makecol(0, 255, 0), makecol(0, 0, 0));
draw_sprite(screen,buf,0,0);
}
else if(ene.size()==0)
{
title = load_bitmap("images/complete.bmp",default_palette);
if(!title)
error_load_bitmap();
clear_to_color(buf,makecol(0,0,0));
draw_sprite(buf,title,0,100);
textout_centre_ex(buf, font, "The adventure continues, write your own levels.",
SCREEN_W / 2, 300,
makecol(0, 255, 0), makecol(0, 0, 0));
textout_centre_ex(buf, font, "Game developed by Sesia Matteo, official member of www.pierotofy.it",
SCREEN_W / 2, 330,
makecol(0, 255, 0), makecol(0, 0, 0));
textout_centre_ex(buf, font, "Contact me at matthew@pierotofy.it for info and to report bugs.",
SCREEN_W / 2, 340,
makecol(0, 255, 0), makecol(0, 0, 0));
textout_centre_ex(buf, font, "Press esc to quit...",
SCREEN_W / 2, 500,
makecol(0, 255, 0), makecol(0, 0, 0));
draw_sprite(screen,buf,0,0);
}
else
{
check_keyboard(cha, bul);
//Move the character
cha->move(obj,cha);
//Destroy enemies killed, move the others
for(unsigned int i=0; i<ene.size(); i++)
{
if(ene[i].getDead())
ene.erase(ene.begin()+i);
else
{
if(ene[i].onScreen())
{
ene[i].move(obj,cha);
if(flag10==10)
{
ene[i].Attack(bul,obj,ene,cha);
}
}
}
}
if(flag10==10) flag10=0;
//Destroy dead bullets and move the others
for(unsigned int i=0; i<bul.size(); i++)
{
if(bul[i].getDead())
bul.erase(bul.begin()+i);
else
{
bul[i].move(obj, ene, cha);
}
}
//Move the dynamic objects
for(unsigned int i=0; i<obj.size(); i++)
{
if(obj[i].getDynamic() && obj[i].onScreen())
{
obj[i].move();
}
}
dx-=cha->getX();
dx*=-1;
//Scroll screen
for(unsigned int i=0; i<ene.size(); i++)
{
ene[i].scroll(dx);
}
for(unsigned int i=0; i<obj.size(); i++)
{
obj[i].scroll(dx);
}
cha->scroll(dx);
absx-=dx;
if(!back)
error_load_bitmap();
draw_screen(buf, back, cha, obj, ene, bul, dx, &absx);
}
}
};
remove_int(timer);
destroy_bitmap(buf);
allegro_exit();
return 0;
}
END_OF_MAIN()