我正在尝试制作一个基本的游戏,在该游戏中,碰到一个物体会导致玩家丧命。我编写代码的方式是,每次物体和玩家接触时都会发生这种情况。我希望玩家只失去一种生命,而不是全部。知道如何解决吗?谢谢
void colision() {
for ( int i = 0; i<cant; i++ ) {
if ( personaje.x > o[i].x && personaje.x < o[i].x + o[i].tam &&
personaje.y > o[i].y && personaje.y < o[i].y + o[i].tam/2) {
//if( dist(personaje.x, personaje.y, o[i].x, o[i].y ) < (personaje.ph/2 + o[i].tam/2) ){
personaje.restarVida();
personaje.reiniciar();
}
}
}
答案 0 :(得分:2)
我的猜测是您正在从draw()
函数内部调用此函数。
(旁注:请发布MCVE而不是未连接的代码段,这样我们就不必猜测了。)
请记住,draw()
函数每秒被调用60次。因此,此代码将每秒运行60次。换句话说,只要您的物体发生碰撞,您就将每秒检测到60次碰撞。
要解决此问题,通常希望在第一次检测到碰撞时至少移动一个对象。这样做的方式取决于您希望游戏的运行方式,但是一些示例可能是彻底清除敌人,将玩家击退或从头开始玩家。
答案 1 :(得分:2)
Kevin提出的将角色击倒的建议非常好:这样可以确保每次碰撞仅一次满足碰撞条件,而不是连续进行直到角色移开为止。您可能需要在发生碰撞之前存储先前的位置。
另一种变体,没有击退字符,是拥有一个布尔变量,该变量可以跟踪字符是否先前被击中。然后,只有在角色当前被命中但以前没有被命中时,才可以减去生命。
以下是基于您的代码的代码段,以作为概念证明:
void colision() {
for ( int i = 0; i < cant; i++ ) {
boolean estChocando = personaje.x > o[i].x && personaje.x < o[i].x + o[i].tam &&
personaje.y > o[i].y && personaje.y < o[i].y + o[i].tam/2;
if (estChocando && !personaje.estabaChocando) {
//if( dist(personaje.x, personaje.y, o[i].x, o[i].y ) < (personaje.ph/2 + o[i].tam/2) ){
personaje.restarVida();
personaje.reiniciar();
// remember the character was hit, so this condition won't be met the next time around
personaje.estabaChocando = true;
}
// reset character was hit flag if no longer colliding
if(!estChocando && personaje.estabaChocando){
personaje.estabaChocando = false;
}
}
}
这假设您已经在角色类中定义了boolean estabaChocando;
。
我个人会接受凯文(Kevin)的建议,即在视觉上容易理解该角色,将其击退,增加游戏的物理/真实感,并且在许多经典游戏中如此普遍,基本上是this SO post
以下是基于上述示例:
void colision() {
for ( int i = 0; i < cant; i++ ) {
boolean estChocando = personaje.x > o[i].x && personaje.x < o[i].x + o[i].tam &&
personaje.y > o[i].y && personaje.y < o[i].y + o[i].tam/2;
if (estChocando) {
//if( dist(personaje.x, personaje.y, o[i].x, o[i].y ) < (personaje.ph/2 + o[i].tam/2) ){
personaje.restarVida();
personaje.reiniciar();
// restore character to last non-collision position
personaje.x = personaje.px;
personaje.y = personaje.py;
}
// update position to restore to
if(!estChocando){
personaje.px = personaje.x;
personaje.py = personaje.y;
}
}
}
以上假设您将px
和py
属性与x
,y
一起添加到字符类(从中实例化personaje
)。 / p>
此特定实现可能是防弹的,因为它没有考虑角色和游戏对象朝哪个方向移动。
另一种方式是开始affordance,乍一看可能会让人感到恐惧,但它们真的很有趣,并且对于整个游戏开发非常有用。
如果要使用矢量,则可以轻松地以负速度(甚至是其倍数)增加角色的位置,以沿相反的行进方向踢角色(一定量):