c++ - C ++ SFML如何用自己的物理特性使子弹产生?
问题描述
我正在用 C++ 和 SFML 制作一个简单的子弹地狱游戏,您可以在其中使用鼠标控制播放器,然后单击目标以增加分数。每次点击一个目标时,它都应该在远离玩家的位置生成一颗子弹,并且具有随机的行进角度。子弹从窗户边缘弹开,并没有消失。
我真的很困惑如何做到这一点,我可能想尝试的一种方法是将子弹数据存储到一个向量中,我还不确定该怎么做,但是,我怎样才能更新每个子弹的位置一旦他们在那里?那么我怎样才能让每个子弹与玩家碰撞检查呢?
这是我的代码,我用许多问号的注释标记了一些有问题的区域:
#include <ctime>
#include <sstream>
#include <vector>
using namespace sf;
//?????????????????????
class enemy{
public:
int xpos, ypos, xvel, yvel;
void spawnEnemy(){
CircleShape enemyc(10);
enemyc.setFillColor(Color::Red);
}
};
//?????????????????????
int main(){
RenderWindow window(VideoMode(800, 600), "SFMLbullet", Style::Close);
window.setMouseCursorVisible(false);
window.setFramerateLimit(60);
srand(time(0));
//?????????????????????
std::vector<enemy> enemies;
//?????????????????????
//define target
int targetx = rand() % 580 - 20;
int targety = rand() % 580 - 20;
bool tregen = false;
CircleShape targetc(20);
targetc.setFillColor(Color::Green);
//define player
CircleShape playerc(10);
playerc.setFillColor(Color::Blue);
playerc.setOrigin(10,10);
//define score count
int score = 0;
std::stringstream scoreconv;
Font scorefont;
scorefont.loadFromFile("SLANT.TTF");
Text scorecount;
scorecount.setFont(scorefont);
scorecount.setCharacterSize(50);
scorecount.setFillColor(Color::White);
scoreconv.str("0");
//main Loop
while(window.isOpen()){
//when target is clicked
if(Mouse::isButtonPressed(Mouse::Left) && !tregen && playerc.getGlobalBounds().intersects(targetc.getGlobalBounds())){
//generate new target
targetx = rand() % 780 - 20;
targety = rand() % 580 - 20;
//add score
score++;
scoreconv.str("");
scoreconv << score;
//?????????????????????
enemy bullet;
enemies.push_back(bullet);
//?????????????????????
tregen = true;
}
//don't regenerate target rapidly
if(!Mouse::isButtonPressed(Mouse::Left)){
tregen = false;
}
//window events
Event event;
while(window.pollEvent(event)){
if(event.type == Event::Closed) window.close();
}
window.clear(Color::Black);
//draw target
targetc.setPosition(targetx, targety);
window.draw(targetc);
//draw player
playerc.setPosition(Mouse::getPosition(window).x, Mouse::getPosition(window).y);
window.draw(playerc);
//?????????????????????
//DRAW BULLETS HERE, ideally with enemyc.move()
//?????????????????????
//score count
scorecount.setString(scoreconv.str());
window.draw(scorecount);
window.display();
}
return 0;
}
解决方案
你已经拥有了子弹所需的数据,你称之为“敌人”。您已经有一个适当的集合来存储您的子弹,您选择使用矢量,这很好。
您只需要调整更新/绘制,并考虑一些简单的碰撞:
//update
targetc.setPosition(targetx, targety);
playerc.setPosition(Mouse::getPosition(window).x, Mouse::getPosition(window).y);
// you can place this in your enemy move function
for (Enemy enemy : enemies) {
if (enemy.xpos < 0 || enemy.xpos > window.getSize().x) {
enemy.xvel *= -1; // revert X velocity if touching side edges
}
if (enemy.ypos < 0 || enemy.ypos > window.getSize().y) {
enemy.yvel *= -1; // revert Y velocity if touching top or bottom edges (don't know whether you want this)
}
enemy.xpos += enemy.xvel;
enemy.ypos += enemy.yvel;
}
//draw
window.draw(targetc);
window.draw(playerc);
for (Enemy enemy : enemies) {
window.draw(
}
还要为你的敌人考虑以下几点
class enemy{
public:
int xpos, ypos, xvel, yvel;
CircleShape enemyc;
void spawnEnemy(){
enemyc = CircleShape(10);
enemyc.setFillColor(Color::Red);
}
};
最后说明:
将您的更新与绘图分开,通常您只想在计算完所有内容后进行绘制。
推荐阅读
- ios - 是否可以打开特定应用程序以注册新帐户?
- wolfram-mathematica - 带通道的矩阵图标记
- typescript - 对象破坏打字稿时找不到属性
- python - 我正在写一个网络爬虫,而我爬取的列表之一有非 unicode 字符,我怎么能忽略这些?
- python - 根据滚动时间窗口分配组号 - Pandas
- powershell - Powershell Sharepoint Online - 将内容类型添加到列表
- javascript - 检查文件是否存在,否则加载另一个页面
- javascript - 如何在反应中将数据从一个组件传输到另一个组件?
- javascript - 计算日期之间的差异并从该结果开始计时器计数
- javascript - 在元素上调用事件