[Mys-venture-commits] SF.net SVN: mys-venture:[79] trunk
Status: Inactive
Brought to you by:
kimmovii
From: <kim...@us...> - 2010-07-29 09:36:21
|
Revision: 79 http://mys-venture.svn.sourceforge.net/mys-venture/?rev=79&view=rev Author: kimmovii Date: 2010-07-29 09:36:14 +0000 (Thu, 29 Jul 2010) Log Message: ----------- Implemented GameMap. Untested. Modified Paths: -------------- trunk/design/game/technical_design.odt trunk/mysventure/include/util/position.h trunk/mysventure/mys-venture.pro trunk/mysventure/source/sub_level/maplayer.cpp Added Paths: ----------- trunk/mysventure/include/sub_level/gamemap.h trunk/mysventure/source/sub_level/gamemap.cpp Modified: trunk/design/game/technical_design.odt =================================================================== (Binary files differ) Added: trunk/mysventure/include/sub_level/gamemap.h =================================================================== --- trunk/mysventure/include/sub_level/gamemap.h (rev 0) +++ trunk/mysventure/include/sub_level/gamemap.h 2010-07-29 09:36:14 UTC (rev 79) @@ -0,0 +1,208 @@ +/* + Mys-venture is a 2D tile-based puzzle game. + Copyright (C) 2010 Kimmo Viitanen + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +/*! \file +Declaration for class GameMap. +*/ + +/*! \todo +The trigger-messages as "specified" by the design +are not implemented yet. +*/ + +#ifndef GAMEMAP_H +#define GAMEMAP_H + +#include <QMap> +#include <QString> + +#include "sub_level/maplayer.h" +#include "util/identification.h" +#include "util/Position.h" + +namespace Sub_GameLevel +{ + + /*! \brief + GameMap represents a single map in the game. + */ + /*! + GameMaps are composed of MapLayers. A map can be initialized on + construction by providing the number of rows, columns and + initial map data. Alternatively, an empty map can be constructed + and modified using resize() and addLayer(). + */ + class GameMap + { + public: + + /*! \brief + Default constructor can be used to initialize the map. + */ + GameMap(unsigned int rows = 0, unsigned int columns = 0, + const QVector<Sub_GameLevel::MapLayer>& mapData = + QVector<Sub_GameLevel::MapLayer>()); + + /*! \brief + Returns the map start message. + */ + QString getStartMessage() const; + + /*! \brief + Sets the map start message. + */ + void setStartMessage(const QString& message); + + /*! \brief + Returns the map end message. + */ + QString getEndMessage() const; + + /*! \brief + Sets the map end message. + */ + void setEndMessage(const QString& message); + + /*! \brief + Returns the map objective message. + */ + QString getObjectiveMessage() const; + + /*! \brief + Sets the map objective message. + */ + void setObjectiveMessage(const QString& message); + + /*! \brief + Adds a layer to the map. + */ + void addLayer(const MapLayer& layer); + + /*! \brief + Removes the layer with layer number layerNumber. + */ + void removeLayer(unsigned int layerNumber); + + /*! \brief + Returns true if the map has a layer with layer number layerNumber. + */ + bool hasLayer(unsigned int layerNumber) const; + + /*! \brief + Returns the size of a column on the map. + */ + unsigned int getColumnSize() const; + + /*! \brief + Returns number of rows on map. Same as column size. + */ + unsigned int getNumberOfRows() const; + + /*! \brief + Returns the size of a row on map. + */ + unsigned int getRowSize() const; + + /*! \brief + Returns the number of columns on map. Same as row size. + */ + unsigned int getNumberOfColumns() const; + + /*! \brief + Resizes the map to rows x columns size. + */ + void resize(unsigned int rows, unsigned int columns); + + /*! \brief + Returns the entity at the given position. + */ + Sub_GameUtility::Identification + getEntity(const Sub_GameUtility::Position& position) const; + + /*! \brief + Returns the entities at position (row, column) from all layers + as a QVector. + */ + QVector<Sub_GameUtility::Identification> + getEntities(unsigned int row, unsigned int column) const; + + /*! + Changes the entity at position to entity. + */ + void setEntity(const Sub_GameUtility::Position& position, + const Sub_GameUtility::Identification& entity); + + /*! \brief + Returns true if position is inside the map boundaries. + */ + bool isInMap(const Sub_GameUtility::Position& position) const; + + /*! \brief + Returns true if the given position is inside the map. + */ + bool isInMap(unsigned int row, unsigned int column) const; + + private: + + /*! + The message meant to be shown to the player when entering + the map. + */ + QString m_startMessage; + + /*! + The message meant to be shown to the player when exiting + the map. + */ + QString m_endMessage; + + /*! + The objective of the map. Basically, why is the player on this + map to begin with. + + This is shown in a place where the player can access it at anytime. + */ + QString m_mapObjective; + + /*! + The layers that make up the map. + */ + QMap<unsigned int, MapLayer> m_layers; + + /*! + The size of a map column. + */ + unsigned int m_columnSize; + + /*! + The size of a map row. + */ + unsigned int m_rowSize; + + + + /*! \brief + Holds the class invariant. + */ + void invariant() const; + + }; + +} // namespace Sub_GameLevel + +#endif // GAMEMAP_H Modified: trunk/mysventure/include/util/position.h =================================================================== --- trunk/mysventure/include/util/position.h 2010-07-28 13:17:23 UTC (rev 78) +++ trunk/mysventure/include/util/position.h 2010-07-29 09:36:14 UTC (rev 79) @@ -58,6 +58,11 @@ unsigned int getLayer() const { return m_layer; } + unsigned int getRowPosition() const { return m_y; } + + unsigned int getColumnPosition() const { return m_x; } + + private: Modified: trunk/mysventure/mys-venture.pro =================================================================== --- trunk/mysventure/mys-venture.pro 2010-07-28 13:17:23 UTC (rev 78) +++ trunk/mysventure/mys-venture.pro 2010-07-29 09:36:14 UTC (rev 79) @@ -25,7 +25,8 @@ source/sub_entity/basegameentitymaker.cpp \ source/sub_entity/entitymanager.cpp \ source/sub_level/mapcolumn.cpp \ - source/sub_level/maplayer.cpp + source/sub_level/maplayer.cpp \ + source/sub_level/gamemap.cpp HEADERS += include/sub_view/mainwindow.h \ include/util/Position.h \ include/util/identification.h \ @@ -53,7 +54,8 @@ include/util/util_functions.h \ include/sub_entity/entitymanager.h \ include/sub_level/mapcolumn.h \ - include/sub_level/maplayer.h + include/sub_level/maplayer.h \ + include/sub_level/gamemap.h FORMS += source/sub_view/mainwindow.ui \ source/sub_view/mapview.ui LIBS += -Llib \ Added: trunk/mysventure/source/sub_level/gamemap.cpp =================================================================== --- trunk/mysventure/source/sub_level/gamemap.cpp (rev 0) +++ trunk/mysventure/source/sub_level/gamemap.cpp 2010-07-29 09:36:14 UTC (rev 79) @@ -0,0 +1,341 @@ +/* + Mys-venture is a 2D tile-based puzzle game. + Copyright (C) 2010 Kimmo Viitanen + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +/*! \file +Implementation for class GameMap. +*/ + +#include "sub_level/gamemap.h" + +using namespace Sub_GameLevel; +using namespace Sub_GameUtility; + + + +/*! +The constructor copies the map data from mapData +and resizes the map to the size passed as arguments. +*/ +Sub_GameLevel +::GameMap::GameMap(unsigned int rows, + unsigned int columns, + const QVector<Sub_GameLevel::MapLayer> &mapData) +: m_columnSize(rows), m_rowSize(columns) +{ + // Copy the layers from mapData to m_layers. + for (int i = 0; i < mapData.size(); ++i) + { + m_layers.insert(mapData.at(i).getLayerNumber(), + mapData.at(i)); + } + + resize(m_columnSize, m_rowSize); + invariant(); +} + + + +QString +Sub_GameLevel +::GameMap::getStartMessage() const +{ + return m_startMessage; +} + + + +void +Sub_GameLevel +::GameMap::setStartMessage(const QString &message) +{ + m_startMessage = message; +} + + + +QString +Sub_GameLevel +::GameMap::getEndMessage() const +{ + return m_endMessage; +} + + + +void +Sub_GameLevel +::GameMap::setEndMessage(const QString &message) +{ + m_endMessage = message; +} + + + +QString +Sub_GameLevel +::GameMap::getObjectiveMessage() const +{ + return m_mapObjective; +} + + + +void +Sub_GameLevel +::GameMap::setObjectiveMessage(const QString &message) +{ + m_mapObjective = message; +} + + + +/*! +If the map already contains a layer with the same layer number +as the new layer, nothing is done. You must explicitly remove the +existing layer in this case. + +If no layer exists with the same layer number, then the new layer +is copied to map. +*/ +void +Sub_GameLevel +::GameMap::addLayer(const MapLayer &layer) +{ + invariant(); + + unsigned int layerNumber = layer.getLayerNumber(); + + // If a layer already exists, return + if (m_layers.contains(layerNumber)) + return; + + // Insert the layer + m_layers.insert(layerNumber, layer); + + Q_ASSERT(m_layers.contains(layerNumber)); + + // Resize the new layer to map size. + m_layers[layerNumber].resize(m_columnSize, m_rowSize); + + invariant(); +} + + + +/*! +Removes the layer with number layerNumber. +*/ +void +Sub_GameLevel +::GameMap::removeLayer(unsigned int layerNumber) +{ + m_layers.remove(layerNumber); + + Q_ASSERT(!(m_layers.contains(layerNumber))); + + invariant(); +} + + + +bool +Sub_GameLevel +::GameMap::hasLayer(unsigned int layerNumber) const +{ + return m_layers.contains(layerNumber); +} + + + +unsigned int +Sub_GameLevel +::GameMap::getColumnSize() const +{ + return m_columnSize; +} + + +unsigned int +Sub_GameLevel +::GameMap::getNumberOfRows() const +{ + return getColumnSize(); +} + + + +unsigned int +Sub_GameLevel +::GameMap::getRowSize() const +{ + return m_rowSize; +} + + + +unsigned int +Sub_GameLevel +::GameMap::getNumberOfColumns() const +{ + return getRowSize(); +} + + + +/*! +*/ +void +Sub_GameLevel +::GameMap::resize(unsigned int rows, unsigned int columns) +{ + // Resizing is performed by calling resize() for each layer. + // MapLayer and MapColumn have a resize() method that takes + // care of the actual resizing. + QMap<unsigned int, MapLayer>::iterator it; + for (it = m_layers.begin(); it != m_layers.end(); ++it) + { + (*it).resize(rows, columns); + + Q_ASSERT((*it).getColumnSize() == rows); + Q_ASSERT((*it).getRowSize() == columns); + } + + // Set new sizes + m_columnSize = rows; + m_rowSize = columns; + + invariant(); +} + + +/*! +If the position provided is not inside the map, an invalid ID +is returned. +*/ +Sub_GameUtility::Identification +Sub_GameLevel +::GameMap::getEntity(const Sub_GameUtility::Position &position) const +{ + // If the layer does not exist, return invalid. + if (!(m_layers.contains(position.getLayer()))) + return Sub_GameUtility::Identification::invalidId(); + + // If the position is not inside the map, return invalid. + if (!(isInMap(position))) + return Sub_GameUtility::Identification::invalidId(); + + return m_layers.value(position.getLayer()).getEntity(position.getYPosition(), + position.getXPosition()); +} + + + +/*! +If the position provided is not inside the map, +an empty vector is returned. +*/ +QVector<Sub_GameUtility::Identification> +Sub_GameLevel +::GameMap::getEntities(unsigned int row, unsigned int column) const +{ + QVector<Sub_GameUtility::Identification> result; + + // If not inside map, return empty vector. + if (!(isInMap(row, column))) + return result; + + QMap<unsigned int, MapLayer>::const_iterator it; + for (it = m_layers.constBegin(); it != m_layers.constEnd(); ++it) + { + result.push_back((*it).getEntity(row, column)); + } + + return result; +} + + + +void +Sub_GameLevel +::GameMap::setEntity(const Sub_GameUtility::Position &position, + const Sub_GameUtility::Identification &entity) +{ + // If position is not inside map, do nothing. + if (!isInMap(position)) + return; + + m_layers[position.getLayer()].setEntity(position.getRowPosition(), + position.getColumnPosition(), + entity); + + invariant(); +} + + +/*! +NOTE: This method also considers the layer information when +determining if the position is in the map. In other words, if the +map doesn't have the layer specified in position, false is returned. +*/ +bool +Sub_GameLevel +::GameMap::isInMap(const Position &position) const +{ + // If no such layer exists, position is outside map. + if (!(m_layers.contains(position.getLayer()))) + return false; + + // If layer exists, then only check if (row, column) + // is inside map. + return isInMap(position.getRowPosition(), + position.getColumnPosition()); +} + + + +/*! +NOTE: This method only considers the row and column dimensions +when determining if the position is on the map. +*/ +bool +Sub_GameLevel +::GameMap::isInMap(unsigned int row, unsigned int column) const +{ + if (row >= m_columnSize || + column >= m_rowSize) + return false; + + return true; +} + + +/*! +The invariant is each layer's row and column size must be +equal to the map's row and column size. +*/ +void +Sub_GameLevel +::GameMap::invariant() const +{ + QMap<unsigned int, MapLayer>::const_iterator it; + for (it = m_layers.constBegin(); it != m_layers.constEnd(); ++it) + { + Q_ASSERT(it.value().getColumnSize() == m_columnSize); + Q_ASSERT(it.value().getRowSize() == m_rowSize); + } +} Modified: trunk/mysventure/source/sub_level/maplayer.cpp =================================================================== --- trunk/mysventure/source/sub_level/maplayer.cpp 2010-07-28 13:17:23 UTC (rev 78) +++ trunk/mysventure/source/sub_level/maplayer.cpp 2010-07-29 09:36:14 UTC (rev 79) @@ -153,7 +153,13 @@ } +/*! +If the new size if greater than the current size, +default-constructed values (invalid IDs) are assigned to the emty space. +If the new size is smaller than the current size, +entities are simply cut from the end. +*/ void Sub_GameLevel ::MapLayer::resize(unsigned int rows, unsigned int columns) @@ -214,8 +220,10 @@ Sub_GameLevel ::MapLayer::fitToSmaller(unsigned int rows, unsigned int columns) { + // Resize the number of columns. m_layer.resize(columns); + // Resize each column. for (int i = 0; i < m_layer.size(); ++i) { m_layer[i].resize(rows); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |