#include <iostream>
#include "SDL.h"
#include "gdlib.hpp"
#include "area.hpp"
#include "gfxlib.hpp"
#include "wm.hpp"
struct Shot {
gdlib::Point pos;
int speed;
bool alive;
};
#define MAX_SHOTS 80
#define SHOT_VIS MAX_VIS_STATES-1
class SpaceShip : public gdlib::Entity {
protected:
Shot shots[MAX_SHOTS];
int rate_of_fire;
public:
SpaceShip();
virtual void Fire();
virtual void Draw();
};
void KeyHandler(const void *arg);
void MainLoop(const void *arg);
#define MOVE_DIST 4
SpaceShip sship;
gdlib::Area area;
bool Init() {
wm::SetHandler(wm::HTYPE_KEY, KeyHandler);
wm::SetHandler(wm::HTYPE_IDLE, MainLoop);
gfxlib::InitVideo(640, 480, false);
sship.SetVisual(new gdlib::Image("data/sship.png"), 0);
sship.SetVisual(new gdlib::Image("data/sship_left.png"), 1);
sship.SetVisual(new gdlib::Image("data/sship_right.png"), 2);
sship.SetVisual(new gdlib::Image("data/shot.png"), SHOT_VIS);
sship.SetPosition(320, 400);
area.AddLayer(new gdlib::Background("data/bg0_big.png"));
area.AddLayer(new gdlib::Background("data/bg1_big.png"));
area.SetVisible(gfxlib::MakeRect(0, 2400 - 480, 640, 2400));
return true;
}
void MainLoop(const void *arg) {
static unsigned long prev;
while(SDL_GetTicks() - prev < 32);
prev = SDL_GetTicks();
sship.SetActiveState(0);
if(wm::GetKeyState(SDLK_UP)) {
sship.Move(0, -MOVE_DIST);
}
if(wm::GetKeyState(SDLK_DOWN)) {
sship.Move(0, MOVE_DIST);
}
if(wm::GetKeyState(SDLK_LEFT)) {
sship.SetActiveState(1);
sship.Move(-MOVE_DIST, 0);
}
if(wm::GetKeyState(SDLK_RIGHT)) {
sship.SetActiveState(2);
sship.Move(MOVE_DIST, 0);
}
if(wm::GetKeyState(SDLK_SPACE)) {
sship.Fire();
}
area.Move(0, -1);
PixelBuffer *pbuf = gfxlib::Lock(0);
gfxlib::Clear(pbuf, 0);
area.SetSurface(pbuf);
area.Draw();
sship.SetSurface(pbuf);
sship.Draw();
gfxlib::Unlock(0);
gfxlib::Flip();
}
void KeyHandler(const void *arg) {
if(((wm::KeyHandlerArg*)arg)->key == 27) {
gfxlib::CloseVideo();
wm::ShutDown();
}
}
int main() {
if(!Init()) {
std::cerr << "Initialization error\n";
return 0;
}
wm::Run();
}
SpaceShip::SpaceShip() {
memset(shots, 0, MAX_SHOTS * sizeof(Shot));
rate_of_fire = 10;
}
void SpaceShip::Fire() {
static unsigned long last_fire;
if(SDL_GetTicks() - last_fire < 1000 / rate_of_fire) return;
for(int i=0; i<MAX_SHOTS; i++) {
if(!shots[i].alive) {
shots[i].alive = true;
shots[i].pos = gdlib::Point(pos.x, pos.y - 60);
shots[i].speed = -10;
last_fire = SDL_GetTicks();
break;
}
}
}
void SpaceShip::Draw() {
Entity::Draw();
for(int i=0; i<MAX_SHOTS; i++) {
if(shots[i].alive) {
shots[i].pos.y += shots[i].speed;
if(shots[i].pos.y <= 0) shots[i].alive = false;
vis[SHOT_VIS]->Set(gdlib::VS_POSITION, shots[i].pos.x, shots[i].pos.y);
vis[SHOT_VIS]->Show();
}
}
}