1
Graphics / Code: how to scroll 1k+ tiles
« on: March 15, 2011, 09:14:56 pm »
This seems to pop up a lot, so I thought I'd share some code snippets to demonstrate how to code an off-screen tile cache to boost rendering performance.
This example is coded in a straight-forward manner, and has only the optimizations that it needs to get acceptable performance with large tile maps. In a production game, I would probably change the map array from a "vector of vector of ints" to use a "dynamic-yet-contiguous pointer-to-pointers-to-tiles" etc. etc.
Here is the header for a simple map class:
This example is coded in a straight-forward manner, and has only the optimizations that it needs to get acceptable performance with large tile maps. In a production game, I would probably change the map array from a "vector of vector of ints" to use a "dynamic-yet-contiguous pointer-to-pointers-to-tiles" etc. etc.
Here is the header for a simple map class:
Code: [Select]
#ifndef _MAP_H
#define _MAP_H
/*
Map data files have the following format:
<string filename>
<int number of tiles across the tilesheet>
<int cell width>
<int cell height>
<int map width>
<int map height>
<int map data, formatted as rows and columns seperated by spaces and newlines>
*/
#include <SFML/graphics.hpp>
#include <vector>
#include <string>
#include <fstream>
using namespace std;
class Map
{
private:
int rows, cols; //the # of rows and columns in the map array
sf::RenderWindow *App;
sf::RenderImage *buffer; //the off-screen scroll buffer
//int target_x, target_y; //where, in world coordinates, we want to center the screen on
float scroll_offset_x, scroll_offset_y; //where we have scrolled to in the world, upper-left corner in pixels
int buffer_scroll_offset_x, buffer_scroll_offset_y; //where we have scrolled to in the buffer, upper-left corner in pixels
int buffer_index_x, buffer_index_y; //where, in map indices, the row and cols of the offscreen buffer start
int buffer_rows, buffer_cols;//how big the buffer is
sf::Sprite *buffer_sprite; //the sprite we use to copy from off-screen to screen
sf::Sprite *buffer2buffer_sprite; //the sprite we use to copy from off-screen to off-screen
sf::Image *tilepic;
sf::Sprite *tilesheet;
float origin_x, origin_y; // pixel offsets of where to start drawing the map on the screen
int num_tiles_across_screen; //how many tiles to display across
int num_tiles_down_screen; //how many tiles to display down
vector<vector<int>> *map; //our 2D map array
int cell_width, cell_height; //dimensions of a single tile, in pixels
int num_tiles_across_tilesheet;//how many tiles are in a row on the tilesheet
void FillBuffer(int index_x, int index_y);
public:
void Scroll(float delta_x, float delta_y);
void SetScreen(float x, float y, int tiles_across, int tiles_down); //call before LoadMap
bool LoadMap(string fname);
bool SaveMap(string fname);
void DrawTile(int tile_num, int x, int y);
void DrawMap(void);
void FreeMem(void);
Map(sf::RenderWindow *the_App);
~Map(void);
};
#endif