Can i do that? (Sorry, long explanation and it's 4AM).

This is a discussion on Can i do that? (Sorry, long explanation and it's 4AM). within the Game Programming forums, part of the General Programming Boards category; Hi everyone. Sorry for a crappy title, but I'm not good at short explanations, plus it's almost 4AM in the ...

  1. #1
    Novice programmer newn's Avatar
    Join Date
    Aug 2010
    Posts
    59

    Can i do that? (Sorry, long explanation and it's 4AM).

    Hi everyone. Sorry for a crappy title, but I'm not good at short explanations, plus it's almost 4AM in the morning over here.
    Anyway, before i start rewriting a nice and readable code for my Ping Pong game, i would like to ask a few questions about general/gaming programming:

    Can i write a menu in one header file and the main game loop, how the game runs in another header file. Like menu.h and game.h. Then write one more file with variables, for example variables.h.

    When i have all this, put the variables(); into both menu.h and header.h files, and inside the int main() loop, write like this:

    Code:
    int main()
    {
    menu();
    if(menu select == 1)
    game();
    }
    Like do the checking in the menu function, then if the menu is that, do the game loop.

    Okay, so another question: Is there more better and efficient way to do this thing? And is there a possibility, that something won't work, while doing it my way? If so, what?

    The reason i am asking, before trying, is because it's a hell lot of code I'm going to rewrite, and i wouldn't like to rewrite it one more time, i even probably would leave the first, crappy to read variant, instead of rewriting it second time. It's not very... Entertaining thing to do.

    P.S. since I'm still working a little bit on the game, I'm going to rewrite it little by little, like I'm still have to do some work on Physics and then make the menu work (Probably going to use dummy images, until i get the real images made). Then it would be just minor stuff, tweaking, which would require a nice code to read, so it should be rewritten by that time.

    Thanks.

  2. #2
    Not stupid, just stupider yaya's Avatar
    Join Date
    May 2007
    Location
    Earthland
    Posts
    204
    I think what you're looking for are function parameters.

  3. #3
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,045
    You can certainly distribute code wherever you want to put it. You could put each function in its own file if you really wanted to. There are only two things you have to make sure of:
    1. Every function call should be to a function which has been declared. In practice this means you should put function prototypes in headers, and include the header files when you need them. (If you enable warnings with e.g. "-W -Wall" with gcc or g++ it will warn you about missing function prototypes. Actually in C++ prototypes are required.)
    2. Every function must exist somewhere. Otherwise the linker won't be able to find it. That's what happens when you get undefined symbol errors from the linker: you put a prototype in, effectively promising the compiler that this function exists somewhere, but in fact it did not.


    Same thing goes for global variables, or any kind of symbol really. Make sure it's declared before use, and make sure it's defined exactly once.

    If you post some of your code I'm sure you'll get more comments on it.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  4. #4
    Registered User NeonBlack's Avatar
    Join Date
    Nov 2007
    Posts
    435
    It's good that you want to separate your code. However, the fact that you want to have a header of global variables tells me that you have a very bad design. How much data do you actually need to share between your game and your menu? My guess is none.

    Having read your other thread, I know that you are very new to programming, so I don't want to discourage you by trying to make you do something too difficult, but I want to give you a push.

    I suggest something similar to the following as a first step. This certainly isn't the best way, but it's a bit simpler than the best way.

    Say this is your main loop:
    Code:
    while (gamestate!=quit)
    {
        // calculate time between frames
        if (gamestate==menu)
        {
            menu.update(dt);
            menu.draw();
        }
        else if (gamestate==game)
        {
            game.update(dt);
            game.draw();
        }
    }
    This would be better as virtual function calls, but for now it's fine.

    In your Menu and Game classes, you would have something like this:
    Code:
    void Menu::update(dt)
    {
        if (user clicked start game)
        {
            gamestate=game;
        }
        else if (user clicked quit)
        {
            gamestate=quit;
        }
    }
    Code:
    void Game::update(dt)
    {
        // update sprite positions, detect collisions etc.
        if (game is over)
        {
            gamestate=menu;
        }
    }
    If you can make your menu and game self-contained like this, it will be a big step in the right direction.

    I haven't seen more than small snippets of your code. As dwks suggested, post your code and we can give you better feedback.
    Last edited by NeonBlack; 08-24-2010 at 10:26 PM. Reason: Corrected typos
    I copied it from the last program in which I passed a parameter, which would have been pre-1989 I guess. - esbo

  5. #5
    Novice programmer newn's Avatar
    Join Date
    Aug 2010
    Posts
    59
    Thanks for replies.
    I will post the code, as some of you asked me to do, so you can see how crappy it is at the moment, lol.

    Code:
    #include <SFML\Graphics.hpp>
    #include <SFML\Audio.hpp>
    #include <stdio.h>
    #include <time.h>
    //#include "advanced menu.h"
    //#include "menu.h"
    
    int main()
    {
    	sf::RenderWindow App(sf::VideoMode(640, 480, 32), "Ping Pong game by Frozenas.co.cc", sf::Style::Close);
    	sf::Image i1;
    	sf::Image i2;
    	sf::Sprite s1;
    	sf::Sprite s2;
    	sf::Image Pong1;
    	sf::Image Pong2;
    	sf::Image DarkBG;
    	sf::Image Ball;
    	sf::Image One;
    	sf::Image Two;
    	sf::Image Three;
    	sf::Image Go;
    	if(!Pong1.LoadFromFile("Resources/pong.png"))
    		return EXIT_FAILURE;
    	if(!Pong2.LoadFromFile("Resources/pong.png"))
    		return EXIT_FAILURE;
    	if(!DarkBG.LoadFromFile("Resources/background.png"))
    		return EXIT_FAILURE;
    	if(!Ball.LoadFromFile("Resources/ball.png"))
    		return EXIT_FAILURE;
    	if(!One.LoadFromFile("Resources/one.png"))
    		return EXIT_FAILURE;
    	if(!Two.LoadFromFile("Resources/two.png"))
    		return EXIT_FAILURE;
    	if(!Three.LoadFromFile("Resources/three.png"))
    		return EXIT_FAILURE;
    	if(!Go.LoadFromFile("Resources/go.png"))
    		return EXIT_FAILURE;
    	Pong1.SetSmooth(false);
    	Pong2.SetSmooth(false);
    	DarkBG.SetSmooth(false);
    	//Ball.SetSmooth(false);
    	One.SetSmooth(false);
    	Two.SetSmooth(false);
    	Three.SetSmooth(false);
    	Go.SetSmooth(false);
    	sf::SoundBuffer Hit;
    	sf::Music Song;
    	if(!Hit.LoadFromFile("Resources/hit.wav"))
    		return EXIT_FAILURE;
    	sf::Sound BufferHit;
    	BufferHit.SetBuffer(Hit);
    	if(!Song.OpenFromFile("Resources/song.ogg"))
    		return EXIT_FAILURE;
    	sf::Font Font;
    	if(!Font.LoadFromFile("Resources/font.ttf", 100))
    		return EXIT_FAILURE;
    	bool GameRunning = true;
    	sf::String EndGame;
    	EndGame.SetPosition(125.f, 200.f);
    	EndGame.SetColor(sf::Color(0, 25, 0));
    	EndGame.SetFont(Font);
    	EndGame.SetSize(35.f);
    	sf::Sprite SpritePong1(Pong1);
    	sf::Sprite SpritePong2(Pong2);
    	sf::Sprite SpriteDarkBG(DarkBG);
    	sf::Sprite SpriteBall(Ball);
    	sf::Sprite SpriteOne(One);
    	sf::Sprite SpriteTwo(Two);
    	sf::Sprite SpriteThree(Three);
    	sf::Sprite SpriteGo(Go);
    	SpritePong1.SetPosition(0.f, 200.f);
    	SpritePong2.SetPosition(633.f, 200.f);
    	SpriteDarkBG.SetPosition(-1.f, -1.f);
    	SpriteBall.SetPosition(240.f, 320.f);
    	SpriteOne.SetPosition(-1.f, -1.f);
    	SpriteTwo.SetPosition(-1.f, -1.f);
    	SpriteThree.SetPosition(-1.f, -1.f);
    	SpriteGo.SetPosition(-1.f, -1.f);
    	const float PI = 3.14159f;
    	float BallSpeed = 400.f;
    	float BallAngle;
    	do
    	{
    	BallAngle = sf::Randomizer::Random(0.f, 2 * PI);
    	}
    	while(std::abs(std::cos(BallAngle)) < 0.7f);
    	sf::Clock Clock;
    	if(App.IsOpened())
    		Song.Play();
    	while(App.IsOpened())
    	{
    		sf::Event Event;
    		while(App.GetEvent(Event))
    		{
    			if(Event.Type == sf::Event::Closed)
    				App.Close();
    			if((Event.Type == sf::Event::KeyPressed) && (Event.Key.Code == sf::Key::Escape))
    				App.Close();
    		}
    		float ElapsedTime = App.GetFrameTime();
    		float Time = Clock.GetElapsedTime();
    		if(GameRunning && Time >= 3.1f)
    		{
    			float Factor = BallSpeed * App.GetFrameTime();
    			SpriteBall.Move(std::cos(BallAngle) * Factor, std::sin(BallAngle) * Factor);
    
    			if(App.GetInput().IsKeyDown(sf::Key::W) && (SpritePong1.GetPosition().y >= 0))
    				SpritePong1.Move(0, -400 * ElapsedTime);
    			if(App.GetInput().IsKeyDown(sf::Key::S) && (SpritePong1.GetPosition().y <= 420))
    				SpritePong1.Move(0, 400 * ElapsedTime);
    			if(App.GetInput().IsKeyDown(sf::Key::Up) && (SpritePong2.GetPosition().y >= 0))
    				SpritePong2.Move(0, -400 * ElapsedTime);
    			if(App.GetInput().IsKeyDown(sf::Key::Down) && (SpritePong2.GetPosition().y <= 420))
    				SpritePong2.Move(0, 400 * ElapsedTime);
    
    			if(SpriteBall.GetPosition().x < SpritePong1.GetPosition().x + SpritePong1.GetSize().x &&
    			   SpriteBall.GetPosition().x > SpritePong1.GetPosition().x + (SpritePong1.GetSize().x / 2.0f) &&
    			   SpriteBall.GetPosition().y + SpriteBall.GetSize().y >= SpritePong1.GetPosition().y &&
    			   SpriteBall.GetPosition().y <= SpritePong1.GetPosition().y + SpritePong1.GetSize().y)
    			{
    				BallAngle = PI - BallAngle;
    				SpriteBall.SetX(SpritePong1.GetPosition().x + SpritePong1.GetSize().x + 0.1f);
    				BufferHit.Play();
    			}
    
    			if(SpriteBall.GetPosition().x + SpriteBall.GetSize().x > SpritePong2.GetPosition().x &&
    			   SpriteBall.GetPosition().x + SpriteBall.GetSize().x < SpritePong2.GetPosition().x + (SpritePong2.GetSize().x / 2.0f) &&
    			   SpriteBall.GetPosition().y + SpriteBall.GetSize().y >= SpritePong2.GetPosition().y &&
    			   SpriteBall.GetPosition().y <= SpritePong2.GetPosition().y + SpritePong2.GetSize().y)
    			{
    				BallAngle = PI - BallAngle;
    				SpriteBall.SetX(SpritePong2.GetPosition().x - SpriteBall.GetSize().x - 0.1f);
    				BufferHit.Play();
    			}
    
    			if(SpriteBall.GetPosition().y < 0.f)
    			{
    				BallAngle = -BallAngle;
    				SpriteBall.SetY(0.1f);
    				BufferHit.Play();
    			}
    
    			if(SpriteBall.GetPosition().y + SpriteBall.GetSize().y > 480.f)
    			{
    				BallAngle = -BallAngle;
    				SpriteBall.SetY(480 - SpriteBall.GetSize().y - 0.1f);
    				BufferHit.Play();
    			}
    
    			if(SpriteBall.GetPosition().x < 0.f)
    			{
    				GameRunning = false;
    				EndGame.SetText("  Player 2 wins!\nCongratulations!");
    			}
    			if(SpriteBall.GetPosition().x + SpriteBall.GetSize().x > App.GetView().GetRect().GetWidth())
    			{
    				GameRunning = false;
    				EndGame.SetText("  Player 1 wins!\nCongratulations!");
    			}
    		}
    		App.Clear(sf::Color(100, 200, 150));
    		if(Time < 0.8f)
    			App.Draw(SpriteThree);
    		else if(Time < 1.8f)
    			App.Draw(SpriteTwo);
    		else if(Time < 2.8f)
    			App.Draw(SpriteOne);
    		else if(Time < 3.3f)
    			App.Draw(SpriteGo);
    		else if(Time > 3.3f)
    			App.Draw(SpriteDarkBG);
    		App.Draw(SpritePong1);
    		App.Draw(SpritePong2);
    		App.Draw(SpriteBall);
    		if(GameRunning == false)
    			App.Draw(EndGame);
    		App.Display();
    	}
    	return EXIT_SUCCESS;
    }
    There we go. There are some unused parts of code, that's just beginnings or tests of what i am doing. Also no menu yet, as i said.

    Also about variables sharing between the menu and the game... It won't share any. Except the options menu. In the options, you will be able to define what some variables will be in the game. I guess i should write them to some config file maybe, not sure if that's the best way though. And i still need to find out how to write/read from .txt file, if this is the better way.

    Anyway, thanks for help, i'm going to wake up a little bit more and start working on better physics.

Popular pages Recent additions subscribe to a feed

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21