碰撞检测仅在对象正好在中心命中时起作用 [英] Collision detection only works when object hits right in the centre

查看:54
本文介绍了碰撞检测仅在对象正好在中心命中时起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我这里有一个摔倒"风格的游戏,其中荷马·辛普森一家的头从天空掉下来,避开沙拉,收集汉堡以提高得分.我已经实施了碰撞检测,因此当荷马打出沙拉时,他应该重新产生并减少其寿命,该方法可以正常工作.但是,如果本垒打的头撞到沙拉的侧面而不是直接在沙拉的中央,则游戏将冻结片刻,然后继续进行,就像什么也没有发生.我不确定为什么会这样,并且想知道我的操作方式是否有问题.这是我的代码如下:

Hi so i have here a 'falling' style game where i have homer simpsons head falling through the sky avoiding the salads and collecting burgers to increase score. I have implemented collision detection so when homer hits a salad he should re-spawn and have a life deducted which works fine. However if homers head hits the side of the salad and not directly in the centre of it the game will freeze for a moment and then carry on like nothing happened. I am not sure why this happens and wondering if there is a problem with how i am doing this. Here is my code below:

碰撞检测不够准确吗?或者我还缺少另一个问题?

Are the collision detection not accurate enough or is there another issue that i am missing?

PImage background;
PImage MenuBackground;
int y=0;//global variable background location
final int End = 0;
final int Active = 1;
final int Menu = 2;
int gameMode = Menu;
int score = 0;
int lives = 3;
Boolean BurgerCollisionInProgress = false;
Boolean BurgerCollisionInProgress2 = false;


Salad salad1;
Salad salad2;
Salad salad3;
Homer user1;
Burger Burger;


public void settings()
{
 size(500,1000); //setup size of canvas
}

void menu()
{
 background = loadImage("spaceBackground.jpg"); //image used for background
 background.resize(500,1000); //resizes the background
 gameMode = Active; 

float rand = random(25,475);
int intRand = int(rand);

float rand2 = random(25,475);
int intRand2 = int(rand2); 

float rand3 = random(25,475);
int intRand3 = int(rand3); 

float rand4 = random(25,475);
int intRand4 = int(rand4); 


 user1 = new Homer(250,100);  //declares new defender as user1
 Burger = new Burger(intRand,900,2);
 salad1 = new Salad(intRand2,900,3);
 salad2 = new Salad(intRand3,900,3);
 salad3 = new Salad(intRand4,900,3); //3 aliens declared with their x and y position and their speed they move at
 draw();
}


void setup()
{
  if(gameMode == 2)
  {    
    MenuBackground = loadImage("simpMenu.png");
    MenuBackground.resize(540,1000);
    image(MenuBackground, 0, y);
    textAlign(CENTER);
    textSize(40);
    fill(252, 3, 3);
    text("Press 'p' to play", 250,500);     
  } 
}


void draw ()
{  
  if (gameMode == Active)
  {        
    if(crash() == false)
    {
      drawBackground();//calls the drawBackground method
      textSize(32);
      fill(22,100,8);
      text("Score: " + score,75,40); 
      text("Lives: " + lives,75,80);
      salad1.update();//calls the update method which holds the move and render methods for alien
      salad2.update();
      salad3.update();
      user1.render();//calls the update method which holds the move and render methods for user
      Burger.update();//calls the update method which holds the move and render methods for burger

      if(Bcrash() == true && BurgerCollisionInProgress == false)
      {
      score = score+1;
      BurgerCollisionInProgress = true;
      Burger.y = 900;
      float rand = random(25,475);
      int intRand = int(rand);
      Burger.x = intRand;
      }

      if(Bcrash() == false)
      {
      BurgerCollisionInProgress = false;
      }


      if(crash() == true && BurgerCollisionInProgress2 == false)
      {
        if (lives < 1)
        {   gameMode = End;
            textSize(28);
            fill(22,100,8);
            text("Game Over, press 'r' to restart",200,200);
        }
        else
        {
          lives = lives - 1;
          BurgerCollisionInProgress2 = true;
          menu();
        }
        if(crash() == false)
      {
      BurgerCollisionInProgress2 = false;
      }
     }      
    }
  }
}

void drawBackground()
{
 image(background, 0, y); //draw background twice adjacent
 image(background, 0, y-background.width);
 y -=2;
 if(y == -background.width)
 y=0; //wrap background
}


  boolean crash()
  {
    if(user1.crash(salad1))
    {
      return true;
    }
    if(user1.crash(salad2))
    {
      return true;
    }
    if(user1.crash(salad3))
    {     
      return true;
    }
    return false;
  }


  boolean Bcrash()
  {
    if(user1.crash(Burger))
    {      
      return true;
    }
    return false;
  }

荷马阶级:

class Homer
{
  PImage UserImage;
  int x,y;  //declaring variables

  Homer(int x, int y)
  {
   this.x = x;
   this.y = y;
   UserImage = loadImage("homer.png");
   UserImage.resize (60, 52);   
  } // end of Homer

  void render()
  {
    //draw a Homer
 image(UserImage,x,y);

  } //end of void render

  boolean crash(Salad A)  
  {   
    if((abs(x-A.x)<=30) && abs(y-A.y)<=30)
    {
    return true;
    }
    return false;
  }// end of crash


  boolean crash(Burger A)
  {
    if((abs(x-A.x)<=30) && abs(y-A.y)<=30)
    {
    return true;
    }
    return false;
  }
} // end of class

汉堡班:

class Burger
{
  PImage burgerImage;
  int x,y, speedX;
  int speedY = 0;

  Burger(int x, int y, int speedY)
  {     
    this.x = x;
    this.y = y;
    this.speedY= speedY;
    burgerImage = loadImage("food.png");
    burgerImage.resize (60, 52);    
  }  

  void render()
  {
    image(burgerImage,x,y);
  }


   void move()
 {
  y = y - speedY;  
  float rand = random(25,475);
  int intRand = int(rand);
   if(this.y < 0)
   {
    this.y = 900;
    this.x = intRand;
   }  
}

void update()
{
 move();
 render();
}
 }

沙拉班:

class Salad
{
 float x,y;
 float speedX, speedY; //declaring variables
 PImage saladImage;

 Salad(int x, int y, int speedY)
 {
  this.x = x;
  this.y = y;
  this.speedY = speedY;
  saladImage = loadImage("salad.png");
  saladImage.resize (60, 52);  
 } //end of salad

 void move()
 {
   y=y-speedY;
   float stepY = random(-5,5);
   y = y + (int)stepY;

   float rand = random(25,475);
   int intRand = int(rand);   

   if(this.y < 0)
   {
    this.y = 900; // once the salads y is less than 0 they restart at 900
    this.x = intRand;
    speedY = speedY + 0.5;
   }
 } //end of void move

 //draw a salad
 void render()
 {
image(saladImage,x,y);

 } //end of void render 

 void update()
 {
  move();
  render();
 }
}// end of alien class

推荐答案

有几件事使这变得比原来更困难.首先,您的相交方法不太正确.然后,可以改进处理坐标的方式.

There are several little things which makes this harder than it could be. First, your intersect method isn't quite right. Then, the way you handle coordinates could be improved upon.

我首先要做的是向您展示如何与矩形相交.之后,我将向您展示如何处理可绘制的objets,以使它们保持易于操作的状态.然后,我将向您展示一些简短,简单的游戏的框架代码,其中的东西会掉落并发生碰撞,为您提供一些帮助,以便您可以将这些建议应用于您的游戏环境.

What I'm going to do first is to show you how to intersect rectangles. After that, I'll show you how I would deal with the drawable objets so they stay easy to manipulate. Then I'll show you some skeleton code for a short, easy game with stuff falling and colliding, and just for you I'll add some help so you can implement these suggestions into the context of your game.

有许多方法可以处理碰撞.它们中的大多数是应用数学,其中一些是利用颜色或不可见的精灵的巧妙算法.也许我也忘记了一些方法.

There are many ways to handle collisions. Most of them are applied mathematics, some of them are clever algorithms making use of colors or invisible sprites. There are probably methods I'm forgetting, too.

我们将仅在矩形之间进行碰撞,因为您的程序似乎对矩形友好,这是更简单的方法.因此,我们将编写一个相交检测算法.

We'll only do collisions between rectangles, as your program seems quite rectangle-friendly and it's the easier method. So we'll write a intersection detection algorithm.

编写算法时要做的第一件事是伪代码.我不是在开玩笑.轻轻松松地用键盘敲击所有杂音,然后按一下即可编译.它在大多数情况下都有效...但是比将您的大脑投入到问题上,它更直观.

First thing to do when writing an algorithm is the pseudocode. I'm not joking. It's easy to go all clakety-clak with your keyboard and hit compile. It works most of the time... but it's more intuitive logic than applying your brain to the problem.

能够伪代码对于程序员来说就像是一种超级能力.永远不要低估它.

Being able to pseudocode is like a superpower for programmers. Never underestimate it.

现在,您如何知道两个矩形是否相交?答案是:

Now, how do you know if two rectangles are intersecting? The answer is:

  1. 两个矩形可以水平或垂直相交的方式有四种.
  2. 它们必须在水平和垂直方向上相交才能真正重叠.

这些是您必须寻找的可能性:

These are the possibilities you have to look for:

  1. 红色矩形大于黑色矩形,黑色矩形完全位于其中.
  2. 两个矩形在左侧(水平)或在顶部(垂直)重叠.
  3. 红色矩形小到可以放在黑色矩形内.
  4. 两个矩形在右侧(水平)或在底部(垂直)重叠.

因为此代码可以在许多地方使用,所以我将其移出上下文,并将其放在一个函数中,该函数接受坐标并返回一个布尔值(如果确实存在冲突,则为true):

Because this code can be used in many places, I took it out of context and put it inside a fonction which takes coordinates and returns a boolean (true if there indeed is a collision):

//  INTERSECT RECTs
boolean intersect(float x1, float y1, float w1, float h1, float x2, float y2, float w2, float h2)
{
    boolean checkX = x1 < x2 && x1+w1 > x2 || x1 < x2+w2 && x1+w1 > x2+w2 || x1 > x2 && x1+w1 < x2+w2 || x1 < x2 && x1+w1 > x2+w2; 
    boolean checkY = y1 < y2 && y1+h1 > y2 || y1 < y2+h2 && y1+h1 > y2+h2 || y1 > y2 && y1+h1 < y2+h2 || y1 < y2 && y1+h1 > y2+h2;

    return checkX && checkY;
}

这是处理矩形之间冲突的一种方法.您可以获取这些信息并将其应用到您的游戏中,然后它就会动摇.

This is one way of handling collisions between rectangles. You could take this information and apply it to your game, and it would rock.

这就是说,您还可以通过继承来改进代码.

This said, you could also improve on your code with Inheritance...

计算机科学中的继承是一种使类获得另一类的属性的方法.大多数人用家庭的方式来解释:有一个父类,有一些子类继承了父类的属性.

Inheritance in computer science is a way to make a class obtain the properties of another one. Most people explains it in term of family: there is a parent class and there are children class which inherits the parent class' properties.

当您的几个类共享相同的属性或方法时,继承特别有用.可绘制对象是一个很好的例子,因为它们都需要坐标.他们都需要一种绘制方法.

Inheritance is especially useful when several of your class share the same properties or methods. Drawable objects are a great example, because they all need coordinates. They all need a method to be drawn.

正如您稍后将在示例游戏中看到的那样,我注意到我所有的矩形都需要这些模态变量:

As you'll see with the example game later, I noticed that all my rectangles needed these modal variables:

protected float x, y, w, h; // x and y coordinate, width and height of the square
protected color fill, stroke;
protected float strokeWeight = 1;

因此,我创建了一个名为"Drawable"的基类.在更大的项目中,它可能是整个类树的基类,如下所示:

So I created a base class named 'Drawable'. In a bigger project, it could be the base class of a whole tree of classes, like this:

因此,在此示例中,Rat是Walker的孩子,Walker是Enemy的孩子,Actor的孩子是Drawable的孩子.

So in this example, Rat would be the child of Walker, which is the child of Enemy, which is the child of Actor, which is the child of Drawable.

优点是每个孩子都从其父母那里继承了一切.这既使您减少了编写代码的数量,又使您可以仅在一个地方而不是在任何地方纠正错误.例如,如果您使用对象坐标的方式有误,则需要在编写此逻辑的类中进行修复,而不是在每个类中都进行修复.

The advantage is that every child inherits everything from it's parent. It both makes you write less code and let you fix your mistakes in only one place instead of everywhere. For an example, if there's a mistake in how you use the coordinates of your objects, you want to fix it in the class where this logic is written, not in every class.

继承还有很多其他优点,但是现在让我们保持简单,好吗?

There are many other advantages to Inheritance, but for now let's keep it simple, all right?

这很简单:这是一个同时使用继承和冲突的示例.您可以将其复制并粘贴到Processing IDE中,然后它将运行.花一些时间来了解这三个类之间的关系,以及每个子类如何具有其父类的模态变量和功能.

This one is very straightforward: this is an example which use both inheritance and collisions. You can copy and paste it into a Processing IDE and it'll run. Take some time to see how the 3 classes relate to one another, and how every child class has the modal variables and functions of it's parent.

Hero hero;
ArrayList<Bomb> bombs = new ArrayList<Bomb>();
int numberOfBombs = 20; // if you change this number the number of bombs will change too. Try it!
int hitCount = 0;

public void settings()
{
  size(800, 600); //setup size of canvas
}

public void setup() {
  hero = new Hero();

  for (int i = 0; i < numberOfBombs; i++) {
    bombs.add(new Bomb(random(20, width-20), random(1, 10)));
  }

  // This part serves no purpose but to demonstrate that you can gather objets which share a parent class together
  ArrayList<Drawable> myDrawables = new ArrayList<Drawable>();
  for (Bomb b : bombs) {
    myDrawables.add(b);
  }
  myDrawables.add(hero);

  for (Drawable d : myDrawables) {
    d.Render();
    // Even though hero and the bombs are different classes, they are in the same ArrayList because they share the Drawable parent class.
    // Drawable has the Render() function, which may be called, but the child class will overshadow the Drawable's method.
    // Proof is that the error message "Drawable child: Render() was not overshadowed." will not appear in the console.
  }
}


public void draw() {
  DrawBackground();

  hero.Update();
  hero.Render();

  for (Bomb b : bombs) {
    b.Update();
    b.Render();
  }

  ShowHitCount();
}


public void DrawBackground() {
  fill(0);
  stroke(0);
  rect(0, 0, width, height, 0); // dark background 
}

public void ShowHitCount() {
  textAlign (RIGHT);
  textSize(height/20);
  fill(color(200, 200, 0));
  text(hitCount, width-20, height/20 + 20);
}


class Drawable {
  protected float x, y, w, h; // 'protected' is like 'private', but child class retain access
  protected color fill, stroke;
  protected float strokeWeight = 1;

  Drawable() {
    this(0, 0, 0, 0);
  }

  Drawable(float x, float y, float w, float h) {
    this.x = x;
    this.y = y;
    this.w = w;
    this.h = h;
  }

  public void Render() { print("Drawable child: Render() was not overshadowed."); } // nothing to see here: this exists so we can overshadow it in the childs
  public void Update() { print("Drawable child: Update() was not overshadowed."); } // same thing
}


class Hero extends Drawable { // 'extends' is keyword for 'will inherit from'
  Hero() {
    // 'super()' calls the parent's constructor
    // in this example, I decided that the hero would be a red 40x60 rectangle that follows the mouse X position
    super(mouseX - 20, height - 80, 40, 60);

    fill = color(200, 0, 0);
    stroke = color(250);
  }

  public void Update() { // when both parents and child have the same function (type and signature), the child's one prevail. That's overshadowing.
    x = mouseX - w/2;
  }

  public void Render() {
    fill(fill);
    stroke(stroke);
    strokeWeight(strokeWeight);
    rect(x, y, w, h);
  }
}


class Bomb extends Drawable {
  protected float fallSpeed;

  Bomb(float xPosition, float fallSpeed) {
    // Bombs will be small blue squares falling from the sky
    super(xPosition, -20, 20, 20);
    this.fallSpeed = fallSpeed;

    fill = color(0, 0, 200);
    stroke = fill;
  }

  private void FallAgain() {
    x = random(20, width-20);
    fallSpeed = random(1, 10);
    y = 0 - random(20, 100);
  }

  public void Update() {
    y += fallSpeed;

    // check for collision with the Hero
    if (intersect(x, y, w, h, hero.x, hero.y, hero.w, hero.h)) {
      hitCount++;
      FallAgain();
    }

    // check if it fell lower than the screen
    if (y > height) {
      FallAgain();
    }
  }

  public void Render() {
    fill(fill);
    stroke(stroke);
    strokeWeight(strokeWeight);
    rect(x, y, w, h);
  }
}


//  INTERSECT RECTs
boolean intersect(float x1, float y1, float w1, float h1, float x2, float y2, float w2, float h2)
{
    boolean checkX = x1 < x2 && x1+w1 > x2 || x1 < x2+w2 && x1+w1 > x2+w2 || x1 > x2 && x1+w1 < x2+w2 || x1 < x2 && x1+w1 > x2+w2; 
    boolean checkY = y1 < y2 && y1+h1 > y2 || y1 < y2+h2 && y1+h1 > y2+h2 || y1 > y2 && y1+h1 < y2+h2 || x1 < y2 && y1+h1 > y2+h2;

    return checkX && checkY;
}



4.奖金:实施方面的帮助

所以...您正在看到这一点,因此您想对程序进行改进.那挺好的.也许您想实现一些继承,也许只是冲突.两者都可能很棘手,而且都不会影响用户.



4. Bonus: help with implementation

So... you're seeing this and it makes you want to improve on your program. That's good. Maybe you want to implement some inheritance, maybe just the collisions. Both can be tricky, and neither is supposed to impact the user.

这就是所谓的重构".

让我们首先实现一个Drawable类.剩下的会更容易了.

Let's implement a Drawable class first. The rest will be easier then.

第一步:找到汉堡,荷马和沙拉的共同点是什么.从您发布的代码中,我可以看到他们需要这些东西:

First step: find what's the common ground with Burger, Homer and Salad. From the code you posted, I can see that they need these things:

int x, y;
int speedX, speedY;
PImage img;
// To which I would add:
int w, h;
boolean isVisible;

我注意到您正在使用整数.很好,但是我强烈建议您使用float作为坐标.当我学习编码时,我做了同样的事情,最终我后悔没有更早地使用float.整数和浮点数都可以解决这个问题(在需要时进行一些强制转换).

I notice that you're using integers. That's fine, but I strongly suggest using float for coordinates. I did the same thing when I was learning to code and I ended up regretting not using float earlier. Both integer and float will probably do the trick for this project (with some cast when needed).

此外,这是它们共享的几个功能:

Also, here are a couple functions that they share:

void Render()
void Update()
void Move()
// To which I would add:
void SetPosition()
void SetIsVisible()
boolean Crash() // so we can check if it intersect with given coordinates

到目前为止,您的Drawable类可能如下所示:

So far, your Drawable class could look like this:

class Drawable {
  public float x, y, w, h; // Making variables public while you could avoid it is bad practice, I'm doing it to avoid writing Get functions. Avoid doing this as much as possible, but bear with me for now.
  protected float speedX, speedY;
  protected PImage img;
  protected boolean isVisible = true;

  Drawable(float x, float y, float w, float h, String imagePath) {
    this.x = x; // starting x position
    this.y = y; // starting y position
    this.w = w; // width if the object (your image in this case)
    this.h = h; // height of the object (height of your image)

    if (imagePath.length() > 0) { // if there is nothing in the string it won't try to load an image
      img = loadImage(imagePath);
    }
  }

  public void Render() {
    if (isVisible && img != null) {
      image(img, x, y);
    }
  }

  public void Update() {
    Move(); // I kept Move() out of Update() so you can overshadow Update() without having to re-code Move() later
  }

  protected void Move() {
    // The 'normal' behavior of a Drawable would then to move according to it's speed.
    // You can then change how they move by changing their speed values.
    // Or... you can overshadow this function in a child class and write your own!
    x += speedX;
    y += speedY;
  }

  public void SetPosition(float x, float y) {
    this.x = x;
    this.y = y;
  }

  public void SetIsVisible(boolean isVisible) {
    this.isVisible = isVisible;
  }

  public boolean Crash(float x, float y, float w, float h) {
    // this function uses the 'intersect' function I wrote earlier, so it would have to be included in the project
    return intersect(this.x, this.y, this.w, this.h, x, y, w, h);
  }
}

到目前为止还不错,不是吗?这将为您的所有对象奠定坚实的基础.现在,让我们看看如何将其实现到您现有的类中:

Not so bad so far, isn't it? This will make a strong base for all your objects. Now, let's see how to implement this into your existing class:

荷马:

class Homer extends Drawable // give Homer the power of the Drawable class!
{
  Homer(float x, float y)
  {
    // I can read in the code that your image will be (60, 52), but you have to write the manipulation here
    super(x, y, 60, 52, "homer.png");
    img.resize (60, 52);   
  }

  public void Update() {
    // do Update stuff so Homer can move around
  }
}

请注意,由于所有Drawable东西都在其他地方处理了,因此该类要小得多.

Notice how smaller this class is now that all the Drawable stuff is dealt elsewhere.

现在,这里是沙拉课:

首先,您可以删除 salad1,salad2,salad3 全局变量.我们会将它们放在列表中,并且您可以根据需要添加或减少它们(您可以将其视为能够更改难度设置):

First, you can drop the salad1, salad2, salad3 global variables. We'll put them in a list, and you'll be able to have more or less of them if you want (you can think of this as being able to change the difficulty setting):

int numberOfSalads = 3;
ArrayList<Salad> salads = new ArrayList<Salad>();

在沙拉沙拉化的地方,您可以循环初始化它们:

In the place where you innitialize the salads, you can initialize them in a loop:

for (int i=0; i<numberOfSalads; i++) {
  salads.add(new Salad(random(25,475), 900, 3);
}

当然,还会对Salad类进行一些修改:

Sure, there will be some modifications to make to the Salad class, too:

class Salad extends Drawable {
  Salad(float x, float y, float speedY)
  {
    super(x, y, 60, 52, "salad.png");
    this.speedY = speedY; // Drawable will take it from here
    img.resize (60, 52);
  }

  protected void Move() // I knew this would come in handy!
  {
    // I have no idea what's going on, just re-writing your stuff
    y = y - speedY;
    y = y + random(-5, 5);

    if (this.y < 0)
    {
      this.y = 900; // once the salads y is less than 0 they restart at 900
      this.x = random(25, 475);
      speedY = speedY + 0.5;
    }
  }
}

到目前为止,太好了.在许多其他地方,您也必须修改代码,但是您应该注意到,到目前为止,您已经删除了添加的更多行.这是好事.只要您的代码易于阅读,将其缩短就意味着您可以在更少的地方查找要修复的讨厌的错误.

So far, so good. There are MANY other places where you'll have to adapt the code, but you should notice that so far you've removed more lines that You've added. That's a good thing. As long as your code is easy to read, making it shorter means that there's less places to look for nasty bugs to fix.

此外,当您避免将相同的行(如所有相同的Render函数)都放在一个位置(在这种情况下为Drawable类)时,也可以避免重复查找相同的代码(如果需要)想要做出改变.这称为DRY码.DRY(不要自己重复)代码易于调试和维护.根据经验,每次复制和粘贴代码时都无需做任何更改,您应该问自己是否可以仅将这些行放在一个集中的位置,而不管它是变量,函数还是类.

Also, when you avoid repeating the same lines (like all those identical Render functions) by having them all in one place (the Drawable class in this case), you also avoid having to hunt down every iteration of your code if you want to make one change. This is called DRY code. DRY (for Dont Repeat Yourself) code is waaay easier to debug and maintain. As a rule of thumb, every time you copy and paste code without any change, you should ask yourself if you could just keep these line in one centralized place, whether it's a variable or a function or a class.

我让您编写Burger类的代码.我认为您已经了解了如何与其他人打交道,就可以进行管理.

I'll let you code the Burger class. I think you'll manage it now that you have seen how to deal with the others.

现在,让我们看看如何更新主循环 draw():

Now, let's take a look at how to update your main loop, draw():

void draw ()
{
  // As a general rule, all your game states should be dealt in the game loop.
  // I like 'switch' statements for this kind of operations
  // Also, try not to clutter the game loop. If you have a lot of code here, you should probably put them into functions
  // it will make it easier to read and the game loop can very easily become a spaghetti nightmare if you're not careful.
  switch(gameMode) {
  case Menu:
    // Do Menu stuff
    break;
  case Active:
    drawBackground();  // Maybe this should be before the switch, I'm not sure how you want to deal with this

    // Updates
    user1.Update();
    burger.Update();
    for (Salad s : salads) {
      s.Update();
    }

    // Check for collisions
    // I may be mistaken but I think only the Homer can collide with stuff
    if (burger.Crash(user1.x, user1.y, user1.w, user1.h)) {
      // Do burger crash stuff
    }
    for (Salad s : salads) {
      if (s.Crash(user1.x, user1.y, user1.w, user1.h)) {
        // Do Salad crash stuff
      }
    }

    // Render
    user1.Render();
    burger.Render();
    for (Salad s : salads) {
      s.Render();
    }
    break;
  case End:
    // Do End stuff
    break;
  }
}

这应该使您步入正轨.

如果由于某种原因您只想使用相交方法:请记住,对象的宽度和高度就是您用于其图像的宽度和高度.

If, for some reason you only want to use the intersect method: remember that the width and height of your objects are the one you use for their images.

您可能有疑问,请不要犹豫.玩得开心!

You probably have questions, don't hesitate to ask away. And have fun!

这篇关于碰撞检测仅在对象正好在中心命中时起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆