Skip to content

Instantly share code, notes, and snippets.

@sillyboyization
Last active October 11, 2016 10:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sillyboyization/216b6898582c2d1ec6e0d22832be2d38 to your computer and use it in GitHub Desktop.
Save sillyboyization/216b6898582c2d1ec6e0d22832be2d38 to your computer and use it in GitHub Desktop.
#include <SFML/Graphics.hpp>
#include <SFML/System.hpp>
#include <vector>
#include <list>
#include <string>
#include <iostream>
#include <algorithm>
enum EntityType {
PLAYER = 0x0,
ENEMY = 0x10,
SKELETON = 0x01,
PARTICLE = 0x20,
PROJECTILE = 0x30,
BULLET = 0x01
};
enum EntityState {
IDLE = 0x001,
FRONT_WALK = 0x003,
RIGHT_WALK = 0x004,
LEFT_WALK = 0x006
};
typedef sf::Int64 int64;
typedef struct {
int type;
sf::Vector3f pos;
sf::Vector3f velocity;
sf::RectangleShape rect;
std::string name;
sf::Clock clock;
sf::Clock clock2;
int idx;
int total_health;
int health;
int state;
} Entity;
float lerp(float, float, float);
bool render_order_sort(Entity*, Entity*);
void do_damage_screen();
void shoot();
bool shoot_flag = false;
bool shot = false;
bool dmg_flag = false;
bool player_dying = false;
int game_state = 1;
int phase = 0;
int score = 0;
float near_view = 5;
float far_view = 100;
float screen_center_x = 0.f;
float screen_center_y = 0.f;
float crosshair_speed = 250.f;
int main()
{
sf::RenderWindow window(sf::VideoMode(800, 600), "SFML Window");
sf::View gview = window.getView();
screen_center_x = window.getSize().x / 2.f;
screen_center_y = window.getSize().y / 2.f;
std::list<Entity*> ents;
/*
-- Skeleton --
Front
97, 15, 13, 17
113, 15, 13, 17
129, 15, 13, 17
-- Glow Pew Pew --
95, 159, 14 14
/*/
sf::Image base_image;
if (!base_image.loadFromFile("rpg_sprite_sheet.png")) {
std::cout << "Texture Missing!: The main texture file is missing, redownload the application." << std::endl;
}
sf::Texture
skele_tex_1,
skele_tex_2,
skele_tex_3,
skele_tex_4,
skele_tex_5,
skele_tex_6,
skele_tex_7,
skele_tex_8,
skele_tex_9,
cross_hair,
pew_pew,
heart1, heart2,
floor_tex;
skele_tex_1.loadFromImage(base_image, sf::IntRect(97, 15, 13, 17));
skele_tex_2.loadFromImage(base_image, sf::IntRect(113, 15, 13, 17));
skele_tex_3.loadFromImage(base_image, sf::IntRect(129, 15, 13, 17));
skele_tex_4.loadFromImage(base_image, sf::IntRect(97, 79, 13, 17));
skele_tex_5.loadFromImage(base_image, sf::IntRect(113, 79, 13, 17));
skele_tex_6.loadFromImage(base_image, sf::IntRect(129, 79, 13, 17));
skele_tex_7.loadFromImage(base_image, sf::IntRect(97, 111, 13, 17));
skele_tex_8.loadFromImage(base_image, sf::IntRect(113, 111, 13, 17));
skele_tex_9.loadFromImage(base_image, sf::IntRect(129, 111, 13, 17));
cross_hair.loadFromImage(base_image, sf::IntRect(183, 134, 53, 53));
pew_pew.loadFromImage(base_image, sf::IntRect(95, 159, 14, 14));
heart1.loadFromImage(base_image, sf::IntRect(95, 145, 13, 11));
heart2.loadFromImage(base_image, sf::IntRect(109, 145, 13, 11));
floor_tex.loadFromImage(base_image, sf::IntRect(124, 146, 23, 18));
sf::Texture *texture_bank[9] = {
&skele_tex_1,
&skele_tex_2,
&skele_tex_3,
&skele_tex_4,
&skele_tex_5,
&skele_tex_6,
&skele_tex_7,
&skele_tex_8,
&skele_tex_9
};
int texture_indicies[0xFFF][3];
int skel = EntityType::ENEMY | EntityType::SKELETON;
texture_indicies[skel | EntityState::FRONT_WALK][0] = 0;
texture_indicies[skel | EntityState::FRONT_WALK][1] = 2;
texture_indicies[skel | EntityState::FRONT_WALK][2] = 350;
texture_indicies[skel | EntityState::RIGHT_WALK][0] = 3;
texture_indicies[skel | EntityState::RIGHT_WALK][1] = 5;
texture_indicies[skel | EntityState::RIGHT_WALK][2] = 350;
texture_indicies[skel | EntityState::LEFT_WALK][0] = 6;
texture_indicies[skel | EntityState::LEFT_WALK][1] = 8;
texture_indicies[skel | EntityState::LEFT_WALK][2] = 350;
texture_indicies[skel | EntityState::IDLE][0] = 0;
texture_indicies[skel | EntityState::IDLE][1] = 0;
texture_indicies[skel | EntityState::IDLE][2] = 200;
sf::RectangleShape player_rect(sf::Vector2f(50.f, 50.f));
sf::RectangleShape enim_rect(sf::Vector2f(30.f, 26.f));
sf::RectangleShape enim_rect2(sf::Vector2f(25.f, 50.f));
enim_rect.setTexture(&skele_tex_1);
enim_rect2.setFillColor(sf::Color::Blue);
sf::RectangleShape crosshair_rect(sf::Vector2f(53.f, 53.f));
crosshair_rect.setTexture(&cross_hair);
crosshair_rect.setFillColor(sf::Color::Red);
crosshair_rect.setOrigin(crosshair_rect.getSize() / 2.f);
crosshair_rect.setPosition(gview.getCenter());
sf::RectangleShape pew_pew_rect(sf::Vector2f(75.f, 75.f));
pew_pew_rect.setTexture(&pew_pew);
pew_pew_rect.setOrigin(pew_pew_rect.getSize() / 2.f);
sf::Color pew_pew_color(255, 255, 255, 200);
pew_pew_rect.setFillColor(sf::Color(0, 0, 0, 0));
sf::Clock pew_limit_clock;
sf::RectangleShape damage_screen(gview.getSize());
sf::Color damage_red(255, 0, 0, 100);
sf::Color trans_red(255, 0, 0, 0);
damage_screen.setFillColor(trans_red);
sf::Font font;
sf::Text game_over_text, retry_text;
font.loadFromFile("PressStart2P.ttf");
game_over_text.setFont(font);
game_over_text.setString("YOU DIED");
sf::FloatRect got_size = game_over_text.getLocalBounds();
game_over_text.setOrigin(got_size.width / 2.f, got_size.height / 2.f);
game_over_text.setPosition(gview.getCenter());
// game_over_text.setFillColor(sf::Color(255, 255/*, 255, 0));
//*/
retry_text.setFont(font);
retry_text.setString("Shoot this message to try again.");
retry_text.setFillColor(sf::Color(150, 0, 0, 255));
retry_text.setCharacterSize(20);
sf::FloatRect rt_size = retry_text.getGlobalBounds();
retry_text.setPosition(gview.getCenter().x - rt_size.width / 2.f, gview.getCenter().y - rt_size.height / 2.f);
sf::ConvexShape floor;
floor.setPointCount(4);
sf::RectangleShape hud_rect(sf::Vector2f(800, 150));
hud_rect.setFillColor(sf::Color::Black);
hud_rect.setPosition(0, 450);
sf::Text hp, lz, tscore;
sf::RectangleShape hp_bar(sf::Vector2f(700, 25)), lz_bar(sf::Vector2f(700, 25));
hp.setFont(font);
hp.setString("HP:");
hp.setPosition(hud_rect.getPosition() + sf::Vector2f(5.f, 5.f));
hp_bar.setPosition(hp.getPosition() + sf::Vector2f(hp.getGlobalBounds().width + 10, 0.f));
hp_bar.setFillColor(sf::Color::Red);
lz.setFont(font);
lz.setString("LZ:");
lz.setPosition(hp.getPosition() + sf::Vector2f(0.f, 30.f));
lz_bar.setPosition(hp_bar.getPosition().x, lz.getPosition().y);
lz_bar.setFillColor(sf::Color::Blue);
tscore.setFont(font);
tscore.setString("Score:" + std::to_string(score));
tscore.setPosition(hp.getPosition() + sf::Vector2f(0.f, 60.f));
floor.setPoint(0, sf::Vector2f(0.f, 311.f));
floor.setPoint(1, sf::Vector2f(800.f, 311.f));
floor.setPoint(2, sf::Vector2f(800.f, 600.f));
floor.setPoint(3, sf::Vector2f(0.f, 600.f));
/*floor.setPoint(0, sf::Vector2f(300.f, 310.f));
floor.setPoint(1, sf::Vector2f(500.f, 310.f));
floor.setPoint(2, sf::Vector2f(1200.f, 600.f));
floor.setPoint(3, sf::Vector2f(-400.f, 600.f));
*///floor.setFillColor(sf::Color::Green);
floor.setTexture(&floor_tex);
floor.setOutlineColor(sf::Color::Black);
floor.setOutlineThickness(2);
sf::Color gray(25, 25, 25);
sf::ConvexShape ceiling;
ceiling.setPointCount(4);
ceiling.setPoint(0, sf::Vector2f(0.f, 0.f));
ceiling.setPoint(1, sf::Vector2f(800.f, 0.f));
ceiling.setPoint(2, sf::Vector2f(800.f, 269.f));
ceiling.setPoint(3, sf::Vector2f(0.f, 269.f));
ceiling.setFillColor(gray);
ceiling.setOutlineColor(sf::Color::Black);
ceiling.setOutlineThickness(2);
sf::ConvexShape wall_left;
wall_left.setPointCount(4);
wall_left.setPoint(0, sf::Vector2f(-400.f, -10.f));
wall_left.setPoint(1, sf::Vector2f(300.f, 270.f));
wall_left.setPoint(2, sf::Vector2f(300.f, 310.f));
wall_left.setPoint(3, sf::Vector2f(-400.f, 600.f));
wall_left.setFillColor(gray);
//floor.setTexture(&floor_tex);
wall_left.setOutlineColor(sf::Color::Black);
wall_left.setOutlineThickness(2);
sf::ConvexShape wall_right;
wall_right.setPointCount(4);
wall_right.setPoint(0, sf::Vector2f(500.f, 270.f));
wall_right.setPoint(1, sf::Vector2f(1200.f,-10.f));
wall_right.setPoint(2, sf::Vector2f(1200.f, 600.f));
wall_right.setPoint(3, sf::Vector2f(500.f, 310.f));
wall_right.setFillColor(gray);
//floor.setTexture(&floor_tex);
wall_right.setOutlineColor(sf::Color::Black);
wall_right.setOutlineThickness(2);
//std::cout << got_size.width << "\n";
//enim_rect.setFillColor(sf::Color::Green);
Entity player{
EntityType::PLAYER,
sf::Vector3f(0.f, 0.f, 5.f),
sf::Vector3f(0.f, 0.f, 0.f),
player_rect,
"Player1",
sf::Clock(),
sf::Clock(),
0,
10,
10,
EntityState::FRONT_WALK
};
Entity * player_ref = &player;
float player_rot = 0.f;
sf::Vector2f winCenter = (sf::Vector2f)window.getSize() / 2.f;
float pcircle_rad = 250.f;
sf::CircleShape s(pcircle_rad);
window.setFramerateLimit(60);
s.setFillColor(sf::Color::Transparent);
s.setOutlineColor(sf::Color::White);
s.setOutlineThickness(1.0f);
sf::Clock deltaTimer, fpsTimer;
s.setPosition(
window.getSize().x / 2.f - pcircle_rad,
window.getSize().y / 2.f - pcircle_rad
);
while (window.isOpen())
{
sf::Time _ttime = deltaTimer.restart();
float delta = _ttime.asSeconds();
if (fpsTimer.getElapsedTime().asMilliseconds() > 1000) {
std::string fpsTitle = "FPS: " + std::to_string((int)(1 / delta));
fpsTimer.restart();
window.setTitle(fpsTitle);
}
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
}
window.clear();
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left)) {
crosshair_rect.move(-crosshair_speed * delta, 0.f);
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right)) {
crosshair_rect.move(crosshair_speed* delta, 0.f);
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up)) {
crosshair_rect.move(0.f, -crosshair_speed* delta);
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down)) {
crosshair_rect.move(0.f, crosshair_speed* delta);
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Space)) {
shoot();
}
crosshair_rect.rotate(50.f * delta);
pew_pew_rect.setPosition(crosshair_rect.getPosition());
std::vector<Entity*> to_remove;
if (game_state == 1) {
if (phase == 0) {
Entity enemy{
EntityType::ENEMY | EntityType::SKELETON,
sf::Vector3f(0.f, 0.f, 120.f),
sf::Vector3f(0.f, 0.f, 0.f),
enim_rect,
"Skelington",
sf::Clock(),
sf::Clock(),
0,
10,
3,
EntityState::FRONT_WALK
};
Entity enemy2{
EntityType::ENEMY | EntityType::SKELETON,
sf::Vector3f(20.f, 0.f, 200.f),
sf::Vector3f(0.f, 0.f, 0.f),
enim_rect,
"Enemy2",
sf::Clock(),
sf::Clock(),
0,
10,
10,
EntityState::FRONT_WALK
};
Entity enemy3{
EntityType::ENEMY | EntityType::SKELETON,
sf::Vector3f(-20.f, 0.f, 90.f),
sf::Vector3f(0.f, 0.f, 0.f),
enim_rect,
"Enemy3",
sf::Clock(),
sf::Clock(),
0,
10,
3,
EntityState::FRONT_WALK
};
ents.push_back(&player);
ents.push_back(&enemy);
ents.push_back(&enemy2);
ents.push_back(&enemy3);
phase = 1;
}
else if (phase == 1) {
float loc_near = .0f, loc_far = .0f;
window.draw(floor);
window.draw(ceiling);
window.draw(wall_left);
window.draw(wall_right);
for (Entity * e : ents) {
bool draw = true;
int ent_type = e->type >> 4;
int ent_sub_type = e->type & 0x0F;
int64 elapsed = e->clock.getElapsedTime().asMilliseconds();
//Player
if (ent_type == 0)
draw = false;
loc_near = player_ref->pos.z + near_view;
loc_far = player_ref->pos.z + far_view;
if (player_ref->health <= 0) {
player_dying = true;
game_state = 2;
}
//Enemy & Others
if (ent_type != 0) {
if (ent_type == 1) {
if (e->health > 0) {
if (e->state == EntityState::FRONT_WALK) {
if (e->pos.z > loc_near) {
e->pos.z -= 25.f * delta;
}
else {
// Melee
if (e->clock2.getElapsedTime().asMilliseconds() > 1500) {
e->clock2.restart();
std::cout << "HP: " << player_ref->health << "\n";
do_damage_screen();
player_ref->health -= 1;
}
}
if (e->idx == 2) e->idx = 0;
}
}
else {
if (e->pos.z < loc_far) {
sf::Color tmpCol = e->rect.getFillColor();
e->rect.setFillColor(tmpCol - sf::Color(0, 0, 0, 20));
e->pos.z += 1;
}
else { to_remove.push_back(e); }
}
}
if (e->health <= 0 && e->state != EntityState::IDLE) {
score += e->total_health;
e->state = EntityState::IDLE;
}
float scaleX = lerp(.5f, 10.f, loc_near / e->pos.z);
//std::cout << "Near: " << loc_near << "\n" << "Far: " << loc_far << "\n";
//std::cout << e->pos.z << "\n";
e->rect.setScale(scaleX, scaleX);
if (scaleX < 0.f) draw = false;
sf::Vector2f artificial_pos(
e->pos.x + screen_center_x - (e->rect.getSize().x * scaleX / 2) + e->pos.x * scaleX,
e->pos.y + screen_center_y - (e->rect.getSize().y * scaleX / 2) + e->pos.y * scaleX);
e->pos += e->velocity;
e->rect.setPosition(artificial_pos);
/*
if (e->pos.z < loc_near)
draw = false;*/
}
int tex_index = e->type | e->state;
if (draw) {
if (elapsed > texture_indicies[tex_index][2] && ent_sub_type != 0) {
if (texture_indicies[tex_index][1] > 0) {
//e->idx = (e->idx++ + texture_indicies[tex_index][0] % texture_indicies[tex_index][1]);
if (e->idx < texture_indicies[tex_index][0])
e->idx = texture_indicies[tex_index][0];
if (e->idx < texture_indicies[tex_index][1]) e->idx++;
else e->idx = texture_indicies[tex_index][0];
}
else
e->idx = texture_indicies[tex_index][0];
e->rect.setTexture(texture_bank[e->idx]);
e->clock.restart();
}
window.draw(e->rect);
}
}
//window.draw(s);
sf::Color col = damage_screen.getFillColor();
if (col.a > 0) {
window.draw(damage_screen);
col.a -= 5;
damage_screen.setFillColor(col);
}
if (dmg_flag) {
damage_screen.setFillColor(damage_red);
dmg_flag = false;
}
window.draw(hud_rect);
window.draw(hp);
hp_bar.setSize(
sf::Vector2f(lerp(0, 700, (float)player_ref->health / (float)player_ref->total_health),
hp_bar.getSize().y));
window.draw(hp_bar);
window.draw(lz);
window.draw(lz_bar);
tscore.setString("Score:" + std::to_string(score));
window.draw(tscore);
}
}
else if (game_state == 2) {
if (player_dying) {
if (phase == 0) {
sf::Color col = game_over_text.getFillColor();
if (col.a < 255) {
col.a += 5;
game_over_text.setFillColor(col);
}
else phase = 1;
}
if (phase == 1) {
if (game_over_text.getPosition().y > window.getView().getSize().y * 0.4f)
game_over_text.move(0.f, -1.f);
else
phase = 2;
}
if (phase == 2)
window.draw(retry_text);
window.draw(game_over_text);
}
}
sf::Color col2 = pew_pew_rect.getFillColor();
if (col2.a > 0) {
window.draw(pew_pew_rect);
col2 -= sf::Color(0, 0, 0, 10);
pew_pew_rect.setFillColor(col2);
}
if (shoot_flag && !shot) {
pew_pew_rect.setFillColor(pew_pew_color);
shoot_flag = false;
shot = true;
pew_limit_clock.restart();
score--;
for (Entity* pew_target : ents) {
if (pew_target->type != 0) {
sf::Vector2f hc = crosshair_rect.getPosition();
sf::FloatRect tg = pew_target->rect.getGlobalBounds();
if (hc.x > tg.left && hc.x < tg.left + tg.width &&
hc.y > tg.top && hc.y < tg.left + tg.height) {
//std::cout << pew_target->name << " was shot!\n";
pew_target->pos.z += 5;
pew_target->health -= 1;
break;
}
}
}
}
if (pew_limit_clock.getElapsedTime().asMilliseconds() > 200) {
shot = false;
pew_limit_clock.restart();
}
for (Entity *rem : to_remove)
ents.erase(std::remove(ents.begin(), ents.end(), rem), ents.end());
ents.sort(render_order_sort);
window.draw(crosshair_rect);
window.display();
}
return 0;
}
void do_damage_screen() {
dmg_flag = true;
}
void shoot() {
shoot_flag = true;
}
float lerp(float v1, float v2, float p) {
return v1 + (v2 - v1) * p;
}
bool render_order_sort(Entity * a, Entity * b) {
return a->pos.z > b->pos.z;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment