Compare commits

...

12 Commits

Author SHA1 Message Date
NaiJi ✨ d897781ca8 docs: Update README according to latest changes 2022-11-04 19:55:33 +04:00
NaiJi ✨ c1cd7e4e1b refactor: Move from Qt build system to CMake
- Get rid of ptr usings
- Rename project to cirno-puzzle
- Move resources from src/
2022-11-04 19:44:26 +04:00
oss 34f35f4ac0 Extend map parser; now it's available to add complex cells in triggers 2020-03-21 01:40:54 +03:00
oss b9d19661ac Add music resources 2020-03-20 01:00:08 +03:00
oss f8060438da Add audio, bug fix in map reader 2020-03-20 00:59:21 +03:00
NaiJi ✨ 6896cf037d Fix comments 2020-03-19 18:42:45 +03:00
NaiJi ✨ 56376641f2 Update binaries 2020-03-19 18:33:38 +03:00
NaiJi ✨ 118d3de73b Merge branch 'oss' into develop 2020-03-19 18:32:29 +03:00
NaiJi ✨ 9f32578bc7 Update with develop 2020-03-19 18:31:21 +03:00
NaiJi ✨ fefd6ddf49 Make everything work 2020-03-19 18:25:58 +03:00
NaiJi ✨ 0a226fa083 Separate scene rendering from Game class 2020-03-18 20:45:01 +03:00
NaiJi ✨ b0cb76d419 Fix framerate issue 2020-03-18 14:45:12 +03:00
26 changed files with 515 additions and 600 deletions

73
.gitignore vendored
View File

@ -1,74 +1,5 @@
# This file is used to ignore files which are generated
# ----------------------------------------------------------------------------
*~
*.autosave
*.a
*.core
*.moc
*.o
*.obj
*.orig
*.rej
*.so
*.so.*
*_pch.h.cpp
*_resource.rc
*.qm
.#*
*.*#
core
!core/
tags
.DS_Store
.directory
*.debug
Makefile*
*.prl
*.app
moc_*.cpp
ui_*.h
qrc_*.cpp
Thumbs.db
*.res
*.rc
/.qmake.cache
/.qmake.stash
# qtcreator generated files
*.pro.user*
# xemacs temporary files
*.flc
# Vim temporary files
.*.swp
# Visual Studio generated files
*.ib_pdb_index
*.idb
*.ilk
*.pdb
*.sln
*.suo
*.vcproj
*vcproj.*.*.user
*.ncb
*.sdf
*.opensdf
*.vcxproj
*vcxproj.*
# MinGW generated files
*.Debug
*.Release
# Python byte code
*.pyc
# Binaries
# --------
*.dll
*.exe
*.stash
build
*.user

20
CMakeLists.txt Normal file
View File

@ -0,0 +1,20 @@
cmake_minimum_required(VERSION 3.5)
project(cirno-puzzle LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Werror -Wextra -Wpedantic -g")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/build)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/build)
set(CMAKE_RESOURCE_DIRECTORY ${CMAKE_SOURCE_DIR}/resources)
include_directories(${CMAKE_SOURCE_DIR}/include)
file(GLOB_RECURSE SOURCES "src/*.cpp" "src/*.h" "include/*.h")
find_package(SFML REQUIRED graphics audio window system)
add_executable(cirno-puzzle ${SOURCES} ${HEADER_FILES} )
target_link_libraries(cirno-puzzle sfml-system sfml-audio sfml-graphics)
file(COPY "${CMAKE_RESOURCE_DIRECTORY}" DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})

View File

@ -1,12 +1,18 @@
# sfml-test
# cirno-puzzle
Just playing around with [sfml](https://www.sfml-dev.org/), since I have nothing better to do anyway.
### How to run on Linux: ###
- Make sure you moved the `/src/font` folder to your build destination.
- Run `./sfml-test` command from your build destination.
### How to build and run on Linux: ###
- Make sure you have SFML, cmake and any compiler supporting C++17 installed
- Clone the project and go to the cloned folder:
```
git clone https://dev.udongein.xyz/NaiJi/cirno-puzzle
cd cirno-puzzle/
```
- Now make it:
```
cmake CMakeLists.txt -B ./build
cd ./build
make
```
### How to build: ###
- Except any C++ compiler which supports C++17 and higher, you also need to have SFML installed and accessible.
- Build the project (my sources work with qmake)
- Move the `/src/font` folder into the folder of your build destination.

Binary file not shown.

View File

@ -1,10 +0,0 @@
size
7 7
map
2 2 2 2 2 2 2
2 0 0 0 0 0 2
2 0 0 1 0 0 2
2 0 0 1 1 0 2
2 1 1 2 2 2 2
2 0 0 0 0 0 2
2 2 2 2 2 2 2

View File

@ -1,123 +0,0 @@
Bitstream Vera Fonts Copyright
The fonts have a generous copyright, allowing derivative works (as
long as "Bitstream" or "Vera" are not in the names), and full
redistribution (so long as they are not *sold* by themselves). They
can be be bundled, redistributed and sold with any software.
The fonts are distributed under the following copyright:
Copyright
=========
Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream
Vera is a trademark of Bitstream, Inc.
Permission is hereby granted, free of charge, to any person obtaining
a copy of the fonts accompanying this license ("Fonts") and associated
documentation files (the "Font Software"), to reproduce and distribute
the Font Software, including without limitation the rights to use,
copy, merge, publish, distribute, and/or sell copies of the Font
Software, and to permit persons to whom the Font Software is furnished
to do so, subject to the following conditions:
The above copyright and trademark notices and this permission notice
shall be included in all copies of one or more of the Font Software
typefaces.
The Font Software may be modified, altered, or added to, and in
particular the designs of glyphs or characters in the Fonts may be
modified and additional glyphs or characters may be added to the
Fonts, only if the fonts are renamed to names not containing either
the words "Bitstream" or the word "Vera".
This License becomes null and void to the extent applicable to Fonts
or Font Software that has been modified and is distributed under the
"Bitstream Vera" names.
The Font Software may be sold as part of a larger software package but
no copy of one or more of the Font Software typefaces may be sold by
itself.
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL
BITSTREAM OR THE GNOME FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL,
OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT
SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.
Except as contained in this notice, the names of Gnome, the Gnome
Foundation, and Bitstream Inc., shall not be used in advertising or
otherwise to promote the sale, use or other dealings in this Font
Software without prior written authorization from the Gnome Foundation
or Bitstream Inc., respectively. For further information, contact:
fonts at gnome dot org.
Copyright FAQ
=============
1. I don't understand the resale restriction... What gives?
Bitstream is giving away these fonts, but wishes to ensure its
competitors can't just drop the fonts as is into a font sale system
and sell them as is. It seems fair that if Bitstream can't make money
from the Bitstream Vera fonts, their competitors should not be able to
do so either. You can sell the fonts as part of any software package,
however.
2. I want to package these fonts separately for distribution and
sale as part of a larger software package or system. Can I do so?
Yes. A RPM or Debian package is a "larger software package" to begin
with, and you aren't selling them independently by themselves.
See 1. above.
3. Are derivative works allowed?
Yes!
4. Can I change or add to the font(s)?
Yes, but you must change the name(s) of the font(s).
5. Under what terms are derivative works allowed?
You must change the name(s) of the fonts. This is to ensure the
quality of the fonts, both to protect Bitstream and Gnome. We want to
ensure that if an application has opened a font specifically of these
names, it gets what it expects (though of course, using fontconfig,
substitutions could still could have occurred during font
opening). You must include the Bitstream copyright. Additional
copyrights can be added, as per copyright law. Happy Font Hacking!
6. If I have improvements for Bitstream Vera, is it possible they might get
adopted in future versions?
Yes. The contract between the Gnome Foundation and Bitstream has
provisions for working with Bitstream to ensure quality additions to
the Bitstream Vera font family. Please contact us if you have such
additions. Note, that in general, we will want such additions for the
entire family, not just a single font, and that you'll have to keep
both Gnome and Jim Lyles, Vera's designer, happy! To make sense to add
glyphs to the font, they must be stylistically in keeping with Vera's
design. Vera cannot become a "ransom note" font. Jim Lyles will be
providing a document describing the design elements used in Vera, as a
guide and aid for people interested in contributing to Vera.
7. I want to sell a software package that uses these fonts: Can I do so?
Sure. Bundle the fonts with your software and sell your software
with the fonts. That is the intent of the copyright.
8. If applications have built the names "Bitstream Vera" into them,
can I override this somehow to use fonts of my choosing?
This depends on exact details of the software. Most open source
systems and software (e.g., Gnome, KDE, etc.) are now converting to
use fontconfig (see www.fontconfig.org) to handle font configuration,
selection and substitution; it has provisions for overriding font
names and subsituting alternatives. An example is provided by the
supplied local.conf file, which chooses the family Bitstream Vera for
"sans", "serif" and "monospace". Other software (e.g., the XFree86
core server) has other mechanisms for font substitution.

Binary file not shown.

Binary file not shown.

View File

@ -1,10 +0,0 @@
size
7 7
map
2 2 2 2 2 2 2
2 0 0 0 0 0 2
2 0 0 1 0 0 2
2 0 0 1 1 0 2
2 1 1 2 2 2 2
2 0 0 0 0 0 2
2 2 2 2 2 2 2

39
include/audio.h Normal file
View File

@ -0,0 +1,39 @@
#pragma once
#include <memory>
#include <array>
#include <string>
#include <SFML/Audio.hpp>
enum SOUND_TYPE {
FOOTSTEP_SOUND = 0,
N_SOUNDS
};
class Audio
{
private:
// Struct for small sounds, like shots, foot steps, etc.
// As we always need to store SoundBuffer in the same scope as Sound, it's better to make struct.
struct SoundEffect {
sf::SoundBuffer buffer;
sf::Sound sound;
};
std::array<std::unique_ptr<SoundEffect>, N_SOUNDS> array_sounds;
std::unique_ptr<sf::Music> background_music;
public:
Audio(const std::string &background_file_name, std::array<std::string, N_SOUNDS> &&sounds_paths);
bool setSound(const SOUND_TYPE &type, const std::string &sound_file_path);
void playSound(const SOUND_TYPE &type);
bool setBackground(const std::string &music_file_path);
void playBackground();
void stopBackground();
void pauseBackground();
void setBackgroundVolume(const float &volume);
};

View File

@ -1,5 +1,4 @@
#ifndef CELL_H
#define CELL_H
#pragma once
#include <memory>
#include <vector>
@ -39,10 +38,6 @@ class Hero;
class Level;
class Cell;
using HeroPtr = std::unique_ptr<Hero>;
using LevelPtr = std::unique_ptr<Level>;
using CellPtr = std::unique_ptr<Cell>;
///////////////////////////////////////
/// Represents interface for all level cells
@ -50,7 +45,7 @@ class Cell : public Entity
{
protected:
sf::Color cell_color;
coordinate height_shift;
coordinate height_shift;
public:
Cell(coordinate cell_row = 0,
@ -61,15 +56,15 @@ public:
sf::Color color() const noexcept;
/// "shift_by_y" indicates the height of current cell
/// Height is a shift of y coordinate on the scene, relatively to the ground (which is 0)
void setHeightShift(coordinate shift_by_y);
coordinate heightShift() const;
/// "shift_by_y" indicates the height of current cell
/// Height is a shift of y coordinate on the scene, relatively to the ground (which is 0)
void setHeightShift(coordinate shift_by_y);
coordinate heightShift() const;
/// Determine if Hero can move onto this cell or not
virtual bool onMovingTo(HeroPtr &hero, LevelPtr &level) = 0;
virtual bool onMovingTo(std::unique_ptr<Hero> &hero, std::unique_ptr<Level> &level) = 0;
virtual CellPtr clone() const = 0;
virtual std::unique_ptr<Cell> clone() const = 0;
};
///////////////////////////////////////
@ -84,9 +79,9 @@ public:
virtual ~PassableCell() override;
virtual bool onMovingTo(HeroPtr &hero, LevelPtr &level) override;
virtual bool onMovingTo(std::unique_ptr<Hero> &hero, std::unique_ptr<Level> &level) override;
virtual CellPtr clone() const override;
virtual std::unique_ptr<Cell> clone() const override;
};
///////////////////////////////////////
@ -101,9 +96,9 @@ public:
virtual ~WaterCell() override;
virtual bool onMovingTo(HeroPtr &hero, LevelPtr &level) override;
virtual bool onMovingTo(std::unique_ptr<Hero> &hero, std::unique_ptr<Level> &level) override;
virtual CellPtr clone() const override;
virtual std::unique_ptr<Cell> clone() const override;
};
///////////////////////////////////////
@ -118,9 +113,9 @@ public:
virtual ~WallCell() override;
virtual bool onMovingTo(HeroPtr &hero, LevelPtr &level) override;
virtual bool onMovingTo(std::unique_ptr<Hero> &hero, std::unique_ptr<Level> &level) override;
virtual CellPtr clone() const override;
virtual std::unique_ptr<Cell> clone() const override;
};
///////////////////////////////////////
@ -137,11 +132,14 @@ public:
int has_charges = 1,
const sf::Color &color = palette::Green);
/// Sets value of cell_charges to num_charges
void setCharges(const int &num_charges);
virtual ~ChargeCell() override;
virtual bool onMovingTo(HeroPtr &hero, LevelPtr &level) override;
virtual bool onMovingTo(std::unique_ptr<Hero> &hero, std::unique_ptr<Level> &level) override;
virtual CellPtr clone() const override;
virtual std::unique_ptr<Cell> clone() const override;
};
///////////////////////////////////////
@ -156,9 +154,9 @@ public:
virtual ~ExitCell() override;
virtual bool onMovingTo(HeroPtr &hero, LevelPtr &level) override;
virtual bool onMovingTo(std::unique_ptr<Hero> &hero, std::unique_ptr<Level> &level) override;
virtual CellPtr clone() const override;
virtual std::unique_ptr<Cell> clone() const override;
};
///////////////////////////////////////
@ -178,11 +176,12 @@ public:
virtual ~TeleportCell() override;
void setDestination(coordinate new_cell_row, coordinate new_cell_col);
/// Set the coordinates of this teleport destination
void setDestination(coordinate new_cell_row, coordinate new_cell_col);
virtual bool onMovingTo(HeroPtr &hero, LevelPtr &level) override;
virtual bool onMovingTo(std::unique_ptr<Hero> &hero, std::unique_ptr<Level> &level) override;
virtual CellPtr clone() const override;
virtual std::unique_ptr<Cell> clone() const override;
};
///////////////////////////////////////
@ -192,24 +191,19 @@ class TriggerCell final : public Cell
{
private:
// Vector of cells to place on map
std::vector<CellPtr> cells;
std::vector<std::unique_ptr<Cell>> vector_cells;
public:
// Vector of cell types you can cast in to
static const std::vector<CELL_TYPE> cells_to_cast;
TriggerCell(//std::vector<CellPtr> &&cells_to_change,
coordinate cell_row = 0,
TriggerCell(coordinate cell_row = 0,
coordinate cell_col = 0,
const sf::Color &color = palette::Pink);
virtual ~TriggerCell() override;
void addTarget(CellPtr &&cell);
/// Add a cell which has to be placed to map when the trigger gets activated
void addTarget(std::unique_ptr<Cell> &&cell);
virtual bool onMovingTo(HeroPtr &hero, LevelPtr &level) override;
virtual bool onMovingTo(std::unique_ptr<Hero> &hero, std::unique_ptr<Level> &level) override;
virtual CellPtr clone() const override;
virtual std::unique_ptr<Cell> clone() const override;
};
#endif // CELL_H

View File

@ -3,20 +3,22 @@
#include <memory>
#include <SFML/Graphics/RenderWindow.hpp>
#include <SFML/System/Time.hpp>
#include <SFML/Window.hpp>
#include "hero.h"
#include "level.h"
#include "audio.h"
#include "renderer.h"
/// The main class where all the process happens
class Game
{
private:
// Game entities
HeroPtr hero;
LevelPtr level;
std::unique_ptr<Hero> hero;
std::unique_ptr<Level> level;
std::unique_ptr<Audio> audio;
std::unique_ptr<Renderer> renderer; // wer is `using RendererPrt = ...` A?A?A?
int current_level;
@ -29,9 +31,6 @@ private:
/// Move player by pressed key
void onMoving(sf::Keyboard::Key &key);
/// Render game state
void renderMap();
/// Prepare map and hero for a game level
//void loadLevel(int level_index = 1);

View File

@ -1,13 +1,16 @@
#ifndef LEVEL_H
#define LEVEL_H
#include <memory>
#include <string>
#include <array>
#include <map>
#include <sstream>
#include "cell.h"
// Very desirable to create module for default values
const std::string default_map_file_name = "test_map";
const std::string default_file_path = "test_map";
/// Abstraction over 2D array to quickly get access to level cells
class Level
@ -15,7 +18,7 @@ class Level
private:
struct Map
{
using Row = std::vector<CellPtr>;
using Row = std::vector<std::unique_ptr<Cell>>;
using Matrix = std::vector<Row>;
enum class SECTION
@ -23,6 +26,7 @@ private:
SIZE,
MAP,
TELEPORT,
CHARGE,
TRIGGER,
NONE
};
@ -32,31 +36,34 @@ private:
{ "size", SECTION::SIZE },
{ "map", SECTION::MAP },
{ "teleport", SECTION::TELEPORT },
{ "charge", SECTION::CHARGE },
{ "trigger", SECTION::TRIGGER },
{ "", SECTION::NONE }
};
Matrix data;
size_t rows, cols;
std::array<CellPtr, N_CELLS> default_cells;
std::array<std::unique_ptr<Cell>, N_CELLS> default_cells;
void init(const std::string &map_file_name = default_map_file_name);
void init(const std::string &path = default_file_path);
/// Prepare prototypes of default cells
void prepareDefaultCells();
/// Map file section readers
// Map file section readers
void readMapSize(std::istringstream &sstr);
void readMapRow(std::istringstream &sstr);
void readTeleport(std::istringstream &sstr);
void readTrigger(std::istringstream &sstr);
void readCellSection(std::istringstream &sstr, const SECTION &section);
std::unique_ptr<TeleportCell> &&readTeleport(std::istringstream &sstr, std::unique_ptr<TeleportCell> &&cell);
std::unique_ptr<ChargeCell> &&readCharge(std::istringstream &sstr, std::unique_ptr<ChargeCell> &&cell);
std::unique_ptr<TriggerCell> &&readTrigger(std::istringstream &sstr, std::unique_ptr<TriggerCell> &&cell);
};
Map map;
sf::Color color_ground;
public:
Level(const std::string &map_file_name = default_map_file_name);
Level(const std::string &path = default_file_path);
/// Number of map rows
size_t rows() const;
@ -65,7 +72,7 @@ public:
size_t cols() const;
/// Get cell at position row, col
CellPtr &getCellAt(coordinate row, coordinate col);
std::unique_ptr<Cell> &getCellAt(coordinate row, coordinate col);
/// Place a bridge cell
void placeBridge(coordinate x, coordinate y);

47
include/renderer.h Normal file
View File

@ -0,0 +1,47 @@
#ifndef RENDERER_H
#define RENDERER_H
#include <SFML/Graphics/RectangleShape.hpp>
#include <SFML/Graphics/ConvexShape.hpp>
#include <SFML/Graphics/Text.hpp>
#include <SFML/Graphics/RenderWindow.hpp>
#include <SFML/Window.hpp>
#include <memory>
class Level;
class Cell;
class Hero;
/// Represents functionality to draw game level onto window
class Renderer
{
private:
float cell_width, cell_height, cell_deviation;
unsigned int window_size;
// Reset for each iteration of window pulling
float init_painter_x, init_painter_y;
float painter_x, painter_y;
float vertical_shift, horizontal_shift;
sf::Text text_charges;
sf::Font font;
sf::RectangleShape brush_background;
sf::ConvexShape brush_cell;
sf::ConvexShape brush_wall;
bool drawCell(const std::unique_ptr<Cell> &cell, sf::RenderWindow &main_window);
public:
explicit Renderer();
bool render(const std::unique_ptr<Level> &level, const std::unique_ptr<Hero> &hero, sf::RenderWindow &main_window);
unsigned int windowSize() const;
};
#endif // RENDERER_H

81
src/audio.cpp Normal file
View File

@ -0,0 +1,81 @@
#include "audio.h"
Audio::Audio(const std::string &background_path, std::array<std::string, N_SOUNDS> &&sounds_paths)
{
std::unique_ptr<sf::Music> music = std::make_unique<sf::Music>();
if (music->openFromFile(background_path))
music->setLoop(true);
else
music = nullptr;
background_music = std::move(music);
std::unique_ptr<SoundEffect> effect;
for (int i = 0; i < N_SOUNDS; ++i)
{
effect = std::make_unique<SoundEffect>();
if (effect->buffer.loadFromFile(sounds_paths[i]))
{
effect->sound.setBuffer(effect->buffer);
array_sounds[i] = std::move(effect);
}
else
{
array_sounds[i] = nullptr;
}
}
}
bool Audio::setSound(const SOUND_TYPE &type, const std::string &sound_file_path)
{
std::unique_ptr<SoundEffect> effect = std::make_unique<SoundEffect>();
if (!effect->buffer.loadFromFile(sound_file_path))
return false;
effect->sound.setBuffer(effect->buffer);
array_sounds[type] = std::move(effect);
return true;
}
void Audio::playSound(const SOUND_TYPE &type)
{
if (array_sounds[type])
array_sounds[type]->sound.play();
}
bool Audio::setBackground(const std::string &music_file_path)
{
std::unique_ptr<sf::Music> music = std::make_unique<sf::Music>();
if (!music->openFromFile(music_file_path))
return false;
background_music = std::move(music);
return true;
}
void Audio::playBackground()
{
if (background_music)
background_music->play();
}
void Audio::stopBackground()
{
if (background_music)
background_music->stop();
}
void Audio::pauseBackground()
{
if (background_music)
background_music->pause();
}
void Audio::setBackgroundVolume(const float &volume)
{
if (background_music)
background_music->setVolume(volume);
}

View File

@ -38,7 +38,7 @@ PassableCell::PassableCell(coordinate cell_row, coordinate cell_col, const sf::C
PassableCell::~PassableCell()
{}
bool PassableCell::onMovingTo(HeroPtr &hero, LevelPtr &level)
bool PassableCell::onMovingTo(std::unique_ptr<Hero> &hero, std::unique_ptr<Level> &level)
{
UNUSED(hero), UNUSED(level);
@ -46,7 +46,7 @@ bool PassableCell::onMovingTo(HeroPtr &hero, LevelPtr &level)
return true;
}
CellPtr PassableCell::clone() const
std::unique_ptr<Cell> PassableCell::clone() const
{
return std::make_unique<PassableCell>();
}
@ -60,7 +60,7 @@ WaterCell::WaterCell(coordinate cell_row, coordinate cell_col, const sf::Color &
WaterCell::~WaterCell()
{}
bool WaterCell::onMovingTo(HeroPtr &hero, LevelPtr &level)
bool WaterCell::onMovingTo(std::unique_ptr<Hero> &hero, std::unique_ptr<Level> &level)
{
// Try to use one charge to place a bridge
if (hero->useCharge())
@ -69,7 +69,7 @@ bool WaterCell::onMovingTo(HeroPtr &hero, LevelPtr &level)
return false;
}
CellPtr WaterCell::clone() const
std::unique_ptr<Cell> WaterCell::clone() const
{
return std::make_unique<WaterCell>();
}
@ -86,7 +86,7 @@ WallCell::WallCell(coordinate cell_row, coordinate cell_col, const sf::Color &co
WallCell::~WallCell()
{}
bool WallCell::onMovingTo(HeroPtr &hero, LevelPtr &level)
bool WallCell::onMovingTo(std::unique_ptr<Hero> &hero, std::unique_ptr<Level> &level)
{
UNUSED(hero), UNUSED(level);
@ -94,7 +94,7 @@ bool WallCell::onMovingTo(HeroPtr &hero, LevelPtr &level)
return false;
}
CellPtr WallCell::clone() const
std::unique_ptr<Cell> WallCell::clone() const
{
return std::make_unique<WallCell>();
}
@ -111,7 +111,12 @@ ChargeCell::ChargeCell(coordinate cell_row, coordinate cell_col, int has_charges
ChargeCell::~ChargeCell()
{}
bool ChargeCell::onMovingTo(HeroPtr &hero, LevelPtr &level)
void ChargeCell::setCharges(const int &num_charges)
{
cell_charges = num_charges;
}
bool ChargeCell::onMovingTo(std::unique_ptr<Hero> &hero, std::unique_ptr<Level> &level)
{
// Hero picks up the charge; remove it from the map
hero->refillCharges(cell_charges);
@ -120,7 +125,7 @@ bool ChargeCell::onMovingTo(HeroPtr &hero, LevelPtr &level)
return true;
}
CellPtr ChargeCell::clone() const
std::unique_ptr<Cell> ChargeCell::clone() const
{
return std::make_unique<ChargeCell>();
}
@ -134,7 +139,7 @@ ExitCell::ExitCell(coordinate cell_row, coordinate cell_col, const sf::Color &co
ExitCell::~ExitCell()
{}
bool ExitCell::onMovingTo(HeroPtr &hero, LevelPtr &level)
bool ExitCell::onMovingTo(std::unique_ptr<Hero> &hero, std::unique_ptr<Level> &level)
{
UNUSED(level);
@ -143,7 +148,7 @@ bool ExitCell::onMovingTo(HeroPtr &hero, LevelPtr &level)
return true;
}
CellPtr ExitCell::clone() const
std::unique_ptr<Cell> ExitCell::clone() const
{
return std::make_unique<ExitCell>();
}
@ -159,7 +164,13 @@ TeleportCell::TeleportCell(coordinate cell_row, coordinate cell_col, coordinate
TeleportCell::~TeleportCell()
{}
bool TeleportCell::onMovingTo(HeroPtr &hero, LevelPtr &level)
void TeleportCell::setDestination(coordinate new_cell_row, coordinate new_cell_col)
{
new_row = new_cell_row;
new_col = new_cell_col;
}
bool TeleportCell::onMovingTo(std::unique_ptr<Hero> &hero, std::unique_ptr<Level> &level)
{
UNUSED(level);
@ -168,27 +179,16 @@ bool TeleportCell::onMovingTo(HeroPtr &hero, LevelPtr &level)
return true;
}
void TeleportCell::setDestination(coordinate new_cell_row, coordinate new_cell_col)
{
new_row = new_cell_row;
new_col = new_cell_col;
}
CellPtr TeleportCell::clone() const
std::unique_ptr<Cell> TeleportCell::clone() const
{
return std::make_unique<TeleportCell>();
}
///////////////////////////////////////
const std::vector<CELL_TYPE> TriggerCell::cells_to_cast { PASSABLE_CELL, WATER_CELL, WALL_CELL, EXIT_CELL };
TriggerCell::TriggerCell(/*std::vector<CellPtr> &&cells_to_change,*/ coordinate cell_row, coordinate cell_col, const sf::Color &color) :
TriggerCell::TriggerCell(coordinate cell_row, coordinate cell_col, const sf::Color &color) :
Cell(cell_row, cell_col, color)
{
//cells = std::move(cells_to_change);
// triggers are a bit higher than ground and water, but lower than walls
height_shift = 5;
}
@ -196,18 +196,17 @@ TriggerCell::TriggerCell(/*std::vector<CellPtr> &&cells_to_change,*/ coordinate
TriggerCell::~TriggerCell()
{}
void TriggerCell::addTarget(CellPtr &&cell)
void TriggerCell::addTarget(std::unique_ptr<Cell> &&cell)
{
UNUSED(cell);
//cells.emplace_back(cell);
vector_cells.emplace_back(std::move(cell));
}
bool TriggerCell::onMovingTo(HeroPtr &hero, LevelPtr &level)
bool TriggerCell::onMovingTo(std::unique_ptr<Hero> &hero, std::unique_ptr<Level> &level)
{
UNUSED(hero);
// We replace needed cells with the ones that the trigger provides.
for (CellPtr &cell : cells)
for (std::unique_ptr<Cell> &cell : vector_cells)
{
const coordinate &row = cell->row();
const coordinate &col = cell->col();
@ -216,11 +215,13 @@ bool TriggerCell::onMovingTo(HeroPtr &hero, LevelPtr &level)
level->getCellAt(row, col) = std::move(cell);
}
vector_cells.clear();
// It's an impassable object, so player can't move to here.
return false;
}
CellPtr TriggerCell::clone() const
std::unique_ptr<Cell> TriggerCell::clone() const
{
return std::make_unique<TriggerCell>();
}

View File

@ -1,123 +0,0 @@
Bitstream Vera Fonts Copyright
The fonts have a generous copyright, allowing derivative works (as
long as "Bitstream" or "Vera" are not in the names), and full
redistribution (so long as they are not *sold* by themselves). They
can be be bundled, redistributed and sold with any software.
The fonts are distributed under the following copyright:
Copyright
=========
Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream
Vera is a trademark of Bitstream, Inc.
Permission is hereby granted, free of charge, to any person obtaining
a copy of the fonts accompanying this license ("Fonts") and associated
documentation files (the "Font Software"), to reproduce and distribute
the Font Software, including without limitation the rights to use,
copy, merge, publish, distribute, and/or sell copies of the Font
Software, and to permit persons to whom the Font Software is furnished
to do so, subject to the following conditions:
The above copyright and trademark notices and this permission notice
shall be included in all copies of one or more of the Font Software
typefaces.
The Font Software may be modified, altered, or added to, and in
particular the designs of glyphs or characters in the Fonts may be
modified and additional glyphs or characters may be added to the
Fonts, only if the fonts are renamed to names not containing either
the words "Bitstream" or the word "Vera".
This License becomes null and void to the extent applicable to Fonts
or Font Software that has been modified and is distributed under the
"Bitstream Vera" names.
The Font Software may be sold as part of a larger software package but
no copy of one or more of the Font Software typefaces may be sold by
itself.
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL
BITSTREAM OR THE GNOME FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL,
OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT
SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.
Except as contained in this notice, the names of Gnome, the Gnome
Foundation, and Bitstream Inc., shall not be used in advertising or
otherwise to promote the sale, use or other dealings in this Font
Software without prior written authorization from the Gnome Foundation
or Bitstream Inc., respectively. For further information, contact:
fonts at gnome dot org.
Copyright FAQ
=============
1. I don't understand the resale restriction... What gives?
Bitstream is giving away these fonts, but wishes to ensure its
competitors can't just drop the fonts as is into a font sale system
and sell them as is. It seems fair that if Bitstream can't make money
from the Bitstream Vera fonts, their competitors should not be able to
do so either. You can sell the fonts as part of any software package,
however.
2. I want to package these fonts separately for distribution and
sale as part of a larger software package or system. Can I do so?
Yes. A RPM or Debian package is a "larger software package" to begin
with, and you aren't selling them independently by themselves.
See 1. above.
3. Are derivative works allowed?
Yes!
4. Can I change or add to the font(s)?
Yes, but you must change the name(s) of the font(s).
5. Under what terms are derivative works allowed?
You must change the name(s) of the fonts. This is to ensure the
quality of the fonts, both to protect Bitstream and Gnome. We want to
ensure that if an application has opened a font specifically of these
names, it gets what it expects (though of course, using fontconfig,
substitutions could still could have occurred during font
opening). You must include the Bitstream copyright. Additional
copyrights can be added, as per copyright law. Happy Font Hacking!
6. If I have improvements for Bitstream Vera, is it possible they might get
adopted in future versions?
Yes. The contract between the Gnome Foundation and Bitstream has
provisions for working with Bitstream to ensure quality additions to
the Bitstream Vera font family. Please contact us if you have such
additions. Note, that in general, we will want such additions for the
entire family, not just a single font, and that you'll have to keep
both Gnome and Jim Lyles, Vera's designer, happy! To make sense to add
glyphs to the font, they must be stylistically in keeping with Vera's
design. Vera cannot become a "ransom note" font. Jim Lyles will be
providing a document describing the design elements used in Vera, as a
guide and aid for people interested in contributing to Vera.
7. I want to sell a software package that uses these fonts: Can I do so?
Sure. Bundle the fonts with your software and sell your software
with the fonts. That is the intent of the copyright.
8. If applications have built the names "Bitstream Vera" into them,
can I override this somehow to use fonts of my choosing?
This depends on exact details of the software. Most open source
systems and software (e.g., Gnome, KDE, etc.) are now converting to
use fontconfig (see www.fontconfig.org) to handle font configuration,
selection and substitution; it has provisions for overriding font
names and subsituting alternatives. An example is provided by the
supplied local.conf file, which chooses the family Bitstream Vera for
"sans", "serif" and "monospace". Other software (e.g., the XFree86
core server) has other mechanisms for font substitution.

Binary file not shown.

View File

@ -1,15 +1,5 @@
#include "game.h"
#include <SFML/Graphics/RectangleShape.hpp>
#include <SFML/Graphics/ConvexShape.hpp>
#include <SFML/Graphics/Text.hpp>
constexpr int cell_width = 60;
constexpr int cell_height = 35;
constexpr int cell_deviation = 25;
constexpr int window_side = cell_width * 4;
Game::Game()
{
// Place the player with 10 initial charges onto x: 1, y: 1
@ -18,41 +8,51 @@ Game::Game()
// Generate level
level = std::make_unique<Level>();
main_window.create(sf::VideoMode(window_side * 3, window_side * 3), "SFML-Test Application", sf::Style::Default);
main_window.setActive();
audio = std::make_unique<Audio>("background_music.ogg", std::array<std::string, N_SOUNDS> { "footstep_sound.wav" });
level->getCellAt(0, 0)->setHeightShift(15);
level->getCellAt(0, 1)->setHeightShift(10);
// Prepare level renderer
renderer = std::make_unique<Renderer>();
main_window.create(sf::VideoMode(renderer->windowSize() * 3, renderer->windowSize() * 2), "SFML-Test Application", sf::Style::Default);
main_window.setActive();
main_window.setFramerateLimit(60);
current_level = 1;
//loadLevel(current_level);
audio->setBackgroundVolume(15.f);
}
int Game::run()
{
audio->playBackground();
// On the game loop
while (main_window.isOpen())
{
sf::Event event;
while (main_window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
main_window.close();
// Handling keyboard activity
if (event.type == sf::Event::KeyPressed)
switch (event.type)
{
// Move
case sf::Event::Closed:
main_window.close();
break;
case sf::Event::KeyPressed:
audio->playSound(FOOTSTEP_SOUND);
onMoving(event.key.code);
break;
default:
break;
}
}
// Draw level
renderMap();
renderer->render(level, hero, main_window);
main_window.display();
}
audio->stopBackground();
return EXIT_SUCCESS;
}
@ -110,95 +110,3 @@ void Game::onMoving(sf::Keyboard::Key &key)
if (!level->getCellAt(attempt_row, attempt_col)->onMovingTo(hero, level))
hero->setPosition(initial_row, initial_col);
}
void Game::renderMap()
{
float painter_x = 60, painter_y = 60;
float horizontal_shift = 0, vertical_shift = 0;
// Brush for cell sprites
sf::ConvexShape convex_brush;
convex_brush.setPointCount(4);
convex_brush.setPoint(0, sf::Vector2f(cell_deviation, 0.f));
convex_brush.setPoint(1, sf::Vector2f(cell_deviation + cell_width, 0.f));
convex_brush.setPoint(2, sf::Vector2f(cell_width, cell_height));
convex_brush.setPoint(3, sf::Vector2f(0.f, cell_height));
convex_brush.setFillColor(palette::Blue);
convex_brush.setOutlineThickness(0);
convex_brush.setPosition(painter_x, painter_y);
// Counter for available charges
sf::Text text;
sf::Font font;
font.loadFromFile("font/VeraMono.ttf");
text.setFont(font);
text.setFillColor(palette::White);
text.setCharacterSize(25);
text.setPosition(50, 350);
text.setString("Available bridge cells: " + std::to_string(hero->charges()));
// Where is hero
coordinate hero_row, hero_col;
hero->position(hero_row, hero_col);
// Draw map from 2D array
for (coordinate x = 0; x < level->cols(); ++x)
{
horizontal_shift = static_cast<float>(level->cols()) * cell_deviation;
for (coordinate y = 0; y < level->rows(); ++y)
{
vertical_shift = static_cast<float>(level->getCellAt(y, x)->heightShift());
// If cell has any height value, we should draw walls for it
if (vertical_shift > 0)
{
// Brush for vertical walls
sf::ConvexShape convex_wall_brush;
convex_wall_brush.setPointCount(6);
convex_wall_brush.setPoint(0, sf::Vector2f(cell_deviation + cell_width, -vertical_shift));
convex_wall_brush.setPoint(1, sf::Vector2f(cell_deviation + cell_width, 0.f));
convex_wall_brush.setPoint(2, sf::Vector2f(cell_width, cell_height));
convex_wall_brush.setPoint(3, sf::Vector2f(0.f, cell_height));
convex_wall_brush.setPoint(4, sf::Vector2f(0.f, cell_height - vertical_shift));
convex_wall_brush.setPoint(5, sf::Vector2f(cell_width, cell_height));
convex_wall_brush.setOutlineThickness(0);
sf::Color wall_color(sf::Uint8(level->getCellAt(y, x)->color().r - 40),
sf::Uint8(level->getCellAt(y, x)->color().g - 40),
sf::Uint8(level->getCellAt(y, x)->color().b - 40));
convex_wall_brush.setFillColor(wall_color);
convex_wall_brush.setPosition(painter_x + horizontal_shift, painter_y);
main_window.draw(convex_wall_brush);
}
// Draw the top surface of the cell itself
float final_x = painter_x + horizontal_shift;
float final_y = painter_y - vertical_shift;
convex_brush.setPosition(final_x, final_y);
convex_brush.setFillColor(level->getCellAt(y, x)->color());
main_window.draw(convex_brush);
if (hero_row == y && hero_col == x)
{
// Draw the hero sprite
convex_brush.setFillColor(palette::White);
main_window.draw(convex_brush);
}
// Move painter to next cell of current column
painter_y += cell_height;
horizontal_shift -= cell_deviation;
}
// Move painter to next column
painter_y = 60;
painter_x += cell_width;
}
main_window.draw(text);
}

View File

@ -1,8 +1,8 @@
#include "level.h"
#include <sstream>
#include <fstream>
#include <algorithm>
#include <iostream>
template<typename D, typename B> // [D]erived - [B]ase
std::unique_ptr<D> static_unique_pointer_cast(std::unique_ptr<B>&& old)
@ -10,12 +10,12 @@ std::unique_ptr<D> static_unique_pointer_cast(std::unique_ptr<B>&& old)
return std::unique_ptr<D>{static_cast<D *>(old.release())};
}
void Level::Map::init(const std::string &map_file_name)
void Level::Map::init(const std::string &path)
{
prepareDefaultCells();
std::ifstream file;
file.open(map_file_name);
file.open(path);
std::string cur_line;
std::istringstream sstr;
@ -28,6 +28,7 @@ void Level::Map::init(const std::string &map_file_name)
continue;
}
sstr.clear();
sstr.str(cur_line);
switch (cur_section)
{
@ -40,11 +41,9 @@ void Level::Map::init(const std::string &map_file_name)
break;
case SECTION::TELEPORT:
readTeleport(sstr);
break;
case SECTION::CHARGE:
case SECTION::TRIGGER:
readTrigger(sstr);
readCellSection(sstr, cur_section);
break;
default:
@ -74,45 +73,90 @@ void Level::Map::readMapSize(std::istringstream &sstr)
void Level::Map::readMapRow(std::istringstream &sstr)
{
data.push_back(Row());
for (int cell_type; sstr >> cell_type;)
data.emplace_back(Row());
int cell_type;
while (sstr >> cell_type)
{
data.back().push_back(default_cells[cell_type]->clone());
data.back().emplace_back(default_cells[cell_type]->clone());
data.back().back()->setPosition(data.size()-1, data.back().size()-1);
}
}
void Level::Map::readTeleport(std::istringstream &sstr)
void Level::Map::readCellSection(std::istringstream &sstr, const SECTION &section)
{
coordinate src_row, src_col;
coordinate dest_row, dest_col;
sstr >> src_row >> src_col;
sstr >> src_row >> src_col >> dest_row >> dest_col;
auto teleport_cell = static_unique_pointer_cast<TeleportCell>(std::move(data[src_row][src_col]));
teleport_cell->setDestination(dest_row, dest_col);
data[src_row][src_col] = std::move(teleport_cell);
switch (section) {
case SECTION::TELEPORT:
data[src_row][src_col] = readTeleport(sstr, static_unique_pointer_cast<TeleportCell>(std::move(data[src_row][src_col])));
break;
case SECTION::CHARGE:
data[src_row][src_col] = readCharge(sstr, static_unique_pointer_cast<ChargeCell>(std::move(data[src_row][src_col])));
break;
case SECTION::TRIGGER:
data[src_row][src_col] = readTrigger(sstr, static_unique_pointer_cast<TriggerCell>(std::move(data[src_row][src_col])));
break;
default:
break;
}
}
void Level::Map::readTrigger(std::istringstream &sstr)
std::unique_ptr<TeleportCell> &&Level::Map::readTeleport(std::istringstream &sstr, std::unique_ptr<TeleportCell> &&cell)
{
coordinate dest_row, dest_col;
sstr >> dest_row >> dest_col;
cell->setDestination(dest_row, dest_col);
return std::move(cell);
}
std::unique_ptr<ChargeCell> &&Level::Map::readCharge(std::istringstream &sstr, std::unique_ptr<ChargeCell> &&cell)
{
int num_charges;
sstr >> num_charges;
cell->setCharges(num_charges);
return std::move(cell);
}
std::unique_ptr<TriggerCell> &&Level::Map::readTrigger(std::istringstream &sstr, std::unique_ptr<TriggerCell> &&cell)
{
coordinate src_row, src_col;
coordinate dest_row, dest_col;
int cell_type;
sstr >> src_row >> src_col >> dest_row >> dest_col >> cell_type;
sstr >> dest_row >> dest_col >> cell_type;
if (std::find(TriggerCell::cells_to_cast.begin(), TriggerCell::cells_to_cast.end(), cell_type) ==
TriggerCell::cells_to_cast.end())
return ;
auto dest_cell = default_cells[cell_type]->clone();
dest_cell->setPosition(dest_row, dest_col);
auto trigger_cell = static_unique_pointer_cast<TriggerCell>(std::move(data[src_row][src_col]));
trigger_cell->addTarget(default_cells[cell_type]->clone());
data[src_row][src_col] = std::move(trigger_cell);
switch (cell_type) {
case TELEPORT_CELL:
dest_cell = readTeleport(sstr, static_unique_pointer_cast<TeleportCell>(std::move(dest_cell)));
break;
case CHARGE_CELL:
dest_cell = readCharge(sstr, static_unique_pointer_cast<ChargeCell>(std::move(dest_cell)));
break;
case TRIGGER_CELL:
dest_cell = readTrigger(sstr, static_unique_pointer_cast<TriggerCell>(std::move(dest_cell)));
break;
default:
break;
}
cell->addTarget(std::move(dest_cell));
return std::move(cell);
}
Level::Level(const std::string &map_file_name)
Level::Level(const std::string &path)
{
map.init(map_file_name);
map.init(path);
}
size_t Level::rows() const
@ -125,7 +169,7 @@ size_t Level::cols() const
return map.cols;
}
CellPtr &Level::getCellAt(coordinate row, coordinate col)
std::unique_ptr<Cell> &Level::getCellAt(coordinate row, coordinate col)
{
return map.data[row][col];
}

130
src/renderer.cpp Normal file
View File

@ -0,0 +1,130 @@
#include "renderer.h"
#include "level.h"
#include "hero.h"
constexpr unsigned int DEFAULT_CELL_WIDTH = 60;
constexpr unsigned int DEFAULT_CELL_HEIGHT = 35;
constexpr unsigned int DEFAULT_CELL_DEVIATION = 25;
constexpr unsigned int DEFAULT_WINDOW_SIDE = DEFAULT_CELL_WIDTH * 4;
Renderer::Renderer() :
cell_width(DEFAULT_CELL_WIDTH),
cell_height(DEFAULT_CELL_HEIGHT),
cell_deviation(DEFAULT_CELL_DEVIATION),
window_size(DEFAULT_WINDOW_SIDE),
init_painter_x(60),
init_painter_y(60),
vertical_shift(0),
horizontal_shift(0)
{
font.loadFromFile("resources/font/VeraMono.ttf");
text_charges.setFont(font);
text_charges.setFillColor(palette::White);
text_charges.setCharacterSize(25);
brush_background.setFillColor(palette::Black);
brush_background.setPosition(0.f, 0.f);
brush_cell.setPointCount(4);
brush_cell.setPoint(0, sf::Vector2f(cell_deviation, 0.f));
brush_cell.setPoint(1, sf::Vector2f(cell_deviation + cell_width, 0.f));
brush_cell.setPoint(2, sf::Vector2f(cell_width, cell_height));
brush_cell.setPoint(3, sf::Vector2f(0.f, cell_height));
brush_cell.setFillColor(palette::Blue);
brush_cell.setOutlineThickness(0);
brush_wall.setPointCount(6); // Points 0 and 4 should be calculated each iteration of rendering
brush_wall.setPoint(1, sf::Vector2f(cell_deviation + cell_width, 0.f));
brush_wall.setPoint(2, sf::Vector2f(cell_width, cell_height));
brush_wall.setPoint(3, sf::Vector2f(0.f, cell_height));
brush_wall.setPoint(5, sf::Vector2f(cell_width, cell_height));
brush_wall.setOutlineThickness(0);
}
bool Renderer::drawCell(const std::unique_ptr<Cell> &cell, sf::RenderWindow &main_window)
{
vertical_shift = static_cast<float>(cell->heightShift());
// If cell has any height value, we should draw walls for it
if (vertical_shift > 0)
{
brush_wall.setPoint(0, sf::Vector2f(cell_deviation + cell_width, -vertical_shift));
brush_wall.setPoint(4, sf::Vector2f(0.f, cell_height - vertical_shift));
sf::Color wall_color(sf::Uint8(cell->color().r - 40), sf::Uint8(cell->color().g - 40), sf::Uint8(cell->color().b - 40));
brush_wall.setFillColor(wall_color);
brush_wall.setPosition(painter_x + horizontal_shift, painter_y);
main_window.draw(brush_wall);
}
// Draw the top surface of the cell itself
float final_x = painter_x + horizontal_shift;
float final_y = painter_y - vertical_shift;
brush_cell.setPosition(final_x, final_y);
brush_cell.setFillColor(cell->color());
main_window.draw(brush_cell);
return true;
}
bool Renderer::render(const std::unique_ptr<Level> &level, const std::unique_ptr<Hero> &hero, sf::RenderWindow &main_window)
{
if (!hero || !level)
return false;
painter_x = init_painter_x;
painter_y = init_painter_y;
horizontal_shift = 0;
vertical_shift = 0;
brush_background.setSize({static_cast<float>(main_window.getSize().x), static_cast<float>(main_window.getSize().y)});
main_window.draw(brush_background);
brush_cell.setPosition(painter_x, painter_y);
// Where is hero
coordinate hero_row, hero_col;
hero->position(hero_row, hero_col);
// Draw map from 2D array
for (coordinate c = 0; c < level->cols(); ++c)
{
horizontal_shift = static_cast<float>(level->cols()) * cell_deviation;
for (coordinate r = 0; r < level->rows(); ++r)
{
drawCell(level->getCellAt(r, c), main_window);
if (hero_row == r && hero_col == c)
{
// Draw the hero sprite
brush_cell.setFillColor(palette::White);
main_window.draw(brush_cell);
}
// Move painter to next cell of current column
painter_y += cell_height;
horizontal_shift -= cell_deviation;
}
// Move painter to next column
painter_y = init_painter_y;
painter_x += cell_width;
}
text_charges.setPosition(50, 350);
text_charges.setString("Available charges left: " + std::to_string(hero->charges()));
main_window.draw(text_charges);
return true;
}
unsigned int Renderer::windowSize() const
{
return window_size;
}

View File

@ -1,26 +0,0 @@
TEMPLATE = app
CONFIG += c++17
CONFIG -= console app_bundle
CONFIG -= qt
QMAKE_CXXFLAGS = -Wall -Werror -Wextra -Wpedantic -Wconversion -std=c++17 -O0 -g
SOURCES += \
cell.cpp \
entity.cpp \
game.cpp \
hero.cpp \
level.cpp \
main.cpp
HEADERS += \
cell.h \
entity.h \
game.h \
hero.h \
level.h
# Only to highlight syntax when I am on Windows
win32:INCLUDEPATH += d:\SFML-2.5.1\include
LIBS += -lsfml-graphics -lsfml-window -lsfml-system