Skip to content

Instantly share code, notes, and snippets.

@Mischa-Alff
Last active August 29, 2015 14:05
Show Gist options
  • Save Mischa-Alff/e817bfff0a407392026b to your computer and use it in GitHub Desktop.
Save Mischa-Alff/e817bfff0a407392026b to your computer and use it in GitHub Desktop.
#include <ctime>
#include <iostream>
#include <SFML/Graphics.hpp>
#include <noise/noise.h>
class Game;
class Level
{
friend class Game;
private:
std::vector<int> m_base;
std::vector<int> m_mezzanine;
int m_seed;
float m_gap;
float m_thickness;
sf::RectangleShape m_tile;
public:
void create(int seed);
void draw(sf::RenderTarget& target);
float getHeight(float x, bool mezzanine=false);
Level();
};
class Game
{
private:
sf::View m_view;
bool m_is_running=true;
sf::RenderTarget* m_target;
std::vector<Level> m_levels;
int m_seed;
std::map<sf::Keyboard::Key, bool> keyboard;
struct {
sf::ConvexShape shape;
int8_t climb_direction;
} m_player;
int m_current_level;
public:
void setTarget(sf::RenderTarget &target);
bool processEvent(sf::Event &event);
bool running();
void terminate();
void draw();
void update(float frametime);
Game();
};
int main()
{
Game LD48;
sf::RenderWindow window{{320, 320}, "LD48", sf::Style::Close, sf::ContextSettings{0,0,0,2,0}};
window.setVerticalSyncEnabled(true);
LD48.setTarget(window);
sf::Clock timer;
while(window.isOpen())
{
float frametime = timer.restart().asMicroseconds()/1e6;
sf::Event event;
while(window.pollEvent(event))
{
if(!LD48.processEvent(event))
{
switch(event.type)
{
case sf::Event::KeyReleased:
switch(event.key.code)
{
case sf::Keyboard::Escape:
LD48.terminate();
window.close();
break;
default: break;
}
}
}
}
window.setTitle(std::string{"LD48 - FPS: "} + std::to_string((int)(1/frametime)));
if(!LD48.running())
window.close();
LD48.update(frametime);
window.clear({240,240,240});
LD48.draw();
window.display();
}
return 0;
}
void Level::create(int seed)
{
m_seed=seed;
noise::module::Perlin perlin;
perlin.SetSeed(seed);
perlin.SetFrequency(0.5);
m_base.clear();
m_mezzanine.clear();
for(int x=0;x<20;++x)
{
m_base.push_back((perlin.GetValue(x/12.34, .0, .0)*128)+128);
double old_freq = perlin.GetFrequency();
perlin.SetFrequency(5.0);
m_mezzanine.push_back((perlin.GetValue(x/12.34, .0, .0)*128)+128);
perlin.SetFrequency(old_freq);
}
}
void Level::draw(sf::RenderTarget& target)
{
m_tile.setFillColor({190, 190, 190});
m_tile.setPosition(0.f-(m_mezzanine.size()/2*m_thickness), 0.f);
for(auto h : m_mezzanine)
{
m_tile.setSize({m_thickness-m_gap, static_cast<float>(h)});
target.draw(m_tile);
m_tile.move(m_thickness, 0.f);
}
m_tile.setFillColor(sf::Color::Black);
m_tile.setPosition(0.f-(m_base.size()/2*m_thickness), 0.f);
for(auto h : m_base)
{
m_tile.setSize({m_thickness-m_gap, static_cast<float>(h)});
target.draw(m_tile);
m_tile.move(m_thickness, 0.f);
}
}
float Level::getHeight(float x, bool mezzanine)
{
if(mezzanine)
return m_mezzanine[x/m_thickness+m_mezzanine.size()/2];
return m_base[x/m_thickness+m_base.size()/2];
}
Level::Level() : m_gap(0.f), m_thickness(24.f)
{
m_tile.setOutlineColor(sf::Color::White);
m_tile.setOutlineThickness(m_gap/2.f);
}
void Game::setTarget(sf::RenderTarget &target)
{
m_target = &target;
m_view.reset({0.f,0.f,static_cast<float>(m_target->getSize().x),static_cast<float>(m_target->getSize().y)});
m_view.setRotation(180.f);
m_view.setCenter(static_cast<sf::Vector2f>(m_target->getSize())/2.f);
}
bool Game::running(){return m_is_running;}
void Game::terminate(){m_is_running=false;return;}
bool Game::processEvent(sf::Event &event)
{
switch(event.type)
{
case sf::Event::Closed:
m_is_running=false;
return true;
case sf::Event::KeyReleased:
keyboard[event.key.code]=false;
switch(event.key.code)
{
case sf::Keyboard::R:
m_seed = std::time(NULL);
m_levels.back().create(m_seed);
m_player.shape.setPosition({0.f, m_levels.back().getHeight(0.f)});
return true;
default: return false;
}
return false;
case sf::Event::KeyPressed:
keyboard[event.key.code]=true;
return false;
default: return false;
}
}
void Game::draw()
{
m_view.setSize(static_cast<sf::Vector2f>(m_target->getSize()));
m_view.setCenter(m_player.shape.getPosition().x, std::max(m_target->getSize().y/2.f, m_player.shape.getPosition().y));
m_target->setView(m_view);
m_levels.back().draw(*m_target);
m_target->draw(m_player.shape);
}
void Game::update(float frametime)
{
sf::Vector2f movement{0.f, 0.f};
if(keyboard[sf::Keyboard::A] || keyboard[sf::Keyboard::Left])
movement.x += 100.f*frametime;
if(keyboard[sf::Keyboard::D] || keyboard[sf::Keyboard::Right])
movement.x -= 100.f*frametime;
if(m_player.shape.getPosition().y+std::abs(movement.x) < m_levels.back().getHeight(m_player.shape.getPosition().x))
{
movement.y = std::abs(movement.x);
movement.x = 0;
}
else
{
if(m_player.shape.getPosition().y <= m_levels.back().getHeight(m_player.shape.getPosition().x))
m_player.shape.setPosition(m_player.shape.getPosition().x, m_levels.back().getHeight(m_player.shape.getPosition().x));
else
m_player.shape.setPosition(m_player.shape.getPosition().x, m_player.shape.getPosition().y-100.f*frametime);
}
m_player.shape.move(movement);
}
Game::Game()
{
m_view.reset({0.f,0.f,320.f,320.f});
m_view.setRotation(180.f);
m_levels.emplace_back();
m_levels.back().create(std::time(NULL));
m_player.shape.setPointCount(3);
m_player.shape.setPoint(0, {-5, 7});
m_player.shape.setPoint(1, { 5, 7});
m_player.shape.setPoint(2, { 0, -7});
m_player.shape.setOrigin({0, -7});
m_player.shape.setFillColor(sf::Color::Black);
m_player.shape.setOutlineThickness(0.5);
m_player.shape.setOutlineColor({130,130,130});
m_player.shape.setPosition({0.f, m_levels.back().getHeight(0.f)});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment