• Advertisement
Sign in to follow this  

Unity [Pong] Debugging Ball Movement

This topic is 1895 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

Hello community,

[i]Project: Pong, Lang + Library: C++, SFML[/i]

I am having a small issue with the Ball movement. It works, when a collision is detected, I negate the Xspeed or Yspeed of the ball so that it reverses direction. Currently I only do this when it hits the screen edge. as I want to understand the issue before I continue. My issue is that when Breakpoint my code (at any place), I find that the X/Y coordinates inflate to a massive size, depending on where the ball was before a break occurred. For example; If the ball is about to hit the right-edge and it breaks on hit, then cycling through the breakpoint makes it jump from 800 (Screen Edge) to 3400, which is way outside the bounds of the play area. It is also same for the Y, even if a collision doesn't occur, it's like the debugger interrupts the logic in some way.

Also, when I break and then return to the window, the sprites on the screen no longer move and nothing happens. I don't remember anything like this happening when I was using Allegro 4, is this some sort of issue with SFML (the display, not so much the logic)?

I have included the code for the Entire ball class and the portion which deals with Collision from the Game loop:


[source lang="cpp"]#ifndef BALL_H
#define BALL_H

class Ball
{
public:

Ball(sf::Vector2f position, float speed); // constructor
~Ball(); // destructor

void MoveBall(float elapsedTime); // Move the ball.
void ReverseSpeed(int colType); // Set the speed to different values depending on what has occured.
bool LoadImage(std::string filename);
void DisplayBall(sf::RenderWindow &targetWindow);
sf::Rect<float> getArea();
private:

sf::Vector2f position_;
float speed_;
sf::Image ballImage_;
sf::Sprite ballSprite_;
bool isFileLoaded_;
float xSpeed_, ySpeed_;
};

#endif BALL_H[/source]

[source lang="cpp"]#include "stdafx.h"
#include "Ball.h"

Ball::Ball(sf::Vector2f position, float speed)
{
position_ = position;
speed_ = 35.0f;
isFileLoaded_ = false;
xSpeed_ = -65.0f;
ySpeed_ = 65.0f;
}

Ball::~Ball()
{
}

void Ball::MoveBall(float elapsedTime)
{
position_.x += (xSpeed_ * elapsedTime);
position_.y += (ySpeed_ * elapsedTime);
}

void Ball::ReverseSpeed(int colType)
{
if(colType == 1)
xSpeed_ = -xSpeed_;
else if(colType == 2)
ySpeed_ = -ySpeed_;
}

bool Ball::LoadImage(std::string filename)
{
// Load an image using the string provided.
if(!ballImage_.LoadFromFile(filename))
{
// If the file cannot be found, then the method returns
// false, could be used to load a default graphic or exit.
return false;
}
else
{
// Else, set the sprite to the image loaded.
// and set file loaded to True.
ballSprite_.SetImage(ballImage_);
// set the sprite position to that of the class position/centre.
ballSprite_.SetCenter(ballSprite_.GetSize().x/2, ballSprite_.GetSize().y/2);
ballSprite_.SetPosition(position_);
// set the file loaded boolean to true, for other functions to use.
isFileLoaded_ = true;

// Return successful.
return true;
}
}

void Ball::DisplayBall(sf::RenderWindow &targetWindow)
{
if(isFileLoaded_)
{
ballSprite_.SetPosition(position_.x, position_.y);
sf::Shape rect = sf::Shape::Rectangle(position_, sf::Vector2f(position_.x + 32, position_.y + 32), sf::Color(255,255,0), 0, sf::Color(0,0,0));
targetWindow.Draw(rect);
targetWindow.Draw(ballSprite_);
}
}

sf::Rect<float> Ball::getArea()
{
/*sf::Shape colRect = sf::Shape::Rectangle(position_.x - (ballSprite_.GetSize().x/2),
position_.y - (ballSprite_.GetSize().y/2),
position_.x + (ballSprite_.GetSize().x/2),
position_.y + (ballSprite_.GetSize().y/2),
sf::Color(0, 0, 0),
0,
sf::Color(0, 0, 0));*/
sf::Rect<float> colRect(position_.x - (ballSprite_.GetSize().x/2),
position_.y - (ballSprite_.GetSize().y/2),
position_.x + (ballSprite_.GetSize().x/2),
position_.y + (ballSprite_.GetSize().y/2));

return colRect;
}[/source]

[source lang="cpp"]//TODO: collision does not work for negative values.
if(ball_->getArea().Left <= 0 || ball_->getArea().Right >= 800)
{
ball_->ReverseSpeed(1);
}
else if(ball_->getArea().Top <= 0 || ball_->getArea().Bottom >= 600)
{
ball_->ReverseSpeed(2);
}
ball_->MoveBall(gameWindow_.GetFrameTime());[/source]


Please ignore some of the hard-coded values for collision/the fact ball handles drawing, it's stuff I intend to work on once I get the basic game down.

Regards,

Stitchs.

Share this post


Link to post
Share on other sites
Advertisement
I dont see how do you count elapsedTime. Its better to have an 50 millisec (or something like that) limit, .....plus pause the game when the window loses focus.

Share this post


Link to post
Share on other sites
Two things:
I'm not sure if elapsed time is your delta time or if it's just a counter variable on how long the application has been running for
So have you tried doing this?

[CODE]
void Ball::MoveBall(float elapsedTime)
{
position_.x += xSpeed_;
position_.y += ySpeed_;
}
[/CODE]

And what's the point of the speed variable? Also you should at least assign the speed variable in your constructor
[CODE]
Ball::Ball(sf::Vector2f position, float speed)
{
position_ = position;
speed_ = speed; // changed from 35.0f
isFileLoaded_ = false;
xSpeed_ = -65.0f;
ySpeed_ = 65.0f;
}
[/CODE]

You could use a sf::Vector2 to determine the direction of what the ball requires to go in (you should pre normalise it though) and your speed variable for the multiplier

i.e.
[CODE]
void Ball::MoveBall(float elapsedTime)
{
// where direction is a normalised vector
position_ += direction_ * speed_;
}
[/CODE] Edited by pinebanana

Share this post


Link to post
Share on other sites
[quote name='pinebanana' timestamp='1352617290' post='4999833']
i.e.
void Ball::MoveBall(float elapsedTime)
{
// where direction is a normalised vector
position_ += direction_ * speed_;
}

[/quote]

[u]speed_x [/u]and [u]speed_y [/u]already determine [u]direction [/u]and [u]speed.[/u]
obejct_position+= move_dir * move_speed can be used when you want the move the object(or camera) "manually" but even then you need the elapsedTime.

Share this post


Link to post
Share on other sites
I derive my elapsed time from the sf::Window.GetFrameTime(), which I have since learned is somewhat inaccurate, so now I manage a Clock provided by SFML. This is passed in and helps to control the speed of the logic.

The speed parameter in my Ball is known to be unset (embarrassingly, I should have edited that out before posting) and it will be used, I was just using hard-coded values in order to determine the cause of my issue, and would set it so after.

@Aliii; how would I limit the frame time, should I divide the FrameTime by a value and make a check on some sort of millisecond cap and reduce should it go over?

Regards,

Stitchs.

Share this post


Link to post
Share on other sites
Just simply limit it:)

At the start of the iteration you have to determine how much time has passed since the last iteration:

[CODE]
gameLoop{

passed_time= whatever.getPassedTime();
if( passed_time > some_value)
passed_time= some_value;

input();
physics( passed_time);
render();
....
....

}
[/CODE]

Its up to you how you measure the delta time. To the physics function always pass the passed seconds in a float.
In a simple game like this it can happen that the passed millisecond since the last iteration will be less than 1 ms, ...so watch out for that.
Ideally if you add all your passed_time values in one real second it should be equal to 1 second.

If some program starts in the background the passed_time can be 1000 millisecs or more ....so if your speed was 15 m/s you will move 15 meters in one iteration. ....you fly through the wall or something ...you dont want that. Thats why you limit it.

Share this post


Link to post
Share on other sites
I had a similar problem that only showed up when I was debugging. Its because the game timer is working off of real wall-clock time and when you pause, the timer is still going. You can can fix it by making your timer send fixed increments or looking for exceptionally large values and capping them at a normal amount. In my system, any frame times > 200ms was considered a significant lag and a 16ms was returned as the frame time. This helped me debug things as though there were happening at a normal rate, while I took my sweet time figuring out my bugs in the debugger.

Cheers,

Bob

Share this post


Link to post
Share on other sites
You should also reposition the ball after collision.

Example
if(ball.y < 0)
{
ball.y = 0;
then reverse directions.
}

Share this post


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

  • Advertisement
  • Advertisement
  • Popular Now

  • Advertisement
  • Similar Content

    • By eldwin11929
      We're looking for programmers for our project.
      Our project is being made in Unity
      Requirements:
      -Skills in Unity
      -C#
      -Javascript
      -Node.js
      We're looking for programmers who can perform a variety of functions on our project.
      Project is a top-down hack-and-slash pvp dungeon-crawler like game. Game is entirely multiplayer based, using randomized dungeons, and a unique combat system with emphasis on gameplay.
      We have a GDD to work off of, and a Lead Programmer you would work under.
      Assignments may include:
      -Creating new scripts of varying degrees specific to the project (mostly server-side, but sometimes client-side)
      -Assembling already created monsters/characters with existing or non-existing code.
      -Creating VFX
      -Assembling already created environment models
      If interested, please contact: eldwin11929@yahoo.com
      This project is unpaid, but with royalties.
       
      ---
      Additional Project Info:
      Summary:
      Bassetune Reapers is a Player-verus-Player, competitive dungeon crawler. This basically takes on aspects of dungeon crawling, but with a more aggressive setting. Players will have the option to play as the "dungeon-crawlers" (called the 'Knights', or "Knight Class", in-game) or as the "dungeon" itself (literally called the 'Bosses', or "Boss Class", in-game). What this means is that players can choose to play as the people invading the dungeon, or as the dungeon-holders themselves.
      Key Features:
      -Intense, fast-paced combat
      -Multiple skills, weapons, and ways to play the game
      -Tons of different Bosses, Minibosses, creatures and traps to utilize throughout the dungeon
      -Multiple unique environments
      -Interesting, detailed lore behind both the game and world
      -Intricate RPG system
      -Ladder and ranking system
      -Lots of customization for both classes s of customization for both classes
    • By RoKabium Games
      Custom coffee mugs have arrived... More caffeine!
      Have a great weekend everyone! 
      #gamedev #indiedev #sama #caffeine
    • By Atwo Studios
       
      Hey guys,

      Anthony here from Atwo Studios bringing you some new updates for the new year!
      In this video I go over our game ROY, the new games and some general updates to the company!

      If you have not checked out ROY feel free to give it a try! Many people have said they enjoyed the game thus far!
      ROY: https://goo.gl/o6JJ5P
       
    • By Affgoo
      https://play.google.com/store/apps/details?id=com.NE.Alien
      still a lot of work to do, but its pretty stable  please let me know what you think <3
      Atlas Sentry is a game of destroy everything. Using your turret, simply swivel and shoot your way to victory, upgrading your weapons to unleash destruction on the variety of spaceships. The bigger your combo’s the more score you get! Earn silver as you play and then purchase new weapons and abilities to better deal with your enemy. Different enemies use different tactics and weapons, work out your own priorities in their destruction order. 

      Features: 
      **2 different game modes 
      **A level select mode with 20 difficult levels including a final boss, can you defeat it? **Arcade mode of endless destruction, how long will you last? 
      **High scores to compete against others, see who can take the top spot. 
       
    • By Chamferbox
      Chamferbox, a mini game asset store has just opened with some nice game assets, 
      Here you can find a free greek statue asset 

      Also check their dragon, zombie dragon and scorpion monster out:



      They're running the Grand Opening Sale, it's 30% off for all items, but for gamedev member, you can use this coupon code:
      GRANDOPEN
      to get 50% off prices What are you waiting for, go to
      http://chamferbox.com
      and get those models now!

      View full story
  • Advertisement