2d map for an rpg

Started by
43 comments, last by Toadhead 12 years, 3 months ago
So what you are gonna do is load 4 files: text file, rock, grass, and bush. Now you're gonna create an array of 20 x 20 which holds images. You will also have an algorithm which does this:

  1. read character from text file
  2. if r add rock to array, if g add grass to array, if b add bush to array
  3. repeat 1 and 2, until you reach the end of the file
  4. then you will take that array and display all the images to the screen

The trick will be to position them properly on the screen.

Once you get to this point, I'd look for a Java 2D Game Library. It will make this endeavour much easier.

Beginner in Game Development?  Read here. And read here.

 

Advertisement
And please post all your code when you done. Thanks :)

Beginner in Game Development?  Read here. And read here.

 

How would you suggest adding the images to the array? I've never worked with multidimensional arrays before.
This is what I tried, but it doesn't seem to be working.


File tileTxt = new File("MapFile.txt");
try {
FileInputStream fis = new FileInputStream(tileTxt);
char current;
int collumn = 0;
int row = 0;
while (fis.available() > 0) {
System.out.println(fis.available());
current = (char) fis.read();
switch(current){
case 'g':
tiles[collumn][row] = grass;
System.out.println("G "+row+","+collumn);
break;
case 'r':
tiles[collumn][row] = rock;
break;
case 'b':
tiles[collumn][row] = bush;
break;
}
collumn++;
if(collumn > 19){
collumn = 0;
row++;
}
}



} catch (IOException e) {
e.printStackTrace();
}
this is how i load map for my tile based engine.
try it.


#pragma once
#include <SFML\Graphics.hpp>
#include <iostream>
#include <vector>
class Tiles
{
protected:
Tiles();
~Tiles();
void LoadTiles();
static short const GrassID = 1, StoneID = 2;
static short const TileX = 32, TileY = 32;
sf::Image GrassImage, StoneImage;
sf::Sprite GrassSprite, StoneSprite;
};



#include "Tiles.h"
Tiles::Tiles()
{
}
Tiles::~Tiles()
{
}
void Tiles::LoadTiles()
{
GrassImage.LoadFromFile("Data/Images/Tiles/grass.png");
StoneImage.LoadFromFile("Data/Images/Tiles/stone.png");
GrassImage.SetSmooth(false);
StoneImage.SetSmooth(false);
GrassSprite.SetImage(GrassImage);
StoneSprite.SetImage(StoneImage);
}



#pragma once
#include <SFML\Graphics.hpp>
#include <iostream>
#include <fstream>
#include <vector>
#include "Tiles.h"
class Map : Tiles
{
public:
Map();
~Map();
void Load();
void Draw(sf::RenderWindow &Window);
private:
static const short MapX = 25, MapY = 19; // MapX = ScreenX(800) / TileX(32) .... MapY = ScreenY(600) / TileY(32)
static const short MapOffsetY = 32;
short map[MapX][MapY];
};



#include "Map.h"
Map::Map()
{
}
Map::~Map()
{
}
void Map::Load()
{
LoadTiles();
std::ifstream ReadFile ("Data/Maps/DemoMap.Data");
if (ReadFile.is_open())
{
while (ReadFile.good())
{
for(int y = 0; y < MapY; y++)
{
for(int x = 0; x < MapX; x++)
{
ReadFile >> map[x][y];
}
}
ReadFile.close();
}
}
else
std::cout << "Unable to open file";
}
void Map::Draw(sf::RenderWindow &Window)
{
for(int x = 0; x < MapX; x++)
{
for(int y = 0; y < MapY; y++)
{
if(map[x][y] == GrassID)
{
GrassSprite.SetPosition((float)x * TileX, (float)y * TileY + MapOffsetY);
Window.Draw(GrassSprite);
}
if(map[x][y] == StoneID)
{
StoneSprite.SetPosition((float)x * TileX, (float)y * TileY + MapOffsetY);
Window.Draw(StoneSprite);
}
}
}
}


final here is my map.txt

1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 2 1 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 2 1 2 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 2 1 2 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 2 1 2 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 2 1 2 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 2 1 2 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 2 2 2 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 2 2 2 2 2 1 1 1 2 2 2 2 2 1 1 1 1 1
1 1 1 1 1 1 1 2 1 1 1 1 1 1 1 2 1 1 1 2 1 1 1 1 1
1 1 1 1 1 1 1 2 1 1 1 1 1 1 1 2 1 1 1 2 2 2 2 2 2
1 1 1 1 1 1 1 2 1 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1


this is the result
Stein, have you ever created a game before?
With all respect, but this is about the most basic stuff in writing an RPG. Perhaps it's better to start making Tetris first, followed by some platformers and puzzle games before you start with a project of this size.

I don't think you'd want each tile to be a "TileObject" - there would be performance and memory usage implications. You could achieve the same effect with the flyweight pattern though.


Hm kind of a hijack, but its still on topic:
Would the performance realy be so bad if the grid was like 20x20?
Perhaps I'm mistaken, but the flyweight pattern is like sharing one object for multiple purposes, containing some variables inside to store the differences. In this case each tile has it's own image, pointers to objects stored on it (players/enemies/animals/items whatever) and whether the tile can be accessed. This cannot easily be done using a flyweight pattern doesn't it?

....excellent code....

Great post, excellent answer. +1 for you.

Beginner in Game Development?  Read here. And read here.

 


[quote name='phil_t' timestamp='1326137764' post='4901035']
I don't think you'd want each tile to be a "TileObject" - there would be performance and memory usage implications. You could achieve the same effect with the flyweight pattern though.


Hm kind of a hijack, but its still on topic:
Would the performance realy be so bad if the grid was like 20x20?

[/quote]

That's probably fine.


Perhaps I'm mistaken, but the flyweight pattern is like sharing one object for multiple purposes, containing some variables inside to store the differences. In this case each tile has it's own image, pointers to objects stored on it (players/enemies/animals/items whatever) and whether the tile can be accessed. This cannot easily be done using a flyweight pattern doesn't it?


I was thinking more like a tile just a tiny descriptor (byte or int or something) that lets you reference additional information. For instance, if a tile is a grass tile, then you can look up static information what the image should be for a grass tile, whether an entity can move onto it, etc...

I guess it's not technically a flyweight pattern unless you make an object that, when given a tile descriptor, would expose information about a tile in a nice easy-to-consume manner. Regardless, the point is that the tile can contain just the minimal amount of information necessary that describes it.

For a 20 x 20 grid though, probably none of this really matters. Just do whatever is easiest/simplest.

Although for dynamic tile information, such as which entities items are on it at the current time, I would tend to favor keeping these in a separate list of entities where each entity stores the coordinates at which it is located. It reduces the micro-management you would need to do of tracking adding an entity to a tile while removing it from another. Of course it makes it more difficult/slower to answer the question "what entity is in this tile?", but given that there is generally a small number of entities compared to tiles, it's not a big deal to loop through them.
I'm going to upload my code now. I just can't seem to figure it out. I'm sure the solution is something so simple, I'm just missing it.

(I've added the images as well.)

This topic is closed to new replies.

Advertisement