SFML Pytanie o mape oraz podskakiwanie

0

Witam
Musze wykonac na projekt w C++ jakis program/ gre. Wpadlem na pomysl zrobienia runnera(biegnie postac z lewej do prawej i musimy podskakiwac w tempo). Lecz nie moge wyswietlic mojej postaci. Okienko wyswietla i nic. Oto kody z moich plikow.

main.cpp

#include "Game.h"

int main()
{
	Game game;
	game.GameStart();
	

	return EXIT_SUCCESS;
} 

Game.h

#include <SFML\Window.hpp>
#include <SFML\Graphics.hpp>
#include <SFML\Window\WindowStyle.hpp>


using namespace sf;

class Game
{
public:

	Game(void);
	
	void GameStart();
	RenderWindow window;
	Texture texture;
	Sprite sprite;

	void PlayerTexture();


private:
	Font font;
	
	
}; 

Game.cpp

#include "Game.h"

Game::Game(void)
{
	window.create(VideoMode(800, 600), "Runner");
}


void Game::PlayerTexture()
{
	
	
	if (!texture.loadFromFile("postac.png"))
	{

		sprite.setTexture(texture);
	}

	
	

	
}

void Game::GameStart()
{
	

	Game::PlayerTexture();
	while (window.isOpen())
	{

		sf::Event event;
		while (window.pollEvent(event))
		{
			window.draw(sprite);
			window.display();
			window.clear();


			if (event.type == sf::Event::Closed || Keyboard::isKeyPressed(Keyboard::Key::Escape))
				window.close();
		}
	}

	


}

 
1

Zamien

 
void Game::GameStart()
{
 
 
    Game::PlayerTexture();
    while (window.isOpen())
    {
 
        sf::Event event;
        while (window.pollEvent(event))
        {
            window.draw(sprite);
            window.display();
            window.clear();
 
 
            if (event.type == sf::Event::Closed || Keyboard::isKeyPressed(Keyboard::Key::Escape))
                window.close();
        }
    }
 

na

 
void Game::GameStart()
{
 
 
    Game::PlayerTexture();
    while (window.isOpen())
    {
 
        sf::Event event;
        while (window.pollEvent(event))
        {
        
            if (event.type == sf::Event::Closed || Keyboard::isKeyPressed(Keyboard::Key::Escape))
                window.close();
        }
    
  window.draw(sprite);
            window.display();
            window.clear();
}

Inaczej będzie ono rysowane tylko przy evencie.

1

Jeszcze jeden błąd

void Game::PlayerTexture()
{
 
 
    if (!texture.loadFromFile("postac.png"))
    {
 
        sprite.setTexture(texture);
    }
 
}

Musi byc if(texture.loadFromFile(...)) a nie if(**!**texture) inaczej ustawiasz tektury dla sprite tylko gdy nie udało się załadować textury.

0

ok wielkie dzieki

a w ladowaniu byl blad bo poczatkowa wersja wyswietlala jeszcze error a pozniej to usunalem a wykrzyknik zostal

dzieki

0

mam jeszcze jedno pytanie zwiazane z mapa

doszla mi 1 klasa

Level.h

#include <SFML\Graphics.hpp>
#include <iostream>
#include <fstream>
#include <cctype>
#include <string>

#include "Game.h"



class Level
{
public:

	void LoadLevel();
	void drawLevel();

	sf::Texture tileTexture;
	sf::Sprite tiles;
	std::string tileLocation;
	std::string str;


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

	friend Game::Game();
	
	

}; 

Level.cpp

#include "Level.h"

void Level::LoadLevel()
{
	std::ifstream openfile("level/map.txt");

	if (openfile.is_open())
	{

		openfile >> tileLocation;

		tileTexture.loadFromFile(tileLocation);
		tiles.setTexture(tileTexture);
		while (!openfile.eof())
		{
			openfile >> str;
			char x = str[0], 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++;
		}
	}

	loadCounter.y++;
}

void Level::drawLevel()
{
	for (int i = 0; i < loadCounter.x; i++)
	{
		for (int j = 0; j < loadCounter.y; j++)
		{
			if (map[i][j].x != -1 && map[i][j].y != -1)
			{
				tiles.setPosition(i * 32, j * 32);
				tiles.setTextureRect(sf::IntRect(map[i][j].x * 32, map[i][j].y * 32, 32, 32));
				
			}
		}
	}

} 

Jak zrobic aby wyswietlic mape na oknie ktore jest tworzone w innej klasie.

0

Musiałbyś zrobić funkcję, która bierze jako argument

sf::RenderWindow& 

lub dziedziczyć posf::Drawable

.
Ps. Użyj do tworzenia tilemapy VertexArray w tutorialu o 
```cpp
sf::VertexArray

jest przykład jak taką mape zaimplementować.

0

no ok mam funkcje DrawLevel ktora bierze jako argument window, ale nie moge teraz wywolac tej funkcji...

0

Pokaż kod tej funkcji i jak ją wywołujesz. Powinieneś zwyczajnie zrobić tą funkcji, potem obiekt klasy i wywołać funkcje

0

dopisalem do funkcji DrawLevel (sf::RenderWindow &window)

a wywoluje w Game.cpp poprzez Level::DrawLevel(window);

0

A dopisałeś

window.draw(tiles);

?

0
tffsts napisał(a):

A dopisałeś

window.draw(tiles);

?

tak dopisalem ale mi sie rzuca o wywolanie funkcji

0

ok zapomnialem o dziedziczeniu klasy, lecz niestety nic sie nie wyswietla na ekranie oprocz ludzika

1

Level::DrawLevel(window); a blad to Error 1 error C2352: 'Level::drawLevel' : illegal call of non-static member function c:\users\dawid\desktop\visual 2013\sfml game\game.cpp 62 1 SFML Game

Nie możesz wywoływać funkcji, która nie jest statyczna za pomocą operatora zasięgu, czyli

::

.
Stwórz obiekt tej klasy i wywołaj funkcje

Level level;
level.loadLevel();
//reszta kodu
level.drawLevel(window); //window - okno aplikacji
0

ok juz mam tylko ze zamiast mapki wyswietla biale kwadraty, jak ma wygladac ten plik z teksturami z ktorego on laduje te kolory

0

tak juz zmieniona bylo jpg zmienilem na png ;)
pierwsza linia mapy :

x,x x,x x,x x,x x,x x,x x,x

0

nie no myslalem ze pierwsza ktora odpowiada za malowanie

tak to pierwsza to jest LevelTexture.png

0

Level.h

#include <SFML\Graphics.hpp>
#include <iostream>
#include <fstream>
#include <cctype>
#include <string>



class Level
{
public:

	void LoadLevel();
	void drawLevel(sf::RenderWindow &window);
	
	

	sf::Texture tileTexture;
	sf::Sprite tiles;
	std::string tileLocation;
	std::string str;


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

}; 

Level.cpp

 
#include "Level.h"

void Level::LoadLevel()
{
	std::ifstream openfile("map.txt");

	if (openfile.is_open())
	{

		openfile >> tileLocation;

		tileTexture.loadFromFile(tileLocation);
		tiles.setTexture(tileTexture);
		while (!openfile.eof())
		{
			openfile >> str;
			char x = str[0], 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++;
		}
	}

	loadCounter.y++;
}

void Level::drawLevel(sf::RenderWindow &window)
{
	Level::LoadLevel();
	for (int i = 0; i < loadCounter.x; i++)
	{
		for (int j = 0; j < loadCounter.y; j++)
		{
			if (map[i][j].x != -1 && map[i][j].y != -1)
			{
				tiles.setPosition(i * 32, j * 32);
				tiles.setTextureRect(sf::IntRect(map[i][j].x * 32, map[i][j].y * 32, 32, 32));
				window.draw(tiles);

			}
		}
	}
	

}

Game.h

 #include <SFML\Window.hpp>
#include <SFML\Graphics.hpp>
#include <SFML\Window\WindowStyle.hpp>
#include "Level.h"


using namespace sf;

class Game : public Level
{
public:

	Game(void);
	
	void GameStart();
	void PlayerTexture();
	void Movement();

	RenderWindow window;
	Texture texture;
	Sprite sprite;
	Event event;


	enum {Down, Left, Right, Up};

	int sourceX = 32, sourceY = Down;

	Vector2i source;

	friend class Level;
	friend void Level::drawLevel(sf::RenderWindow &window);
	
	Level level;
};

Game.cpp

#include "Game.h"



Game::Game(void)
{
	Vector2i source(1, Down);
	window.create(VideoMode(800,600), "Runner");
}


void Game::PlayerTexture()
{


	if (texture.loadFromFile("postac.png"))
	{
		sprite.setTexture(texture);
	}
	sprite.setPosition(0,200);
}

void Game::Movement()
{
	
	if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right))
	{
		source.y = Right;

		sprite.move(0.5, 0);
	}

	if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left))
	{
		source.y = Left;

		sprite.move(-0.5, 0);
	}
}

void Game::GameStart()
{
	

	Game::PlayerTexture();
	while (window.isOpen())
	{

		while (window.pollEvent(event))
		{
			


			if (event.type == sf::Event::Closed || Keyboard::isKeyPressed(Keyboard::Key::Escape))
				window.close();
		}
		
		Game::Movement();
		level.drawLevel(window);
		sprite.setTextureRect(IntRect(source.x * 32, source.y * 32, 32, 32));
		
		
		
		window.draw(sprite);
		window.display();
		window.clear();
		
	}

}

 

main.cpp

 #include "Game.h"

int main()
{
	Game game;
	game.GameStart();
	

	return EXIT_SUCCESS;
}
1
  1. Nie musisz dziedziczyć po klasie Level
  2. Te przyjaźnie niepotrzebne
  3. Zła kolejność rysowania. Powinno być tak:
    I. Czyść ekran (.clear())
    II. Rysuj wszystko co potrzebne
    III. Pokaż ekran (.display())
  4. Skoro wywołujesz funkcje, które są zadeklarowane w tej samej klasie, to nie musisz używać operatora zasięgu (np. Game::Movement()) wystarczy Movement().
0

ehh nadal mam ten efekt doczytywania i to takiego dziwnego

0

Mam pytanie probuje do mojej gry napisac podskakiwanie. Lecz gdy napisze jakis algorytm podskakiwania to postac doslownie odlatuje. Jak powinno to wygladac zeby postac sie tylko odbila i zaraz spadla na platforme.

1 użytkowników online, w tym zalogowanych: 0, gości: 1