Jump to content
  • Advertisement
Sign in to follow this  
Camilos

noob stuck with code

This topic is 1438 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

ok, i'm a total noob at coding (just started two days ago) and finished reading "Learning c++ through game programming".

There where still something I have problems with but I really wanted to take a break a screw around a bit so I started programming something I hope it will be an asteroids copy. I want to do it step by step and is more for the fun before i really start studying again.

But i'm currently stuck and I really want to know how to fix it (I think I know the problem but i just don't really know how to fix it)(I'm using the pong example of sfml as reference)

#include <SFML\Graphics.hpp>
#include <SFML\Window.hpp>
#include <iostream>
#include <ctime>

int main(){
	// Constanten//
	const int GameWidth = 800;
	const int GameHeight = 600;
	const int Speed = 5;
	sf::Clock clock;
	bool isPlaying = false;
	sf::RenderWindow window(sf::VideoMode(GameWidth,GameHeight ,32),"Asteroids");

	//bouwen van schip//
	sf::CircleShape triangle(15,3);
	triangle.setFillColor(sf::Color::Black);
	triangle.setOutlineColor(sf::Color::White);
	triangle.setOutlineThickness(3);
	triangle.setPosition((GameWidth/2),(GameHeight/2));
	
	// Opening scherm //
	while(window.isOpen()){
		sf::Event Event;
		bool isPlaying = false;
		while(window.pollEvent(Event)){
			if((Event.type == sf::Event::Closed)||((Event.type == sf::Event::KeyPressed)&&(Event.key.code== sf::Keyboard::Escape))){
				window.close();
			};
			//starten//					
			if((Event.type == sf::Event::KeyPressed)&&(Event.key.code == sf::Keyboard::E)){
				if(!isPlaying){
					isPlaying = true;
					triangle.setPosition((GameWidth/2),(GameHeight/2));
				}
				if(isPlaying){
						
					if((Event.type == sf::Event::KeyPressed)&&(Event.key.code == sf::Keyboard::Z))
					{
						sf::Time tijd = clock.getElapsedTime();

						float deltaTime = tijd.asSeconds();

						triangle.move(0, -Speed*deltaTime);
						clock.restart();
					}
				}
			}

			//Weergeven schermen //
			window.clear(sf::Color::Black);
			window.draw(triangle);
			window.display();
		};
	};
return 0;
}

The place where i'm stuck is the movement code. I'm thinking it is because there is to little time between activation and restarting for it to really move but still I can't see anything. Please tell me what i did wrong and how I can fix this

Edited by Camilos

Share this post


Link to post
Share on other sites
Advertisement

Don't do logic updating inside your event reactions.

 

Here's an example of a possible layout that works decently well:

int main()
{
	const float UpdateTickInterval = (1.0f / 30.0f); //30 times a second.

	//Create the window.
	sf::RenderWindow renderWindow.create(sf::VideoMode(800, 600), "My game");

	//Set the icon.
	sf::Image iconImage;
	AssertExpr(iconImage.loadFromFile("./Icon.png"));
	renderWindow.setIcon(iconImage.getSize().x, iconImage.getSize().y, iconImage.getPixelsPtr());

	//Begin tracking the framerate.
	sf::Clock updateClock;

	//Create the root gamestate.
	RootGameState rootGameState;

	//Main loop.
	while(rootGameState.StillRunning())
	{
		//Process the events.
		sf::Event event;
		while(renderWindow.pollEvent(event))
		{
			//Send the game states the events.
			rootGameState.DoReacting(event);
		}

		//Update everything, if we've accumulated enough time.
		//Also do logic; for performance reasons, we don't need to do thinking and updating every frame.
		if(updateClock.getElapsedTime().asSeconds() > UpdateTickInterval)
		{
			rootGameState.DoUpdating(updateClock.restart().asSeconds());
		}

		//Clear the window.
		renderWindow.clear(sf::Color::Black);

		//Draw everything.
		rootGameState.DoDrawing(renderWindow);

		//Display everything.
		renderWindow.display();
	}

	return 0;
}

Note: There are better ways to handle updating, so things look smoother, but for a basic 2D game, this works well enough.

 

When you get a keypress, store the result like 'movingLeft = true' (or let SFML store it for you in sf::Keyboard::isKeyPressed()), as Misantes mentioned), and then in your update function, update the movement for as long as 'movingLeft' is still true, based on the speed of the player and the amount of time pressed. Or you can give the player a velocity, change the current velocity in the event-handling function, but continually apply the velocity to the actual player position, based on the amount of time passed, in the update() function.

Share this post


Link to post
Share on other sites

Thanks alot for you're comments, the problem is now fixed :D

Think there where 2 main problems:

1) is the fact the isPlaying kept on getting resetted to false (thx crossbones)

2) I messed up with my loops: the part of code that was responsible of the movement was inside if statement for activating the game (thx Diego)

 

also thank you Misantes  for telling me how to have a smoother action.

Share this post


Link to post
Share on other sites

So i've been playing around moving my triangle when I noticed something and I wonder if it can be fixed:

when i'm turning and holding down both Z and Q or D, I turn but when i let go of Q or D and keep Z down, it stops moving. Now i'm wondering why and how I can fix this.

This is the code i'm using.

// Opening scherm //
	while(window.isOpen()){
		sf::Event Event;
		
		while(window.pollEvent(Event)){
			if((Event.type == sf::Event::Closed)||((Event.type == sf::Event::KeyPressed)&&(Event.key.code== sf::Keyboard::Escape))){
				window.close();
			};
			//starten//					
			if((Event.type == sf::Event::KeyPressed)&&(Event.key.code == sf::Keyboard::E)){
				if(!isPlaying){
					isPlaying = true;
					triangle.setPosition((GameWidth/2),(GameHeight/2));
				}
			}
			
			

			if((isPlaying && sf::Keyboard::isKeyPressed(sf::Keyboard::Z)))
					{

						
					float SpeedY = (Speed * cos(triangle.getRotation()*degree)) ;
					float SpeedX = (Speed * sin(triangle.getRotation()*degree));
					 

					triangle.move(SpeedX,-SpeedY);
														 
			};

				if(isPlaying && sf::Keyboard::isKeyPressed(sf::Keyboard::Q))
				{	
					triangle.setRotation(triangle.getRotation()-1);
					
				};
				
				if(isPlaying && sf::Keyboard::isKeyPressed(sf::Keyboard::D)){
					triangle.setRotation(triangle.getRotation()+1);
						if(isPlaying && sf::Keyboard::isKeyPressed(sf::Keyboard::Q))
				{	
					triangle.setRotation(triangle.getRotation()-1);
					
				};
					
				};
						  
			if((isPlaying && sf::Keyboard::isKeyPressed(sf::Keyboard::S)))
					{

						
					float SpeedY = (Speed * cos(triangle.getRotation()*degree)) ;
					float SpeedX = (Speed * sin(triangle.getRotation()*degree));
					 

					triangle.move(SpeedX,SpeedY);

														 
			};		
			if(isPlaying && sf::Keyboard::isKeyPressed(sf::Keyboard::Space)){
				window.draw(bullet);
			}

			}

			//Weergeven schermen //
			window.clear(sf::Color::Black);
			window.draw(triangle);
			window.display();
	};
	
return 0;
}

Share this post


Link to post
Share on other sites

The "while(window.pollEvent(Event))" loop will only be accessed when an event occurs, and holding a key down is not an event.

 

Inside that loop, check for events, like closing the window. The "isKeyPressed" calls should be done outside that loop.

 

EDIT: Sorry, I see you get an event, but with the delay Misantes mentioned. But, anyway, the isKeyPressed should be outside the loop, see if that makes a difference.

Edited by DiegoSLTS

Share this post


Link to post
Share on other sites

I have another question (hopefully this doesn't annoy you guys)

Basicly i want to create an object that starts moving at the beginning of the game and keeps on moving until something happens and i succeeded. The problem is that the movement happens in "jumps": it moves, then stops for a sec and then moves again. Now i'm wondering how i can move it without stopping and without using keys or something like that.

 

ps here is the code i'm using, it's pretty simple: 

Ball.move(std::cos(BallAngle)*BallSpeed*deltaTime,std::sin(BallAngle)*BallSpeed*deltaTime);

Share this post


Link to post
Share on other sites

Where are you putting that line? You may want to post a larger snippet of the code for this question. It could depend on how you're calculating deltaTime, BallSpeed, where you're placing this line or any number of things.

 

You may want to take a look at implementing a time-step. I'm not sure if that's the issue, but often times without one, you'll get funny updates. As a minor note, if your ball angle is pretty consistent, and only changes on certain states, you may not want to recalculate the sin/cos of the angle every iteration (unless it's say, a homing missile headed for a moving target). Calculate the angle once, when needed, and set it as your move parameter until its state needs to change, recalculate, etc (also, probably not the issue).

Edited by Misantes

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!