这一Part,我们会让球动起来!!!
在VisibleGameObject.h的public部分
//获取精灵对象的宽
virtual float GetWidth() const;
//获取精灵对象的高
virtual float GetHeight() const;
//获取精灵对象的矩形区域
virtual sf::Rect<float> GetBoundingRect() const;
VisibleGameObject.cpp
float VisibleGameObject::GetHeight() const
{
return _sprite.getLocalBounds().height;
}
float VisibleGameObject::GetWidth() const
{
return _sprite.getLocalBounds().width;
}
sf::Rect<float> VisibleGameObject::GetBoundingRect() const
{
return _sprite.getGlobalBounds();
}
接下来回到Game类补充一个函数,Game.h的public部分
const static GameObjectManager& GetGameObjectManager();
Game.cpp中的实现
const GameObjectManager& Game::GetGameObjectManager()
{
return Game::_gameObjectManager;
}
最后就是我们的压轴嘉宾——GameBall类,代码有点长,GameBall.h
#pragma once
#include "visiblegameobject.h"
//继承自VisibleGameObject
class GameBall :
public VisibleGameObject
{
public:
GameBall();
virtual ~GameBall();
void Update(float); //更新弹球属性状态
private:
float _velocity; //速度
float _angle; //移动的方向
float _elapsedTimeSinceStart; //游戏总时间
float LinearVelocityX(float angle); //水平线速度
float LinearVelocityY(float angle); //垂直线速度
};
GameBall.cpp
View Code
#include "StdAfx.h"
#include "GameBall.h"
#include "Game.h"
GameBall::GameBall() :
_velocity(230.0f),
_elapsedTimeSinceStart(0.0f)
{
//assert方法作用:括号里面的表达式必须返回true,若返回false则会出现系统错误
Load("images/ball.png");
assert(IsLoaded());
GetSprite().setOrigin(15,15);
//设置弹球的移动方向为1到360之间的随机值
_angle = std::rand() % 360 + 1;
//_angle = (float)(sf::Randomizer::Random(0,360);
}
GameBall::~GameBall()
{
}
void GameBall::Update(float elapsedTime)
{
_elapsedTimeSinceStart += elapsedTime;
// 设置弹球在开始游戏3秒后才开始更新
if(_elapsedTimeSinceStart < 3.0f)
return;
//弹球每帧的移动距离
float moveAmount = _velocity * elapsedTime;
//水平位移
float moveByX = LinearVelocityX(_angle) * moveAmount;
//垂直位移
float moveByY = LinearVelocityY(_angle) * moveAmount;
//当弹球碰撞到屏幕两边时的处理
if(GetPosition().x + moveByX <= 0 + GetWidth()/2
|| GetPosition().x + GetHeight()/2 + moveByX >= Game::SCREEN_WIDTH)
{
//调整方向以及更改水平位移使其反弹
_angle = 360.0f - _angle;
if(_angle > 260.0f && _angle < 280.0f)
_angle += 20.0f;
if(_angle > 80.0f && _angle < 100.0f)
_angle += 20.0f;
moveByX = -moveByX;
}
//获取玩家弹板
PlayerPaddle* player1 = dynamic_cast<PlayerPaddle*>(Game::GetGameObjectManager().Get("Paddle1"));
if(player1 != NULL)
{
//存储玩家弹板的矩形区域
sf::Rect<float> p1BB = player1->GetBoundingRect();
//检测玩家弹板的矩形区域与弹球的矩形区域是否有重叠
//有则表示发生了碰撞,然后处理相关反弹的细节
if(p1BB.intersects(GetBoundingRect()))
{
_angle = 360.0f - (_angle - 180.0f);
if(_angle > 360.0f)
_angle -= 360.0f;
moveByY = -moveByY;
// 确保弹球不会跑到弹板的矩形区域内
if(GetBoundingRect().width > player1->GetBoundingRect().top)
{
SetPosition(GetPosition().x,player1->GetBoundingRect().top - GetWidth()/2 -1 );
}
float playerVelocity = player1->GetVelocity();
//当弹板向左移动时
if(playerVelocity < 0)
{
//使弹球角度减少
_angle -= 20.0f;
if(_angle < 0 )
_angle = 360.0f - _angle;
}
else if(playerVelocity > 0)
{
_angle += 20.0f;
if(_angle > 360.0f)
_angle = _angle - 360.0f;
}
//每次碰撞弹板都使弹球速度增加
_velocity += 5.0f;
}
//当弹球碰撞到屏幕上方则令其反弹
if(GetPosition().y - GetHeight()/2 <= 0)
{
_angle = 180 - _angle;
moveByY = -moveByY;
}
//当弹球落到比弹板低的地方则重置弹球
if(GetPosition().y + GetHeight()/2 + moveByY >= Game::SCREEN_HEIGHT)
{
GetSprite().setPosition(Game::SCREEN_WIDTH/2, Game::SCREEN_HEIGHT/2);
_angle = std::rand() % 360 + 1;
_velocity = 220.0f;
_elapsedTimeSinceStart = 0.0f;
}
//弹球的移动函数
GetSprite().move(moveByX,moveByY);
}
}
float GameBall::LinearVelocityX(float angle)
{
angle -= 90;
if (angle < 0)
angle = 360 + angle;
return (float)std::cos( angle * ( 3.1415926 / 180.0f ));
}
float GameBall::LinearVelocityY(float angle)
{
angle -= 90;
if (angle < 0)
angle = 360 + angle;
return (float)std::sin( angle * ( 3.1415926 / 180.0f ));
}
至此如无意外你将得到像下图那样游戏,赶快按F5试试吧~~~~~