9 Replies - 2788 Views - Last Post: 19 July 2011 - 08:47 AM Rate Topic: -----

#1 Mr. House  Icon User is offline

  • New D.I.C Head

Reputation: 4
  • View blog
  • Posts: 30
  • Joined: 18-July 11

Problem with drawing lasers in Asteroids game using SFML

Posted 18 July 2011 - 02:11 AM

Hello DIC, I've been toying with this for the past few days trying to get this to work.

Basically, my bullet is reaching where it needs to go fine, it's just that the animation to see it moving isn't working.
I know the code is crap and is messy, but I'm pretty new to SFML and game programming in general.

So without further adieu, here's the code.

main.cpp
#include <SFML/Graphics.hpp>
#include "Ship.h"
#include <iostream>
#include <sstream>
#include <string>

int main()
{
    sf::RenderWindow GameWindow(sf::VideoMode(380, 300, 32), "Asteroids");

	Ship ShipObj;

	sf::Font MyFont;
    MyFont.LoadFromFile("Colleged.ttf");



    while (Gamewindow.IsOpened()){

    	sf::Event Event;
        while (Gamewindow.GetEvent(Event))
        {
            // Close window : exit
            if (Event.Type == sf::Event::Closed)
                Gamewindow.Close();
			if ((Event.Type == sf::Event::KeyPressed) && (Event.Key.Code == sf::Key::Escape))
                Gamewindow.Close();

        }

		//DIC, IGNORE THIS CODE!!! This is just here to parse the angle and location of the ship
		//So I can see it on screen
        float val = ShipObj.returnAngle();
        float posx = ShipObj.returnPosx();
        float posy = ShipObj.returnPosy();
		 std::string Angle;
 		 std::stringstream ss (std::stringstream::in | std::stringstream::out);

 		 ss << val;
 		 ss >> Angle;

 		 sf::String Text("ANGLE " + Angle, MyFont, 15);
		Text.SetColor(sf::Color::White);
		Text.SetPosition(50.f, 50.f);

		 std::string Posx;
 		 std::stringstream ssp (std::stringstream::in | std::stringstream::out);

 		 ssp << posx;
 		 ssp >> Posx;
			sf::String Positionx("X " + Posx, MyFont, 15);
			Positionx.SetColor(sf::Color::White);
			Positionx.SetPosition(50.f, 70.f);

			std::string Posy;
 		 std::stringstream ssx (std::stringstream::in | std::stringstream::out);

 		 ssx << posy;
 		 ssx >> Posy;
			sf::String Positiony("Y " + Posy, MyFont, 15);
			Positiony.SetColor(sf::Color::White);
			Positiony.SetPosition(50.f, 90.f);
		//END IGNORE
		

        float ElapsedTime = Gamewindow.GetFrameTime();
        static float keyTime = 0;
        keyTime += ElapsedTime;

		Gamewindow.Clear();

		ShipObj.Movement(&keyTime, &GameWindow);				///SHIP MOVEMENT
		ShipObj.Shoot(&keyTime, &GameWindow);					///SHIP SHOOT
		ShipObj.drawBullet(&GameWindow);						///DRAW BULLET
		ShipObj.distanceCheck();								///CHECKS FOR LASER DISTANCE


		Gamewindow.Draw(Text);
		Gamewindow.Draw(Positionx);
		Gamewindow.Draw(Positiony);
		Gamewindow.Draw(ShipObj.returnShape());

    	Gamewindow.Display();
    }
    return 0;
}



Ship.h
#ifndef SHIP_H
#define SHIP_H
#include <SFML/Graphics.hpp>

class Ship
{
	sf::Shape ShipShape;
	float ShipTheta;

	class Shot{
	public:
	sf::Shape Bullet;
	bool rof;
	sf::Vector2f pos; //position in pixels of the shot
	float BulletAngle; //direction of the shot
	float distanceTraveled;
	};

	Shot ShotObj;

public:
	Ship();
	void Movement(float *keyTime, sf::RenderWindow *GameWindow);
	void drawBullet(sf::RenderWindow *GameWindow);
	void Shoot(float *keyTime, sf::RenderWindow *GameWindow);
	sf::Shape returnShape();
	sf::Shape returnBullet();
	float returnPosx();
	float returnPosy();
	float returnAngle();
	void distanceCheck();

};

#endif // SHIP_H



Ship.cpp
#include "Ship.h"

Ship::Ship()
{
	ShipShape.AddPoint(25, -10,   sf::Color(0, 0, 0),     sf::Color::White);
	ShipShape.AddPoint(0, 0,   sf::Color(0, 0, 0),   sf::Color::White);
	ShipShape.AddPoint(25, 10,  sf::Color(0, 0, 0), sf::Color::White);
	ShipShape.SetPosition(180, 130);
	ShipShape.SetOutlineWidth(1);
	ShotObj.pos = ShipShape.GetPosition();
	ShotObj.Bullet = sf::Shape::Circle(ShotObj.pos.x, ShotObj.pos.y, 1, sf::Color::White, 1, sf::Color::White);
	ShotObj.distanceTraveled = 0;
}


void Ship::Movement(float *keyTime, sf::RenderWindow *GameWindow){
       	if(GameWindow->GetInput().IsKeyDown(sf::Key::Up) && *keyTime > .01){
        	//cos2 + sin2 = 1
        	if (GameWindow->GetInput().IsKeyDown(sf::Key::Right)){
        	ShipShape.Rotate(-5);
        	*keyTime = 0;
        	}
			if (GameWindow->GetInput().IsKeyDown(sf::Key::Left)){
        	ShipShape.Rotate(5);
        	*keyTime = 0;
       		 }

        	float x =0, y=0;
        	if(ShipShape.GetRotation()>= 0 && ShipShape.GetRotation() <= 90){
        		ShipTheta = ShipShape.GetRotation();
        		ShipTheta = (ShipTheta * 3.14159265)/180;
        	x = -cos(ShipTheta);
        	y = sin(ShipTheta);
        	}

        	if(ShipShape.GetRotation()> 90 && ShipShape.GetRotation() <= 180){
        		ShipTheta = 180 - ShipShape.GetRotation();
        		ShipTheta = (ShipTheta * 3.14159265)/180;
        	x = cos(ShipTheta);
        	y = sin(ShipTheta);
        	}

        	if(ShipShape.GetRotation()> 180 && ShipShape.GetRotation() <= 270){
        		ShipTheta = ShipShape.GetRotation() - 180;
        		ShipTheta = (ShipTheta * 3.14159265)/180;
        	x = cos(ShipTheta);
        	y = -sin(ShipTheta);
        	}

			if(ShipShape.GetRotation()> 270 && ShipShape.GetRotation() < 360){
        		ShipTheta = 360-ShipShape.GetRotation() ;
        		ShipTheta = (ShipTheta * 3.14159265)/180;
        	x = -cos(ShipTheta);
        	y = -sin(ShipTheta);
        	}

        	ShipShape.Move(x*3,y*3);
        	*keyTime = 0;
        }
        if (GameWindow->GetInput().IsKeyDown(sf::Key::Left) && *keyTime > .01){
        	ShipShape.Rotate(5);
        	*keyTime = 0;
        }
        if (GameWindow->GetInput().IsKeyDown(sf::Key::Right) && *keyTime > .01){
        	ShipShape.Rotate(-5);
        	*keyTime = 0;
        }
}

sf::Shape Ship::returnShape(){
	return ShipShape;
}

float Ship::returnAngle(){
	return ShipShape.GetRotation();
}

float Ship::returnPosx(){
	return ShipShape.GetPosition().x;
}
float Ship::returnPosy(){
	return ShipShape.GetPosition().y;
}

sf::Shape Ship::returnBullet(){
	return ShotObj.Bullet;
}

void Ship::drawBullet(sf::RenderWindow *GameWindow){
	GameWindow->Draw(ShotObj.Bullet);
}

void Ship::distanceCheck(){
	if(ShotObj.distanceTraveled > 150){
		ShotObj.Bullet.SetPosition(ShipShape.GetPosition().x - 180, ShipShape.GetPosition().y - 130);
		ShotObj.distanceTraveled = 0;
	}
}


void Ship::Shoot(float *keyTime, sf::RenderWindow *GameWindow){
	if(!GameWindow->GetInput().IsKeyDown(sf::Key::Space))
		ShotObj.rof = true;

	if(GameWindow->GetInput().IsKeyDown(sf::Key::Space) && *keyTime > .04 && ShotObj.rof == true){
		ShotObj.rof = false;
		ShotObj.BulletAngle = ShipShape.GetRotation();
        	float x =0, y=0;
        	if(ShipShape.GetRotation()>= 0 && ShipShape.GetRotation() <= 90){
        		ShotObj.BulletAngle = (ShotObj.BulletAngle * 3.14159265)/180;
        	x = -cos(ShotObj.BulletAngle);
        	y = sin(ShotObj.BulletAngle);
        	}

        	if(ShipShape.GetRotation()> 90 && ShipShape.GetRotation() <= 180){
        		ShotObj.BulletAngle = 180 - ShotObj.BulletAngle;
        		ShotObj.BulletAngle = (ShotObj.BulletAngle * 3.14159265)/180;
        	x = cos(ShotObj.BulletAngle);
        	y = sin(ShotObj.BulletAngle);
        	}

        	if(ShipShape.GetRotation()> 180 && ShipShape.GetRotation() <= 270){
        		ShotObj.BulletAngle = ShotObj.BulletAngle - 180;
        		ShotObj.BulletAngle = (ShotObj.BulletAngle * 3.14159265)/180;
        	x = cos(ShotObj.BulletAngle);
        	y = -sin(ShotObj.BulletAngle);
        	}

			if(ShipShape.GetRotation()> 270 && ShipShape.GetRotation() < 360){
        		ShotObj.BulletAngle = 360-ShotObj.BulletAngle ;
        		ShotObj.BulletAngle = (ShotObj.BulletAngle * 3.14159265)/180;
        	x = -cos(ShotObj.BulletAngle);
        	y = -sin(ShotObj.BulletAngle);
        	}

		float elapsedtime = (GameWindow->GetFrameTime());
		while(1){
			GameWindow->Draw(ShotObj.Bullet);
			*keyTime += elapsedtime;
			if(*keyTime > 1){
				GameWindow->Draw(ShotObj.Bullet);
				ShotObj.Bullet.Move(x/3, y/3);
				ShotObj.distanceTraveled += 1;
				if(ShotObj.distanceTraveled > 120)
					break;
				*keyTime = 0;
			}
		}


	}
}



The main problem is this snippet of code right here:

float elapsedtime = (GameWindow->GetFrameTime());
		while(1){
			GameWindow->Draw(ShotObj.Bullet);
			*keyTime += elapsedtime;
			if(*keyTime > 0.5){
				GameWindow->Draw(ShotObj.Bullet);
				ShotObj.Bullet.Move(x/3, y/3);
				ShotObj.distanceTraveled += ;
				if(ShotObj.distanceTraveled > 120)
					break;
				*keyTime = 0;
			}
		}



It seems that GameWindow->Draw(ShotObj.Bullet); is never drawing the laser as it loops. I believe the problem lies as to how I'm passing in ShotObj.Bullet or using GameWindow, but I've tried all the different combinations and it gives me syntax errors.

So if you can help me or at least give me some pointers as to how I can improve this, much thanks to you.

Is This A Good Question/Topic? 0
  • +

Replies To: Problem with drawing lasers in Asteroids game using SFML

#2 stayscrisp  Icon User is offline

  • フカユ
  • member icon

Reputation: 1040
  • View blog
  • Posts: 4,325
  • Joined: 14-February 08

Re: Problem with drawing lasers in Asteroids game using SFML

Posted 18 July 2011 - 02:23 AM

Shot may be better suited to being a struct if you insist on defining it inside the class like that. Although it may be better to make shot a class with its own logic and update methods rather than have ship update the bullets. So when ship calls shoot it creates a shot object and passes in the angle and other needed values.

Shot could also have an animate method that is called for the lifetime of the bullet and updates it's animation.

Just some pointers that may help you :)
Was This Post Helpful? 0
  • +
  • -

#3 Mr. House  Icon User is offline

  • New D.I.C Head

Reputation: 4
  • View blog
  • Posts: 30
  • Joined: 18-July 11

Re: Problem with drawing lasers in Asteroids game using SFML

Posted 18 July 2011 - 02:26 AM

Well thanks. Nothing about the drawing error though? That's really my main problem, everything else can be tweaked.
Was This Post Helpful? 0
  • +
  • -

#4 stayscrisp  Icon User is offline

  • フカユ
  • member icon

Reputation: 1040
  • View blog
  • Posts: 4,325
  • Joined: 14-February 08

Re: Problem with drawing lasers in Asteroids game using SFML

Posted 18 July 2011 - 03:02 AM

What happens to the bullet? does it not draw? is it jerky?
Was This Post Helpful? 0
  • +
  • -

#5 Mr. House  Icon User is offline

  • New D.I.C Head

Reputation: 4
  • View blog
  • Posts: 30
  • Joined: 18-July 11

Re: Problem with drawing lasers in Asteroids game using SFML

Posted 18 July 2011 - 03:16 AM

It doesn't draw. I press space, it waits for the bullet to reach a certain distance, and then it draws it at the final position only after the program breaks from the Shoot() function and returns to the main loop.

The actual movement is fine, it's just not drawing as it moves.

I'm thinking of just making a function that is executed from the main loop that just moves and updates the position of the bullets.

This post has been edited by Mr. House: 18 July 2011 - 03:18 AM

Was This Post Helpful? 0
  • +
  • -

#6 stayscrisp  Icon User is offline

  • フカユ
  • member icon

Reputation: 1040
  • View blog
  • Posts: 4,325
  • Joined: 14-February 08

Re: Problem with drawing lasers in Asteroids game using SFML

Posted 18 July 2011 - 03:36 AM

Sounds like the while loop is the problem, step through it and see how things work. Why not just use an update function

void Shot::Update(float elapsedTime)
{
    if(distanceTravelled < 120)
    {
        GameWindow->Draw(Bullet);
        Bullet.Move(x/3, y/3);
        distanceTravelled++;
    }
    else
    {
        distanceTravelled = 0;
    }
}



Or something similar to this. You should keep individual objects functions separate, don't chuck them into the main function it will cause headaches later when you want to alter your code.
Was This Post Helpful? 1
  • +
  • -

#7 Mr. House  Icon User is offline

  • New D.I.C Head

Reputation: 4
  • View blog
  • Posts: 30
  • Joined: 18-July 11

Re: Problem with drawing lasers in Asteroids game using SFML

Posted 18 July 2011 - 04:06 AM

Well, I'm gonna tweak the structure a bit. My main problem is just that GameWindow->Draw(Bullet); simply isn't drawing the bullet, probably since I just have it set up wrong.

But thanks for your help. I'll probably make a function like the one above and just return a value to another function that just draws the bullets.
Was This Post Helpful? 0
  • +
  • -

#8 Mr. House  Icon User is offline

  • New D.I.C Head

Reputation: 4
  • View blog
  • Posts: 30
  • Joined: 18-July 11

Re: Problem with drawing lasers in Asteroids game using SFML

Posted 18 July 2011 - 05:17 AM

Alright, I moved it out of the Shoot() function and into the drawBullet() function which is constantly being drawn. I now have a bullet that is animated during flight.

Now to get it to animate while my ship is moving.
Was This Post Helpful? 0
  • +
  • -

#9 stayscrisp  Icon User is offline

  • フカユ
  • member icon

Reputation: 1040
  • View blog
  • Posts: 4,325
  • Joined: 14-February 08

Re: Problem with drawing lasers in Asteroids game using SFML

Posted 18 July 2011 - 05:20 AM

Nice work! Good luck and let us know if you run into any more issues :)
Was This Post Helpful? 0
  • +
  • -

#10 sparkart  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 115
  • View blog
  • Posts: 696
  • Joined: 16-February 09

Re: Problem with drawing lasers in Asteroids game using SFML

Posted 19 July 2011 - 08:47 AM

You might want to take a look at learning abit about polymorphism. It is an extremely important concept, especially for simulations like video games.

A great way to organize a game is to start off with a simple object that other objects would be derived from:

class Object
{
public:
    virtual void Create();
    virtual void Destroy();
    virtual void Update();
    virtual void Display();
private:
    Vector2d position;
    bool visible;
    sf::Image texture;
};



For example, you can derive your ship and bullet from this base class.

With polymorphism, you can maintain a list of objects. This allows you to manage all of your different objects through a common interface.

For example, your bullet objects can override the Object::Update() method so that its position changes.

Take a look at my tutorial about polymorphism to get a better idea of how it works and how it ties into game development: Polymorphism Tutorial
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1