Java 处理中的多个类

Java 处理中的多个类,java,collision-detection,Java,Collision Detection,我在做一个游戏,你控制一个正方形,物体会在随机的地方产生,你必须捡起来才能得分,同时还要躲避从一边到另一边的大正方形。现在我有两个职业(一个是为敌人-大方块-和一个为英雄),我还没有做点系统的产卵对象,但这不是我现在要做的 所以我现在的问题是,我真的不知道当你与你的英雄接触“敌人”时,如何让这个人失去游戏/生命。我知道不用上课怎么做,但我想知道当他们在不同的班级时怎么做 如果有人能用代码和注释解释这将如何实现,这将对我有很大帮助:)(我读了一些关于类的“扩展”的文章,但我不确定这是否是我应该使用

我在做一个游戏,你控制一个正方形,物体会在随机的地方产生,你必须捡起来才能得分,同时还要躲避从一边到另一边的大正方形。现在我有两个职业(一个是为敌人-大方块-和一个为英雄),我还没有做点系统的产卵对象,但这不是我现在要做的

所以我现在的问题是,我真的不知道当你与你的英雄接触“敌人”时,如何让这个人失去游戏/生命。我知道不用上课怎么做,但我想知道当他们在不同的班级时怎么做

如果有人能用代码和注释解释这将如何实现,这将对我有很大帮助:)(我读了一些关于类的“扩展”的文章,但我不确定这是否是我应该使用的)

下面是我的游戏目前的屏幕截图,以便更好地说明:

以下是主代码页:

Hero myHero = new Hero(400,480,5);
Enemies myEnemies = new Enemies(50,50,10);
Enemies myEnemies2 = new Enemies(50,350,15);
Enemies myEnemies3 = new Enemies(50,650,12);

void setup() {
    size(900,800);
    frameRate(30);
    smooth();
}

void draw() {
    background(0);
    myHero.keyPressed();
    myEnemies.enemyDisplay();
    myEnemies.enemyMove();
    myEnemies2.enemyDisplay();
    myEnemies2.enemyMove();
    myEnemies3.enemyDisplay();
    myEnemies3.enemyMove();
}
第1类:

class Enemies {
    float xpos, ypos, speed;

    Enemies(float x, float y, float s) {
        xpos = x;
        ypos = y;
        speed = s;
    } 

    void enemyDisplay() {
        rect(xpos, ypos, 100, 100); 
    }

    void enemyMove() {
        xpos += speed;
        if((xpos > width - 100) || (xpos < 0)) {
            speed *= -1;
        }
    }
}

您需要了解碰撞检测,以及当您的对象相互碰撞时,一些基本的信息,如:

class Enemy 
{
//...
public boolean isColliding(Hero hero)
{
  //figure out the distance between two objects, if its less than their size, they are colliding..
  //...
}
//...
}

然后,你需要游戏循环的一部分来检查是否有任何东西与你的英雄、皮卡、墙壁等发生碰撞。

你需要帮助的第一部分似乎是碰撞检测。我给出的一个简短的答案几乎毫无疑问会引导你提出更多的问题,那就是看看Area类(特别是Area.intersect)。您可能还想看看我为显示和管理区域而创建的类

我相信您提出的问题涉及基本的碰撞检测和对象交互

首先,我会将
敌人
设置为一个
列表
,并在
设置()过程中创建它/添加元素
调用:

List<Enemies> enemies = new List<Enemies>();
enemies.add(new Enemies(50,50,10));
此方法将位于您的一个类中:

public boolean isColliding(Enemies enemy)
{
  // check the x and y coordinates of each object

}

我希望这有助于为您指明正确的方向。

这里有几个问题涉及到应用程序设计和惯例。在尝试解决碰撞检测问题之前,应首先解决这些问题

敌人
类只代表一个敌人,因此类的名称应该反映这一点。此外,在方法名称前加上“敌人”是多余的,可以删除。其他变更已在下面的修订类中进行了注释

public class Enemy {
  // Instead of hard-coding in the width and height of an enemy, allow the 
  // instantiating code to specify the enemy's size.  This will allow you 
  // to have different size enemies and prevents you from having "magic numbers" 
  // in your code.
  private float xpos, ypos, width, height, speed;

  public Enemy(float x, float y, float s, float w, float h) {
    xpos = x;
    ypos = y;
    width = w;
    height = h;
    speed = s;
  }

  /* These getters will be used for collision detection later */

  public float getX() {
    return xpos;
  }

  public float getY() {
    return ypos;
  }

  public float getWidth() {
    return width;
  }

  public float getHeight() {
    return height;
  }

  // I've changed `display` to `draw` to be consistent with the method name in 
  // your main `draw` method.
  public void draw() {
    rect(xpos, ypos, width, height); 
  }

  // This method now accepts a screenWidth parameter so that the enemy can know
  // when they've collided with the left or right wall of the screen without 
  // having to rely on an global variable.
  public void move(int screenWidth) {
    xpos += speed;

    if ((xpos > screenWidth - width) || (xpos < 0)) {
      speed *= -1;
    }
  }
}
有关边界框交点的详细信息,请参见此

现在,您的类已经就绪,是时候处理主代码了。我们需要更新方法名称,并且,正如@jamest所建议的,您应该创建一个敌人列表,而不是为每个敌人创建一个新的独立对象。这将使您在将来更容易添加或删除敌人,并且能够使用一段代码处理所有敌人,而无需重复您自己

// Use constants to remove magic numbers.
private static final int SCREEN_WIDTH = 900;
private static final int SCREEN_HEIGHT = 800;

private Hero myHero = new Hero(400, 480, 30, 30, 5);
private List<Enemy> enemies = new ArrayList<Enemy>();

void setup() {
  size(SCREEN_WIDTH, SCREEN_HEIGHT);
  frameRate(30);
  smooth();

  enemies.add(new Enemy(50, 50, 100, 100, 10));
  enemies.add(new Enemy(50, 350, 100, 100, 15));
  enemies.add(new Enemy(50, 650, 100, 100, 12));
}

void draw() {
  hasCollision = false;

  background(0);

  // I've changed the order of draw->move to move->draw.  If you draw first, then 
  // move, then detect collisions, it will appear to your user that your hero has 
  // not yet collided with an enemy even though you act as they have (e.g.: they 
  // will not see the collision until the next time you draw the scene).
  myHero.move();
  myHero.draw();

  for (Enemy enemy : enemies) {
    enemy.move();
    enemy.draw(SCREEN_WIDTH);

    if (!hasCollision &&  myHero.isColliding(enemy)) {
      hasCollision = true;
    }
  }

  if (hasCollision) {
    // Handle enemy collision here
  }
}
//使用常量删除幻数。
专用静态最终int屏幕_宽度=900;
专用静态最终int屏幕_高度=800;
私人英雄myHero=新英雄(400、480、30、30、5);
private List=new ArrayList();
无效设置(){
尺寸(屏幕宽度、屏幕高度);
帧率(30);
光滑的();
增加(新敌人(50,50,100,100,10));
增加(新敌人(5035010010015));
增加(新敌人(5065010010012));
}
作废提款(){
hasCollision=false;
背景(0);
//我改变了画画->移动->移动->画画的顺序。如果你先画画,那么
//移动,然后检测碰撞,你的用户会觉得你的英雄
//尚未与敌人发生碰撞,即使你的行为与他们相同(例如:他们
//直到下次绘制场景时才会看到碰撞)。
我的英雄。移动();
我的英雄。画();
为(敌人:敌人){
敌人。移动();
敌人。抽签(屏幕宽度);
如果(!hascolling&&myHero.isColliding(敌人)){
hasCollision=true;
}
}
如果(碰撞){
//在这里处理敌人的碰撞
}
}

您会注意到,我还为所有内容添加了可访问性修饰符。虽然从技术上来说,排除它们并使用默认值是有效的,但包含它们会使代码更具可读性,因为这样更为明显。当你刚开始的时候,越明显越好。

好吧,多亏了你们这些乐于助人的优秀员工,这一切才得以实现

我这样做:

public boolean isColliding(Enemies h){
   float distance = dist(x,y,h.x,h.y);
    if(distance<100){
      return true;
    }else{
      return false;
    }
  }

我之前有一个非常类似的“修复”,但我出错的原因是因为我在“if”函数中使用了英雄h而不是敌人h,所以这只是一个非常愚蠢的错误,我忽略了:p

与其让我们做所有的工作,不如让我们看看(用代码)在没有类的情况下如何做,我们可以指导您使用所创建的类所做的更改。对于您控制的对象和“敌人”,我只需要使用不同的变量。然后就是基本的if(xhero>xenemy&&xy敌军&&yThanks,这很有帮助。我将进一步尝试:)我做到了:公共布尔集合(Hero h){float distance=dist(x,y,h.x,h.y);if(distance谢谢!在tho之前我没有在for循环中使用:希望它能在处理上起作用:P看起来像“list”在Processing中不存在请记住,
列表
使用迭代器(或Java中增强的for循环),数组可以使用标准for循环。如果您对
列表
数据类型不满意,可以创建一个
敌人
数组,例如:
敌人[]敌人;
它可能应该是
new ArrayList
,而不是
new List
它也可以是,不过,您是对的,
new ArrayList
可能更适合本例中的操作。
ArrayList
对于不经常波动的已知数据量更有效,而
列表
对于波动较大或数量未知的数据更有效。@JamesT新列表()不可能。它必须是arraylist。请尝试。
public class Hero {
  private float xpos, ypos, width, height, speed;

  public Hero(float x, float y, float s, float w, float h) {
    xpos = x;
    ypos = y;
    width = w;
    height = h;
    speed = s;
  }

  // Change this method name to draw for consistency with the Enemy class
  public void draw() {
    // Key press functionality has been moved to the `move` method for consistency 
    // with the Enemy class.
    rect(xpos, ypos, WIDTH, HEIGHT);
  }

  // This method uses the variables key, keyCoded, UP, DOWN, LEFT, and RIGHT.  You 
  // did not include any import statements with your code, so they may be coming 
  // from there; however, if they are globals, you should pass them to this method 
  // as arguments whenever you call it.
  public void move() {
    // If this condition isn't satisfied, return immediately.  This prevents 
    // unnecessary nesting and work below.
    if (key != CODED) {
      return;
    }

    if (keyCode == UP) {
      ypos -= speed;
    }
    // Use `else if` here and below to prevent multiple unnecessary 
    // comparisons of keyCode.
    else if (keyCode == DOWN) {
      ypos += speed;
    }
    else if (keyCode == LEFT) {
      xpos -= speed;
    }
    else if (keyCode == RIGHT) {
      xpos += speed;
    }
  }

  public boolean isColliding(Enemy enemy) {
     // Collision detection is easy since all of your game entities (the hero and 
     // the enemies) are all rectangles and axis-aligned (not rotated). You can 
     // use a method known as "bounding box intersection."

     return (Math.abs(enemy.getX() - xpos) * 2 < (enemy.getWidth() + width))
       && (Math.abs(enemy.getY() - ypos) * 2 < (enemy.getHeight() + height));
  }
}
// Use constants to remove magic numbers.
private static final int SCREEN_WIDTH = 900;
private static final int SCREEN_HEIGHT = 800;

private Hero myHero = new Hero(400, 480, 30, 30, 5);
private List<Enemy> enemies = new ArrayList<Enemy>();

void setup() {
  size(SCREEN_WIDTH, SCREEN_HEIGHT);
  frameRate(30);
  smooth();

  enemies.add(new Enemy(50, 50, 100, 100, 10));
  enemies.add(new Enemy(50, 350, 100, 100, 15));
  enemies.add(new Enemy(50, 650, 100, 100, 12));
}

void draw() {
  hasCollision = false;

  background(0);

  // I've changed the order of draw->move to move->draw.  If you draw first, then 
  // move, then detect collisions, it will appear to your user that your hero has 
  // not yet collided with an enemy even though you act as they have (e.g.: they 
  // will not see the collision until the next time you draw the scene).
  myHero.move();
  myHero.draw();

  for (Enemy enemy : enemies) {
    enemy.move();
    enemy.draw(SCREEN_WIDTH);

    if (!hasCollision &&  myHero.isColliding(enemy)) {
      hasCollision = true;
    }
  }

  if (hasCollision) {
    // Handle enemy collision here
  }
}
public boolean isColliding(Enemies h){
   float distance = dist(x,y,h.x,h.y);
    if(distance<100){
      return true;
    }else{
      return false;
    }
  }
 if(myHero.isColliding(myEnemies)){
    println("You lost!");
  }