Jump to content

  • Log In with Google      Sign In   
  • Create Account


Problem animating sprite in SFML 2


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
1 reply to this topic

#1 pharaoh357   Members   -  Reputation: 132

Like
0Likes
Like

Posted 22 October 2012 - 03:27 AM

Hello guys I am new to game programming, I never programmed a game in my life, I am starting small with C++ and sfml 2 creating a pong game, but, I ran into an issue, I was trying to deform the ball when it hits the borders, but I am failing to get the result I want, the animation is no seamless and don't know how to correct It. Can someone help.

Here is the code (you can get it too at : https://bitbucket.or...n/pong-pong/src)

header file

[source lang="cpp"]/** FILE : PongBall.hxx* AUTHOR : ed3lgon* CREATED : Oct 21, 2012* MODIFIED : Undefined* PURPOSE : Undefined* DESCRIPTION : Undefined*/#ifndef PONGBALL_HXX_#define PONGBALL_HXX_#include <SFML/Graphics.hpp>using namespace sf;class PongBall{ public: PongBall(RenderWindow& pGameDisplay); ~PongBall(); void move(const Time& pElapsedTime); void draw(); const Sprite& getSprite(); private: static const float BALL_SPEED = 120.0f; static const float BALL_DIAMETER = 50.0f; int mImageIndex; // reference to game window RenderWindow& mGameDisplay; Texture mBallSpriteSheet; Sprite mBallSprite; // will hold coordinates to images in the texture IntRect mTextureRect[9]; enum Direction { NEGATIVE_X, NEGATIVE_Y, NEGATIVE_DIAGONAL1, NEGATIVE_DIAGONAL_2, POSITIVE_X, POSITIVE_Y, POSITIVE_DIAGONAL1, POSITIVE_DIAGONAL2, NONE, }; enum AnimationStatus { START_ANIMATE, END_ANIMATE, DEFAULT_ANIMATE, }; // indicates the direction the ball is facing, i.e. It is moving to. Direction mDirection; AnimationStatus mAnimtionStatus;};#endif /* PONGBALL_HXX_ */[/source]

here is the implementation:
[source lang="cpp"]/** FILE : PongBall.cxx* AUTHOR : ed3lgon* CREATED : Oct 21, 2012* MODIFIED : Undefined* PURPOSE : Undefined* DESCRIPTION : Undefined*/#include "PongBall.hxx"#include <iostream>PongBall::PongBall(RenderWindow& pGameDisplay) : mImageIndex(0), mGameDisplay(pGameDisplay), mDirection(POSITIVE_X), mAnimtionStatus(DEFAULT_ANIMATE){ // initialize horizontal images coordinates. // this one is the default image, i.e. with no deformation. mTextureRect[0].left = 0; mTextureRect[0].top = 0; mTextureRect[0].width = 51; mTextureRect[0].height = 51; // ball with minimum horizontal deformation. mTextureRect[1].left = 51; mTextureRect[1].top = 0; mTextureRect[1].width = 49; mTextureRect[1].height = 51; // ball with medium horizontal deformation. mTextureRect[2].left = 99; mTextureRect[2].top = 0; mTextureRect[2].width = 48; mTextureRect[2].height = 51; // the second most deformed ball. mTextureRect[3].left = 147; mTextureRect[3].top = 0; mTextureRect[3].width = 46; mTextureRect[3].height = 51; // ball with max horizontal deformation. mTextureRect[3].left = 197; mTextureRect[3].top = 0; mTextureRect[3].width = 42; mTextureRect[3].height = 51; // initialize vertical images coordinates. // minimum vertical deformation. mTextureRect[4].left = 0; mTextureRect[4].top = 51; mTextureRect[4].width = 51; mTextureRect[4].height = 48; // medium vertical deformation. mTextureRect[5].left = 51; mTextureRect[5].top = 51; mTextureRect[5].width = 51; mTextureRect[5].height = 47; // maximum vertical deformation. mTextureRect[6].left = 102; mTextureRect[6].top = 51; mTextureRect[6].width = 52; mTextureRect[6].height = 45; // maximum vertical deformation. mTextureRect[6].left = 154; mTextureRect[6].top = 51; mTextureRect[6].width = 51; mTextureRect[6].height = 43; // load ball texture and set sprite texture. mBallSpriteSheet.loadFromFile("res/gfx/ball_sheet.png"); mBallSprite.setTexture(mBallSpriteSheet); mBallSprite.setTextureRect(mTextureRect[mImageIndex]); // position ball at (100, 100) mBallSprite.setPosition(500.0f, 300.0f);}PongBall::~PongBall(){}void PongBall::move(const Time& pElapsedTime){ // get ball position on screen. Vector2f ballPosition = mBallSprite.getPosition(); const float amount = BALL_SPEED * pElapsedTime.asSeconds(); // move the ball acording to the position It is facing switch (mDirection) { // here I decrement ball's X cordinate and check if it has it the border. case NEGATIVE_X: ballPosition.x -= amount; // if ball has touched the border invert direction if (ballPosition.x < 1) { ballPosition.x = 0; switch (mAnimtionStatus) { case START_ANIMATE: ++mImageIndex; if (mImageIndex == 5) { mAnimtionStatus = END_ANIMATE; } break; case END_ANIMATE: --mImageIndex; if (mImageIndex == 0) { mDirection = POSITIVE_X; mAnimtionStatus = DEFAULT_ANIMATE; } break; case DEFAULT_ANIMATE: mAnimtionStatus = START_ANIMATE; break; default: break; } } break; case NEGATIVE_Y: ballPosition.y -= amount; if (ballPosition.y < 0) { ballPosition.y += amount; mDirection = POSITIVE_Y; } break; case NEGATIVE_DIAGONAL1: break; case NEGATIVE_DIAGONAL_2: break; case POSITIVE_X: ballPosition.x += amount; // if ball has touched the right border if (ballPosition.x > (1024 - BALL_DIAMETER)) { ballPosition.x -= amount; switch (mAnimtionStatus) { case START_ANIMATE: mImageIndex++; if (mImageIndex == 5) { mAnimtionStatus = END_ANIMATE; } break; case END_ANIMATE: mImageIndex--; if (mImageIndex == 0) { mDirection = NEGATIVE_X; mAnimtionStatus = DEFAULT_ANIMATE; } break; case DEFAULT_ANIMATE: mAnimtionStatus = START_ANIMATE; break; default: break; } } break; case POSITIVE_Y: ballPosition.y += amount; if (ballPosition.y > (600 - BALL_DIAMETER)) { ballPosition.y -= amount; mDirection = NEGATIVE_Y; } break; case POSITIVE_DIAGONAL1: break; case POSITIVE_DIAGONAL2: break; default: break; } // update sprite rect. mBallSprite.setTextureRect(mTextureRect[mImageIndex]); // update sprite position mBallSprite.setPosition(ballPosition);}void PongBall::draw(){ mGameDisplay.draw(mBallSprite);}[/source]

Sponsor:

#2 nox_pp   Members   -  Reputation: 490

Like
2Likes
Like

Posted 22 October 2012 - 08:40 AM

You're controlling the speed of the ball, but you aren't controlling the speed of the animation. In the same way that you calculate "amount" in PongBall::move, you need to calculate what frame of the animation you should be on based upon what fps you would like your animation to play at. Only increment mImageIndex when you've accumulated enough time for a frame.

Something like this, following the pattern of your code:


mAnimationAccum += ANIMATION_SPEED * pElapsedTime.AsSeconds();

if(mAnimationAccum >= 1){
    mAnimationAccum = 0;
    ++mImageIndex;
}

Say ANIMATION_SPEED is 30, for 30 fps. Then everytime mAnimationAccum == 1, 1/30 of a second has passed, so we increment the frame we're on and reset the accumulator. You'll probably want ANIMATION_SPEED to be 5-10 fps, but I suppose it depends on how fast the ball is moving on screen.

Between Scylla and Charybdis: First Look <-- The game I'm working on

 

Object-Oriented Programming Sucks <-- The kind of thing I say





Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS