如何向我的 class 提供有关其环境的一些信息?
How can my class be provided some information about its environment?
这是我在考虑封装和组合的情况下编写的代码示例:
class Bullet {
private:
Vector2 position;
Vector2 speed;
public:
void move(float time_delta) {
position += speed * time_delta;
}
};
基本上,只是有一个抛射物在无处移动。然而,一颗子弹实际上可以e。 G。从墙上弹开,speed
发生了显着变化。是否有考虑此类交互的好方法?我既不希望我的 Bullet
知道 "higher-rank" 类(应该自己使用它),也不希望编写像这样的一次性解决方案:
template<typename F> void move(float time_delta, F collision_checker);
更新: 如果您想缩小这个问题的范围,值得一读。下面是移动 Bullet
的希望逻辑的简化示例(我并不是指 Bullet::move()
成员函数!)以及它们与其他实体的交互:
Vector2 destination = bullet.position + bullet.speed * time_delta;
if (std::optional<Creature> target = get_first_creature(bullet.position, destination)) {
// decrease Bullet::speed depending on the target (and calculate the damage)
} else if (std::optional<Wall> obstacle = get_first_wall(bullet.position, destination)) {
// calculate the ricochet changing Bullet::position and Bullet::speed
}
所有由注释表示的代码段都应该使用 Creature
和 Wall
class
es.
的一些属性
从设计的角度来看,如果你的子弹不知道如何检测它何时... passing_through 障碍物 (scnr) 可能是最好的。因此,将您的 Bullet
class 变成 struct
可能会更好,即让它表现得像一个被操作的东西,而不是一个被操作的东西。
你仍然可以添加你的便利函数,但让它是非可变的:
struct Bullet {
Vector2 position;
Vector2 speed;
Vector2 move(float time_delta) const {
return position + speed * time_delta;
}
};
这样您就可以从调用范围计算冲突:
auto dest = bullet.move(dt);
while (std::optional<Collision> const col = detectCollision(bullet.position,dest)) {
bullet.position = col->intersectPoint;
bullet.speed = col->reflectedSpeed;
dest = col->reflectDest;
}
bullet.position = dest;
此处detectCollision
检查子弹当前位置到新位置dest
的直线是否与任何障碍物相交并计算反射参数。实际上,您曲折地到达目的地,这将由子弹的所有连续乒乓球和潜在障碍物造成。
这是我在考虑封装和组合的情况下编写的代码示例:
class Bullet {
private:
Vector2 position;
Vector2 speed;
public:
void move(float time_delta) {
position += speed * time_delta;
}
};
基本上,只是有一个抛射物在无处移动。然而,一颗子弹实际上可以e。 G。从墙上弹开,speed
发生了显着变化。是否有考虑此类交互的好方法?我既不希望我的 Bullet
知道 "higher-rank" 类(应该自己使用它),也不希望编写像这样的一次性解决方案:
template<typename F> void move(float time_delta, F collision_checker);
更新: 如果您想缩小这个问题的范围,值得一读。下面是移动 Bullet
的希望逻辑的简化示例(我并不是指 Bullet::move()
成员函数!)以及它们与其他实体的交互:
Vector2 destination = bullet.position + bullet.speed * time_delta;
if (std::optional<Creature> target = get_first_creature(bullet.position, destination)) {
// decrease Bullet::speed depending on the target (and calculate the damage)
} else if (std::optional<Wall> obstacle = get_first_wall(bullet.position, destination)) {
// calculate the ricochet changing Bullet::position and Bullet::speed
}
所有由注释表示的代码段都应该使用 Creature
和 Wall
class
es.
从设计的角度来看,如果你的子弹不知道如何检测它何时... passing_through 障碍物 (scnr) 可能是最好的。因此,将您的 Bullet
class 变成 struct
可能会更好,即让它表现得像一个被操作的东西,而不是一个被操作的东西。
你仍然可以添加你的便利函数,但让它是非可变的:
struct Bullet {
Vector2 position;
Vector2 speed;
Vector2 move(float time_delta) const {
return position + speed * time_delta;
}
};
这样您就可以从调用范围计算冲突:
auto dest = bullet.move(dt);
while (std::optional<Collision> const col = detectCollision(bullet.position,dest)) {
bullet.position = col->intersectPoint;
bullet.speed = col->reflectedSpeed;
dest = col->reflectDest;
}
bullet.position = dest;
此处detectCollision
检查子弹当前位置到新位置dest
的直线是否与任何障碍物相交并计算反射参数。实际上,您曲折地到达目的地,这将由子弹的所有连续乒乓球和潜在障碍物造成。