Skip to content

Commit

Permalink
episode 9 - the level class - part 3
Browse files Browse the repository at this point in the history
  • Loading branch information
mark committed Sep 28, 2015
1 parent 3d225dd commit c2ce873
Show file tree
Hide file tree
Showing 7 changed files with 254 additions and 16 deletions.
48 changes: 48 additions & 0 deletions notes/episode 9 - the level class - part 3.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
=====================================================
Remaking Cavestory in C++
Episode 9 - The level class - Part 3
By: Limeoats
Website: www.limeoats.com
Twitter: @Limeoats
Github: https://github.com/Limeoats/cavestory-development
Reddit: http://www.reddit.com/r/Limeoats
=====================================================


=====================================================
Problem
=====================================================
-Now that we have our map built, we need our program to read and understand it
-Before that, WE need to understand it



=====================================================
Details
=====================================================
-We'll parse XML with TinyXML library



=====================================================
Solution
=====================================================
-Add SDL_DestroyRenderer (thanks Symbiotic)
-Create Tile class
-Create Tileset struct (in level.h)
-Add new variables to Level class
-Include TinyXML in level.cpp and implement LoadMap



=====================================================
Next time
=====================================================
-Gravity!
-Collision!
-Jumping!
-Player spawn point




26 changes: 26 additions & 0 deletions source/headers/level.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,15 @@
#define LEVEL_H

#include <string>
#include <vector>

#include "globals.h"
#include "tile.h"

class Graphics;
struct SDL_Texture;
struct SDL_Rect;
struct Tileset;

class Level {
public:
Expand All @@ -19,14 +23,36 @@ class Level {
private:
std::string _mapName;
Vector2 _spawnPoint;

Vector2 _size;
Vector2 _tileSize;

SDL_Texture* _backgroundTexture;

std::vector<Tile> _tileList;
std::vector<Tileset> _tilesets;

/* void loadMap
* Loads a map
*/
void loadMap(std::string mapName, Graphics &graphics);

};

//Tileset structure
struct Tileset {
SDL_Texture* Texture;
int FirstGid;
Tileset() {
this->FirstGid = -1;
}
Tileset(SDL_Texture* texture, int firstGid) {
this->Texture = texture;
this->FirstGid = firstGid;
}
};




#endif
23 changes: 23 additions & 0 deletions source/headers/tile.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#ifndef TILE_H
#define TILE_H

#include "globals.h";

struct SDL_Texture;
class Graphics;

class Tile {
public:
Tile();
Tile(SDL_Texture* tileset, Vector2 size, Vector2 tilesetPosition, Vector2 position);
void update(int elapsedTime);
void draw(Graphics &graphics);
private:
SDL_Texture* _tileset;
Vector2 _size;
Vector2 _tilesetPosition;
Vector2 _position;
};


#endif
2 changes: 1 addition & 1 deletion source/src/game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ void Game::gameLoop() {
SDL_Event event;

this->_player = Player(graphics, 100, 100);
this->_level = Level("map 1", Vector2(100, 100), graphics);
this->_level = Level("Map 1", Vector2(100, 100), graphics);

int LAST_UPDATE_TIME = SDL_GetTicks();
//Start the game loop
Expand Down
1 change: 1 addition & 0 deletions source/src/graphics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ Graphics::Graphics() {

Graphics::~Graphics() {
SDL_DestroyWindow(this->_window);
SDL_DestroyRenderer(this->_renderer);
}

SDL_Surface* Graphics::loadImage(const std::string &filePath) {
Expand Down
147 changes: 132 additions & 15 deletions source/src/level.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,16 @@
#include "graphics.h"
#include "globals.h"

#include "tinyxml2.h"

#include <SDL2/SDL.h>

#include <sstream>
#include <algorithm>
#include <cmath>

using namespace tinyxml2;

Level::Level() {}

Level::Level(std::string mapName, Vector2 spawnPoint, Graphics &graphics) :
Expand All @@ -19,27 +27,136 @@ Level::~Level() {
}

void Level::loadMap(std::string mapName, Graphics &graphics) {
//TEMPORARY CODE TO LOAD THE BACKGROUND
this->_backgroundTexture = SDL_CreateTextureFromSurface(graphics.getRenderer(),
graphics.loadImage("content/backgrounds/bkBlue.png"));
this->_size = Vector2(1280, 960);
//Parse the .tmx file
XMLDocument doc;
std::stringstream ss;
ss << "maps/" << mapName << ".tmx"; //Pass in Map 1, we get maps/Map 1.tmx
doc.LoadFile(ss.str().c_str());

XMLElement* mapNode = doc.FirstChildElement("map");

//Get the width and the height of the whole map and store it in _size
int width, height;
mapNode->QueryIntAttribute("width", &width);
mapNode->QueryIntAttribute("height", &height);
this->_size = Vector2(width, height);

//Get the width and the height of the tiles and store it in _tileSize
int tileWidth, tileHeight;
mapNode->QueryIntAttribute("tilewidth", &tileWidth);
mapNode->QueryIntAttribute("tileheight", &tileHeight);
this->_tileSize = Vector2(tileWidth, tileHeight);

//Loading the tilesets
XMLElement* pTileset = mapNode->FirstChildElement("tileset");
if (pTileset != NULL) {
while (pTileset) {
int firstgid;
const char* source = pTileset->FirstChildElement("image")->Attribute("source");
char* path;
std::stringstream ss;
ss << source;
pTileset->QueryIntAttribute("firstgid", &firstgid);
SDL_Texture* tex = SDL_CreateTextureFromSurface(graphics.getRenderer(), graphics.loadImage(ss.str()));
this->_tilesets.push_back(Tileset(tex, firstgid));

pTileset = pTileset->NextSiblingElement("tileset");
}
}

//Loading the layers
XMLElement* pLayer = mapNode->FirstChildElement("layer");
if (pLayer != NULL) {
while (pLayer) {
//Loading the data element
XMLElement* pData = pLayer->FirstChildElement("data");
if (pData != NULL) {
while (pData) {
//Loading the tile element
XMLElement* pTile = pData->FirstChildElement("tile");
if (pTile != NULL) {
int tileCounter = 0;
while (pTile) {
//Build each individual tile here
//If gid is 0, no tile should be drawn. Continue loop
if (pTile->IntAttribute("gid") == 0) {
tileCounter++;
if (pTile->NextSiblingElement("tile")) {
pTile = pTile->NextSiblingElement("tile");
continue;
}
else {
break;
}
}

//Get the tileset for this specific gid
int gid = pTile->IntAttribute("gid");
Tileset tls;
for (int i = 0; i < this->_tilesets.size(); i++) {
if (this->_tilesets[i].FirstGid <= gid) {
//This is the tileset we want
tls = this->_tilesets.at(i);
break;
}
}

if (tls.FirstGid == -1) {
//No tileset was found for this gid
tileCounter++;
if (pTile->NextSiblingElement("tile")) {
pTile = pTile->NextSiblingElement("tile");
continue;
}
else {
break;
}
}

//Get the position of the tile in the level
int xx = 0;
int yy = 0;
xx = tileCounter % width;
xx *= tileWidth;
yy += tileHeight * (tileCounter / width);
Vector2 finalTilePosition = Vector2(xx, yy);

//Calculate the position of the tile in the tileset
int tilesetWidth, tilesetHeight;
SDL_QueryTexture(tls.Texture, NULL, NULL, &tilesetWidth, &tilesetHeight);
int tsxx = gid % (tilesetWidth / tileWidth) - 1;
tsxx *= tileWidth;
int tsyy = 0;
int amt = (gid / (tilesetWidth / tileWidth));
tsyy = tileHeight * amt;
Vector2 finalTilesetPosition = Vector2(tsxx, tsyy);

//Build the actual tile and add it to the level's tile list
Tile tile(tls.Texture, Vector2(tileWidth, tileHeight),
finalTilesetPosition, finalTilePosition);
this->_tileList.push_back(tile);
tileCounter++;

pTile = pTile->NextSiblingElement("tile");
}
}

pData = pData->NextSiblingElement("data");
}
}

pLayer = pLayer->NextSiblingElement("layer");
}
}

}

void Level::update(int elapsedTime) {

}

void Level::draw(Graphics &graphics) {
//Draw the background
SDL_Rect sourceRect = { 0, 0, 64, 64 };
SDL_Rect destRect;
for (int x = 0; x < this->_size.x / 64; x++) {
for (int y = 0; y < this->_size.y / 64; y++) {
destRect.x = x * 64 * globals::SPRITE_SCALE;
destRect.y = y * 64 * globals::SPRITE_SCALE;
destRect.w = 64 * globals::SPRITE_SCALE;
destRect.h = 64 * globals::SPRITE_SCALE;
graphics.blitSurface(this->_backgroundTexture, &sourceRect, &destRect);
}
for (int i = 0; i < this->_tileList.size(); i++) {
this->_tileList.at(i).draw(graphics);
}
}
23 changes: 23 additions & 0 deletions source/src/tile.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#include "tile.h"
#include "graphics.h"

#include <SDL2/SDL.h>

Tile::Tile() {}

Tile::Tile(SDL_Texture* tileset, Vector2 size, Vector2 tilesetPosition, Vector2 position) :
_tileset(tileset),
_size(size),
_tilesetPosition(tilesetPosition),
_position(Vector2(position.x * globals::SPRITE_SCALE, position.y * globals::SPRITE_SCALE))
{}

void Tile::update(int elapsedTime) {}

void Tile::draw(Graphics &graphics) {
SDL_Rect destRect = { this->_position.x, this->_position.y,
this->_size.x * globals::SPRITE_SCALE, this->_size.y * globals::SPRITE_SCALE };
SDL_Rect sourceRect = { this->_tilesetPosition.x, this->_tilesetPosition.y, this->_size.x, this->_size.y };

graphics.blitSurface(this->_tileset, &sourceRect, &destRect);
}

0 comments on commit c2ce873

Please sign in to comment.