Chris Hoy
Chris Hoy

Reputation: 7

Manipulating sfml Vertex Array

I am doing research on the sfml Vertex Array functions.Based on this tutorial I've been introduced to a basic implementation and am wanting to add to it. Unfortunately I am relatively new at OOP and would appreciate any help adding to this. The output generates a checkerboard like pattern using a sprite grid.

My goal is to connect the grid-floor tiles using a pathfinding algorithm(recursive bactracker) to generate a path.

the rest of this part is instantiated in the main.cpp:

//load the texture for our background vertex array
Texture textureBackground;
textureBackground.loadFromFile("graphics/background_sheet.png");

once in the game loop as:

                //pass the vertex array by reference to the createBackground function
            int tileSize = createBackground(background, arena);

and finally in the draw scene:

        window.draw(background, &textureBackground);

#include "stdafx.h"
#include <SFML/Graphics.hpp>
#include "zArena.h"

int createBackground(VertexArray& rVA, IntRect arena)
{
    // Anything we do to rVA we are actually doing to background (in the main function)

    // How big is each tile/texture
    const int TILE_SIZE = 50;
    const int TILE_TYPES = 3;
    const int VERTS_IN_QUAD = 4;

    int worldWidth = arena.width / TILE_SIZE;
    int worldHeight = arena.height / TILE_SIZE;

    // What type of primitive are we using?
    rVA.setPrimitiveType(Quads);

    // Set the size of the vertex array
    rVA.resize(worldWidth * worldHeight * VERTS_IN_QUAD);

    // Start at the beginning of the vertex array
    int currentVertex = 0;

    for (int w = 0; w < worldWidth; w++)
    {
        for (int h = 0; h < worldHeight; h++)
        {
            // Position each vertex in the current quad
            rVA[currentVertex + 0].position = Vector2f(w * TILE_SIZE, h * TILE_SIZE);
            rVA[currentVertex + 1].position = Vector2f((w * TILE_SIZE) + TILE_SIZE, h * TILE_SIZE);
            rVA[currentVertex + 2].position = Vector2f((w * TILE_SIZE) + TILE_SIZE, (h * TILE_SIZE) + TILE_SIZE);
            rVA[currentVertex + 3].position = Vector2f((w * TILE_SIZE), (h * TILE_SIZE) + TILE_SIZE);

            // Define the position in the Texture to draw for current quad
            // Either mud, stone, grass or wall
            //if (h == 0 || h == worldHeight - 1 || w == 0 || w == worldWidth - 1)
            if ((h % 2 !=0)&& (w % 2 != 0))
            {
                // Use the wall texture
                rVA[currentVertex + 0].texCoords = Vector2f(0, 0 + TILE_TYPES * TILE_SIZE);
                rVA[currentVertex + 1].texCoords = Vector2f(TILE_SIZE, 0 + TILE_TYPES * TILE_SIZE);
                rVA[currentVertex + 2].texCoords = Vector2f(TILE_SIZE, TILE_SIZE + TILE_TYPES * TILE_SIZE);
                rVA[currentVertex + 3].texCoords = Vector2f(0, TILE_SIZE + TILE_TYPES * TILE_SIZE);
            }
            else
            {

                // Use a random floor texture
                srand((int)time(0) + h * w - h);
                int mOrG = (rand() % TILE_TYPES);
                int verticalOffset = mOrG * TILE_SIZE;
                //int verticalOffset = 0;

                rVA[currentVertex + 0].texCoords = Vector2f(0, 0 + verticalOffset);
                rVA[currentVertex + 1].texCoords = Vector2f(TILE_SIZE, 0 + verticalOffset);
                rVA[currentVertex + 2].texCoords = Vector2f(TILE_SIZE, TILE_SIZE + verticalOffset);
                rVA[currentVertex + 3].texCoords = Vector2f(0, TILE_SIZE + verticalOffset);

            }

            // Position ready for the next for vertices
            currentVertex = currentVertex + VERTS_IN_QUAD;
        }
    }

    return TILE_SIZE;
}

Upvotes: 0

Views: 1238

Answers (1)

alseether
alseether

Reputation: 1993

As far as i see, there you're generating your tiles on the fly. If you want to create something like a walkable space, you should generate your tile map first, and then draw it based on the content generated.

Maybe overkilling your question, there are several ways to generate random maps satisfying specific constraints.

When you have the choice done, then you can simply draw as you do, but instead of

// Use a random floor texture
            srand((int)time(0) + h * w - h);
            int mOrG = (rand() % TILE_TYPES);
            int verticalOffset = mOrG * TILE_SIZE;

should have something like

// Select texture rect based on generated tilemap
            int mOrG = tilemap[w][h];    // Or tilemap[h * worldWidth + w] if you do it as unidimensional array
            int verticalOffset = mOrG * TILE_SIZE;

With this approach you must pass tilemap to your render method or, even better, create a TileMap class overriding draw() method

Upvotes: 0

Related Questions