SFML Tilemap не отображается из файла .txt, как должно

#c #drawing #rendering #render #sfml

#c #рисование #рендеринг #визуализация #sfml

Вопрос:

Я пытаюсь создать игру Pacman. Пока у меня есть только призрак, который я могу перемещать с помощью клавиш со стрелками, и я хотел создать tilemap, но моя программа рисует ее иначе, чем в файле .txt, и я не знаю почему. Вот его изображение

Это мои файлы:

main.cpp

 #include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>
#include <SFML/System.hpp>
#include <iostream>
#include <fstream>
#include <cctype>
#include <string>

#include "tilemap.hpp"

int main()
{
    // WINDOW
    sf::RenderWindow appWindow( sf::VideoMode( 1280, 1024, 32 ), "Pacman" );
    appWindow.setVerticalSyncEnabled(true);

    // IMAGES
    sf::Texture spriteSheet;
    spriteSheet.loadFromFile( "spriteSheet.png" );
    sf::Image test;
    test.create(1280, 1024, sf::Color::Black);

    // SPRITES
    sf::Sprite ghostSprite;
    ghostSprite.setTexture( spriteSheet );
    ghostSprite.setTextureRect(sf::IntRect( 0, 0, 64, 64 ));
    ghostSprite.setOrigin( 32, 32 );
    ghostSprite.setPosition( 400, 300 );

    bool upPressed = false;
    bool leftPressed = false;
    bool rightPressed = false;
    bool downPressed = false;

    while( appWindow.isOpen() )
    {

        sf::Event event;
        while( appWindow.pollEvent( event ) )
        {
            if(( event.type == sf::Event::KeyPressed amp;amp; event.key.code == sf::Keyboard::Escape) || event.type == sf::Event::Closed )
            {
                appWindow.close();
            }
            if( event.type == sf::Event::KeyPressed amp;amp; event.key.code == sf::Keyboard::Up )
            {
                upPressed = true;
                leftPressed = false;
                rightPressed = false;
                downPressed = false;
            }
            if( event.type == sf::Event::KeyPressed amp;amp; event.key.code == sf::Keyboard::Left )
            {
                upPressed = false;
                leftPressed = true;
                rightPressed = false;
                downPressed = false;
            }
            if( event.type == sf::Event::KeyPressed amp;amp; event.key.code == sf::Keyboard::Right )
            {
                upPressed = false;
                leftPressed = false;
                rightPressed = true;
                downPressed = false;
            }
            if( event.type == sf::Event::KeyPressed amp;amp; event.key.code == sf::Keyboard::Down )
            {
                upPressed = false;
                leftPressed = false;
                rightPressed = false;
                downPressed = true;
            }

        }


        if( upPressed )
        {
            ghostSprite.move( 0, -6 );
            ghostSprite.setTextureRect(sf::IntRect( 132, 0, 64, 64 ));

        }
        if( downPressed )
        {
            ghostSprite.move( 0, 6 );
            ghostSprite.setTextureRect(sf::IntRect( 198, 0, 64, 64 ));
        }
        if( rightPressed )
        {
            ghostSprite.move( 6, 0 );
            ghostSprite.setTextureRect(sf::IntRect( 0, 0, 64, 64 ));
        }
        if( leftPressed )
        {
            ghostSprite.move( -6, 0 );
            ghostSprite.setTextureRect(sf::IntRect( 66, 0, 64, 64 ));
        }


        appWindow.clear( sf::Color::Black );
        appWindow.draw( ghostSprite );
        generateMap(appWindow);
        appWindow.display();

        sf::sleep(sf::microseconds(100));
    }
    return 0;
}
  

tilemap.cpp

 #include <SFML/Graphics.hpp>
#include <iostream>
#include <fstream>
#include <cctype>
#include <string>
#include "tilemap.hpp"

void generateMap(sf::RenderWindow amp;window)
{
    std::ifstream openfile("Map2.txt");

    sf::Texture tileTexture;
    sf::Sprite tiles;

    sf::Vector2i map[100][100];
    sf::Vector2i loadCounter = sf::Vector2i(0,0);

    if(openfile.is_open())
    {
        std::string tileLocation;
        tileLocation = "tile.png";
        tileTexture.loadFromFile(tileLocation);
        tiles.setTexture(tileTexture);

        while(!openfile.eof())
        {
            std::string str;
            openfile >> str;
            char x = str[0];
            char y = str[2];
            if(!isdigit(x) || !isdigit(y))
            {
                map[loadCounter.x][loadCounter.y] = sf::Vector2i(-1,-1);
            }
            else
            {
                map[loadCounter.x][loadCounter.y] = sf::Vector2i(x - '0', y - '0');
            }

            if(openfile.peek() == 'n')
            {
                loadCounter.x = 0;
                loadCounter.y  ;
            }
            else
            {
                loadCounter.x  ;
            }


            for(int i = 0; i < loadCounter.x; i  )
            {
                for(int j = 0; j < loadCounter.y; j  )
                {
                    if(map[i][j].x != -1 amp;amp; map[i][j].y != -1)
                    {
                        tiles.setPosition(i * 32, j * 32);

                    }
                }
            }
            window.draw(tiles);
        }
    }
}
  

и tilemap.hpp

 #pragma once
#include <SFML/Graphics.hpp>

void generateMap(sf::RenderWindow amp;window);
  

Я новичок в создании игр, поэтому я не удивлюсь, если что-то упущу.

Комментарии:

1. Вы должны изменять текстуру вашего pacman каждый раз, когда он меняет направление, а не каждый раз, когда он перемещается

Ответ №1:

Я начну с того, что дам вам совет, чтобы избежать подобных вещей:

             if( event.type == sf::Event::KeyPressed amp;amp; event.key.code == sf::Keyboard::Up )
        {
            upPressed = true;
            leftPressed = false;
            rightPressed = false;
            downPressed = false;
        }
  

Просто сохраните вашу переменную pressedKey в перечислении, которое принимает ВЛЕВО, ВПРАВО, ВВЕРХ и ВНИЗ, и измените его значение один раз для каждой нажатой клавиши
Теперь вот как прочитать ваш файл:

 std::string line;
int lineCount = 0;
while (getline(openfile, line)) {
lineCount  
    for(int column = 0; mapLength; column  )
        if (line[column] = '1')
            map[lineCount][column] = 1;
        else
            map[lineCount][column] = -1; 
}
  

И как должен выглядеть ваш файл:

 0011001100
0011001100
0000001100
0000001111
  

Кроме того, вы должны поместить все спрайты в вектор / массив и отображать их один за другим

Комментарии:

1. Мне удалось заставить его работать с вашим кодом после некоторых настроек. Вместо того, чтобы загружать мою карту в Vector2i или массив, я заставил ее рисовать мои плитки во время чтения моей карты .txt. Спасибо!

2. При первом использовании stackoverflow: P

3. Возможно, немного поздно говорить об этом, но если вы напрямую извлекаете файлы из файлов и нигде их не сохраняете, нет способа проверить, находится ли ваш PacMan в стене или нет … то же самое относится, если вы хотите перерисовать свой уровень в каждом кадре