Wyświetlanie pionków + prawie w pełni oprogramowana klasa planszy

This commit is contained in:
Bartłomiej Pluta
2016-05-18 16:19:52 +02:00
parent 751c90b6ea
commit 291111dda3
6 changed files with 172 additions and 21 deletions

View File

@@ -3,28 +3,30 @@
/* Plik zawiera implementację planszy(board) do gry w warcaby. */
#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
#include "pawn.hh"
class Board
{
private:
// Tablica pionków
// Pawn*** board
// Plansza (czyli dwuwymiarowa tablica wskaźników na pionki)
Pawn* board[TILES_COUNT][TILES_COUNT];
public:
// Konstruktor inicjujący planszę
Board() {}
Board();
// Utwórz nowy pionek na zadanej pozycji
Pawn& createPawn(Vector position);
Pawn* createPawn(Vector position, Color color);
// Pobierz pionek z określonej pozycji
Pawn& getPawn(Vector position);
Pawn* getPawn(Vector position);
// Przesuń pionek na określoną pozycję(target)
void setPawnPosition(Vector position, Vector target);
// Przesuń pionek o określony wektor
void movePawn(Vector position, Vector vector);
// Przesuń pionek na określoną pozycję
bool movePawn(Vector position, Vector target);
// Czy ruch jest możliwy (czy dana pozycja jest osiągalna)
bool isMovementPossible(Vector position, Vector target);
@@ -33,10 +35,10 @@ public:
Pawn deletePawn(Vector position);
// Rysuj planszę wraz z pionkami
void draw(sf::RenderWindow window);
void draw(sf::RenderWindow& window);
// Destruktor
~Board();
~Board() {}
};

View File

@@ -5,11 +5,26 @@
/* Plik zawiera definicje stałych globalnych oraz przedefiniowanie istniejących typów. */
// Ilość pól w każdym wymiarze
const int TILES_COUNT = 10;
// Długość boku pojedynczego kafelka(który jest kwadratem)
const int TILE_SIZE = 64;
// Odpowiednie przeskalowanie pionka, aby zachowany był margines względem krawędzi kafelka
const int PAWN_MARGIN = 5;
const int PAWN_MARGIN = 10;
// Grubość konturu zwykłego pionka
const int PAWN_OUTLINE_THICKNESS = 2;
// Grubość konturu pionka-królowej
const int QUEEN_PAWN_OUTLINE_THICKNESS = 4;
// Szerokość okna
const int WINDOW_WIDTH = TILES_COUNT * TILE_SIZE;
// Wysokość okna
const int WINDOW_HEIGHT = TILES_COUNT * TILE_SIZE;
// Przedefiniowanie sf::Vector2f na RealVector
typedef sf::Vector2f RealVector;

View File

@@ -23,17 +23,41 @@ private:
// Kolor pionka
Color color;
// Czy pionek jest zaznaczony
bool selected;
// Czy pionek jest królową
bool queen;
public:
// Konstruktor tworzący pionek na zadanej pozycji startowej i o określonym kolorze
Pawn(Vector _position, Color _color) : Object(_position), color(_color) {}
Pawn(Vector _position, Color _color) : Object(_position), color(_color), selected(false), queen(false) {}
// Pobierz kolor
Color getColor() const { return color; }
// Rysuj pionek na obiekcie window
void draw(sf::RenderWindow& window);
// Czy jest zaznaczony
bool isSelected() const { return selected; }
// Czy jest królową
bool isQueen() const { return queen; }
// Zaznacz pionek
void select() { selected = true; }
// Odznacz pionek
void deselect() { selected = false; }
// Zamień na królową
void upgrade() { queen = true; }
// Zamień spowrotem w zwykłego pionka
void downgrade() { queen = false; }
// Destruktor
~Pawn() {}
};

View File

@@ -1 +1,92 @@
#include "../inc/board.hh"
Board::Board()
{
// Czyścimy całą tablicę
for(int i=0; i<TILES_COUNT; ++i) for(int j=0; j<TILES_COUNT; ++j) board[i][j] = NULL;
// Tworzymy czarne pionki
for(int i=1; i<TILES_COUNT; i=i+2) createPawn(Vector(i, 0), CL_BLACK);
for(int i=0; i<TILES_COUNT; i=i+2) createPawn(Vector(i, 1), CL_BLACK);
for(int i=1; i<TILES_COUNT; i=i+2) createPawn(Vector(i, 2), CL_BLACK);
// Tworzymy białe pionki
for(int i=0; i<TILES_COUNT; i=i+2) createPawn(Vector(i, TILES_COUNT-1), CL_WHITE);
for(int i=1; i<TILES_COUNT; i=i+2) createPawn(Vector(i, TILES_COUNT-2), CL_WHITE);
for(int i=0; i<TILES_COUNT; i=i+2) createPawn(Vector(i, TILES_COUNT-3), CL_WHITE);
}
Pawn* Board::createPawn(Vector position, Color color)
{
// Jeżeli nie istnieje w tym miejscu pionek, to go tworzymy
if(!board[position.x][position.y])
board[position.x][position.y] = new Pawn(position, color);
// Zwracamy istniejący w tym miejscu pionek (dopiero co utworzony, lub isntiejący wcześniej)
return board[position.x][position.y];
}
Pawn* Board::getPawn(Vector position)
{
return board[position.x][position.y];
}
bool Board::movePawn(Vector position, Vector target)
{
// Jeżeli na pozycji startowej nie ma pionka
if(!getPawn(position)) return false;
// Jeżeli na pozycji docelowej jest pionek(miejsce zajęte)
if(getPawn(target)) return false;
// Przesuwamy pionek na planszy
board[target.x][target.y] = board[position.x][position.y];
board[position.x][position.y] = NULL;
// Aktualizujemy informację o pozycji w pionku
board[target.x][target.y]->setPosition(target);
// Zwracamy prawdę, że się udało
return true;
}
bool Board::isMovementPossible(Vector position, Vector target)
{
// TODO
return true;
}
Pawn Board::deletePawn(Vector position)
{
Pawn deleted_pawn = *board[position.x][position.y];
delete board[position.x][position.y];
board[position.x][position.y] = NULL;
return deleted_pawn;
}
void Board::draw(sf::RenderWindow& window)
{
// Wymiar X
for(int x=0; x<TILES_COUNT; ++x)
{
// Wymiar Y
for(int y=0; y<TILES_COUNT; ++y)
{
// Tworzymy pojedynczy kafelek o wymiarach TILE_SIZE x TILE_SIZE
sf::RectangleShape tile(sf::Vector2f(TILE_SIZE, TILE_SIZE));
// Ustawiamy pozycję na i*TILE_SIZE, j*TILE_SIZE -- czyli np. dla TILE_SIZE = 64: (0,0), (0,64), (0,128), ...
tile.setPosition(x*TILE_SIZE, y*TILE_SIZE);
// Ustawiamy kolor wypełnienia co drugiego kafelka na jasny
tile.setFillColor(((x+y)%2)?sf::Color(150, 74, 0):sf::Color(248, 246, 184));
// Rysujemy kafelki
window.draw(tile);
// Jeżeli istnieją na danym polu pionki, to je rysujemy
if(board[x][y]) board[x][y]->draw(window);
}
}
}

View File

@@ -5,13 +5,14 @@
#include "../inc/misc.hh"
#include "../inc/object.hh"
#include "../inc/pawn.hh"
#include "../inc/board.hh"
int main()
{
sf::ContextSettings settings;
settings.antialiasingLevel = 8;
sf::RenderWindow window(sf::VideoMode(800, 600, 32), "Warcaby", sf::Style::Default, settings);
Pawn pawn(Vector(0, 0), CL_BLACK);
sf::RenderWindow window(sf::VideoMode(WINDOW_WIDTH, WINDOW_HEIGHT, 32), "Warcaby", sf::Style::Close, settings);
Board board;
while(window.isOpen())
{
sf::Event event;
@@ -20,7 +21,7 @@ int main()
if(event.type == sf::Event::Closed) window.close();
}
window.clear(sf::Color(255, 255, 255));
pawn.draw(window);
board.draw(window);
window.display();
}
return 0;

View File

@@ -3,14 +3,32 @@
void Pawn::draw(sf::RenderWindow& window)
{
// Tworzymy nowy kształt koła o promieniu równym połowie długości boku kafelka i odjęciu dwóch marginesów
sf::CircleShape pawn(TILE_SIZE/2 - PAWN_MARGIN*2);
sf::CircleShape pawn(TILE_SIZE/2 - PAWN_MARGIN);
// Ustawiamy jego pozycję na pozycję zwróconą przez getPosition() uwzględniając marginesy
pawn.setPosition(getPosition().getRealVector() + sf::Vector2f(PAWN_MARGIN, PAWN_MARGIN));
// Wypełniamy odpowiednim kolorem
pawn.setFillColor((color==CL_WHITE)?sf::Color::White:sf::Color::Black);
// Jeżeli nie jest zaznaczony,
// wypełniamy odpowiednim kolorem w zależności od pionka(czy biały, czy czarny)
if(!selected)
pawn.setFillColor((color==CL_WHITE)?sf::Color(225, 223, 212):sf::Color(41, 0, 0));
// w przeciwnym razie wypełniamy nieco jaśniejszymi kolorami
else
pawn.setFillColor((color==CL_WHITE)?sf::Color(255, 255, 250):sf::Color(71, 30, 30));
// Ustawiamy odpowiedni kontur
if(!queen) // W zależności od pionka(czy biały, czy czarny)
{
pawn.setOutlineThickness(PAWN_OUTLINE_THICKNESS);
pawn.setOutlineColor((color==CL_WHITE)?sf::Color(133, 116, 38):sf::Color(10, 0, 0));
}
else // Dla królowej zawsze złoty
{
pawn.setOutlineThickness(QUEEN_PAWN_OUTLINE_THICKNESS);
pawn.setOutlineColor(sf::Color(255, 200, 0));
}
// Rysujemy na obiekcie window
window.draw(pawn);
}