Ocena gry w SFML 2.0

0

Witam, przez jakiś tam czas z wiedzy co nabyłem starałem się napisać grę, proszę żebyście ocenili i powiedzieli co poprawić (to dla mnie ważny by się wciąż dokształcać), wiem że mam problemy z nazywaniem zmiennych. Tu jest kod:

(Pomyliło mi się na początku pisania kometa z statkiem, więc klasa Comet jest dla statku, a klasa ship dla komet)

Link do gry: http://www.sendspace.pl/file/c9ea039ac96288dc3585a9e

Pastebin: http://pastebin.com/CxcJ9dKt

#include <SFML/Graphics.hpp>
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <sstream>

enum gs {MENU, PLAYING, GAME_OVER};
int game_state = MENU;


class ship;
class comet
{
	sf::RectangleShape rect;
	sf::RectangleShape line;
	sf::RectangleShape bullets[5];
	float moveSpeed;
	sf::Clock clock, clock_for_animation;
	sf::Clock clockForShootiong, timeBetweenShooting;

	sf::Font font;
	sf::Text score, lives;
	bool isBulletAlive[5];
	unsigned int player_score;
	unsigned int player_lives;
	
public:
	comet(){}
	comet(sf::RectangleShape &r, sf::RectangleShape &l, sf::Clock &c, sf::Font &f, sf::Text &s) : moveSpeed(400.0f), player_score(0), player_lives(3)
	{
		r.setSize(sf::Vector2f(55,50));
		r.setPosition(5,300);
		r.setOutlineColor(sf::Color::Red);
		r.setFillColor(sf::Color::Green);
		r.setOutlineThickness(3);
		rect = r;

		l.setSize(sf::Vector2f(65, 5));
		l.setFillColor(sf::Color::Blue);
		l.setPosition(rect.getPosition().x, rect.getPosition().y+25);
		line = l;

		c= clock;
		for(int i=0;i<5;i++)
		{
			bullets[i].setFillColor(sf::Color::Black);
			bullets[i].setSize(sf::Vector2f(10,3));
			isBulletAlive[i]=false;
		}
		if(!f.loadFromFile("tomb.ttf"))
			std::cout << "break" << std::endl;
		font =f;


		s.setString("Points: 0");
		s.setCharacterSize(30);
		s.setFont(font);
		s.setPosition(250/2, 50);
		s.setColor(sf::Color(232,232,232));
		score = s;

		lives.setString("Lives: 3");
		lives.setCharacterSize(30);
		lives.setFont(font);
		lives.setPosition(600, 50);
		lives.setColor(sf::Color(232,232,232));

		
		
	}
	void move();
	void updateLinePosition();
	void drawShip(sf::RenderWindow *okno);
	void checkShipPosition();

	void fireABullet();
	void updateBullet();
	void drawBullet(sf::RenderWindow *okno);
	void updateScore();
	void updateLives();


	friend void collisionBulletComet(ship &s, comet &c);
	friend void collisionShipComet(ship &s, comet &c);

	int getPoints();
	
};

class ship
{
	sf::CircleShape comets[7];
	sf::Clock clock, clockMoving;
	bool isCometAlive[7];
	float moveSpeed;
	unsigned int comets_lost;
public:
	ship(sf::CircleShape c[7], sf::Clock &cl);
	void spawnComet();
	void drawComet(sf::RenderWindow *okno);
	void moveComet();
	int getLostComets();

	friend void collisionBulletComet(ship &s, comet &c);
	friend void collisionShipComet(ship &s, comet &c);
};

class game_over
{
	sf::Font font;
	sf::Text statistics, points, lost_comets;
	sf::Texture game_over_bg_texture; 
	sf::Sprite game_over_bg;
public:
	game_over(sf::Font &f, sf::Text &s, sf::Text &sc, sf::Text &l_c, sf::Texture &go_bg_texture, sf::Sprite &go_bg);
	void draw_stats(sf::RenderWindow *okno);
	void score_Points(int p_points);
	void lost_comet(int l_comets);

};

class menu
{
	sf::Text play, quit;
	sf::Font font;
	sf::Texture bg_texture;
	sf::Sprite bg; //background
public:
	menu(sf::Text &p, sf::Text &q, sf::Font &f, sf::Texture &bg_text, sf::Sprite &background);
	void check_for_action(sf::RenderWindow &window);
	void draw_options(sf::RenderWindow *window);
};

int main()
{
	srand(time(NULL));
    sf::RenderWindow window(sf::VideoMode(800, 600), "ShipAndComets");
	sf::RectangleShape rect,line;
	sf::CircleShape comets[7];
	sf::Clock clock;
	sf::Text score, statistics, lost_comets, play, quit;
	sf::Font font;
	sf::Texture bg_texture, playing_bg_texture;
	sf::Sprite bg, playing_bg;

	if(!playing_bg_texture.loadFromFile("my_bg_for_playing.png"))
		std::cout << "break in main" << std::endl;

	playing_bg.setTexture(playing_bg_texture);

    comet com(rect,line,clock, font, score);
	ship sh(comets, clock);
	game_over go(font, statistics, score, lost_comets, bg_texture, bg);
	menu m(play, quit, font, bg_texture, bg);

    while (window.isOpen())
    {

        sf::Event event;
        while (window.pollEvent(event))
        {
            if (event.type == sf::Event::Closed)
                window.close();
        }

        window.clear();
		if(game_state == MENU)
		{
			m.draw_options(&window);
			m.check_for_action(window);
		}
		if(game_state == PLAYING){
			window.draw(playing_bg);
		com.drawShip(&window);
		com.move();
		com.fireABullet();
		com.updateBullet();
		com.drawBullet(&window);
		sh.spawnComet();
		sh.moveComet();
		sh.drawComet(&window);
		collisionBulletComet(sh,com);
		collisionShipComet(sh,com);
		}
		else if(game_state == GAME_OVER)
		{
			go.score_Points(com.getPoints());
			go.lost_comet(sh.getLostComets());
			go.draw_stats(&window);
		}

        window.display();
    }

    return 0;
}
//COMET = PLAYER ( should be ship)


void comet::move()
{
	sf::Time delta = clock.restart();
	if(sf::Keyboard::isKeyPressed(sf::Keyboard::Right))
	{
		rect.move(moveSpeed * delta.asSeconds(), 0);
	}
	else if(sf::Keyboard::isKeyPressed(sf::Keyboard::Left))
	{
		rect.move(-moveSpeed * delta.asSeconds(), 0);
	}
	else if(sf::Keyboard::isKeyPressed(sf::Keyboard::Up))
	{
		rect.move(0, -moveSpeed *delta.asSeconds());
	}
	else if(sf::Keyboard::isKeyPressed(sf::Keyboard::Down))
	{
		rect.move(0, moveSpeed * delta.asSeconds());
	}
	updateLinePosition();
	checkShipPosition();
}
void comet::updateLinePosition()
{
	line.setPosition(rect.getPosition().x, rect.getPosition().y + 25);
}
void comet::drawShip(sf::RenderWindow *okno)
{
	okno->draw(rect);
	okno->draw(line);
	okno->draw(score);
	okno->draw(lives);
}


void comet::fireABullet()
{

	if(sf::Keyboard::isKeyPressed(sf::Keyboard::Space))
	{
	for(int i=0;i<5;i++)
	{
		if(timeBetweenShooting.getElapsedTime().asMilliseconds() >= 200.f){
		if(!isBulletAlive[i])
		{
			isBulletAlive[i] = true;
			bullets[i].setPosition(line.getPosition().x + 62, line.getPosition().y);	
			timeBetweenShooting.restart();
		}
		}
	}
	}
}
void comet::updateBullet()
{
	sf::Time delta = clockForShootiong.restart();
	for(int i=0;i<5;i++)
	{
		if(isBulletAlive[i])
		{
			bullets[i].move(moveSpeed *delta.asSeconds(), 0);
			if(bullets[i].getPosition().x >= 800)
				isBulletAlive[i] = false;
		}
	}
}
void comet::updateScore()
{
	player_score+=1;
	std::stringstream str;
	str << "Points: " << player_score;
	
	score.setString(str.str());
}
void comet::updateLives()
{
	player_lives-=1;
	std::stringstream str;
	str << "Lives: " << player_lives;

	lives.setString(str.str());
}
void comet::checkShipPosition()
{
	if(rect.getPosition().x + 55 >= 355)
		rect.setPosition(299, rect.getPosition().y);

	if(rect.getPosition().x <= 1)
		rect.setPosition(2, rect.getPosition().y);

	if(rect.getPosition().y + 50 >= 600)
		rect.setPosition(rect.getPosition().x, 545);

	if(rect.getPosition().y <= 1)
		rect.setPosition(rect.getPosition().x, 2);
	
}
int comet::getPoints()
{
	return player_score;
}
void comet::drawBullet(sf::RenderWindow *okno)
{
	for(int i=0;i<5;i++)
	{
		if(isBulletAlive[i])
			okno->draw(bullets[i]);
	}
}


ship::ship(sf::CircleShape c[7], sf::Clock &cl) : moveSpeed(300.0f), comets_lost(0)
{
	for(int i=0;i<7;i++)
	{
		comets[i].setRadius(30);
		comets[i].setFillColor(sf::Color::Red);
		isCometAlive[i]=false;
	}
	
	clock = cl;
}
void ship::spawnComet()
{
	for(int i=0;i<7;i++)
	{
		if(!isCometAlive[i])
		{
			if(clock.getElapsedTime().asMilliseconds() >= 75.f)
			{
			
				comets[i].setPosition(799, rand()%400+100);
				isCometAlive[i]=true;
				clock.restart();
			}
		}
	}
}
void ship::moveComet()
{
	sf::Time delta = clockMoving.restart();
	for(int i=0;i<7;i++)
	{
		if(isCometAlive[i])
		{
			comets[i].move(-moveSpeed * delta.asSeconds(),0);
			if(comets[i].getPosition().x <= 0){
				isCometAlive[i]=false;
				comets_lost++;
			}
		}
	}
}
void ship::drawComet(sf::RenderWindow *okno)
{
	for(int i=0;i<7;i++)
	{
		if(isCometAlive[i])
			okno->draw(comets[i]);
	}
}
int ship::getLostComets()
{
	return comets_lost;
}



void collisionBulletComet(ship &s, comet &c)
{
	for(int i=0;i<5;i++)
	{
		if(c.isBulletAlive[i])
		{
			for(int j=0;j<7;j++)
			{
				if(s.isCometAlive[j])
				{
					if((c.bullets[i].getPosition().x  > s.comets[j].getPosition().x
						&&	c.bullets[i].getPosition().x < s.comets[j].getPosition().x + s.comets[j].getPosition().x + s.comets[j].getRadius()) &&
						(c.bullets[i].getPosition().y  > s.comets[j].getPosition().y)
						&& c.bullets[i].getPosition().y  < s.comets[j].getPosition().y+s.comets[j].getRadius() + 30) 
					{
						c.isBulletAlive[i]=false;						
						s.isCometAlive[j]=false;
						c.updateScore();
					}
					
				}
			}
		}
	}
}

void collisionShipComet(ship &s, comet &c)
{
	for(int j=0;j<7;j++)
	{
		if(s.isCometAlive[j])
		{
			if((s.comets[j].getPosition().x- 15 < c.rect.getPosition().x + 50) &&
				(s.comets[j].getPosition().x + 15 > c.rect.getPosition().x - 50) &&
				(s.comets[j].getPosition().y - 15 < c.rect.getPosition().y + 45) &&
				(s.comets[j].getPosition().y + 15 > c.rect.getPosition().y - 45))
			{
				s.isCometAlive[j]=false;
				c.updateLives();
				if(c.player_lives <= 0 )
					game_state = GAME_OVER;
			}
			 
		}
	}
}

game_over::game_over(sf::Font &f, sf::Text &s, sf::Text &sc, sf::Text &l_c, sf::Texture &go_bg_texture, sf::Sprite &go_bg)
{
	if(!f.loadFromFile("tomb.ttf"))
		std::cout << "break" << std::endl;
	font = f;
	s.setCharacterSize(55);
	s.setColor(sf::Color(179,213,136));
	s.setFont(font);
	s.setString("STATISTICS");
	s.setPosition(240, 75);
	statistics = s;

	sc.setCharacterSize(40);
	sc.setColor(sf::Color(13,172,234));
	sc.setFont(font);
	sc.setPosition(150, 175);
	points = sc;

	l_c.setCharacterSize(40);
	l_c.setColor(sf::Color(13,172,234));
	l_c.setFont(font);
	l_c.setPosition(150, 245);
	lost_comets = l_c;

	if(!go_bg_texture.loadFromFile("my_bg.png"))
		std::cout << "break in game over" << std::endl;

	go_bg.setTexture(go_bg_texture);

	game_over_bg_texture = go_bg_texture;
	game_over_bg = go_bg;
	
}
void game_over::score_Points(int p_points)
{
	std::stringstream str;
	str << "Points scored: " << p_points;
	
	points.setString(str.str());
	
}
void game_over::lost_comet(int l_comets)
{
	std::stringstream str;
	str << "Lost comets: " << l_comets;

	lost_comets.setString(str.str());
}

void game_over::draw_stats(sf::RenderWindow *okno)
{
	okno->draw(game_over_bg);
	okno->draw(statistics);
	okno->draw(points);
	okno->draw(lost_comets);
}

menu::menu(sf::Text &p, sf::Text &q, sf::Font &f, sf::Texture &bg_text, sf::Sprite &background)
{
	if(!f.loadFromFile("tomb.ttf"))
		std::cout << "break" << std::endl;
	font = f;

	p.setCharacterSize(65);
	p.setPosition(205, 125);
	p.setColor(sf::Color(36,137,176));
	p.setStyle(sf::Text::Bold);
	p.setFont(font);
	p.setString("New Game");

	play = p;
//------------------------------------------//
	q.setCharacterSize(65);
	q.setPosition(200, 300);
	q.setStyle(sf::Text::Bold);
	q.setColor(sf::Color(36, 137, 176));
	q.setString("Quit game");
	q.setFont(font);

	quit = q;

	if(!bg_text.loadFromFile("my_bg.png"))
		std::cout << " break bg " << std::endl;

	background.setTexture(bg_text);
	bg = background;

}
void menu::draw_options(sf::RenderWindow *window)
{
	window->draw(bg);
	window->draw(play);
	window->draw(quit);
}
void menu::check_for_action(sf::RenderWindow &window)
{
	sf::Vector2i mousePos(sf::Mouse::getPosition(window).x, sf::Mouse::getPosition(window).y);

	if((mousePos.x >= play.getPosition().x && mousePos.x <= play.getPosition().y + play.getLocalBounds().width + 75)&&
		(mousePos.y >= play.getPosition().y && mousePos.y <= play.getPosition().y + play.getLocalBounds().height))
	{
		play.setColor(sf::Color::Red);
		if(sf::Mouse::isButtonPressed(sf::Mouse::Left))
			game_state = PLAYING;
	}
	else
	{
		play.setColor(sf::Color(36,137,176));
	}


	if((mousePos.x >= quit.getPosition().x && mousePos.x <= quit.getPosition().y + quit.getLocalBounds().width - 105)&&
		(mousePos.y >= quit.getPosition().y && mousePos.y <= quit.getPosition().y + quit.getLocalBounds().height))
	{
		quit.setColor(sf::Color::Red);
		if(sf::Mouse::isButtonPressed(sf::Mouse::Left))
			window.close();
	}
	else
	{
		quit.setColor(sf::Color(36,137,176));
	}
}

2
  • łatwiej pracować z kodem podzielonym na pliki (.hpp/.h / *.cpp/*c)
  • widzę masz dużo argumentów, ogranicz to ustawiając na początku wszystkie tła, fonty itp
  • daj plik .exe wraz z potrzebnymi grafikami

Przeanalizowałem kod "z grubsza" więc może są inne błędy.

0

(Pomyliło mi się na początku pisania kometa z statkiem, więc klasa Comet jest dla statku, a klasa ship dla komet)

Nazwę możesz zmienić, nie bój się LOL.

0
Trebuh napisał(a):
  • łatwiej pracować z kodem podzielonym na pliki (.hpp/.h / *.cpp/*c)
  • widzę masz dużo argumentów, ogranicz to ustawiając na początku wszystkie tła, fonty itp
  • daj plik .exe wraz z potrzebnymi grafikami

Przeanalizowałem kod "z grubsza" więc może są inne błędy.

specjalnie to robiłem w jednym pliku zazwyczaj robię w wielu
exe nie mogę zbytnio bo akurat na lapku jestem

2
>no design patterns(see: http://gameprogrammingpatterns.com/)
>magic numbers
>only one file
>a lot of if-trees
>no const-correctness
>mixing C++ and C arrays when not needed
>naming mistakes
>ship spawns comets?
>used frienship when not needed
>big constructors
>no foreach loops when really needed
>postincrementation instead of preincrementation
>mixing code styles

2/10 would NOT bang.

1
  • po przegranej nie da się zagrać nowej gry.
  • fajnie by było gdyby punkty były odejmowane za statki których nie zdążyłeś zestrzelić
  • popracuj nad grafiką - w internecie można znaleźć wiele ciekawych za darmo

Ogólnie gra przeciętna - niczym nowym się nie wyróżnia; jak na początek wydaje się być fajna ;)

3

Gra:

  • do testowania nie udostępniaj instalatorów, bo to trochę irytuje ;), tylko wersje spakowane
  • konsola w trybie Release powinna być wyłączona

Kod:

  • klasy do osobnych plików
  • podzielić metody na mniejsze
  • jeśli chcesz zmienić nazwę zmiennej/klasy etc. to w normalnym IDE jest do tego odpowiednia funkcja (np. "Refactor - rename")
  • ogólnie funkcja main powinna być bardzo krótka, coś w stylu:
int main(int argc, char *argv[])
{
    Application a(argc, argv);
    a.prepare();

    return a.exec();
}
0

dzięki za rady, na pewno poprawie i poszperam po google jak będę miał wątpliwości, jak ktoś chce coś jeszcze dopisać to bardzo proszę

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