我现在对SFML还是很陌生,我想知道最有效的方法是根据相机位置在矢量中生成和销毁对象吗?目前,我正在实例化墙“点”的向量,该向量将在调试后链接在一起。我应该基于凸轮位置创建或销毁它们,还是将已经存在的凸轮移至正确的位置?
我也不会介意为此提供一些反馈。
保存Chaos.cpp
int main()
{
//get classes from CaveChaos.h
CaveChaos::Wall objWall;
CaveChaos::Player objPlayer;
//set render window size and name
sf::RenderWindow window(sf::VideoMode(800, 600), "CaveChaos");
//set the view
sf::View view1(sf::Vector2f(0.f, 0.f), sf::Vector2f(window.getSize().x, window.getSize().y));
//create the player object as a triangle
sf::CircleShape Player(20, 3);
//initialise random
srand(time(0));
//sets the player position to a good position based on camera size
objPlayer.posx = window.getSize().x / 2;
objPlayer.posy = window.getSize().y / 1.1;
Player.setPosition(objPlayer.posx, objPlayer.posy);
//used to instantiate wall points
int locationsX[numofpoints];
//add random x values to locations
for (int i = 0; i < numofpoints; i++)
{
locationsX[i] = (rand() % 50) + 1;
}
while (window.isOpen())
{
sf::Event event;
//clear the window with black color
window.clear(sf::Color::Black);
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
}
//calls wallspawn in Walls.cpp which creates the wall points
WallSpawn(window, locationsX );
//calls playermove in Player.cpp which move the player
PlayerMove(window, Player);
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
}
//set the player as the cam follow point
view1.setCenter(Player.getPosition().x, Player.getPosition().y - objPlayer.posy / 3);
//set the view to the player
window.setView(view1);
window.display();
}
return 0;
}
当前,当我调用WallSpawn()时,它将循环遍历10个对象并生成它们,是否有办法生成无限数量的对象呢?
Walls.cpp
void WallSpawn(sf::RenderWindow& window, int locationsX[] )
{
//initiate random
srand(time(0));
//class objects
CaveChaos::Wall objWall;
CaveChaos::Player objPlayer;
//creates a vector of circleshapes
std::vector<sf::CircleShape> points;
//defines and circle of size 5
sf::CircleShape shape(5);
//loop through all of the points
for (int i = 0; i < numofpoints; i++)
{
//set the shape position to the random variable from CaveChaos.cpp
shape.setPosition(locationsX[i], objPlayer.posy + i * 55);
//set shape color to green
shape.setFillColor(sf::Color(100, 250, 50));
// copy shape to vector
points.push_back(shape);
}
// iterate through vector
for (std::vector<sf::CircleShape>::iterator it = points.begin(); it != points.end(); ++it)
{
//draw wall points on screen
window.draw(*it);
}
}
在生成这些对象之后移动或销毁这些对象的最佳方法是什么?
如果此方法完全错误,或者我根本不应该使用此方法,请告诉我。
感谢您的帮助。
答案 0 :(得分:4)
因此,首先stackoverflow不是进行代码检查的正确位置。如果您需要完整的评论,请询问codereview。但是,这是我注意到的一些事情:
rand
或srand
。如果要使用RNG,请使用<random>
(通常为uniform_int_distribution
或uniform_real_distribution
)。locationsX
使用本机数组? std::vector
似乎更合理。WallSpawn
,WallSpawn
本身每次都会创建一个新的向量sf::CircleShape
),这可以避免。稍后再讨论。std::vector
为vector.reserve()
预先分配空间。auto
代替std::vector<sf::CircleShape>::iterator
可以提高可读性。通常,游戏循环如下所示:
例如,您的WallSpawn
函数显示了不应执行的操作。您要生成新的游戏实体(墙点),然后在相同的函数中立即绘制它们。
我对SFML的经验有限,但是我知道有一个sf::Drawable
基类,可以用于需要在窗口上绘制的所有内容。您不必使用它,但它旨在简化OOP开发。例如,您可以为您的墙点或整个墙创建类型(取决于您对这些点的实际用途):
class WallPoint : public sf::Drawable
{
public:
WallPoint(int x, int y) :
position(x, y), circle(x, y, 5)
{
}
/*
* Getter and setter for position
*/
void draw(RenderTarget& target, RenderStates states) const override
{
target.draw(circle);
}
private:
sf::Point position;
sf::CircleShape circle;
};
然后将这些点的集合保存在游戏循环之外的变量中。
具有成千上万个游戏实体(车辆,树木,岩石,墙壁,武器,弹药,弹丸,人群,NPC等)的大型游戏存在以下问题:在管理方面,它们必须非常高效他们。但是,在您的情况下,只有几个简单的圆形,有效的管理并不是真正的问题。无需优化就不必优化。
您提供的有关游戏行为的信息太少,无法提出建议,所以这里有些猜测。
游戏进度如何影响您的实体?您的案例(亚军游戏)表明环境不断沿一个轴(左<>右或上<>下)运动。如果这是真的,则意味着您的墙尖始终在当前环境的边缘生成和消失。在这种情况下,std::deque
是存储数据的理想容器。
通常,std::vector
是涉及容器的可靠工具。
当您不再需要实体时,总会销毁它们。例如,如果您的墙尖离开视口(并且您确定它们不会再次进入视口),则将其移出容器。
考虑到我上面写的所有内容,您的游戏循环现在可能像这样:
int main()
{
// Create window and init everything you need
std::deque<WallPoint> wallPoints;
// create some initial points
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
// event handling
}
// update game state
// add new wall points
// remove old points
// move the player
// draw the new game state
window.Clear();
for (const auto& point : wallPoints)
window.draw(point);
window.draw(player);
}
}