#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 в стене или нет … то же самое относится, если вы хотите перерисовать свой уровень в каждом кадре