Browse Source

add stub for Level

master
noerw 1 year ago
parent
commit
4cb31fbe86
8 changed files with 309 additions and 147 deletions
  1. 39
    0
      IDEAS.md
  2. 1
    1
      Makefile
  3. 12
    0
      game.cpp
  4. 2
    0
      game.hpp
  5. 50
    0
      level.cpp
  6. 39
    0
      level.hpp
  7. 16
    0
      random.hpp
  8. 150
    146
      vec2util.hpp

+ 39
- 0
IDEAS.md View File

@@ -0,0 +1,39 @@
- gameobject:
- has associated groundspace
- can spawn new game objects with timers
- player, enemies, powerups, bullets(?)

- groundspace
- limits players area to move, over bounds -> game over
- everything else may leave groundspace
- circular, fades out after time
- size & timeout depends on associated enemy HP
- overrideable
- some helper spaces stay indefinitely
- idea: multiple floors: player falls down -> parallax layers rotate

- enemies
- spawn new enemies after time in patterns (dependend on HP?)
- spawn in semirandomized direction (not backwards), buffered by current groundspace
- types:
- stationshooter (different patterns -> colorcoding)
- (shooting)follower: always facing player (different speeds?)
- fastmover:
- grower: fast to kill but grows until dead

- player actions
- primary & secondary gun (fast/slow bullets?, raygun?)
- speed boost: cost: attracts other gameobjects
- make room: grow distance & size of gameobjects
- slow bullet that creates groundspace around it

- level
- based on patterns spawned by enemies
- maybe: not random patterns but predefined selection per level
- increasing difficulty:
- incresing angle of random nextspawn vectors
- reduced groundspace per spawn
- faster groundspace timeout
- faster spawn rate

- powerups?

+ 1
- 1
Makefile View File

@@ -8,7 +8,7 @@ LDFLAGS = -L "SFML21/lib" -lsfml-system -lsfml-window -lsfml-graphics
# for Windows using MinGW
#LDFLAGS = -L "SFML21/lib" -lmingw32 -lsfml-main -lsfml-system -lsfml-window -lsfml-graphics

OBJ = game.o player.o background.o mainmenu.o main.o
OBJ = level.o game.o player.o background.o mainmenu.o main.o

game: $(OBJ)
$(CC) $(CFLAGS) -o game.bin $(OBJ) $(LDFLAGS)

+ 12
- 0
game.cpp View File

@@ -48,6 +48,7 @@ namespace Proto4 {

void Game::draw(sf::RenderTarget &window, sf::RenderStates states) const {
window.setView(mainView);
window.draw(level);
window.draw(player);
}

@@ -59,6 +60,17 @@ namespace Proto4 {

bool Game::start() {
player.setPosition(mainView.getCenter());
level = Level(mainView.getCenter());
level.spawn(200);
level.spawn(200);
level.spawn(200);
level.spawn(700);
level.spawn(100);
level.spawn(100);
level.spawn(100);
level.spawn(100);
level.spawn(100);
level.spawn(100);
state = GameState::Running;
return true;
}

+ 2
- 0
game.hpp View File

@@ -4,6 +4,7 @@
#include <SFML/Window.hpp>

#include "player.hpp"
#include "level.hpp"

#pragma once

@@ -29,6 +30,7 @@ namespace Proto4 {
sf::View mainView{};
GameState state = GameState::Uninitialized;
Player player{};
Level level{};
uint32_t score = 0;
};
}

+ 50
- 0
level.cpp View File

@@ -0,0 +1,50 @@
#include "level.hpp"
#include "vec2util.hpp"
#include "random.hpp"

namespace Proto4 {

Ground::Ground() {}

Ground::Ground(sf::Vector2f pos, float size, sf::Time timeout) {
shape = sf::CircleShape{size, 50};
shape.setFillColor(sf::Color(90, 100, 120));
shape.setOrigin(size, size);
shape.setPosition(pos);
}

void Ground::update(float timestep) {}

void Ground::draw(sf::RenderTarget &window, sf::RenderStates states) const {
window.draw(shape);
}

/////////////////////////////////////////

Level::Level() {}
Level::Level(sf::Vector2f pos = sf::Vector2f(0, 0)) {
lastSpawn.position = pos;
Proto4::rotate(lastSpawn.direction, sf::Vector2f(1, 1), randomFloat() * 360.f);

// initialize with first ground
spawn(400);
}

void Level::update(float timestep) {}

void Level::draw(sf::RenderTarget &window, sf::RenderStates states) const {
for (auto &ground : groundArea) {
window.draw(ground);
}
}

void Level::spawn(float size) {
float firstOffset = lastSpawn.size == 0 ? 0.f : 1.f;

lastSpawn.direction = normalized(Proto4::rotate(lastSpawn.direction, randomFloat() * 160 - 80));
lastSpawn.position += lastSpawn.direction * (lastSpawn.size + firstOffset * 0.7f * size);
lastSpawn.size = size;

groundArea.push_back(Ground(lastSpawn.position, size, sf::seconds(10000)));
}
}

+ 39
- 0
level.hpp View File

@@ -0,0 +1,39 @@
#pragma once

#include <SFML/Graphics.hpp>

namespace Proto4 {


class Ground : public sf::Drawable, public sf::Transformable {
sf::CircleShape shape{};

public:
Ground();
Ground(sf::Vector2f pos, float size, sf::Time timeout);
// Ground(Killable parentEntity);

virtual void draw(sf::RenderTarget &window, sf::RenderStates states) const;
void update(float timestep);
};


struct SpawnState {
sf::Vector2f position;
float size = 0;
sf::Vector2f direction;
};

class Level : public sf::Drawable, public sf::Transformable {
std::vector<Ground> groundArea;
SpawnState lastSpawn{};

public:
Level();
Level(sf::Vector2f pos);

virtual void draw(sf::RenderTarget &window, sf::RenderStates states) const;
void update(float timestep);
void spawn(float size);
};
}

+ 16
- 0
random.hpp View File

@@ -0,0 +1,16 @@
#pragma once

#include <random>

namespace Proto4 {
namespace Random {
std::random_device r;
std::seed_seq seed{r(), r(), r(), r(), r(), r(), r(), r()};
std::mt19937 eng{seed};
std::uniform_real_distribution<> dist(0, 1);
}

inline float randomFloat() {
return Random::dist(Random::eng);
}
}

+ 150
- 146
vec2util.hpp View File

@@ -12,166 +12,170 @@

typedef sf::Vector2f Vec2;

/**
* @brief dot
* @param a vector
* @param b vector
* @return a . b
*/
static inline float dot (const Vec2& a, const Vec2& b)
{
return a.x*b.x + a.y*b.y;
}
namespace Proto4 {

/**
* @brief dot
* @param a vector
* @param b vector
* @return a . b
*/
static inline float dot (const Vec2& a, const Vec2& b)
{
return a.x*b.x + a.y*b.y;
}

/**
* @brief magnitudeSq
* @param v vector
* @return |v|^2
*/
static inline float magnitudeSq (const Vec2& v)
{
return v.x*v.x + v.y*v.y;
}
/**
* @brief magnitudeSq
* @param v vector
* @return |v|^2
*/
static inline float magnitudeSq (const Vec2& v)
{
return v.x*v.x + v.y*v.y;
}

/**
* @brief magnitude
* @param v vector
* @return |v|
*/
static inline float magnitude (const Vec2& v)
{
return sqrt (v.x*v.x + v.y*v.y);
}
/**
* @brief magnitude
* @param v vector
* @return |v|
*/
static inline float magnitude (const Vec2& v)
{
return sqrt (v.x*v.x + v.y*v.y);
}


/**
* @brief normalize
* @param v vector
* v' = v / |v|
*/
static inline void normalize (Vec2& v)
{
float len = sqrt (v.x*v.x + v.y*v.y);
if (len != 0) {
v.x = v.x / len;
v.y = v.y / len;
/**
* @brief normalize
* @param v vector
* v' = v / |v|
*/
static inline void normalize (Vec2& v)
{
float len = sqrt (v.x*v.x + v.y*v.y);
if (len != 0) {
v.x = v.x / len;
v.y = v.y / len;
}
}
}

/**
* @brief normalized (faster)
* @param res vector
* @param v vector
* res = v / |v|
*/
static inline void normalized (Vec2& res, const Vec2& v)
{
float len = sqrt (v.x*v.x + v.y*v.y);
if (len != 0) {
res.x = v.x / len;
res.y = v.y / len;
/**
* @brief normalized (faster)
* @param res vector
* @param v vector
* res = v / |v|
*/
static inline void normalized (Vec2& res, const Vec2& v)
{
float len = sqrt (v.x*v.x + v.y*v.y);
if (len != 0) {
res.x = v.x / len;
res.y = v.y / len;
}
}
}

/**
* @brief normalized
* @param v vector
* @return res = v / |v|
*/
static inline Vec2 normalized (const Vec2& v)
{
Vec2 res;
normalized(res, v);
return res;
}
/**
* @brief normalized
* @param v vector
* @return res = v / |v|
*/
static inline Vec2 normalized (const Vec2& v)
{
Vec2 res;
normalized(res, v);
return res;
}

/**
* @brief truncate (faster)
* @param res vector
* @param v vector
* @param max magnitude
* res = max * v / |v|
*/
static inline void truncate (Vec2& res, const Vec2& v, float max)
{
float len = sqrt (v.x*v.x + v.y*v.y);
if (len > max)
/**
* @brief truncate (faster)
* @param res vector
* @param v vector
* @param max magnitude
* res = max * v / |v|
*/
static inline void truncate (Vec2& res, const Vec2& v, float max)
{
res = normalized(v);
res *= max;
} else {
res = v;
float len = sqrt (v.x*v.x + v.y*v.y);
if (len > max)
{
res = normalized(v);
res *= max;
} else {
res = v;
}
}
}

/**
* @brief truncate
* @param v vector
* @param max magnitude
* @return res = max * v / |v|
*/
static inline Vec2 truncate (const Vec2& v, float max)
{
Vec2 res;
truncate(res, v, max);
return res;
}
/**
* @brief truncate
* @param v vector
* @param max magnitude
* @return res = max * v / |v|
*/
static inline Vec2 truncate (const Vec2& v, float max)
{
Vec2 res;
truncate(res, v, max);
return res;
}

/**
* @brief lerp (faster)
* @param res vector
* @param a vector
* @param b vector
* @param t alpha value
* res = (1-t)*a + t*b
*/
static inline void lerp (Vec2& res, const Vec2& a, const Vec2& b, float t)
{
res.x = (1-t)*a.x + t*b.x;
res.y = (1-t)*a.y + t*b.y;
}
/**
* @brief lerp (faster)
* @param res vector
* @param a vector
* @param b vector
* @param t alpha value
* res = (1-t)*a + t*b
*/
static inline void lerp (Vec2& res, const Vec2& a, const Vec2& b, float t)
{
res.x = (1-t)*a.x + t*b.x;
res.y = (1-t)*a.y + t*b.y;
}

/**
* @brief lerp
* @param a vector
* @param b vector
* @param t alpha value
* @return res = (1-t)*a + t*b
*/
static inline Vec2 lerp (const Vec2& a, const Vec2& b, float t)
{
Vec2 res;
lerp(res, a, b, t);
return res;
}
/**
* @brief lerp
* @param a vector
* @param b vector
* @param t alpha value
* @return res = (1-t)*a + t*b
*/
static inline Vec2 lerp (const Vec2& a, const Vec2& b, float t)
{
Vec2 res;
lerp(res, a, b, t);
return res;
}

/**
* @brief rotate
* @param res vector
* @param v vector
* @param angle
* R = |cos -sin|
* |sin cos|
* res = v * R
*/
static inline void rotate (Vec2& res, const Vec2& v, float angle)
{
const float rad = DEG2RAD * angle;
const float sin0 = sin(rad);
const float cos0 = cos(rad);
res.x = v.x * cos0 + v.y * -sin0;
res.y = v.x * sin0 + v.y * cos0;
}
/**
* @brief rotate
* @param res vector
* @param v vector
* @param angle
* R = |cos -sin|
* |sin cos|
* res = v * R
*/
static inline void rotate (Vec2& res, const Vec2& v, float angle)
{
const float rad = DEG2RAD * angle;
const float sin0 = sin(rad);
const float cos0 = cos(rad);
res.x = v.x * cos0 + v.y * -sin0;
res.y = v.x * sin0 + v.y * cos0;
}

/**
* @brief rotate
* @param v vector
* @param angle
* @return res = v * R
*/
static inline Vec2 rotate (Vec2& v, float angle)
{
Vec2 res;
rotate(res, v, angle);
return res;
}

/**
* @brief rotate
* @param v vector
* @param angle
* @return res = v * R
*/
static inline Vec2 rotate (Vec2& v, float angle)
{
Vec2 res;
rotate(res, v, angle);
return res;
}

Loading…
Cancel
Save