SFMl, tilemaps



  • Guten Abend/Gute Nacht,
    ich arbeite gerade mit Tilemaps und bisher hat es eigentlich funktioniert, ich erhalte keine Fehlermeldung, aber es wird mir nur eine Textur in der oberen rechten Ecke angezeigt!
    Hier der Code:

    #include <SFML/Graphics.hpp>
    
    using namespace sf;
    
    int main()
    {
        RenderWindow window(VideoMode(800, 400), "00 Race");
    
    	int width = 50;
    	int height = 25;
    	int tilesize = 16;
    
    	Texture player;
    	player.loadFromFile("data\\tex\\sp.png");
    	Sprite sp;
    	sp.setTexture(player);
    
    	Texture w,g1,g0;
    	w.loadFromFile("data\\tex\\w1.png");
    	g1.loadFromFile("data\\tex\\g1.png");
    	g0.loadFromFile("data\\tex\\g0.png");
    	Sprite tile[1250];
    
    	int map[50][25] = {
    		0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    		0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    		0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,
    		0,0,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,0,0,
    		0,0,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,0,0,
    		0,0,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,0,0,
    		0,0,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,0,0,
    		0,0,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,0,0,
    		0,0,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,0,0,
    		0,0,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,0,0,
    		0,0,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,0,0,
    		0,0,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,0,0,
    		0,0,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,0,0,
    		0,0,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,0,0,
    		0,0,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,0,0,
    		0,0,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,0,0,
    		0,0,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,0,0,
    		0,0,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,0,0,
    		0,0,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,0,0,
    		0,0,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,0,0,
    		0,0,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,0,0,
    		0,0,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,0,0,
    		0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,
    		0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    		0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
    	};
    
        while (window.isOpen())
        {
            Event event;
            while (window.pollEvent(event))
            {
                if (event.type == Event::Closed)
                    window.close();
    			if(Keyboard::isKeyPressed(Keyboard::Escape))
    				window.close();
            }
    
    		for(int y; y < 25; y++)
    		{
    			for(int x; x < 50; x++)
    			{
    				int z = y+1;
    				int i = z*x;
    
    				if(map[y][x] == 0){
    					tile[i].setTexture(w);
    				}else if(map[y][x] == 1){
    					tile[i].setTexture(g0);
    				}else if(map[y][x] == 2){
    					tile[i].setTexture(g1);
    				}
    
    				tile[i].setPosition(x*16,y*16);
    
    				window.clear();
    				window.draw(tile[i]);
    				window.display();
    			}
    		}
        }
    
        return 0;
    }
    

    ich weiß leider nicht, wo der Fehler steckt, vielen Dank im voraus 👍



  • Dieser Thread wurde von Moderator/in SeppJ aus dem Forum C++ (alle ISO-Standards) in das Forum Spiele-/Grafikprogrammierung verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • Initialisiere mal deine beiden Schleifenvariablen x und y (auf 0).

    Und lerne mit dem Debugger umzugehen 😉



  • Hallöchen,

    ich will nicht unfreundlich sein: Dein Fehler liegt darin, dass du erstmal das *ganze* SFML Tutorial durchlesen solltest, am Besten selbst ausprobieren. Man lernt sehr viel und es ist sehr hilfreich. http://www.sfml-dev.org/learn.php

    Das Tutorial hat auch eine Tilemap als Beispiel: http://www.sfml-dev.org/tutorials/2.3/graphics-vertex-array.php#example-tile-map

    Noch eine Anmerkung: Magische Konstanten wie 1025 , 25 und 50 sollten vermieden werden. Nur ein Beispiel: wenn du Höhe/Breite ändern möchtest, musst du das Programm an mehreren Stellen anpassen. Da du schon width und height zu Beginn definierst, würde ich diese dann auch verwenden (evtl. mit const / constexpr )

    LG
    HarteWare



  • Hallo,

    window.clear und window.display müssen raus aus der Schleife.

    lg



  • Mittler Weile klappt alles. Kann später noch den aktuellen code hochladen



  • #include <SFML/Graphics.hpp>
    #include <SFML/Audio.hpp>
    #include <sstream>
    #pragma comment(linker, "/SUBSYSTEM:windows /ENTRY:mainCRTStartup")
    
    using namespace sf;
    
    int main()
    {
        RenderWindow window(VideoMode(800, 400), "00 Race");
    	window.setFramerateLimit(25);
    
    	int width = 50;
    	int height = 25;
    
    	int map[25][50] = {
    		0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    		0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    		0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,
    		0,0,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,0,0,
    		0,0,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,0,0,
    		0,0,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,0,0,
    		0,0,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,0,0,
    		0,0,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,0,0,
    		0,0,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,0,0,
    		0,0,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,0,0,
    		0,0,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,0,0,
    		0,0,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,0,0,
    		0,0,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,0,0,
    		0,0,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,0,0,
    		0,0,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,0,0,
    		0,0,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,0,0,
    		0,0,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,0,0,
    		0,0,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,0,0,
    		0,0,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,0,0,
    		0,0,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,0,0,
    		0,0,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,0,0,
    		0,0,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,0,0,
    		0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,
    		0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    		0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
    	};
    
    	Texture player;
    	player.loadFromFile("data\\tex\\sp.png");
    	Sprite sp;
    	sp.setTexture(player);
    	sp.setOrigin(8,8);
    	sp.setPosition(400,200);
    
    	Texture w,g1,g0;
    	w.loadFromFile("data\\tex\\w1.png");
    	g1.loadFromFile("data\\tex\\g1.png");
    	g0.loadFromFile("data\\tex\\g0.png");
    	Sprite tile[1250];
    
    	Texture hit;
    	hit.loadFromFile("data\\tex\\p1.png");
    	Sprite box;
    	box.setTexture(hit);
    	box.setOrigin(8,8);
    	box.setPosition(400, 200);
    
    	int box_x = 400, box_y = 200;
    	int score = -1;
    	bool game = false;
    	int tt = 0;
    	Clock timer;
    	std::stringstream ss;
    	ss << "Punkte: " << score;
    
    	Font arial;
    	arial.loadFromFile("data\\wri\\arial.ttf");
    	Text punkte;
    	Text start;
    
    	punkte.setFont(arial);
    	punkte.setString(ss.str());
    	punkte.setCharacterSize(24);
    	punkte.setColor(Color::Black);
    	punkte.setPosition(2,2);
    
    	start.setFont(arial);
    	start.setString("Press 'S'");
    	start.setCharacterSize(32);
    	start.setColor(Color::Black);
    	start.setPosition(100, 100);
    
    	SoundBuffer m,p,c;
    	m.loadFromFile("data\\mus\\m.ogg");
    	p.loadFromFile("data\\mus\\p.wav");
    	c.loadFromFile("data\\mus\\c.wav");
    	Sound music,point,crash;
    	music.setBuffer(m);
    	music.setVolume(50);
    	point.setBuffer(p);
    	point.setVolume(75);
    	crash.setBuffer(c);
    	crash.setVolume(100);
    
    	window.clear();
    	music.play();
    
        while (window.isOpen())
        {
            Event event;
            while (window.pollEvent(event))
            {
                if (event.type == Event::Closed)
                    window.close();
    			if(Keyboard::isKeyPressed(Keyboard::Escape))
    				window.close();
            }
    
    		for(int y = 0; y < 25; y++)
    		{
    			for(int x = 0; x < 50; x++)
    			{
    				int z = y+1;
    				int i = z*x;
    
    				if(map[y][x] == 0){
    					tile[i].setTexture(w);
    				}else if(map[y][x] == 1){
    					tile[i].setTexture(g0);
    				}else if(map[y][x] == 2){
    					tile[i].setTexture(g1);
    				}
    
    				tile[i].setPosition(x*16,y*16);
    
    				window.draw(tile[i]);
    				window.draw(box);
    				window.draw(sp);
    				window.draw(punkte);
    			}
    		}
    
    		int a = sp.getPosition().y / 16;
    		int b = sp.getPosition().x / 16;
    
    		if(map[a][b] == 1)
    		{
    			score = score -10;
    			std::stringstream ss;
    			ss << "Score: " << score;
    			punkte.setString(ss.str());
    			sp.setPosition(400,200);
    
    			crash.play();
    		}
    
    		if(sp.getGlobalBounds().intersects(box.getGlobalBounds()))
    		{
    			score++;
    			box_x = 56 + (rand() % 688);
    			box_y = 56 + (rand() % 288);
    			box.setPosition(box_x, box_y);
    
    			std::stringstream ss;
    			ss << "Score: " << score;
    			punkte.setString(ss.str());
    			point.play();
    		}
    
    		if(game == true)
    		{
    			tt = timer.getElapsedTime().asSeconds();
    			if(tt == 60)
    			{
    				game = false;
    			}
    
    			if(Keyboard::isKeyPressed(Keyboard::Up) && !Keyboard::isKeyPressed(Keyboard::Down) && !Keyboard::isKeyPressed(Keyboard::Left) && !Keyboard::isKeyPressed(Keyboard::Right))
    			{
    				sp.move(Vector2f(0,-16.0f));
    				sp.setRotation(0);
    			}else if(!Keyboard::isKeyPressed(Keyboard::Up) && Keyboard::isKeyPressed(Keyboard::Down) && !Keyboard::isKeyPressed(Keyboard::Left) && !Keyboard::isKeyPressed(Keyboard::Right))
    			{
    				sp.move(Vector2f(0,16.0f));
    				sp.setRotation(180);
    			}else if(!Keyboard::isKeyPressed(Keyboard::Up) && !Keyboard::isKeyPressed(Keyboard::Down) && Keyboard::isKeyPressed(Keyboard::Left) && !Keyboard::isKeyPressed(Keyboard::Right))
    			{
    				sp.move(Vector2f(-16.0f,0));
    				sp.setRotation(270);
    			}else if(!Keyboard::isKeyPressed(Keyboard::Up) && !Keyboard::isKeyPressed(Keyboard::Down) && !Keyboard::isKeyPressed(Keyboard::Left) && Keyboard::isKeyPressed(Keyboard::Right))
    			{
    				sp.move(Vector2f(16.0f,0));
    				sp.setRotation(90);
    			}
    		}else if(game == false){
    			start.setString("Press 'S'");
    
    			if(Keyboard::isKeyPressed(Keyboard::S))
    			{
    				music.setLoop(true);
    				score = -1;
    				box.setPosition(400, 200);
    				sp.setPosition(400, 200);
    				start.setString("");
    				timer.restart();
    				game = true;
    				window.clear();
    			}
    		}
    	window.draw(start);
    	window.display();
        }
    
        return 0;
    }
    

    So sieht es am Ende aus und funktioniert, danke für die HIlfe



  • Reiner Zufall!

    Warum hat tile 1250 Elemente? Was soll z und i darstellen?



  • *begin klugsch...*
    Bei solchen Programmgrößen würde es sich anbieten, nicht mehr alles in main() zu packen, sondern mal das Zeugs auszulagern. Z.B. in eine "App" Klasse, mit der Methode "execute/run" und dann z.B. "handleInput", "update", "render". Ebenfalls Dinge with ein "ResourceManager" erweisen sich als praktisch.

    tile hat 1250 = 25 x 50 Elemente, weil OP jedes Tile mit einem Sprite darstellen will, anstatt mal meinen Link zu lesen (offizielles SFML Tutorial!!!) und dann zu wissen, dass man große Tilemaps lieber mit sf::VertexArray darstellt! Würde OP, wie ich ebenfalls ihm/ihr schon zu Herzen gelegt habe, keine magischen Konstanten verwenden, sondern das nette const/constexpr nutzen, wäre dies auch ersichtlich!

    Mit i und z versucht OP vermutlich die Positionen in seiner 2D Map mit denen in dem 1D SpriteArray zu "vernetzen". Die Regel lautet aber index(1D) = x + y * breite
    Haben wir also z.B. Map[2][4], dann liegt das entsprechende Sprite bei tile[2 + 425] = tile[102]
    analog Map[24][49] = tile[24 + 49
    25] = tile[1249] (letztes Element)

    *klugsch... ende*

    Ich finde es aber sinnlos hier versuchen zu helfen, da der OP schon meinen letzten gut gemeinten Post 100% ignoriert hat.

    LG
    P.S.: Habe ich schon erwähnt? Offizielles SFML Tutorial zu TileMaps lesen!
    P.P.S.: Ich denke TGGC hat nicht so gefragt, weil er keine Ahnung hatte, sondern weil das die bessere Methode ist dem OP was beizubringen (zu kritischen Hinterfragungen des eigenen Codes animieren).


Log in to reply