#include <SFML/Graphics.hpp>
#include <vector>
int main(int argv, char** argc)
{
//Create the game window
sf::RenderWindow Game(sf::VideoMode(800, 600, 32), "Simple 5x5 tilemap");
//Create the event handler
sf::Event Event;
//Declare the size of the tile map
const int tileMapWidth = 5;
const int tileMapHeight = 5;
//Fill up the tile map with data (for sprites)
int map[tileMapWidth][tileMapHeight] =
{
1, 1, 1, 1, 1,
1, 0, 0, 0, 1,
1, 0, 0, 0, 1,
1, 0, 0, 0, 1,
1, 1, 1, 1, 1
};
//Choose the size of the tiles
int tileWidth = 64;
int tileHeight = 64;
//Load and store all the sprite images into a vector (0 = Grass, 1 = Dirt)
std::vector<sf::Sprite> tileTextures;
sf::Image image;
sf::Image image2;
sf::Sprite sprite;
if(!image.LoadFromFile("grass.jpg"))
return 1;
sprite.SetImage(image);
tileTextures.push_back(sprite);
if(!image2.LoadFromFile("dirt.jpg"))
return 1;
sprite.SetImage(image2);
tileTextures.push_back(sprite);
//Load the player sprite image and sets it staring location and movement speed
sf::Sprite player;
sf::Image playerImage;
if(!playerImage.LoadFromFile("player.png"))
return 1;
player.SetImage(playerImage);
int x = 128;
int y = 128;
int movement = 1;
//Main game loop
while(Game.IsOpened())
{
//Handle the events in the game
while(Game.GetEvent(Event))
{
//If the game is X'd out then close the game
if(Event.Type == sf::Event::Closed)
Game.Close();
}
//Exit the game if Escape is pressed
if(Game.GetInput().IsKeyDown(sf::Key::Escape))
Game.Close();
//Move the player around
if(Game.GetInput().IsKeyDown(sf::Key::W))
y -= movement;
if(Game.GetInput().IsKeyDown(sf::Key::S))
y += movement;
if(Game.GetInput().IsKeyDown(sf::Key::A))
x -= movement;
if(Game.GetInput().IsKeyDown(sf::Key::D))
x += movement;
player.SetPosition(sf::Vector2f(x, y));
//Clear the game screen and set it to cornflower blue
Game.Clear(sf::Color(100, 149, 236));
//Draw the tile map and scale down the sprites to 1/4 the original size
for(int x = 0; x < tileMapWidth; x++)
{
for(int y = 0; y < tileMapHeight; y++)
{
int textureIndex = map[y][x];
sf::Sprite texture = tileTextures[textureIndex];
texture.SetPosition(sf::Vector2f(x * tileWidth, y * tileHeight));
texture.SetScale(sf::Vector2f(0.25f, 0.25f));
Game.Draw(texture);
}
}
//Draw the player sprite
Game.Draw(player);
//Display the graphics to the game window
Game.Display();
}
return EXIT_SUCCESS;
}
Collision for a tilemap
Right now I know it is pretty basic only a 5x5 tile map in a 2D array with images stored into a vector, but I wanted to keep it small till I figure out how to determine collision between certain areas of the tilemap. For instance in my little example here I would like to collide with the dirt area and not be able to move into it, but maintain movement everywhere else. I am having a hard time coming up with a way to test for collision, anyone able to assist me on this little problem so I can move on to actual doing something with this? Any ideas/suggestions are appreciated and thanks in advance.
[Edited by - wicked357 on May 4, 2010 1:50:16 PM]
Okay since no one has come up with any ideas here, ill give one and see if it can be workable with this way to do a tile map.
I am not really sure how well this would work because it cannot be just a simple one object test, if you tested it on all the type of tiles in this case say textureIndex is 1 for the dirt, you would always have collision unless there are a lot of && in the arguments.
Here is an example how I was looking at using this...
Any kind of ideas are very welcome here and appreciated by any. I am not sure if I am even working in the right direction since this is my first tilemap program and I will be trying to check for collision.
bool checkCollision(sf::Sprite sprite1, sf::Sprite sprite2){ //Check rect collision of each sprite}
I am not really sure how well this would work because it cannot be just a simple one object test, if you tested it on all the type of tiles in this case say textureIndex is 1 for the dirt, you would always have collision unless there are a lot of && in the arguments.
Here is an example how I was looking at using this...
checkCollision(player, tileTextures[1]){ //Test all rects of collision //If no collision found return false}
Any kind of ideas are very welcome here and appreciated by any. I am not sure if I am even working in the right direction since this is my first tilemap program and I will be trying to check for collision.
You can store a seperate 2d array which contains collision data. Extremely quick example coming up.
Your tilemap:
The collision map:
Check the collision map for collisions
Your tilemap:
// each int refers to a tile sprite.// 0 = grass// 1 = dirt// 2 = water.... int map[tileMapWidth][tileMapHeight] = { 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1 };
The collision map:
// 0 = tile is passable// 1 = tile is impassable int collisionmap[tileMapWidth][tileMapHeight] = { 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1 };
Check the collision map for collisions
// player wants to move to tile 3,1if(collisionmap[3][1] == 1){// cannot move here}else{// can move here}
You could have your tile map refer to a list of TileType data - your current idea uses it for sprites, but what if it also contained information about collision?
Eg:
You could create an array or vector of these types, and then do a quick lookup do get the info you need.
eg: int TileType = tilemap[x][y];
if (tileTypes[TileType].Collidable == 1)
{
... etc
}
A downside of this is that you'll have to give all tiles of the same type the exact same properties. So to make secret walls you'd have you have a different TypeId and use the same graphics.
Alternatively, as stated before you could keep a separate map for collision types. This gives you the benefit of having special collision maps that exist outside of the graphics, but may be harder to manage.
Eg:
struct TileType{ int TileTypeId; bool Collidable; ... sprite info ... ... anything else ...};
You could create an array or vector of these types, and then do a quick lookup do get the info you need.
eg: int TileType = tilemap[x][y];
if (tileTypes[TileType].Collidable == 1)
{
... etc
}
A downside of this is that you'll have to give all tiles of the same type the exact same properties. So to make secret walls you'd have you have a different TypeId and use the same graphics.
Alternatively, as stated before you could keep a separate map for collision types. This gives you the benefit of having special collision maps that exist outside of the graphics, but may be harder to manage.
Okay at either, firstly it would seem you could do the same thing with just map instead of having a collisionMap unless you wanted to have invisible walls than you would want to create a separate map for collision. Secondly, other seems a bit redundant when it comes to having a large map but would work fine on a simple little map as my example shows, but I plan on getting much larger. For collision I am thinking instead of stoping the movement from happening it would take x and store it in previous x and make x = previous x or same for y that way the movement can still happen but moving in that area would make you stay at the previous location, but could still move away, is that right?
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement