一个人玩未免有点沉闷,现在让我们来添加一个AI弹板来充当对手吧!!!
AIPaddle.h
#pragma once
#include "visiblegameobject.h"
class AIPaddle :
public VisibleGameObject
{
public:
AIPaddle(void);
~AIPaddle(void);
void Update(float elapsedTime);
void Draw(sf::RenderWindow& rw);
float GetVelocity() const;
private:
float _velocity;
float _maxVelocity;
};
AIPaddle.cpp
View Code
#include "StdAfx.h"
#include "AIPaddle.h"
#include "Game.h"
#include "GameBall.h"
AIPaddle::AIPaddle() :
_velocity(0),
_maxVelocity(600.0f)
{
Load("images/paddle.png");
assert(IsLoaded());
GetSprite().setOrigin(GetSprite().getLocalBounds().width /2, GetSprite().getLocalBounds().height / 2);
}
AIPaddle::~AIPaddle()
{
}
void AIPaddle::Draw(sf::RenderWindow & rw)
{
VisibleGameObject::Draw(rw);
}
float AIPaddle::GetVelocity() const
{
return _velocity;
}
void AIPaddle::Update(float elapsedTime)
{
const GameBall* gameBall = static_cast<GameBall*>
(Game::GetGameObjectManager().Get("Ball"));
sf::Vector2f ballPosition = gameBall->GetPosition();
if(GetPosition().x -20 < ballPosition.x)
_velocity += 15.0f;
else if(GetPosition().x +20 > ballPosition.x)
_velocity -= 10.0f;
else
_velocity = 0.0f;
if(_velocity > _maxVelocity)
_velocity = _maxVelocity;
if(_velocity < -_maxVelocity)
_velocity = -_maxVelocity;
sf::Vector2f pos = this->GetPosition();
if(pos.x <= GetSprite().getLocalBounds().width/2
|| pos.x >= (Game::SCREEN_WIDTH - GetSprite().getLocalBounds().width/2))
{
_velocity = -_velocity;
}
GetSprite().move(_velocity * elapsedTime, 0);
}
由于AI弹板也会反弹弹球,所以要把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;
//获取玩家弹板
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 playerVelocity1 = player1->GetVelocity();
//当弹板向左移动时
if(playerVelocity1 < 0)
{
//使弹球角度减少
_angle -= 20.0f;
if(_angle < 0 )
_angle = 360.0f - _angle;
}
else if(playerVelocity1 > 0)
{
_angle += 20.0f;
if(_angle > 360.0f)
_angle = _angle - 360.0f;
}
//每次碰撞弹板都使弹球速度增加
_velocity += 5.0f;
}
}
//敌人AI的设置
AIPaddle* player2 = dynamic_cast<AIPaddle*>(Game::GetGameObjectManager().Get("Paddle2"));
if(player2 != NULL)
{
//存储AI弹板的矩形区域
sf::Rect<float> p2BB = player2->GetBoundingRect();
//检测AI弹板的矩形区域与弹球的矩形区域是否有重叠
//有则表示发生了碰撞,然后处理相关反弹的细节
if(p2BB.intersects(GetBoundingRect()))
{
_angle = 360.0f - (_angle - 180.0f);
if(_angle > 360.0f)
_angle -= 360.0f;
moveByY = -moveByY;
// 确保弹球不会跑到弹板的矩形区域内
if(GetBoundingRect().width > player2->GetBoundingRect().width)
{
SetPosition(GetPosition().x,player2->GetBoundingRect().width - GetWidth()/2 -1 );
}
float playerVelocity2 = player2->GetVelocity();
//当弹板向左移动时
if(playerVelocity2 < 0)
{
//使弹球角度减少
_angle -= 20.0f;
if(_angle < 0 )
_angle = 360.0f - _angle;
}
else if(playerVelocity2 > 0)
{
_angle += 20.0f;
if(_angle > 360.0f)
_angle = _angle - 360.0f;
}
//每次碰撞弹板都使弹球速度增加
_velocity += 5.0f;
}
}
//当弹球碰撞到屏幕两边时的处理
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;
}
//当弹球碰撞到屏幕上方则令其反弹
if(GetPosition().y - GetHeight()/2 <= 0)
{
// _angle = 180 - _angle;
// moveByY = -moveByY;
GetSprite().setPosition(Game::SCREEN_WIDTH/2, Game::SCREEN_HEIGHT/2);
_angle = std::rand() % 360 + 1;
_velocity = 220.0f;
_elapsedTimeSinceStart = 0.0f;
}
//当弹球落到比弹板低的地方则重置弹球
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 ));
}
最后还要回到Game.cpp中把AI弹板加进去(Game.h别忘记include AIPaddle)
//添加玩家弹板并设置其位置
PlayerPaddle *player1 = new PlayerPaddle();
player1->Load("images/paddle.png");
player1->SetPosition((SCREEN_WIDTH/2),700);
//添加敌人AI
AIPaddle * player2 = new AIPaddle();
player2->SetPosition((SCREEN_WIDTH/2),40);
//添加弹球
GameBall *ball = new GameBall();
ball->SetPosition((SCREEN_WIDTH/2),(SCREEN_HEIGHT/2)-15);
_gameObjectManager.Add("Paddle1",player1);
_gameObjectManager.Add("Paddle2",player2);
_gameObjectManager.Add("Ball",ball);
于是一个游戏的雏形就此诞生了
如果觉得过程太乱的话,下载完整代码回去慢慢查看吧~~~~~
Part2
原文链接: https://www.cnblogs.com/tomboy/archive/2012/06/30/2571076.html
欢迎关注
微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍
原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/54079
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!