Bullets in tower defense game (C++ | SFML)



  • Im currently programming a simple tower defense game and have implemented a tower and player class, but the bullets are not always flying in the right direction (sometimes right and sometimes left of the player). What have I done wrong? Here's the code:

    #include <SFML/Graphics.hpp>
    #include <iostream>
    #include <vector>
    #include <ctime>
    #include <cmath>
    #include <random>
    
    using namespace sf;
    using namespace std;
    
    #define PI 3.1415926535
    
    //	TARGET - POSITION = VECTOR TO TARGET	//
    
    #define WINDOW_SIZE_X 800
    #define WINDOW_SIZE_Y 600
    
    float length(const Vector2f& vec) {
    	return sqrt(vec.x * vec.x + vec.y * vec.y);
    }
    
    void normalize(Vector2f& vec) {
    	float vecLength = length(vec);
    	vec = Vector2f(vec.x / vecLength, vec.y / vecLength);
    }
    
    struct Bullet {
    	Sprite shape;
    	Vector2f position;
    	Vector2f destination;
    };
    
    class Player {
    private:
    	Texture playerTexture;
    	Sprite player;
    public:
    	Player(Vector2f position = Vector2f(WINDOW_SIZE_X / 2, WINDOW_SIZE_Y / 2)) {
    		playerTexture.loadFromFile("player.png");
    		player.setTexture(playerTexture);
    		player.setOrigin(25, 25);
    		player.setPosition(position);
    	}
    	Vector2f getPosition() { return player.getPosition(); }
    	void update(float dt) {
    		if (Keyboard::isKeyPressed(Keyboard::W)) {
    			player.move(Vector2f(0, -1 * dt * 500));
    			player.setRotation(270);
    		}
    		if (Keyboard::isKeyPressed(Keyboard::S)) {
    			player.move(Vector2f(0, 1 * dt * 500));
    			player.setRotation(90);
    		}
    		if (Keyboard::isKeyPressed(Keyboard::D)) {
    			player.move(Vector2f(1 * dt * 500, 0));
    			player.setRotation(360);
    		}
    		if (Keyboard::isKeyPressed(Keyboard::A)) {
    			player.move(Vector2f(-1 * dt * 500, 0));
    			player.setRotation(180);
    		}
    	}
    	void render(RenderWindow& window) {
    		window.draw(player);
    	}
    };
    
    class Turret {
    private:
    	Player* target;
    	vector<Bullet> bullets;
    	float as;
    	float time;
    	int spread;
    	Texture towerTexture;
    	Texture bulletTexture;
    	Sprite tower;
    public:
    	Turret(Player* target, float as = 1, int spread = 1, Vector2f position = Vector2f(0, 0)) : target(target), as(as), spread(spread) {
    		bulletTexture.loadFromFile("bullet.png");
    		towerTexture.loadFromFile("tower.png");
    		tower.setTexture(towerTexture);
    		tower.setOrigin(25, 25);
    		tower.setPosition(position);
    		time = as;
    	}
    	void setAS(float _as) { as = _as; }
    	float getAS() { return as; }
    	void setPosition(Vector2f position) { tower.setPosition(position); }
    	Vector2f getPosition() { return tower.getPosition(); }
    	void setSpread(int _spread) { spread = _spread; }
    	int getSpread() { return spread; }
    	void update(float dt) {
    		if (time >= 1 / as) {
    	//I have done something wrong in this area, but dont know what
    time = 0;
    			Vector2f direction = tower.getPosition() - target->getPosition();
    			normalize(direction);
    			float angle = atan2(direction.x, direction.y) * 180 / PI;
    			float angle2; 
    			if (spread > 0)
    				angle2 = angle + rand() % spread;
    			else
    				angle2 = angle;
    			Bullet bull;
    			bull.destination = Vector2f(target->getPosition().x + sin(angle2) * 180 / PI, target->getPosition().y + cos(angle2) * 180 / PI);
    
    			cout << bull.destination.x << "\t" << bull.destination.y << "\t\t" << target->getPosition().x << "\t" << target->getPosition().y << endl;
    
    			Sprite bullet;
    			bullet.setTexture(bulletTexture);
    			bullet.setOrigin(15, 3);
    			bullet.setRotation(270 - angle);
    			bullet.setPosition(tower.getPosition());
    
    			bull.shape = bullet;
    			bull.position = tower.getPosition();
    			bullets.push_back(bull);
                   ///////////////////////////////////////		
    }
    		else {
    			time += dt;
    		}
    		for (auto i = bullets.begin(); i != bullets.end(); ++i) {
    			Vector2f direction = i->destination - i->position;
    			if (length(direction) <= 0)
    				i = bullets.erase(i);
    			normalize(direction);
    			i->shape.move(direction * dt * 500.f);
    		}
    		Vector2f direction(target->getPosition() - tower.getPosition());
    		normalize(direction);
    		tower.setRotation(180 - atan2(direction.x, direction.y) * 180 / PI);
    	}
    	void render(RenderWindow& window) {
    		window.draw(tower);
    		for (auto i = bullets.begin(); i != bullets.end(); ++i)
    			window.draw(i->shape);
    	}
    };
    
    int main() {
    	RenderWindow window(VideoMode(WINDOW_SIZE_X, WINDOW_SIZE_Y), "SFML!");
    
    	Texture backgroundTexture;
    	Sprite background;
    	backgroundTexture.loadFromFile("background.png");
    	background.setTexture(backgroundTexture);
    
    	Player player;
    	Turret turret(&player, 10, 0, Vector2f(400, 300));
    
    	Clock clock;
    	srand(time(NULL));
    
    	while (window.isOpen()) {
    		Event event;
    		if (window.pollEvent(event))
    			if (event.type == event.Closed)
    				window.close();
    		if (Keyboard::isKeyPressed(Keyboard::Escape))
    			window.close();
    
    		float dt = clock.restart().asSeconds();
    
    		player.update(dt);
    		turret.update(dt);
    
    		window.clear();
    		window.draw(background);
    
    		player.render(window);
    		turret.render(window);
    
    		window.display();
    	}
    	return 0;
    }
    


  • Das letzte Mal, als ich einen Beitrag von dir (ausführlich) beantwortet hatte, gab es keine Antwort mehr von dir. https://www.c-plusplus.net/forum/340511

    Werde ich mir jetzt 200 Zeilen Code anschauen, meinen eigenen Code raussuchen und schauen wie du es am besten machst, und nebenbei 20 Dinge abklären die du sonst noch verbessern könntest (Zeitaufwand gesamt min. 15 Minuten), nur weil du zu bequem bist mal selbst zu debuggen und mit Stift + Papier dein Problem zu analysieren, ganz abgesehen davon, dass am Ende alles für die Katz war?

    Ich denke die Frage beantwortet sich von selbst.

    LG



  • Du fütterst sin und cos mit nem Winkel in Grad.


Anmelden zum Antworten