mirror of
https://github.com/Motschen/Adventura.git
synced 2025-12-13 10:25:09 +01:00
Support multiple and custom levels
This commit is contained in:
@@ -1,16 +1,21 @@
|
||||
#pragma once
|
||||
#include "identifier.hpp"
|
||||
#include "color.hpp"
|
||||
#include "blockSettings.hpp"
|
||||
|
||||
class Block {
|
||||
private:
|
||||
Identifier id = Identifier("adventure", "missing");
|
||||
char encoding;
|
||||
Color color;
|
||||
BlockSettings settings;
|
||||
|
||||
public:
|
||||
Block(Identifier id, char encoding, BlockSettings settings) {
|
||||
Block(Identifier id, char encoding, BlockSettings settings) : Block(id, encoding, Color::RESET, settings) {};
|
||||
Block(Identifier id, char encoding, Color color, BlockSettings settings) {
|
||||
this->id = id;
|
||||
this->encoding = encoding;
|
||||
this->color = color;
|
||||
this->settings = settings;
|
||||
};
|
||||
|
||||
@@ -21,6 +26,9 @@ public:
|
||||
Identifier getId() {
|
||||
return id;
|
||||
}
|
||||
Color getColor() {
|
||||
return color;
|
||||
}
|
||||
char getEncoding() {
|
||||
return encoding;
|
||||
}
|
||||
|
||||
@@ -9,17 +9,23 @@ using std::string;
|
||||
class BlockRegistry {
|
||||
public:
|
||||
Block AIR = Block(Identifier("adventura", "air"), ' ', BlockSettingsBuilder().nonSolid().build());
|
||||
Block WATER = Block(Identifier("adventura", "water"), '~', Color::BRIGHT_BLUE, BlockSettingsBuilder().nonSolid().build());
|
||||
Block PLATFORM = Block(Identifier("adventura", "platform"), '-', BlockSettingsBuilder().build());
|
||||
Block LADDER = Block(Identifier("adventura", "ladder"), 'H', BlockSettingsBuilder().climbableFromBottom().climbableFromTop().build());
|
||||
Block START = Block(Identifier("adventura", "start"), 'S', BlockSettingsBuilder().build());
|
||||
Block GOAL = Block(Identifier("adventura", "goal"), 'O', BlockSettingsBuilder().build());
|
||||
Block LADDER = Block(Identifier("adventura", "ladder"), 'H', Color::BRIGHT_MAGENTA, BlockSettingsBuilder().climbableFromBottom().climbableFromTop().build());
|
||||
Block START = Block(Identifier("adventura", "start"), 'S', BlockSettingsBuilder().nonSolid().build());
|
||||
Block GOAL = Block(Identifier("adventura", "goal"), 'O', Color::BRIGHT_GREEN, BlockSettingsBuilder().nonSolid().build());
|
||||
Block WALL = Block(Identifier("adventura", "wall"), '0', Color::BRIGHT_BLACK, BlockSettingsBuilder().collidable().build());
|
||||
Block SPIKE = Block(Identifier("adventura", "spike"), '^', Color::BRIGHT_RED, BlockSettingsBuilder().lethal().build());
|
||||
|
||||
BlockRegistry() {
|
||||
registerBlock(AIR);
|
||||
registerBlock(WATER);
|
||||
registerBlock(PLATFORM);
|
||||
registerBlock(LADDER);
|
||||
registerBlock(START);
|
||||
registerBlock(GOAL);
|
||||
registerBlock(GOAL);
|
||||
registerBlock(WALL);
|
||||
registerBlock(SPIKE);
|
||||
}
|
||||
|
||||
const Block getByEncoding(char encoding) {
|
||||
|
||||
@@ -4,9 +4,15 @@ class BlockSettings {
|
||||
bool isSolid() {
|
||||
return isSolid_;
|
||||
}
|
||||
bool hasCollision() {
|
||||
return hasCollision_;
|
||||
}
|
||||
bool isMovable() {
|
||||
return isMovable_;
|
||||
}
|
||||
bool isLethal() {
|
||||
return isLethal_;
|
||||
}
|
||||
bool isClimbableFromTop() {
|
||||
return isClimbableFromTop_;
|
||||
}
|
||||
@@ -20,6 +26,12 @@ class BlockSettings {
|
||||
void setMovable(bool isMovable) {
|
||||
this->isMovable_ = isMovable;
|
||||
}
|
||||
void setCollision(bool hasCollision) {
|
||||
this->hasCollision_ = hasCollision;
|
||||
}
|
||||
void setLethal(bool isLethal) {
|
||||
this->isLethal_ = isLethal;
|
||||
}
|
||||
void setClimbableFromTop(bool isClimbableFromTop) {
|
||||
this->isClimbableFromTop_ = isClimbableFromTop;
|
||||
}
|
||||
@@ -32,6 +44,8 @@ class BlockSettings {
|
||||
bool isMovable_ = false;
|
||||
bool isClimbableFromTop_ = false;
|
||||
bool isClimbableFromBottom_ = false;
|
||||
bool isLethal_ = false;
|
||||
bool hasCollision_ = false;
|
||||
};
|
||||
class BlockSettingsBuilder {
|
||||
public:
|
||||
@@ -43,6 +57,14 @@ class BlockSettingsBuilder {
|
||||
blockSettings.setMovable(true);
|
||||
return *this;
|
||||
}
|
||||
BlockSettingsBuilder collidable() {
|
||||
blockSettings.setCollision(true);
|
||||
return *this;
|
||||
}
|
||||
BlockSettingsBuilder lethal() {
|
||||
blockSettings.setLethal(true);
|
||||
return *this;
|
||||
}
|
||||
BlockSettingsBuilder climbableFromTop() {
|
||||
blockSettings.setClimbableFromTop(true);
|
||||
return *this;
|
||||
|
||||
16
src/color.hpp
Normal file
16
src/color.hpp
Normal file
@@ -0,0 +1,16 @@
|
||||
#include <iostream>
|
||||
|
||||
enum class Color {
|
||||
RESET = 0,
|
||||
BRIGHT_BLACK= 90,
|
||||
BRIGHT_RED= 91,
|
||||
BRIGHT_GREEN= 92,
|
||||
BRIGHT_YELLOW= 93,
|
||||
BRIGHT_BLUE= 94,
|
||||
BRIGHT_MAGENTA= 95,
|
||||
BRIGHT_CYAN= 96,
|
||||
BRIGHT_WHITE= 97
|
||||
};
|
||||
std::ostream& operator<<(std::ostream& os, Color color) {
|
||||
return os << "\033[" << static_cast<int>(color) << "m";
|
||||
}
|
||||
18
src/main.cpp
18
src/main.cpp
@@ -1,5 +1,6 @@
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <filesystem>
|
||||
#include "world.hpp"
|
||||
#include "player.hpp"
|
||||
#include "blockRegistry.hpp"
|
||||
@@ -8,26 +9,33 @@
|
||||
using std::string;
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
void render(World &world, Player &player);
|
||||
void redraw(World &world, Player &player);
|
||||
void jumpBackOneLine();
|
||||
bool startWorld(string worldFile);
|
||||
|
||||
int main() {
|
||||
for (const auto & entry : fs::directory_iterator("./worlds"))
|
||||
if (!startWorld(entry.path())) return 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
bool startWorld(string worldFile) {
|
||||
BlockRegistry blockRegistry = BlockRegistry();
|
||||
World world = World(blockRegistry);
|
||||
|
||||
string worldFile = "worlds/world.txt";
|
||||
world.loadFromFile(worldFile);
|
||||
Player player = Player(world.getStartPos(), world);
|
||||
render(world, player);
|
||||
while (player.isAlive()) {
|
||||
while (player.isAlive() && !player.hasReachedGoal()) {
|
||||
char lastChar;
|
||||
cin >> lastChar;
|
||||
if (onInput(lastChar, world, player)) redraw(world, player);
|
||||
else jumpBackOneLine();
|
||||
}
|
||||
return 0;
|
||||
return player.hasReachedGoal();
|
||||
}
|
||||
void jumpBackOneLine() {
|
||||
std::cout << "\033[1A";
|
||||
@@ -48,10 +56,10 @@ void render(World &world, Player &player) {
|
||||
for (unsigned int y = 0; y <= world.getMaxY(); y++) {
|
||||
for (unsigned int x = 0; x <= world.getMaxX(); x++) {
|
||||
if (playerTexture.size() > y && playerTexture.at(y).size() > x && playerTexture.at(y).at(x) != ' ') {
|
||||
cout << playerTexture.at(y).at(x);
|
||||
cout << Color::BRIGHT_YELLOW << playerTexture.at(y).at(x);
|
||||
}
|
||||
else if (canvas.size() > y && canvas.at(y).size() > x) {
|
||||
cout << canvas.at(y).at(x).getEncoding();
|
||||
cout << canvas.at(y).at(x).getColor() << canvas.at(y).at(x).getEncoding();
|
||||
}
|
||||
else cout << ' ';
|
||||
}
|
||||
|
||||
@@ -2,19 +2,20 @@
|
||||
#include "world.hpp"
|
||||
#include "blockRegistry.hpp"
|
||||
|
||||
bool tryWalk(World& world, Player& player, bool left);
|
||||
bool tryGoDown(World& world, Player& player);
|
||||
bool tryGoUp(World& world, Player& player);
|
||||
|
||||
bool onInput(char lastChar, World& world, Player& player) {
|
||||
switch (lastChar) {
|
||||
case ' ':
|
||||
case 'w':
|
||||
case 'W':
|
||||
return tryGoUp(world, player);
|
||||
|
||||
case 'a':
|
||||
case 'A':
|
||||
player.move(-1, 0);
|
||||
return true;
|
||||
return tryWalk(world, player, true);
|
||||
|
||||
case 's':
|
||||
case 'S':
|
||||
@@ -22,12 +23,18 @@ bool onInput(char lastChar, World& world, Player& player) {
|
||||
|
||||
case 'd':
|
||||
case 'D':
|
||||
player.move(1, 0);
|
||||
return true;
|
||||
return tryWalk(world, player, false);
|
||||
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
bool tryWalk(World& world, Player& player, bool left) {
|
||||
if (!world.getBlockAt(player.getPos()+(left ? BlockPos(-1, 1) : BlockPos(1, 1))).getSettings().hasCollision()) {
|
||||
player.move(left ? BlockPos(-1, 0) : BlockPos(1,0));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool tryGoDown(World& world, Player& player) {
|
||||
if (world.getBlockAt(player.getPos()+BlockPos(0, 2)).getSettings().isClimbableFromTop() || world.getBlockAt(player.getPos()+BlockPos(0, 3)).getSettings().isClimbableFromTop()) {
|
||||
player.move(0, 1);
|
||||
@@ -40,5 +47,13 @@ bool tryGoUp(World& world, Player& player) {
|
||||
player.move(0, -1);
|
||||
return true;
|
||||
}
|
||||
else if (world.getBlockAt(player.getPos()+BlockPos(1, 1)).getSettings().hasCollision() && !world.getBlockAt(player.getPos()+BlockPos(1, 0)).getSettings().isSolid()) {
|
||||
player.move(1, -1);
|
||||
return true;
|
||||
}
|
||||
else if (world.getBlockAt(player.getPos()+BlockPos(-1, 1)).getSettings().hasCollision() && !world.getBlockAt(player.getPos()+BlockPos(-1, 0)).getSettings().isSolid()) {
|
||||
player.move(-1, -1);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -30,6 +30,8 @@ public:
|
||||
}
|
||||
this->pos = pos;
|
||||
|
||||
if (world.getBlockAt(pos) == world.getBlockRegistry().GOAL) reachedGoal = true;
|
||||
|
||||
isFreeFalling = !world.getBlockAt(pos+BlockPos(0, 2)).getSettings().isSolid();
|
||||
if (isFreeFalling) {
|
||||
move(BlockPos(0, 1));
|
||||
@@ -37,10 +39,15 @@ public:
|
||||
if (fallLength > 5) alive = false;
|
||||
}
|
||||
else fallLength = 0;
|
||||
|
||||
if (world.getBlockAt(pos+BlockPos(0, 2)).getSettings().isLethal()) alive = false;
|
||||
}
|
||||
bool isAlive() {
|
||||
return alive;
|
||||
}
|
||||
bool hasReachedGoal() {
|
||||
return reachedGoal;
|
||||
}
|
||||
vector<vector<char>> mapToWorldspace() {
|
||||
vector<vector<char>> map;
|
||||
for (unsigned int y = 0; y <= world.getMaxY(); y++) {
|
||||
@@ -69,5 +76,6 @@ private:
|
||||
BlockPos pos = BlockPos(0, 0);
|
||||
bool alive = true;
|
||||
bool isFreeFalling = false;
|
||||
bool reachedGoal = false;
|
||||
int fallLength = 0;
|
||||
};
|
||||
15
worlds/2.txt
Normal file
15
worlds/2.txt
Normal file
@@ -0,0 +1,15 @@
|
||||
|
||||
|
||||
o
|
||||
S /|\
|
||||
/ \
|
||||
------------- -----------
|
||||
H H
|
||||
H H
|
||||
H H
|
||||
H --------- -------
|
||||
-------- H 0 0
|
||||
H H 0 0
|
||||
H H 0 0 O
|
||||
H H 0^^^^^0
|
||||
----------------------------------------
|
||||
15
worlds/3.txt
Normal file
15
worlds/3.txt
Normal file
@@ -0,0 +1,15 @@
|
||||
|
||||
----------------------
|
||||
00
|
||||
00
|
||||
00
|
||||
---------
|
||||
0 o 00----- O
|
||||
0 S /|\ 00 0
|
||||
0 / \ 00 0 ---------------
|
||||
---------------- 0 H 0
|
||||
0 H 0
|
||||
0 H 0
|
||||
0 H 0
|
||||
0~~~~~~0---------
|
||||
--------
|
||||
Reference in New Issue
Block a user