对撞机(java 处理中)
Collider (java processing)
我正在尝试制作一款基本游戏,在该游戏中,玩家通过击中一个物体而失去生命。按照我编写代码的方式,每次对象和玩家接触时都会发生这种情况。我希望玩家只失去一条生命,而不是全部。知道如何解决吗?谢谢
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();
}
}
}
我猜你是从 draw()
函数内部调用这个函数。
(旁注:请 post 使用 MCVE 而不是断开连接的代码段,这样我们就不必猜测了。)
请记住,draw()
函数每秒调用 60 次。所以这段代码每秒要 运行 60 次。换句话说,只要您的对象发生碰撞,您就会每秒检测到该碰撞 60 次。
为了解决这个问题,您通常希望在第一次检测到碰撞时至少移动一个对象。您执行此操作的方式取决于您希望游戏如何运行,但一些示例可能是完全移除敌人、击退玩家或让玩家从头开始。
凯文关于将角色击退的建议很棒:这将确保每次碰撞碰撞条件只为真一次,而不是一直持续到角色移开为止。您可能需要在碰撞发生之前存储之前的位置。
另一种不击退角色的变体是有一个布尔变量来跟踪角色之前是否被击中。如果角色当前被击中但之前没有被击中,那么您只能减去生命。
这是一个基于您的代码的片段作为概念证明:
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;
}
}
}
这假设您已经在角色 class 中定义了 boolean estabaChocando;
。
就我个人而言,我会同意凯文的建议,将角色击退,因为视觉上很容易理解,添加到游戏的 physics/realism 中,并且在很多 classic 中非常普遍游戏基本上是 affordance.
下面是一个基于上述的例子:
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
一起添加到字符 class(从 personaje
被实例化)。
这个特定的实现可能是防弹的,因为它没有考虑角色和游戏对象移动的方向。
另一种方法是开始 using vectors,一开始可能会感到害怕,但它们真的很有趣,而且对整体游戏开发非常有用。
如果你要使用向量,你可以很容易地增加角色的位置负速度(甚至是负速度的倍数)以将角色踢向相反的行进方向(一定量):
我正在尝试制作一款基本游戏,在该游戏中,玩家通过击中一个物体而失去生命。按照我编写代码的方式,每次对象和玩家接触时都会发生这种情况。我希望玩家只失去一条生命,而不是全部。知道如何解决吗?谢谢
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();
}
}
}
我猜你是从 draw()
函数内部调用这个函数。
(旁注:请 post 使用 MCVE 而不是断开连接的代码段,这样我们就不必猜测了。)
请记住,draw()
函数每秒调用 60 次。所以这段代码每秒要 运行 60 次。换句话说,只要您的对象发生碰撞,您就会每秒检测到该碰撞 60 次。
为了解决这个问题,您通常希望在第一次检测到碰撞时至少移动一个对象。您执行此操作的方式取决于您希望游戏如何运行,但一些示例可能是完全移除敌人、击退玩家或让玩家从头开始。
凯文关于将角色击退的建议很棒:这将确保每次碰撞碰撞条件只为真一次,而不是一直持续到角色移开为止。您可能需要在碰撞发生之前存储之前的位置。
另一种不击退角色的变体是有一个布尔变量来跟踪角色之前是否被击中。如果角色当前被击中但之前没有被击中,那么您只能减去生命。
这是一个基于您的代码的片段作为概念证明:
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;
}
}
}
这假设您已经在角色 class 中定义了 boolean estabaChocando;
。
就我个人而言,我会同意凯文的建议,将角色击退,因为视觉上很容易理解,添加到游戏的 physics/realism 中,并且在很多 classic 中非常普遍游戏基本上是 affordance.
下面是一个基于上述的例子:
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
一起添加到字符 class(从 personaje
被实例化)。
这个特定的实现可能是防弹的,因为它没有考虑角色和游戏对象移动的方向。
另一种方法是开始 using vectors,一开始可能会感到害怕,但它们真的很有趣,而且对整体游戏开发非常有用。
如果你要使用向量,你可以很容易地增加角色的位置负速度(甚至是负速度的倍数)以将角色踢向相反的行进方向(一定量):