博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
使用C++与SFML编写一个简单的撞球游戏Part8——添加AI弹板
阅读量:5902 次
发布时间:2019-06-19

本文共 6984 字,大约阅读时间需要 23 分钟。

一个人玩未免有点沉闷,现在让我们来添加一个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
(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
(Game::GetGameObjectManager().Get("Paddle1")); if(player1 != NULL) { //存储玩家弹板的矩形区域 sf::Rect
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
(Game::GetGameObjectManager().Get("Paddle2")); if(player2 != NULL) { //存储AI弹板的矩形区域 sf::Rect
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);

 

于是一个游戏的雏形就此诞生了

 

 

如果觉得过程太乱的话,下载完整代码回去慢慢查看吧~~~~~

转载于:https://www.cnblogs.com/tomboy/archive/2012/06/30/2571076.html

你可能感兴趣的文章
DW 正则
查看>>
抓屏原理
查看>>
UNIX网络编程读书笔记:TCP输出、UDP输出和SCTP输出
查看>>
扩展 DbUtility (1)
查看>>
iOS开发UI篇—使用picker View控件完成一个简单的选餐应用
查看>>
Apple Developer Registration and DUNS Number Not Accepted
查看>>
Hadoop学习笔记系列文章导航
查看>>
SpringMVC中ModelAndView addObject()设置的值jsp取不到的问题
查看>>
Prometheus : 入门
查看>>
使用 PowerShell 创建和修改 ExpressRoute 线路
查看>>
PHP如何学习?
查看>>
在C#中获取如PHP函数time()一样的时间戳
查看>>
Redis List数据类型
查看>>
大数据项目实践(四)——之Hive配置
查看>>
初学vue2.0-组件-文档理解笔记v1.0
查看>>
NG-ZORRO-MOBILE 0.11.9 发布,基于 Angular 7 的 UI 组件
查看>>
我就是一个救火员(DBA救援)
查看>>
Centos7安装Gitlab10.0
查看>>
Windows Server 笔记(六):Active Directory域服务:域控制器安装
查看>>
discuz X3登录流程分析
查看>>