Big refactor, FSM for game state, input event callbacks
This commit is contained in:
parent
328fd40a55
commit
2e299dbcfa
12 changed files with 624 additions and 432 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -32,3 +32,4 @@ build
|
|||
*.log
|
||||
imgui.ini
|
||||
*.sublime*
|
||||
*.dll
|
||||
|
|
160
src/App.cpp
Normal file
160
src/App.cpp
Normal file
|
@ -0,0 +1,160 @@
|
|||
//
|
||||
// Created by Adrian on 2017-09-19.
|
||||
//
|
||||
|
||||
#include "App.h"
|
||||
#include <SDL.h>
|
||||
#include <ctime>
|
||||
#include "Config.h"
|
||||
#include "Renderer.h"
|
||||
#include "imgui.h"
|
||||
#include "Input.h"
|
||||
#include "Gamestate.h"
|
||||
#include "PlayState.h"
|
||||
|
||||
Uint64 perfFreq;
|
||||
double currTime() {
|
||||
return SDL_GetPerformanceCounter() / (double)perfFreq;
|
||||
}
|
||||
|
||||
bool App::init() {
|
||||
//setenv("MESA_DEBUG", "", 0);
|
||||
|
||||
Config cfg = Config("dungeon.cfg");
|
||||
cfg.load();
|
||||
|
||||
int windowWidth = cfg.getInt("ResolutionX", 1280);
|
||||
int windowHeight = cfg.getInt("ResolutionY", 720);
|
||||
bool vsync = cfg.getBool("VSync", false);
|
||||
bool wireframe = cfg.getBool("Wireframes", false);
|
||||
|
||||
cfg.save();
|
||||
|
||||
int err = 0;
|
||||
err = SDL_Init(SDL_INIT_TIMER | SDL_INIT_VIDEO);
|
||||
SDL_LogSetAllPriority(SDL_LOG_PRIORITY_DEBUG);
|
||||
if (err != 0) {
|
||||
const char* error = SDL_GetError();
|
||||
fprintf(stderr, error);
|
||||
SDL_Quit();
|
||||
return false;
|
||||
}
|
||||
SDL_LogVerbose(SDL_LOG_CATEGORY_SYSTEM,"SDL initialized.\n");
|
||||
|
||||
renderer = new Renderer();
|
||||
if (!renderer->Init("Dungeon", windowWidth, windowHeight)) {
|
||||
const char* error = SDL_GetError();
|
||||
SDL_LogCritical(SDL_LOG_CATEGORY_SYSTEM, "%s", error);
|
||||
SDL_ShowSimpleMessageBox(0, "Error", error, nullptr);
|
||||
SDL_Quit();
|
||||
return false;
|
||||
}
|
||||
|
||||
renderer->SetVSyncEnabled(vsync);
|
||||
renderer->SetWireframesEnabled(wireframe);
|
||||
|
||||
input = new Input();
|
||||
srand(static_cast<unsigned int>(time(nullptr)));
|
||||
perfFreq = SDL_GetPerformanceFrequency();
|
||||
return true;
|
||||
}
|
||||
|
||||
int App::start() {
|
||||
current = new PlayState();
|
||||
current->init(this);
|
||||
current->load();
|
||||
|
||||
double dt = 1.0/30;
|
||||
double currentTime = currTime();
|
||||
double accumulator = dt;
|
||||
|
||||
bool running = true;
|
||||
Gamestate* nextstate = nullptr;
|
||||
|
||||
while (running) {
|
||||
double newTime = currTime();
|
||||
double frametime = newTime - currentTime;
|
||||
if (frametime > 1.0/30) {
|
||||
frametime = 1.0/30;
|
||||
}
|
||||
|
||||
if (nextstate != nullptr) {
|
||||
current->quit();
|
||||
delete current;
|
||||
current = nextstate;
|
||||
current->init(this);
|
||||
current->load();
|
||||
}
|
||||
|
||||
currentTime = newTime;
|
||||
accumulator += frametime;
|
||||
|
||||
SDL_Event ev{};
|
||||
ImGuiIO &io = ImGui::GetIO();
|
||||
renderer->ImguiNewFrame();
|
||||
while (SDL_PollEvent(&ev)) {
|
||||
renderer->ImguiProcessEvents(&ev);
|
||||
switch (ev.type) {
|
||||
case SDL_WINDOWEVENT:
|
||||
switch (ev.window.event) {
|
||||
case SDL_WINDOWEVENT_CLOSE:
|
||||
running = false;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SDL_MOUSEMOTION:
|
||||
if (!io.WantCaptureMouse) {
|
||||
InputEvent inputEvent = input->set_mouse_pos(ev.motion.x, ev.motion.y, ev.motion.xrel, ev.motion.yrel);
|
||||
current->inputevent(&inputEvent);
|
||||
}
|
||||
break;
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
if (!io.WantCaptureMouse) {
|
||||
InputEvent inputEvent = input->set_mouse_button(ev.button.button, ev.button.x, ev.button.y, true);
|
||||
current->inputevent(&inputEvent);
|
||||
}
|
||||
break;
|
||||
case SDL_MOUSEBUTTONUP:
|
||||
if (!io.WantCaptureMouse) {
|
||||
InputEvent inputEvent = input->set_mouse_button(ev.button.button, ev.button.x, ev.button.y, false);
|
||||
current->inputevent(&inputEvent);
|
||||
}
|
||||
break;
|
||||
case SDL_KEYDOWN:
|
||||
if (!io.WantCaptureKeyboard) {
|
||||
InputEvent inputEvent = input->setkey(ev.key.keysym.sym, (SDL_Keymod)ev.key.keysym.mod, true);
|
||||
current->inputevent(&inputEvent);
|
||||
}
|
||||
break;
|
||||
case SDL_KEYUP:
|
||||
if (!io.WantCaptureKeyboard){
|
||||
InputEvent inputEvent = input->setkey(ev.key.keysym.sym, (SDL_Keymod)ev.key.keysym.mod, false);
|
||||
current->inputevent(&inputEvent);
|
||||
}
|
||||
break;
|
||||
case SDL_QUIT:
|
||||
running = false;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (running && accumulator >= dt) {
|
||||
nextstate = current->update(dt);
|
||||
input->newframe();
|
||||
|
||||
accumulator -= dt;
|
||||
}
|
||||
|
||||
renderer->Clear();
|
||||
current->draw(accumulator / dt);
|
||||
renderer->Present();
|
||||
SDL_Delay(1);
|
||||
}
|
||||
delete renderer;
|
||||
SDL_Quit();
|
||||
SDL_LogVerbose(SDL_LOG_CATEGORY_SYSTEM, "Quit.");
|
||||
return 0;
|
||||
}
|
24
src/App.h
Normal file
24
src/App.h
Normal file
|
@ -0,0 +1,24 @@
|
|||
//
|
||||
// Created by Adrian on 2017-09-19.
|
||||
//
|
||||
|
||||
#ifndef DUNGEON_APP_H
|
||||
#define DUNGEON_APP_H
|
||||
|
||||
#pragma once
|
||||
|
||||
class Gamestate;
|
||||
class Renderer;
|
||||
class Input;
|
||||
|
||||
class App {
|
||||
public:
|
||||
Gamestate* current;
|
||||
Renderer* renderer;
|
||||
Input* input;
|
||||
bool init();
|
||||
int start();
|
||||
};
|
||||
|
||||
|
||||
#endif //DUNGEON_APP_H
|
265
src/Game.cpp
265
src/Game.cpp
|
@ -1,265 +0,0 @@
|
|||
#include "Game.h"
|
||||
|
||||
#include "imgui.h"
|
||||
#include "Input.h"
|
||||
#include "Renderer.h"
|
||||
|
||||
#include "Tilemap.h"
|
||||
#include "Tileset.h"
|
||||
#include "Hero.h"
|
||||
#include "Goblin.h"
|
||||
#include "Shaman.h"
|
||||
|
||||
const int mapwidth = 32;
|
||||
const std::string map =
|
||||
"# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #"
|
||||
"# @ . . . # # # # # # # # . . . . . . . . . . . . . . . . . # #"
|
||||
"# . . . . . . . . # # # # . # # . # # # # # # . # # # # # . # #"
|
||||
"# . . . . # # # . . . . . . # . g . # # # # # . # # # . . g . #"
|
||||
"# . . . . # # # # # # # # . # . . . # # . . . . . . . . . . . #"
|
||||
"# # # . # # # # # # # # # . . . . g # # . # # # . # # . . g . #"
|
||||
"# . . . . . . . . . . . . . # # # # # . . . # # . # # # # # # #"
|
||||
"# . # # # # # # # # . # # . # # # # # . g . # # . # . . g . . #"
|
||||
"# . . . . g # # . . . # . . . # # # # . . . # # . # . . . . . #"
|
||||
"# . . g . . # # . # # # . s . . . # # # # # # # . . . . s . . #"
|
||||
"# . . . . . # # . . . # . . . # . . . . . . . . . # . g . . . #"
|
||||
"# # . # # # # # . # . # # # # # # # # # . # # # # # # # # . # #"
|
||||
"# . . . . . . . . # . . . . . . . . . . . . . . . . . . . . . #"
|
||||
"# . # # # # # # # # # # . # . # # # # # # # # # # . # # # # . #"
|
||||
"# . . . . . . . . . . . . # . # . . . . # . . . . . # # # . . #"
|
||||
"# # # # # # . # # # . # # # . # . . . . # . . . # . # # # . # #"
|
||||
"# . . . . # . # . . . . . # . . . . . . . . . . # . # # . . . #"
|
||||
"# . . . . # . # . . . . . # . # . . . . # # # # # . . . . . . #"
|
||||
"# . . . . . . # . . . . . # . # # # # # # . . . . . # # . . . #"
|
||||
"# . . . . # . # # # # # # # . . . . . . . . # # # # # # # # # #"
|
||||
"# . . . . # . . . . . . . . . # # # # # # # # # # # # # # # # #"
|
||||
"# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #"
|
||||
"# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #"
|
||||
"# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #"
|
||||
"# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #"
|
||||
"# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #"
|
||||
"# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #"
|
||||
"# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #"
|
||||
"# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #"
|
||||
"# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #"
|
||||
"# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #"
|
||||
"# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #"
|
||||
"# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #";
|
||||
|
||||
Renderer* renderer;
|
||||
Input* input;
|
||||
|
||||
Tileset* ascii;
|
||||
Tilemap* tilemap;
|
||||
Hero* hero;
|
||||
|
||||
bool paused;
|
||||
bool debug = false;
|
||||
|
||||
void init() {
|
||||
paused = true;
|
||||
|
||||
if (tilemap != nullptr) {
|
||||
delete tilemap;
|
||||
tilemap = nullptr;
|
||||
hero = nullptr;
|
||||
}
|
||||
|
||||
if (hero != nullptr) {
|
||||
delete hero;
|
||||
hero = nullptr;
|
||||
}
|
||||
|
||||
SDL_LogVerbose(SDL_LOG_CATEGORY_SYSTEM, "Creating tilemap...\n");
|
||||
tilemap = new Tilemap(32, 32);
|
||||
int y = 0;
|
||||
int x = 0;
|
||||
for (int i = 0; i < map.length(); i++) {
|
||||
|
||||
if (y >= 32) {
|
||||
break;
|
||||
}
|
||||
if (x >= mapwidth) {
|
||||
y++;
|
||||
x = 0;
|
||||
}
|
||||
if (map[i] == ' ' || map[i] == '\t' || map[i] == '\n') {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (map[i] == '@') {
|
||||
hero = new Hero(tilemap, vec2i(x, y));
|
||||
tilemap->AddActor(hero);
|
||||
tilemap->SetTile(x, y, '.');
|
||||
}
|
||||
else if (map[i] == 'g') {
|
||||
tilemap->AddActor(new Goblin(tilemap, vec2i(x, y)));
|
||||
tilemap->SetTile(x, y, '.');
|
||||
}
|
||||
else if (map[i] == 's') {
|
||||
tilemap->AddActor(new Shaman(tilemap, vec2i(x, y)));
|
||||
tilemap->SetTile(x, y, '.');
|
||||
}
|
||||
else {
|
||||
tilemap->SetTile(x, y, map[i]);
|
||||
}
|
||||
x++;
|
||||
}
|
||||
SDL_LogVerbose(SDL_LOG_CATEGORY_SYSTEM, "Done.\n");
|
||||
SDL_LogVerbose(SDL_LOG_CATEGORY_SYSTEM, "Calculating initial FOV...\n");
|
||||
hero->CalcFOV();
|
||||
SDL_LogVerbose(SDL_LOG_CATEGORY_SYSTEM, "Done.\n");
|
||||
}
|
||||
|
||||
void load(Renderer* rend, Input* inp) {
|
||||
renderer = rend;
|
||||
input = inp;
|
||||
SDL_LogVerbose(SDL_LOG_CATEGORY_SYSTEM, "Creating ascii tileset...\n");
|
||||
ascii = new Tileset(renderer, "./assets/12x12.bmp", 192, 192, 12, 12);
|
||||
SDL_LogVerbose(SDL_LOG_CATEGORY_SYSTEM, "Created ascii tileset.\n");
|
||||
input->bindkey(SDLK_r, ACTION_RESET);
|
||||
input->bindkey(SDLK_SPACE, ACTION_PAUSE);
|
||||
input->bindkey(SDLK_RETURN, ACTION_STEP);
|
||||
input->bindkey(SDLK_F1, ACTION_TOGGLE_DEBUG);
|
||||
SDL_LogVerbose(SDL_LOG_CATEGORY_SYSTEM, "Keybinds bound.\n");
|
||||
init();
|
||||
}
|
||||
|
||||
float delay = .5;
|
||||
double timer;
|
||||
|
||||
void update(double dt) {
|
||||
if (input->wasJustPressed(ACTION_TOGGLE_DEBUG)) {
|
||||
debug = !debug;
|
||||
}
|
||||
if (input->wasJustPressed(ACTION_PAUSE)) {
|
||||
paused = !paused;
|
||||
}
|
||||
if (input->wasJustPressed(ACTION_RESET)) {
|
||||
init();
|
||||
}
|
||||
|
||||
timer += dt;
|
||||
if (!paused || input->wasJustPressed(ACTION_STEP)) {
|
||||
if (timer >= delay) {
|
||||
timer = 0;
|
||||
|
||||
auto actors = tilemap->GetActorList();
|
||||
for (Actor* var : *actors) {
|
||||
var->Update();
|
||||
}
|
||||
for (int i = (int)actors->size() - 1; i >= 0; i--) {
|
||||
if (!actors->at(i)->alive) {
|
||||
if (actors->at(i) == hero) {
|
||||
hero = nullptr;
|
||||
}
|
||||
delete actors->at(i);
|
||||
actors->erase(actors->begin() + i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void draw(double alpha) {
|
||||
|
||||
|
||||
if (debug) {
|
||||
bool wireframe = renderer->IsWireframesEnabled();
|
||||
ImGui::Checkbox("Wireframes", &wireframe);
|
||||
renderer->SetWireframesEnabled(wireframe);
|
||||
bool vsync = renderer->IsVSyncEnabled();
|
||||
ImGui::Checkbox("VSync", &vsync);
|
||||
renderer->SetVSyncEnabled(vsync);
|
||||
|
||||
ImGui::BeginMainMenuBar();
|
||||
|
||||
if (ImGui::BeginMenu("File")) {
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
if (ImGui::BeginMenu("Edit")) {
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
if (ImGui::BeginMenu("View")) {
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
ImGui::EndMainMenuBar();
|
||||
|
||||
ImGui::SliderFloat("turndelay", &delay, .01f, 1);
|
||||
}
|
||||
|
||||
|
||||
for (int x = 0; x < 32; x++) {
|
||||
for (int y = 0; y < 32; y++) {
|
||||
if (hero == nullptr || hero->HasSeen(x, y)) {
|
||||
renderer->SetColor(1, 1, 1, 1);
|
||||
renderer->DrawSprite(ascii->GetSprite(tilemap->GetTile(x, y)), x * 12, y * 12);
|
||||
if (hero != nullptr && !hero->CanSee(x, y)) {
|
||||
renderer->SetColor(0, 0, 0, .5f);
|
||||
renderer->DrawSprite(ascii->GetSprite(219), x * 12, y * 12);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
auto actors = tilemap->GetActorList();
|
||||
for (Actor* var : *actors) {
|
||||
vec2i pos = var->getPosition();
|
||||
if (hero == nullptr || hero->CanSee(pos.x, pos.y)) {
|
||||
renderer->SetColor(0, 0, 0, 255);
|
||||
renderer->DrawSprite(ascii->GetSprite(219), pos.x * 12, pos.y * 12);
|
||||
|
||||
int sprite;
|
||||
switch (var->Type()) {
|
||||
case ACT_HERO:
|
||||
renderer->SetColor(.2f, .6f, 1, 1);
|
||||
sprite = '@';
|
||||
break;
|
||||
case ACT_GOBLIN:
|
||||
renderer->SetColor(.6f, 1, .2f, 1);
|
||||
sprite = 'g';
|
||||
break;
|
||||
case ACT_SHAMAN:
|
||||
renderer->SetColor(.2f, 1, .6f, 1);
|
||||
sprite = 's';
|
||||
break;
|
||||
default:
|
||||
renderer->SetColor(1, 1, 1, 1);
|
||||
sprite = 2;
|
||||
break;
|
||||
}
|
||||
renderer->DrawSprite(ascii->GetSprite(sprite), pos.x * 12, pos.y * 12);
|
||||
}
|
||||
}
|
||||
if (hero != nullptr) {
|
||||
renderer->SetColor(155, 5, 5, 255);
|
||||
for (int i = 0; i < hero->health; i++) {
|
||||
renderer->SetColor(0, 0, 0, 255);
|
||||
renderer->DrawSprite(ascii->GetSprite(219), i * 12, 0);
|
||||
renderer->SetColor(255, 0, 0, 255);
|
||||
renderer->DrawSprite(ascii->GetSprite(3), i * 12, 0);
|
||||
}
|
||||
}
|
||||
if (paused) {
|
||||
renderer->SetColor(255, 0, 0, 255);
|
||||
renderer->DrawSprite(ascii->GetSprite(219), 12 * 0, 0);
|
||||
renderer->DrawSprite(ascii->GetSprite(219), 12 * 1, 0);
|
||||
renderer->DrawSprite(ascii->GetSprite(219), 12 * 2, 0);
|
||||
renderer->DrawSprite(ascii->GetSprite(219), 12 * 3, 0);
|
||||
renderer->DrawSprite(ascii->GetSprite(219), 12 * 4, 0);
|
||||
renderer->DrawSprite(ascii->GetSprite(219), 12 * 5, 0);
|
||||
renderer->DrawSprite(ascii->GetSprite(219), 12 * 6, 0);
|
||||
renderer->DrawSprite(ascii->GetSprite(219), 12 * 7, 0);
|
||||
renderer->SetColor(0, 0, 0, 255);
|
||||
renderer->DrawSprite(ascii->GetSprite('-'), 12 * 0, 0);
|
||||
renderer->DrawSprite(ascii->GetSprite('P'), 12 * 1, 0);
|
||||
renderer->DrawSprite(ascii->GetSprite('A'), 12 * 2, 0);
|
||||
renderer->DrawSprite(ascii->GetSprite('U'), 12 * 3, 0);
|
||||
renderer->DrawSprite(ascii->GetSprite('S'), 12 * 4, 0);
|
||||
renderer->DrawSprite(ascii->GetSprite('E'), 12 * 5, 0);
|
||||
renderer->DrawSprite(ascii->GetSprite('D'), 12 * 6, 0);
|
||||
renderer->DrawSprite(ascii->GetSprite('-'), 12 * 7, 0);
|
||||
}
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
class Renderer;
|
||||
class Input;
|
||||
|
||||
void load(Renderer* rend, Input* inp);
|
||||
void update(double dt);
|
||||
void draw(double alpha);
|
10
src/Gamestate.cpp
Normal file
10
src/Gamestate.cpp
Normal file
|
@ -0,0 +1,10 @@
|
|||
//
|
||||
// Created by Adrian on 2017-09-19.
|
||||
//
|
||||
|
||||
#include "Gamestate.h"
|
||||
#include "App.h"
|
||||
|
||||
void Gamestate::init(App *app) {
|
||||
this->app = app;
|
||||
}
|
24
src/Gamestate.h
Normal file
24
src/Gamestate.h
Normal file
|
@ -0,0 +1,24 @@
|
|||
//
|
||||
// Created by Adrian on 2017-09-19.
|
||||
//
|
||||
|
||||
#ifndef DUNGEON_GAMESTATE_H
|
||||
#define DUNGEON_GAMESTATE_H
|
||||
|
||||
class App;
|
||||
struct InputEvent;
|
||||
|
||||
class Gamestate {
|
||||
protected:
|
||||
App* app;
|
||||
public:
|
||||
void init(App* app);
|
||||
virtual void load() = 0;
|
||||
virtual Gamestate* update(double delta) = 0;
|
||||
virtual void draw(double delta) = 0;
|
||||
virtual void quit() = 0;
|
||||
virtual void inputevent(InputEvent* event) = 0;
|
||||
};
|
||||
|
||||
|
||||
#endif //DUNGEON_GAMESTATE_H
|
|
@ -16,17 +16,21 @@ Input::~Input()
|
|||
{
|
||||
}
|
||||
|
||||
void Input::newframe()
|
||||
{
|
||||
for(int i = 0; i < INPUTACTION_END; i++)
|
||||
{
|
||||
void Input::newframe() {
|
||||
for(int i = 0; i < INPUTACTION_END; i++) {
|
||||
justpressed[i] = false;
|
||||
justreleased[i] = false;
|
||||
}
|
||||
}
|
||||
|
||||
void Input::setkey(SDL_Keycode key, SDL_Keymod mod, bool pressed)
|
||||
InputEvent Input::setkey(SDL_Keycode key, SDL_Keymod mod, bool pressed)
|
||||
{
|
||||
InputEvent event;
|
||||
event.type = INPUT_KEY_EVENT;
|
||||
event.key_press_event.key = key;
|
||||
event.key_press_event.mod = mod;
|
||||
event.pressed = pressed;
|
||||
|
||||
if (mod & KMOD_NUM) { // let's ignore numlock
|
||||
mod = (SDL_Keymod)(mod ^ KMOD_NUM);
|
||||
}
|
||||
|
@ -37,45 +41,66 @@ void Input::setkey(SDL_Keycode key, SDL_Keymod mod, bool pressed)
|
|||
if (binds.find(bind) != binds.end())
|
||||
{
|
||||
InputAction action = binds[bind];
|
||||
|
||||
if (ispressed[action] != pressed) // Ignore keypress/release if it's already pressed/released, this disables repeats.
|
||||
{
|
||||
event.action = action;
|
||||
event.key_press_event.echo = ispressed[action] != pressed;
|
||||
if (event.key_press_event.echo) { // Ignore keypress/release if it's already pressed/released, this disables repeats.
|
||||
ispressed[action] = pressed;
|
||||
if (pressed)
|
||||
{
|
||||
if (pressed) {
|
||||
justpressed[action] = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
justreleased[action] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return event;
|
||||
}
|
||||
|
||||
void Input::bindkey(SDL_Keycode key, InputAction action, SDL_Keymod mod)
|
||||
{
|
||||
void Input::bindkey(SDL_Keycode key, InputAction action, SDL_Keymod mod) {
|
||||
Bind bind = { key, mod };
|
||||
binds[bind] = action;
|
||||
}
|
||||
|
||||
void Input::unbindkey(SDL_Keycode key, SDL_Keymod mod)
|
||||
{
|
||||
void Input::unbindkey(SDL_Keycode key, SDL_Keymod mod) {
|
||||
Bind bind = { key, mod };
|
||||
binds.erase(bind);
|
||||
}
|
||||
|
||||
bool Input::isPressed(InputAction action)
|
||||
{
|
||||
bool Input::isPressed(InputAction action) {
|
||||
return ispressed[action];
|
||||
}
|
||||
|
||||
bool Input::wasJustPressed(InputAction action)
|
||||
{
|
||||
bool Input::wasJustPressed(InputAction action) {
|
||||
return justpressed[action];
|
||||
}
|
||||
|
||||
bool Input::wasJustReleased(InputAction action)
|
||||
{
|
||||
bool Input::wasJustReleased(InputAction action) {
|
||||
return justreleased[action];
|
||||
}
|
||||
|
||||
InputEvent Input::set_mouse_pos(int x, int y, int dx, int dy) {
|
||||
mouse_x = x;
|
||||
mouse_y = y;
|
||||
|
||||
InputEvent event;
|
||||
event.type = INPUT_MOUSE_MOVE_EVENT;
|
||||
event.mouse_move_event.x = x;
|
||||
event.mouse_move_event.y = y;
|
||||
event.mouse_move_event.dx = dx;
|
||||
event.mouse_move_event.dy = dy;
|
||||
return event;
|
||||
}
|
||||
|
||||
InputEvent Input::set_mouse_button(int button, int x, int y, bool pressed) {
|
||||
mouse_x = x;
|
||||
mouse_y = y;
|
||||
|
||||
InputEvent event;
|
||||
event.type = INPUT_MOUSE_CLICK_EVENT;
|
||||
event.action = ACTION_NONE;
|
||||
event.pressed = pressed;
|
||||
event.mouse_click_event.button = button;
|
||||
event.mouse_click_event.x = x;
|
||||
event.mouse_click_event.y = y;
|
||||
return event;
|
||||
}
|
||||
|
|
51
src/Input.h
51
src/Input.h
|
@ -5,10 +5,17 @@
|
|||
|
||||
enum InputAction {
|
||||
ACTION_NONE,
|
||||
ACTION_PAUSE,
|
||||
ACTION_ESCAPE_MENU,
|
||||
ACTION_RESET,
|
||||
ACTION_STEP,
|
||||
ACTION_TOGGLE_DEBUG,
|
||||
ACTION_MOVE_NORTH,
|
||||
ACTION_MOVE_NORTHWEST,
|
||||
ACTION_MOVE_NORTHEAST,
|
||||
ACTION_MOVE_WEST,
|
||||
ACTION_MOVE_EAST,
|
||||
ACTION_MOVE_SOUTH,
|
||||
ACTION_MOVE_SOUTHWEST,
|
||||
ACTION_MOVE_SOUTHEAST,
|
||||
INPUTACTION_END // Used to get the length of the enum. Must be the final entry.
|
||||
};
|
||||
|
||||
|
@ -24,17 +31,55 @@ struct Bind {
|
|||
}
|
||||
};
|
||||
|
||||
enum InputEventType {
|
||||
INPUT_MOUSE_MOVE_EVENT,
|
||||
INPUT_MOUSE_CLICK_EVENT,
|
||||
INPUT_KEY_EVENT,
|
||||
};
|
||||
struct InputEvent {
|
||||
InputEventType type;
|
||||
InputAction action;
|
||||
bool pressed;
|
||||
|
||||
struct MouseMoveEvent { // mouse click;
|
||||
int x;
|
||||
int y;
|
||||
int dx;
|
||||
int dy;
|
||||
};
|
||||
struct MouseClickEvent { // mouse click;
|
||||
int x;
|
||||
int y;
|
||||
int button;
|
||||
};
|
||||
struct KeyPressEvent { // key
|
||||
SDL_Keycode key;
|
||||
SDL_Keymod mod;
|
||||
bool echo;
|
||||
};
|
||||
|
||||
union {
|
||||
MouseMoveEvent mouse_move_event;
|
||||
MouseClickEvent mouse_click_event;
|
||||
KeyPressEvent key_press_event;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
class Input
|
||||
{
|
||||
std::map<Bind, InputAction> binds;
|
||||
bool ispressed[INPUTACTION_END];
|
||||
bool justpressed[INPUTACTION_END];
|
||||
bool justreleased[INPUTACTION_END];
|
||||
int mouse_x, mouse_y;
|
||||
public:
|
||||
Input();
|
||||
~Input();
|
||||
void newframe();
|
||||
void setkey(SDL_Keycode key, SDL_Keymod mod, bool pressed);
|
||||
InputEvent setkey(SDL_Keycode key, SDL_Keymod mod, bool pressed);
|
||||
InputEvent set_mouse_pos(int x, int y, int dx, int dy);
|
||||
InputEvent set_mouse_button(int button, int x, int y, bool pressed);
|
||||
void bindkey(SDL_Keycode key, InputAction action, SDL_Keymod mod = KMOD_NONE);
|
||||
void unbindkey(SDL_Keycode key, SDL_Keymod mod);
|
||||
bool isPressed(InputAction action);
|
||||
|
|
141
src/Main.cpp
141
src/Main.cpp
|
@ -1,139 +1,12 @@
|
|||
//#define _ALLOW_ITERATOR_DEBUG_LEVEL_MISMATCH
|
||||
//#define _ITERATOR_DEBUG_LEVEL 0
|
||||
|
||||
#include "App.h"
|
||||
|
||||
#include <SDL.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <string>
|
||||
#include <time.h>
|
||||
|
||||
#include "Renderer.h"
|
||||
#include "Input.h"
|
||||
#include "Config.h"
|
||||
#include "Game.h"
|
||||
|
||||
#include "imgui.h"
|
||||
|
||||
Uint64 perfFreq;
|
||||
|
||||
double currTime();
|
||||
|
||||
#undef main
|
||||
//#undef main
|
||||
int main(int argc, char* argv[]) {
|
||||
Renderer* renderer;
|
||||
Input* input;
|
||||
|
||||
//setenv("MESA_DEBUG", "", 0);
|
||||
|
||||
Config cfg = Config("dungeon.cfg");
|
||||
cfg.load();
|
||||
|
||||
int windowWidth = cfg.getInt("ResolutionX", 1280);
|
||||
int windowHeight = cfg.getInt("ResolutionY", 720);
|
||||
bool vsync = cfg.getBool("VSync", false);
|
||||
bool wireframe = cfg.getBool("Wireframes", false);
|
||||
|
||||
cfg.save();
|
||||
|
||||
int err = 0;
|
||||
err = SDL_Init(SDL_INIT_TIMER | SDL_INIT_VIDEO);
|
||||
SDL_LogSetAllPriority(SDL_LOG_PRIORITY_DEBUG);
|
||||
if (err != 0) {
|
||||
const char* error = SDL_GetError();
|
||||
SDL_LogCritical(SDL_LOG_CATEGORY_SYSTEM, "%s", error);
|
||||
SDL_Quit();
|
||||
return 1;
|
||||
App app{};
|
||||
int err = 1;
|
||||
if (app.init()) {
|
||||
err = app.start();
|
||||
}
|
||||
SDL_LogVerbose(SDL_LOG_CATEGORY_SYSTEM,"SDL initialized.\n");
|
||||
|
||||
renderer = new Renderer();
|
||||
if (!renderer->Init("Dungeon", windowWidth, windowHeight)) {
|
||||
const char* error = SDL_GetError();
|
||||
SDL_LogCritical(SDL_LOG_CATEGORY_SYSTEM, "%s", error);
|
||||
SDL_ShowSimpleMessageBox(0, "Error", error, nullptr);
|
||||
SDL_Quit();
|
||||
return 1;
|
||||
}
|
||||
|
||||
renderer->SetVSyncEnabled(vsync);
|
||||
renderer->SetWireframesEnabled(wireframe);
|
||||
|
||||
input = new Input();
|
||||
srand(time(nullptr));
|
||||
load(renderer, input);
|
||||
|
||||
perfFreq = SDL_GetPerformanceFrequency();
|
||||
|
||||
double dt = 1.0/30;
|
||||
double currentTime = currTime();
|
||||
double accumulator = dt;
|
||||
|
||||
int currentframe = 0;
|
||||
bool running = true;
|
||||
|
||||
while (running) {
|
||||
double newTime = currTime();
|
||||
double frametime = newTime - currentTime;
|
||||
if (frametime > 1.0/30) {
|
||||
frametime = 1.0/30;
|
||||
}
|
||||
currentTime = newTime;
|
||||
|
||||
accumulator += frametime;
|
||||
|
||||
//dt = (SDL_GetTicks() - currentframe) * 0.001f;
|
||||
currentframe = SDL_GetTicks();
|
||||
|
||||
SDL_Event ev;
|
||||
ImGuiIO &io = ImGui::GetIO();
|
||||
renderer->ImguiNewFrame();
|
||||
while (SDL_PollEvent(&ev)) {
|
||||
renderer->ImguiProcessEvents(&ev);
|
||||
switch (ev.type) {
|
||||
case SDL_WINDOWEVENT:
|
||||
switch (ev.window.event) {
|
||||
case SDL_WINDOWEVENT_CLOSE:
|
||||
running = false;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SDL_KEYDOWN:
|
||||
if (!io.WantCaptureKeyboard)
|
||||
input->setkey(ev.key.keysym.sym, (SDL_Keymod)ev.key.keysym.mod, true);
|
||||
break;
|
||||
case SDL_KEYUP:
|
||||
if (!io.WantCaptureKeyboard)
|
||||
input->setkey(ev.key.keysym.sym, (SDL_Keymod)ev.key.keysym.mod, false);
|
||||
break;
|
||||
case SDL_QUIT:
|
||||
running = false;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
while (running && accumulator >= dt) {
|
||||
update(dt);
|
||||
input->newframe();
|
||||
|
||||
accumulator -= dt;
|
||||
}
|
||||
|
||||
renderer->Clear();
|
||||
draw(accumulator / dt);
|
||||
renderer->Present();
|
||||
SDL_Delay(1);
|
||||
}
|
||||
delete renderer;
|
||||
SDL_Quit();
|
||||
SDL_LogVerbose(SDL_LOG_CATEGORY_SYSTEM, "Quit.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
double currTime() {
|
||||
return SDL_GetPerformanceCounter() / (double)perfFreq;
|
||||
return err;
|
||||
}
|
||||
|
|
268
src/PlayState.cpp
Normal file
268
src/PlayState.cpp
Normal file
|
@ -0,0 +1,268 @@
|
|||
//
|
||||
// Created by Adrian on 2017-09-21.
|
||||
//
|
||||
|
||||
#include "PlayState.h"
|
||||
#include "Input.h"
|
||||
#include "Renderer.h"
|
||||
#include "Actor.h"
|
||||
#include "App.h"
|
||||
#include "Tilemap.h"
|
||||
#include "Tileset.h"
|
||||
#include "imgui.h"
|
||||
#include "Hero.h"
|
||||
#include "Goblin.h"
|
||||
#include "Shaman.h"
|
||||
|
||||
const int mapwidth = 32;
|
||||
const std::string map =
|
||||
"# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #"
|
||||
"# @ . . . # # # # # # # # . . . . . . . . . . . . . . . . . # #"
|
||||
"# . . . . . . . . # # # # . # # . # # # # # # . # # # # # . # #"
|
||||
"# . . . . # # # . . . . . . # . g . # # # # # . # # # . . g . #"
|
||||
"# . . . . # # # # # # # # . # . . . # # . . . . . . . . . . . #"
|
||||
"# # # . # # # # # # # # # . . . . g # # . # # # . # # . . g . #"
|
||||
"# . . . . . . . . . . . . . # # # # # . . . # # . # # # # # # #"
|
||||
"# . # # # # # # # # . # # . # # # # # . g . # # . # . . g . . #"
|
||||
"# . . . . g # # . . . # . . . # # # # . . . # # . # . . . . . #"
|
||||
"# . . g . . # # . # # # . s . . . # # # # # # # . . . . s . . #"
|
||||
"# . . . . . # # . . . # . . . # . . . . . . . . . # . g . . . #"
|
||||
"# # . # # # # # . # . # # # # # # # # # . # # # # # # # # . # #"
|
||||
"# . . . . . . . . # . . . . . . . . . . . . . . . . . . . . . #"
|
||||
"# . # # # # # # # # # # . # . # # # # # # # # # # . # # # # . #"
|
||||
"# . . . . . . . . . . . . # . # . . . . # . . . . . # # # . . #"
|
||||
"# # # # # # . # # # . # # # . # . . . . # . . . # . # # # . # #"
|
||||
"# . . . . # . # . . . . . # . . . . . . . . . . # . # # . . . #"
|
||||
"# . . . . # . # . . . . . # . # . . . . # # # # # . . . . . . #"
|
||||
"# . . . . . . # . . . . . # . # # # # # # . . . . . # # . . . #"
|
||||
"# . . . . # . # # # # # # # . . . . . . . . # # # # # # # # # #"
|
||||
"# . . . . # . . . . . . . . . # # # # # # # # # # # # # # # # #"
|
||||
"# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #"
|
||||
"# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #"
|
||||
"# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #"
|
||||
"# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #"
|
||||
"# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #"
|
||||
"# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #"
|
||||
"# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #"
|
||||
"# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #"
|
||||
"# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #"
|
||||
"# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #"
|
||||
"# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #"
|
||||
"# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #";
|
||||
|
||||
void PlayState::load() {
|
||||
SDL_LogVerbose(SDL_LOG_CATEGORY_SYSTEM, "Creating ascii tileset...\n");
|
||||
ascii = new Tileset(app->renderer, "./assets/12x12.bmp", 192, 192, 12, 12);
|
||||
SDL_LogVerbose(SDL_LOG_CATEGORY_SYSTEM, "Created ascii tileset.\n");
|
||||
|
||||
app->input->bindkey(SDLK_ESCAPE, ACTION_ESCAPE_MENU);
|
||||
app->input->bindkey(SDLK_KP_8, ACTION_MOVE_NORTH);
|
||||
app->input->bindkey(SDLK_KP_7, ACTION_MOVE_NORTHWEST);
|
||||
app->input->bindkey(SDLK_KP_9, ACTION_MOVE_NORTHEAST);
|
||||
app->input->bindkey(SDLK_KP_4, ACTION_MOVE_WEST);
|
||||
app->input->bindkey(SDLK_KP_6, ACTION_MOVE_EAST);
|
||||
app->input->bindkey(SDLK_KP_2, ACTION_MOVE_SOUTH);
|
||||
app->input->bindkey(SDLK_KP_1, ACTION_MOVE_SOUTHWEST);
|
||||
app->input->bindkey(SDLK_KP_3, ACTION_MOVE_SOUTHEAST);
|
||||
app->input->bindkey(SDLK_F1, ACTION_TOGGLE_DEBUG);
|
||||
|
||||
app->input->bindkey(SDLK_r, ACTION_RESET);
|
||||
|
||||
SDL_LogVerbose(SDL_LOG_CATEGORY_SYSTEM, "Keybinds bound.\n");
|
||||
new_game();
|
||||
}
|
||||
|
||||
Gamestate *PlayState::update(double delta) {
|
||||
timer += delta;
|
||||
if (!paused) {
|
||||
if (timer >= delay) {
|
||||
timer = 0;
|
||||
|
||||
auto actors = tilemap->GetActorList();
|
||||
for (Actor* var : *actors) {
|
||||
var->Update();
|
||||
}
|
||||
for (int i = (int)actors->size() - 1; i >= 0; i--) {
|
||||
if (!actors->at(i)->alive) {
|
||||
if (actors->at(i) == hero) {
|
||||
hero = nullptr;
|
||||
}
|
||||
delete actors->at(i);
|
||||
actors->erase(actors->begin() + i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void PlayState::draw(double delta) {
|
||||
if (debug) {
|
||||
bool wireframe = app->renderer->IsWireframesEnabled();
|
||||
ImGui::Checkbox("Wireframes", &wireframe);
|
||||
app->renderer->SetWireframesEnabled(wireframe);
|
||||
bool vsync = app->renderer->IsVSyncEnabled();
|
||||
ImGui::Checkbox("VSync", &vsync);
|
||||
app->renderer->SetVSyncEnabled(vsync);
|
||||
|
||||
ImGui::BeginMainMenuBar();
|
||||
|
||||
if (ImGui::BeginMenu("File")) {
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
if (ImGui::BeginMenu("Edit")) {
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
if (ImGui::BeginMenu("View")) {
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
ImGui::EndMainMenuBar();
|
||||
|
||||
ImGui::SliderFloat("turndelay", &delay, .01f, 1);
|
||||
}
|
||||
|
||||
|
||||
for (int x = 0; x < 32; x++) {
|
||||
for (int y = 0; y < 32; y++) {
|
||||
if (hero == nullptr || hero->HasSeen(x, y)) {
|
||||
app->renderer->SetColor(1, 1, 1, 1);
|
||||
app->renderer->DrawSprite(ascii->GetSprite(tilemap->GetTile(x, y)), x * 12, y * 12);
|
||||
if (hero != nullptr && !hero->CanSee(x, y)) {
|
||||
app->renderer->SetColor(0, 0, 0, .5f);
|
||||
app->renderer->DrawSprite(ascii->GetSprite(219), x * 12, y * 12);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
auto actors = tilemap->GetActorList();
|
||||
for (Actor* var : *actors) {
|
||||
vec2i pos = var->getPosition();
|
||||
if (hero == nullptr || hero->CanSee(pos.x, pos.y)) {
|
||||
app->renderer->SetColor(0, 0, 0, 255);
|
||||
app->renderer->DrawSprite(ascii->GetSprite(219), pos.x * 12, pos.y * 12);
|
||||
|
||||
int sprite;
|
||||
switch (var->Type()) {
|
||||
case ACT_HERO:
|
||||
app->renderer->SetColor(.2f, .6f, 1, 1);
|
||||
sprite = '@';
|
||||
break;
|
||||
case ACT_GOBLIN:
|
||||
app->renderer->SetColor(.6f, 1, .2f, 1);
|
||||
sprite = 'g';
|
||||
break;
|
||||
case ACT_SHAMAN:
|
||||
app->renderer->SetColor(.2f, 1, .6f, 1);
|
||||
sprite = 's';
|
||||
break;
|
||||
default:
|
||||
app->renderer->SetColor(1, 1, 1, 1);
|
||||
sprite = 2;
|
||||
break;
|
||||
}
|
||||
app->renderer->DrawSprite(ascii->GetSprite(sprite), pos.x * 12, pos.y * 12);
|
||||
}
|
||||
}
|
||||
if (hero != nullptr) {
|
||||
app->renderer->SetColor(155, 5, 5, 255);
|
||||
for (int i = 0; i < hero->health; i++) {
|
||||
app->renderer->SetColor(0, 0, 0, 255);
|
||||
app->renderer->DrawSprite(ascii->GetSprite(219), i * 12, 0);
|
||||
app->renderer->SetColor(255, 0, 0, 255);
|
||||
app->renderer->DrawSprite(ascii->GetSprite(3), i * 12, 0);
|
||||
}
|
||||
}
|
||||
if (paused) {
|
||||
app->renderer->SetColor(255, 0, 0, 255);
|
||||
app->renderer->DrawSprite(ascii->GetSprite(219), 12 * 0, 0);
|
||||
app->renderer->DrawSprite(ascii->GetSprite(219), 12 * 1, 0);
|
||||
app->renderer->DrawSprite(ascii->GetSprite(219), 12 * 2, 0);
|
||||
app->renderer->DrawSprite(ascii->GetSprite(219), 12 * 3, 0);
|
||||
app->renderer->DrawSprite(ascii->GetSprite(219), 12 * 4, 0);
|
||||
app->renderer->DrawSprite(ascii->GetSprite(219), 12 * 5, 0);
|
||||
app->renderer->DrawSprite(ascii->GetSprite(219), 12 * 6, 0);
|
||||
app->renderer->DrawSprite(ascii->GetSprite(219), 12 * 7, 0);
|
||||
app->renderer->SetColor(0, 0, 0, 255);
|
||||
app->renderer->DrawSprite(ascii->GetSprite('-'), 12 * 0, 0);
|
||||
app->renderer->DrawSprite(ascii->GetSprite('P'), 12 * 1, 0);
|
||||
app->renderer->DrawSprite(ascii->GetSprite('A'), 12 * 2, 0);
|
||||
app->renderer->DrawSprite(ascii->GetSprite('U'), 12 * 3, 0);
|
||||
app->renderer->DrawSprite(ascii->GetSprite('S'), 12 * 4, 0);
|
||||
app->renderer->DrawSprite(ascii->GetSprite('E'), 12 * 5, 0);
|
||||
app->renderer->DrawSprite(ascii->GetSprite('D'), 12 * 6, 0);
|
||||
app->renderer->DrawSprite(ascii->GetSprite('-'), 12 * 7, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void PlayState::quit() {
|
||||
|
||||
}
|
||||
|
||||
void PlayState::inputevent(InputEvent *event) {
|
||||
if (event->pressed) {
|
||||
switch (event->action) {
|
||||
case ACTION_TOGGLE_DEBUG: debug = !debug; break;
|
||||
case ACTION_ESCAPE_MENU: paused = !paused; break;
|
||||
case ACTION_RESET: new_game(); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PlayState::new_game() {
|
||||
paused = true;
|
||||
|
||||
if (tilemap != nullptr) {
|
||||
delete tilemap;
|
||||
tilemap = nullptr;
|
||||
hero = nullptr;
|
||||
}
|
||||
|
||||
if (hero != nullptr) {
|
||||
delete hero;
|
||||
hero = nullptr;
|
||||
}
|
||||
|
||||
SDL_LogVerbose(SDL_LOG_CATEGORY_SYSTEM, "Creating tilemap...\n");
|
||||
tilemap = new Tilemap(32, 32);
|
||||
int y = 0;
|
||||
int x = 0;
|
||||
for (int i = 0; i < map.length(); i++) {
|
||||
|
||||
if (y >= 32) {
|
||||
break;
|
||||
}
|
||||
if (x >= mapwidth) {
|
||||
y++;
|
||||
x = 0;
|
||||
}
|
||||
if (map[i] == ' ' || map[i] == '\t' || map[i] == '\n') {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (map[i] == '@') {
|
||||
hero = new Hero(tilemap, vec2i(x, y));
|
||||
tilemap->AddActor(hero);
|
||||
tilemap->SetTile(x, y, '.');
|
||||
}
|
||||
else if (map[i] == 'g') {
|
||||
tilemap->AddActor(new Goblin(tilemap, vec2i(x, y)));
|
||||
tilemap->SetTile(x, y, '.');
|
||||
}
|
||||
else if (map[i] == 's') {
|
||||
tilemap->AddActor(new Shaman(tilemap, vec2i(x, y)));
|
||||
tilemap->SetTile(x, y, '.');
|
||||
}
|
||||
else {
|
||||
tilemap->SetTile(x, y, map[i]);
|
||||
}
|
||||
x++;
|
||||
}
|
||||
SDL_LogVerbose(SDL_LOG_CATEGORY_SYSTEM, "Done.\n");
|
||||
SDL_LogVerbose(SDL_LOG_CATEGORY_SYSTEM, "Calculating initial FOV...\n");
|
||||
hero->CalcFOV();
|
||||
SDL_LogVerbose(SDL_LOG_CATEGORY_SYSTEM, "Done.\n");
|
||||
}
|
35
src/PlayState.h
Normal file
35
src/PlayState.h
Normal file
|
@ -0,0 +1,35 @@
|
|||
//
|
||||
// Created by Adrian on 2017-09-21.
|
||||
//
|
||||
|
||||
#ifndef DUNGEON_PLAYSTATE_H
|
||||
#define DUNGEON_PLAYSTATE_H
|
||||
|
||||
|
||||
#include "Gamestate.h"
|
||||
|
||||
class Tileset;
|
||||
class Tilemap;
|
||||
class Actor;
|
||||
|
||||
class PlayState : public Gamestate {
|
||||
Tileset* ascii;
|
||||
Tilemap* tilemap;
|
||||
Actor * hero;
|
||||
|
||||
float delay = .5;
|
||||
double timer;
|
||||
|
||||
bool paused;
|
||||
bool debug;
|
||||
public:
|
||||
void new_game();
|
||||
void load() override;
|
||||
Gamestate* update(double delta) override;
|
||||
void draw(double delta) override;
|
||||
void quit() override;
|
||||
void inputevent(InputEvent* event) override;
|
||||
};
|
||||
|
||||
|
||||
#endif //DUNGEON_PLAYSTATE_H
|
Loading…
Reference in a new issue