summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/config.h6
-rw-r--r--src/enemy.cpp62
-rw-r--r--src/enemy.h18
-rw-r--r--src/explosion.cpp51
-rw-r--r--src/explosion.h19
-rw-r--r--src/game.cpp254
-rw-r--r--src/game.h37
-rw-r--r--src/gameobject.cpp86
-rw-r--r--src/gameobject.h36
-rw-r--r--src/kamikaze.cpp47
-rw-r--r--src/kamikaze.h15
-rw-r--r--src/main.cpp33
-rw-r--r--src/movinggameobject.cpp18
-rw-r--r--src/movinggameobject.h19
-rw-r--r--src/player.cpp80
-rw-r--r--src/player.h20
-rw-r--r--src/shot.cpp28
-rw-r--r--src/shot.h16
18 files changed, 845 insertions, 0 deletions
diff --git a/src/config.h b/src/config.h
new file mode 100644
index 0000000..bf07d44
--- /dev/null
+++ b/src/config.h
@@ -0,0 +1,6 @@
+#pragma once
+
+#define WINDOW_HEIGHT 700
+#define WINDOW_WIDTH 500
+
+#define ASSET_PATH "assets/" \ No newline at end of file
diff --git a/src/enemy.cpp b/src/enemy.cpp
new file mode 100644
index 0000000..6f2fc91
--- /dev/null
+++ b/src/enemy.cpp
@@ -0,0 +1,62 @@
+#include "enemy.h"
+#include "config.h"
+#include "graphics.h"
+#include "shot.h"
+#include "game.h"
+#include <random>
+#include <ctime>
+using namespace std;
+
+Enemy::Enemy(float pos_x, float pos_y, float size_x, float size_y, float orientation, string texture, float speed) : MovingGameObject(pos_x, pos_y, size_x, size_y, orientation, texture, speed){
+
+ last_time_shot = graphics::getGlobalTime();
+
+ srand((unsigned int)time(NULL));
+ final_pos = rand() % 100;
+
+}
+
+Enemy::~Enemy(){
+
+}
+
+void Enemy::update(){
+
+ MovingGameObject::update();
+
+ float pos_y = this -> getPosY();
+ float pos_x = this -> getPosX();
+ float speed = this -> getSpeed();
+
+ if(pos_y < 50 + final_pos){
+ pos_y += speed * graphics::getDeltaTime();
+ this -> setPosY(pos_y);
+ }
+
+ if(graphics::getGlobalTime() > last_time_shot + 2000){
+
+ Game * game = reinterpret_cast<Game *>(graphics::getUserData());
+ game -> addObject(new Shot(pos_x , pos_y + 40, 80, 80, this -> getOrientation(), "enemy_shot", -0.5f));
+ last_time_shot = graphics::getGlobalTime();
+
+ }
+
+}
+
+void Enemy::draw(){
+
+ MovingGameObject::draw();
+
+ float pos_y = this -> getPosY();
+ float pos_x = this -> getPosX();
+
+ graphics::Brush br;
+ br.outline_opacity = 0.0f;
+ int exhaust_number = (int)(graphics::getGlobalTime()/100) % 4 + 1;
+ br.texture = string(ASSET_PATH) + this -> getTexture() + "_exhaust" + to_string(exhaust_number) + ".png";
+
+ graphics::setOrientation(this -> getOrientation());
+ graphics::drawRect(pos_x+2, pos_y-50, 30, 30, br);
+ graphics::resetPose();
+
+} \ No newline at end of file
diff --git a/src/enemy.h b/src/enemy.h
new file mode 100644
index 0000000..e889b93
--- /dev/null
+++ b/src/enemy.h
@@ -0,0 +1,18 @@
+#pragma once
+
+#include "movinggameobject.h"
+
+class Enemy : public MovingGameObject {
+
+ float last_time_shot;
+ float final_pos;
+
+public:
+
+ Enemy(float pos_x, float pos_y, float size_x, float size_y, float orientation, string texture, float speed);
+ virtual ~Enemy();
+
+ void update() override;
+ void draw() override;
+
+}; \ No newline at end of file
diff --git a/src/explosion.cpp b/src/explosion.cpp
new file mode 100644
index 0000000..f917c58
--- /dev/null
+++ b/src/explosion.cpp
@@ -0,0 +1,51 @@
+#include "explosion.h"
+#include "graphics.h"
+#include "gameobject.h"
+#include "config.h"
+#include <iostream>
+
+using namespace std;
+
+Explosion::Explosion(float pos_x, float pos_y, float size_x, float size_y) : GameObject(pos_x, pos_y, size_x, size_y, 0.0f, "explosion1_"){
+
+ time = graphics::getGlobalTime();
+ graphics::playSound(string(ASSET_PATH) + "explosion1_.mp3", 0.5f, false);
+
+}
+
+Explosion::~Explosion(){
+
+}
+
+void Explosion::update(){
+
+ if(graphics::getGlobalTime() - time > 550){
+
+ this -> setTerminate(true);
+
+ }
+}
+
+void Explosion::draw(){
+
+ for(int i=1;i<12;++i){
+
+ if(graphics::getGlobalTime() - time > i * 50){
+
+ graphics::Brush br;
+ br.outline_opacity = 0.0f;
+ br.texture = string(ASSET_PATH) + this -> getTexture() + to_string(i) + ".png";
+
+ graphics::drawRect(this -> getPosX(), this -> getPosY(), this -> getSizeX(), this -> getSizeY(), br);
+
+ }
+
+ }
+
+}
+
+bool Explosion::collidable(){
+
+ return false;
+
+} \ No newline at end of file
diff --git a/src/explosion.h b/src/explosion.h
new file mode 100644
index 0000000..972c0c8
--- /dev/null
+++ b/src/explosion.h
@@ -0,0 +1,19 @@
+#pragma once
+
+#include "gameobject.h"
+
+class Explosion : public GameObject {
+
+ float time;
+
+public:
+
+ Explosion(float pos_x, float pos_y, float size_x, float size_y);
+ virtual ~Explosion();
+
+ void update() override;
+ void draw() override;
+
+ bool collidable() override;
+
+}; \ No newline at end of file
diff --git a/src/game.cpp b/src/game.cpp
new file mode 100644
index 0000000..208aa01
--- /dev/null
+++ b/src/game.cpp
@@ -0,0 +1,254 @@
+#include "game.h"
+#include "graphics.h"
+#include "config.h"
+#include "player.h"
+#include "gameobject.h"
+#include "enemy.h"
+#include "kamikaze.h"
+#include "explosion.h"
+#include "shot.h"
+
+#include <cmath>
+#include <ctime>
+#include <random>
+
+using namespace std;
+
+Game::Game(){
+
+ graphics::setFont(string(ASSET_PATH) + "font.otf");
+ graphics::playMusic(string(ASSET_PATH) + "menu.mp3", 0.1f, true, 0);
+
+ last_enemy_spawn_time = 0;
+ last_kamikaze_spawn_time = 0;
+ game_state = 0;
+ object_counter = 0;
+ pressed_space = 0;
+
+}
+
+Game::~Game(){
+
+}
+
+void Game::update(){
+
+ switch(game_state){
+ case 0:
+ updateStartScreen();
+ break;
+ case 1:
+ updateGame();
+ break;
+ case 2:
+ updateGameOverScreen();
+ break;
+ }
+}
+
+void Game::draw(){
+
+ graphics::Brush br;
+ br.texture = std::string(ASSET_PATH) + "background.png";
+ br.outline_opacity = 0.0f;
+ float offset = fmod(graphics::getGlobalTime(), WINDOW_HEIGHT);
+
+ graphics::drawRect(WINDOW_WIDTH/2, WINDOW_HEIGHT/2 + offset, WINDOW_WIDTH, WINDOW_HEIGHT, br);
+ graphics::drawRect(WINDOW_WIDTH/2, -WINDOW_HEIGHT/2 + offset, WINDOW_WIDTH, WINDOW_HEIGHT, br);
+
+ switch(game_state){
+ case 0:
+ drawStartScreen();
+ break;
+ case 1:
+ drawGame();
+ break;
+ case 2:
+ drawGameOverScreen();
+ break;
+ }
+
+}
+
+void Game::addObject(GameObject * object){
+ game_objects[object_counter] = object;
+ object_counter++;
+}
+
+void Game::updateStartScreen(){
+
+ if (graphics::getKeyState(graphics::SCANCODE_SPACE) && graphics::getGlobalTime() > pressed_space + 200){
+
+ game_state = 1;
+ game_time_started = graphics::getGlobalTime();
+ player = new Player(WINDOW_WIDTH/2, WINDOW_HEIGHT*3/4, 100, 100, 90, "ship", 0.7f);
+
+ }
+
+}
+
+void Game::drawStartScreen(){
+
+ graphics::Brush br;
+ br.fill_color[0] = 1.f;
+ br.fill_color[1] = 1.f;
+ br.fill_color[2] = 0.f;
+
+ graphics::drawText(140, 100, 40, "Star Wars", br);
+
+ br.fill_opacity = 0.5f + 0.5f * sinf(graphics::getGlobalTime()/200);
+ graphics::drawText(130, WINDOW_HEIGHT-100, 20, "Press SPACE to start", br);
+
+ br.texture = string(ASSET_PATH) + "ship.png";
+ br.outline_opacity = 0.f;
+ br.fill_opacity = 1.0f;
+ br.fill_color[2] = 1.f;
+ graphics::drawRect(WINDOW_WIDTH/2, WINDOW_HEIGHT/2, 200, 200, br);
+
+}
+
+void Game::updateGame(){
+
+ score = ( graphics::getGlobalTime() - game_time_started )/100 ;
+
+ if(graphics::getGlobalTime() > last_enemy_spawn_time + max(3000 - score, 1000)){
+
+ srand((unsigned int)time(NULL));
+ addObject(new Enemy(rand() % 400 + 50, 0 , 70, 70, -90, "enemy", 0.3f));
+ last_enemy_spawn_time = graphics::getGlobalTime();
+
+ }
+
+ if(graphics::getGlobalTime() > last_kamikaze_spawn_time + max(5000 - score, 2000)){
+
+ srand((unsigned int)time(NULL));
+ int temp_a[2] = {1 ,-1};
+ int temp_n = temp_a[rand() % 2];
+ addObject(new Kamikaze(250 - temp_n * 400, player -> getPosY(), 100, 100, temp_n * 180, "kamikaze", temp_n * 0.3f));
+ last_kamikaze_spawn_time = graphics::getGlobalTime();
+
+ }
+
+ for(int i=0;i<object_counter;++i){
+
+ if(game_objects[i] -> collidable()){
+
+ if(checkCollision(player, game_objects[i])){
+
+ player -> setTerminate(true);
+ addObject(new Explosion(player -> getPosX(), player -> getPosY(), player -> getSizeX(), player -> getSizeY()));
+ game_objects[i] -> setTerminate(true);
+ addObject(new Explosion(game_objects[i] -> getPosX(), game_objects[i] -> getPosY(), game_objects[i] -> getSizeX(), game_objects[i] -> getSizeY()));
+
+ }
+ }
+ }
+
+ for(int i=0;i<object_counter;++i){
+
+ for(int j=i+1;j<object_counter;++j){
+
+ if(game_objects[i] -> collidable() && game_objects[j] -> collidable()){
+
+ if(checkCollision(game_objects[i], game_objects[j])){
+
+ game_objects[i] -> setTerminate(true);
+ addObject(new Explosion(game_objects[i] -> getPosX(), game_objects[i] -> getPosY(), game_objects[i] -> getSizeX(), game_objects[i] -> getSizeY()));
+ game_objects[j] -> setTerminate(true);
+ addObject(new Explosion(game_objects[j] -> getPosX(), game_objects[j] -> getPosY(), game_objects[j] -> getSizeX(), game_objects[j] -> getSizeY()));
+
+ }
+
+ }
+
+ }
+
+ }
+
+ for(int i=0;i<object_counter;++i){
+
+ if(game_objects[i] -> getTerminate()){
+
+ delete game_objects[i];
+ game_objects[i] = nullptr;
+ game_objects[i] = game_objects[--object_counter];
+
+ }
+
+ else game_objects[i] -> update();
+
+ }
+
+ if(player -> getTerminate()){
+
+ delete player;
+
+ for(int i=0;i<object_counter;++i) delete game_objects[i];
+
+ object_counter = 0;
+ game_state = 2;
+
+ srand((unsigned int)time(NULL));
+
+
+ graphics::playSound(string(ASSET_PATH) + to_string(rand()%2) + ".mp3", 1.0f, false);
+
+
+ }
+ else player -> update();
+
+}
+
+void Game::drawGame(){
+
+ graphics::Brush br;
+ br.fill_color[0] = 1.f;
+ br.fill_color[1] = 1.f;
+ br.fill_color[2] = 0.f;
+
+ graphics::drawText(WINDOW_WIDTH/2 - 60, WINDOW_HEIGHT - 50, 25, "Score: " + to_string(score), br);
+
+ for(int i=0;i<object_counter;++i) game_objects[i] -> draw();
+
+ player -> draw();
+
+}
+
+void Game::updateGameOverScreen(){
+ if (graphics::getKeyState(graphics::SCANCODE_SPACE)){
+ game_state = 0;
+ pressed_space = graphics::getGlobalTime();
+ }
+}
+
+void Game::drawGameOverScreen(){
+
+ graphics::Brush br;
+ br.fill_color[0] = 1.f;
+ br.fill_color[1] = 1.f;
+ br.fill_color[2] = 0.f;
+
+ graphics::drawText(110, 200, 50, "Game Over", br);
+ graphics::drawText(170, 400, 30, "Score: "+ to_string(score) , br);
+
+ br.fill_opacity = 0.5f + 0.5f * sinf(graphics::getGlobalTime()/200);
+ graphics::drawText(130, WINDOW_HEIGHT-100, 20, "Press SPACE to restart", br);
+
+
+}
+
+bool Game::checkCollision(GameObject * ob1, GameObject * ob2){
+
+ float pos_x1, pos_y1;
+ float pos_x2, pos_y2;
+
+ pos_x1 = ob1 -> getPosX();
+ pos_y1 = ob1 -> getPosY();
+ pos_x2 = ob2 -> getPosX();
+ pos_y2 = ob2 -> getPosY();
+
+ if(sqrt( pow(pos_x1 - pos_x2, 2) + pow(pos_y1 - pos_y2, 2) ) < (ob1 -> getRadius() + ob2 -> getRadius())/2) return true;
+
+ return false;
+
+} \ No newline at end of file
diff --git a/src/game.h b/src/game.h
new file mode 100644
index 0000000..691e6a7
--- /dev/null
+++ b/src/game.h
@@ -0,0 +1,37 @@
+#pragma once
+
+#include "gameobject.h"
+#include "player.h"
+
+using namespace std;
+
+class Game {
+
+ int game_state, object_counter, score;
+ float last_enemy_spawn_time, last_kamikaze_spawn_time;
+ float game_time_started, pressed_space;
+ GameObject * game_objects[1000];
+ Player * player;
+
+ void updateStartScreen();
+ void drawStartScreen();
+
+ void updateGame();
+ void drawGame();
+
+ void updateGameOverScreen();
+ void drawGameOverScreen();
+
+ bool checkCollision(GameObject * ob1, GameObject * ob2);
+
+public:
+
+ Game();
+ ~Game();
+
+ void update();
+ void draw();
+
+ void addObject(GameObject * object);
+
+}; \ No newline at end of file
diff --git a/src/gameobject.cpp b/src/gameobject.cpp
new file mode 100644
index 0000000..c217722
--- /dev/null
+++ b/src/gameobject.cpp
@@ -0,0 +1,86 @@
+#include "config.h"
+#include "graphics.h"
+#include "gameobject.h"
+
+#include <string>
+
+using namespace std;
+
+GameObject::GameObject(float pos_x, float pos_y, float size_x, float size_y, float orientation, string texture){
+ this -> pos_x = pos_x;
+ this -> pos_y = pos_y;
+ this -> size_x = size_x;
+ this -> size_y = size_y;
+ this -> orientation = orientation;
+ this -> texture = texture;
+ terminate = false;
+}
+
+GameObject::~GameObject(){
+
+}
+
+void GameObject::update(){
+
+ if((pos_x < 0 - WINDOW_WIDTH) || (pos_x > WINDOW_WIDTH*2) || (pos_y < 0 - WINDOW_HEIGHT) || (pos_y > WINDOW_HEIGHT*2)) terminate = true;
+
+}
+
+void GameObject::draw(){
+
+ graphics::Brush br;
+ br.outline_opacity = 0.0f;
+ br.texture = string(ASSET_PATH) + texture + ".png";
+
+ graphics::setOrientation(orientation);
+ graphics::drawRect(pos_x, pos_y, size_x, size_y, br);
+ graphics::resetPose();
+}
+
+float GameObject::getPosX(){
+ return pos_x;
+}
+
+float GameObject::getPosY(){
+ return pos_y;
+}
+
+float GameObject::getSizeX(){
+ return size_x;
+}
+
+float GameObject::getSizeY(){
+ return size_y;
+}
+
+float GameObject::getOrientation(){
+ return orientation;
+}
+
+float GameObject::getRadius(){
+ return (size_y + size_x)/4;
+}
+
+bool GameObject::getTerminate(){
+ return terminate;
+}
+
+string GameObject::getTexture(){
+ return texture;
+}
+
+void GameObject::setPosX(float pos_x){
+ this -> pos_x = pos_x;
+}
+
+void GameObject::setPosY(float pos_y){
+ this -> pos_y = pos_y;
+}
+
+void GameObject::setTerminate(bool terminate){
+ this -> terminate = terminate;
+}
+
+bool GameObject::collidable(){
+ return true;
+} \ No newline at end of file
diff --git a/src/gameobject.h b/src/gameobject.h
new file mode 100644
index 0000000..fe317df
--- /dev/null
+++ b/src/gameobject.h
@@ -0,0 +1,36 @@
+#pragma once
+
+#include <string>
+
+using namespace std;
+
+class GameObject {
+
+ float pos_x, pos_y, size_x, size_y, orientation;
+ bool terminate;
+ string texture;
+
+public:
+
+ GameObject(float pos_x, float pos_y, float size_x, float size_y, float orientation, string texture);
+ virtual ~GameObject();
+
+ virtual void update();
+ virtual void draw();
+
+ float getPosX();
+ float getPosY();
+ float getSizeX();
+ float getSizeY();
+ float getOrientation();
+ float getRadius();
+ bool getTerminate();
+ string getTexture();
+
+ void setPosX(float pos_x);
+ void setPosY(float pos_y);
+ void setTerminate(bool terminate);
+
+ virtual bool collidable();
+
+}; \ No newline at end of file
diff --git a/src/kamikaze.cpp b/src/kamikaze.cpp
new file mode 100644
index 0000000..ea07baf
--- /dev/null
+++ b/src/kamikaze.cpp
@@ -0,0 +1,47 @@
+#include "kamikaze.h"
+#include "config.h"
+#include "graphics.h"
+#include <random>
+#include <ctime>
+using namespace std;
+
+Kamikaze::Kamikaze(float pos_x, float pos_y, float size_x, float size_y, float orientation, string texture, float speed) : MovingGameObject(pos_x, pos_y, size_x, size_y, orientation, texture, speed){
+ srand((unsigned int)time(NULL));
+}
+
+Kamikaze::~Kamikaze(){
+
+}
+
+void Kamikaze::update(){
+
+ MovingGameObject::update();
+
+
+ float pos_x = this -> getPosX();
+ float speed = this -> getSpeed();
+
+ pos_x += speed * graphics::getDeltaTime();
+ this -> setPosX(pos_x);
+
+}
+
+void Kamikaze::draw(){
+
+ MovingGameObject::draw();
+
+ float pos_y = this -> getPosY();
+ float pos_x = this -> getPosX();
+ float orientation = this -> getOrientation();
+
+ graphics::Brush br;
+ br.outline_opacity = 0.0f;
+ int exhaust_number = (int)(graphics::getGlobalTime()/100) % 4 + 1;
+ br.texture = string(ASSET_PATH) + this -> getTexture() +"_exhaust" + to_string(exhaust_number) + ".png";
+
+ graphics::setOrientation(orientation);
+ if (orientation > 0 ) graphics::drawRect(pos_x-45, pos_y+1, 35, 35, br);
+ else graphics::drawRect(pos_x+45, pos_y+1, 35, 35, br);
+ graphics::resetPose();
+
+} \ No newline at end of file
diff --git a/src/kamikaze.h b/src/kamikaze.h
new file mode 100644
index 0000000..523d11d
--- /dev/null
+++ b/src/kamikaze.h
@@ -0,0 +1,15 @@
+#pragma once
+
+#include "movinggameobject.h"
+
+class Kamikaze : public MovingGameObject {
+
+public:
+
+ Kamikaze(float pos_x, float pos_y, float size_x, float size_y, float orientation, string texture, float speed);
+ virtual ~Kamikaze();
+
+ void update() override;
+ void draw() override;
+
+}; \ No newline at end of file
diff --git a/src/main.cpp b/src/main.cpp
new file mode 100644
index 0000000..41d1b05
--- /dev/null
+++ b/src/main.cpp
@@ -0,0 +1,33 @@
+#include "graphics.h"
+#include "game.h"
+#include "config.h"
+
+void update(float ms){
+
+ Game * game = reinterpret_cast<Game *>(graphics::getUserData());
+ game -> update();
+
+}
+
+void draw(){
+
+ Game * game = reinterpret_cast<Game *>(graphics::getUserData());
+ game -> draw();
+
+}
+
+int main()
+{
+ graphics::createWindow(WINDOW_WIDTH, WINDOW_HEIGHT, "Star Wars Episode 0: Return of the Developer");
+ graphics::setCanvasSize(WINDOW_WIDTH, WINDOW_HEIGHT);
+ graphics::setCanvasScaleMode(graphics::CANVAS_SCALE_FIT);
+ graphics::setDrawFunction(draw);
+ graphics::setUpdateFunction(update);
+
+ Game game;
+ graphics::setUserData(&game);
+
+ graphics::startMessageLoop();
+
+ return 0;
+}
diff --git a/src/movinggameobject.cpp b/src/movinggameobject.cpp
new file mode 100644
index 0000000..9e8e886
--- /dev/null
+++ b/src/movinggameobject.cpp
@@ -0,0 +1,18 @@
+#include "movinggameobject.h"
+#include "gameobject.h"
+
+#include <string>
+
+using namespace std;
+
+MovingGameObject::MovingGameObject(float pos_x, float pos_y, float size_x, float size_y, float orientation, string texture, float speed) : GameObject(pos_x, pos_y, size_x, size_y, orientation, texture){
+ this -> speed = speed;
+}
+
+MovingGameObject::~MovingGameObject(){
+
+}
+
+float MovingGameObject::getSpeed(){
+ return this -> speed;
+} \ No newline at end of file
diff --git a/src/movinggameobject.h b/src/movinggameobject.h
new file mode 100644
index 0000000..5c48297
--- /dev/null
+++ b/src/movinggameobject.h
@@ -0,0 +1,19 @@
+#pragma once
+
+#include "gameobject.h"
+#include <string>
+
+using namespace std;
+
+class MovingGameObject : public GameObject {
+
+ float speed;
+
+public:
+
+ MovingGameObject(float pos_x, float pos_y, float size_x, float size_y, float orientation, string texture, float speed);
+ virtual ~MovingGameObject();
+
+ float getSpeed();
+
+}; \ No newline at end of file
diff --git a/src/player.cpp b/src/player.cpp
new file mode 100644
index 0000000..1d79ccb
--- /dev/null
+++ b/src/player.cpp
@@ -0,0 +1,80 @@
+#include "config.h"
+#include "graphics.h"
+#include "player.h"
+#include "movinggameobject.h"
+#include "game.h"
+#include "shot.h"
+
+#include <string>
+
+using namespace std;
+
+Player::Player(float pos_x, float pos_y, float size_x, float size_y, float orientation, string texture, float speed) : MovingGameObject(pos_x, pos_y, size_x, size_y, orientation, texture, speed){
+
+ last_time_shot = graphics::getGlobalTime();
+
+}
+
+Player::~Player(){
+
+}
+
+void Player::update(){
+
+ MovingGameObject::update();
+
+ float pos_y = this -> getPosY();
+ float pos_x = this -> getPosX();
+ float speed = this -> getSpeed();
+
+ float temp_pos;
+
+ if (graphics::getKeyState(graphics::SCANCODE_W) || graphics::getKeyState(graphics::SCANCODE_UP)){
+ temp_pos = pos_y - speed * graphics::getDeltaTime();
+ if(temp_pos > WINDOW_HEIGHT/2 + 50) pos_y = temp_pos;
+ }
+ if (graphics::getKeyState(graphics::SCANCODE_S) || graphics::getKeyState(graphics::SCANCODE_DOWN)){
+ temp_pos = pos_y + speed * graphics::getDeltaTime();
+ if(temp_pos < WINDOW_HEIGHT - 50) pos_y = temp_pos;
+ }
+ if (graphics::getKeyState(graphics::SCANCODE_A) || graphics::getKeyState(graphics::SCANCODE_LEFT)){
+ temp_pos = pos_x - speed * graphics::getDeltaTime();
+ if(temp_pos > 50) pos_x = temp_pos;
+ }
+ if (graphics::getKeyState(graphics::SCANCODE_D) || graphics::getKeyState(graphics::SCANCODE_RIGHT)){
+ temp_pos = pos_x + speed * graphics::getDeltaTime();
+ if(temp_pos < WINDOW_WIDTH - 50) pos_x = temp_pos;
+ }
+
+ this -> setPosX(pos_x);
+ this -> setPosY(pos_y);
+
+ if(graphics::getGlobalTime() > last_time_shot + 500){
+
+ if (graphics::getKeyState(graphics::SCANCODE_SPACE)){
+
+ Game * game = reinterpret_cast<Game *>(graphics::getUserData());
+ game -> addObject(new Shot(pos_x + 3 , pos_y - 60, 100, 100, this -> getOrientation(), "shot", 1));
+ last_time_shot = graphics::getGlobalTime();
+ }
+ }
+}
+
+void Player::draw(){
+
+ MovingGameObject::draw();
+
+ float pos_y = this -> getPosY();
+ float pos_x = this -> getPosX();
+
+ graphics::Brush br;
+ br.outline_opacity = 0.0f;
+ int exhaust_number = (int)(graphics::getGlobalTime()/100) % 4 + 1;
+ br.texture = string(ASSET_PATH) + "exhaust" + to_string(exhaust_number) + ".png";
+
+ graphics::setOrientation(this -> getOrientation());
+ graphics::drawRect(pos_x-5, pos_y+50, 30, 30, br);
+ graphics::drawRect(pos_x+8, pos_y+50, 30, 30, br);
+ graphics::resetPose();
+
+} \ No newline at end of file
diff --git a/src/player.h b/src/player.h
new file mode 100644
index 0000000..15f2f15
--- /dev/null
+++ b/src/player.h
@@ -0,0 +1,20 @@
+#pragma once
+
+#include "movinggameobject.h"
+#include <string>
+
+using namespace std;
+
+class Player : public MovingGameObject {
+
+ float last_time_shot;
+
+public:
+
+ Player(float pos_x, float pos_y, float size_x, float size_y, float orientation, string texture, float speed);
+ virtual ~Player();
+
+ void update() override;
+ void draw() override;
+
+}; \ No newline at end of file
diff --git a/src/shot.cpp b/src/shot.cpp
new file mode 100644
index 0000000..bbe7d42
--- /dev/null
+++ b/src/shot.cpp
@@ -0,0 +1,28 @@
+#include "shot.h"
+#include "graphics.h"
+#include "config.h"
+
+using namespace std;
+
+Shot::Shot(float pos_x, float pos_y, float size_x, float size_y, float orientation, string texture, float speed) : MovingGameObject(pos_x, pos_y, size_x, size_y, orientation, texture, speed){
+
+ graphics::playSound(string(ASSET_PATH) + this -> getTexture() + ".mp3", 0.5f, false);
+
+}
+
+Shot::~Shot(){
+
+}
+
+void Shot::update(){
+
+ MovingGameObject::update();
+
+ float pos_y = this -> getPosY();
+ float speed = this -> getSpeed();
+
+ pos_y -= speed * graphics::getDeltaTime();
+
+ this -> setPosY(pos_y);
+
+} \ No newline at end of file
diff --git a/src/shot.h b/src/shot.h
new file mode 100644
index 0000000..55c156d
--- /dev/null
+++ b/src/shot.h
@@ -0,0 +1,16 @@
+#pragma once
+
+#include "movinggameobject.h"
+
+using namespace std;
+
+class Shot : public MovingGameObject {
+
+public:
+
+ Shot(float pos_x, float pos_y, float size_x, float size_y, float orientation, string texture, float speed);
+ virtual ~Shot();
+
+ void update();
+
+}; \ No newline at end of file