Comment puis commencer un mouvement d'arrêt

Josiah Parrott:

Mon code arrête un carré rouge quand il touche un carré bleu, mais je ne veux pas le carré rouge pour arrêter indéfiniment. Comment puis-je résoudre ce problème?

J'ai créé la détection de collision, et il fait la vitesse = 0 si le carré rouge touche le carré bleu.

//r=red
float rx = 200;
float ry = 375;
float rw = 50;
float rh = 50;

//b=blue
float bx = 550;
float by = 375;
float bw = 50;
float bh = 50;

float speed = 2;
//float cspeed = 2;

void setup() {
  size(800, 800);
  noStroke();
  noSmooth();
  noCursor();
}

void draw() {
  surface.setTitle(mouseX + ", " + mouseY);
  background(50);
  collision();
  move();
  display();
}

void collision() {
  //Check if blue and red are touching
  boolean hit = rectRect(rx, ry, rw, rh, bx, by, bw, bh);
  if (hit) {
    speed = 0;
  } else {
    speed = 2;
  }
}

void display() {

  fill(0, 0, 255);  //Blue square
  rect(bx, by, bw, bh);

  fill(255, 0, 0);  //Red square
  rect(rx, ry, rw, rh);
}



void move() {
  //Red square movement
  if (keyPressed) {
    if (key == 'd' || key == 'D') {
      rx = rx + speed;
      if (rx > width) {
      }
    }
  }


  if (keyPressed) {
    if (key == 'a' || key == 'A') {
      rx = rx - speed;
      if (rx > width) {
      }
    }
  }

  if (keyPressed) {
    if (key == 'w' || key == 'W') {
      ry = ry - speed;
      if (ry > width) {
      }
    }
  }

  if (keyPressed) {
    if (key == 's' || key == 'S') {
      ry = ry + speed;
      if (ry > width) {
      }
    }
  }
}




boolean rectRect(float rx, float ry, float rw, float rh, float bx, float by, float bw, float bh) {

  //is red touching blue?

  if (rx + rw >= bx && 
    rx <= bx + bw &&   
    ry + rh >= by &&    
    ry <= by + bh) { 
    return true;
  }
  return false;
}

Je ne veux pas le carré rouge et le carré bleu à se chevaucher, mais je veux continuer à jouer si elles ne touchent. En ce moment, l'arrêt carré rouge indéfiniment.

laancelot:

En void collision()vous configurez que la vitesse de la place abaissera à 0,01 quand il y a une collision.

Vous vérifiez de collision après votre carré déplacé .

Une fois vos places entre en collision, ils ne peuvent plus bouger, de sorte que la vitesse est bloquée à 0,01. Pour toujours.

Il y a plusieurs façons que vous pouvez résoudre ce problème. Étant donné que le carré bleu ne bouge, vous pouvez vérifier un mouvement collision avant chevauchement, ou « rebond » le carré rouge quand il y a une collision.

Une solution rapide / facile serait de modifier cette fonction:

void move() {
  //Red square movement
  // You only need to check for input once, then for which input interests you
  if (keyPressed) {
    // I think this would look better in a switch statement, but we'll keep it an If for simplicity
    if (key == 'd' || key == 'D') {
      // checking if the square will collide BEFORE it does
      // notice that the square won't move if it detects that this move will be a collision
      if (!rectRect(rx + speed, ry, rw, rh, bx, by, bw, bh)) {
        rx = rx + speed;
      }
    }
    else if (key == 'a' || key == 'A') {
      if (!rectRect(rx - speed, ry, rw, rh, bx, by, bw, bh)) {
        rx = rx - speed;
      }
    }
    else if (key == 'w' || key == 'W') {
      if (!rectRect(rx, ry - speed, rw, rh, bx, by, bw, bh)) {
        ry = ry - speed;
      }
    }
    else if (key == 's' || key == 'S') {
      if (!rectRect(rx, ry + speed, rw, rh, bx, by, bw, bh)) {
        ry = ry + speed;
      }
    }

    if (ry > width) {
      // insert whatever you were planning with this condition
    }
  }
}

Maintenant, void collision()a été pris en charge par void move(), de sorte que vous pouvez effacer void collision. Il va littéralement jamais arriver, car nous nous arrêtons la place avant toute collision peut se produire.



Maintenant ... vous voulez ajouter quelques places. Facile.

Bien sûr, vous pouvez écrire une movefonction pour chaque carré. Mais cela est fatiguant, et sûr qu'il doit y avoir une meilleure façon.

Il y a, mais cela permettra de tester vos compétences. Nous allons garder les choses simples pour vous éviter écrasante dès le départ, mais sachez que nous allons fil dans le territoire POO (programmation orientée objet). Si vous êtes à l'école, vous bénéficierez beaucoup de la classe compréhension (bien, même si vous n'êtes pas en classe d'école sont toujours génial).

Tout d'abord, nous allons écrire une classe simple, nous pouvons utiliser pour créer et gérer les rectangles que vous utilisez des formes dans ce programme. Si vous utilisez le traitement IDE, je vous suggère de créer un « nouvel onglet » donc nous gardons le code bien rangé. Vous ne devez pas absolument, car le compilateur ne verra pas la différence, mais que votre projet deviennent des onglets plus complexes sont un excellent outil pour organiser votre code.

Dans votre nouvel onglet, entrez ce code:

class Rectangle {
  // This should be 'private', but I'm using 'protected' in case I wan to inherit those later, and 'public' to keep things simple
  public float x = 0;
  public float y = 0;
  public float w = 50;
  public float h = 50;
  protected boolean isVisible = true;
  protected color fillColor;

  // This is the constructor. It serves to initialize the class.
  public Rectangle(float xx, float yy, float ww, float hh, color cc) {
    x = xx;
    y = yy;
    w = ww;
    h = hh;
    fillColor = cc;
  }

  public void Render() {
    // I like to let my class draw themselves!
    if (isVisible) {
      fill(fillColor);
      rect(x, y, w, h);
    }
  }

  public void Move(float moveX, float moveY) {
    // This will be used to move. Since the variables are 'protected', they cannot be accessed from outside this class, so I have to create a tool to use them.
    // It is good practice to set 'public' only what's needed, and to manage class variables inside the class.
    // This is for many good reasons. Among those, remember that it's harder to debug 'why is my x position weird' when it can be accessed from anywhere.
    x += moveX;
    y += moveY;
  }

  public boolean Collision(float xx, float yy, float ww, float hh, float moveX, float moveY) {
    // Give coordinates to this function and it will tell you if there's a collision with this rectangle
    return Intersect(x + moveX, y + moveY, w, h, xx, yy, ww, hh);
  }
}

Terminé? Génial! Maintenant, vous avez une classe Rectangle qui contiendra des choses comme les coordonnées, la couleur, etc. de vos rectangles.

Maintenant, nous allons devoir faire un changement couple à votre code.

Tout d'abord, vous n'avez pas besoin des variables globales pour suivre les positions du carré rouge et bleu, comme cela sera traité par la classe que vous venez de créer. Vous pouvez effacer ceux-ci. Les variables globales sont utiles, mais en règle générale, moins vous utilisez mieux vous y serez, en tant que variables globales peuvent devenir un cauchemar pour suivre et provoquer des erreurs imprévues.

Ensuite, vous devrez initialiser votre nouvelle classe en un rectangle de belle couple. Pour garder les choses en ordre, nous avons un rectangle nommé « rouge », et un ArrayList de rectangles sans noms qui seront les obstacles. ArrayLists sont un excellent outil, vous pouvez apprendre à utiliser plus tard; pour l'instant, disons simplement qu'il contiendra tous ces obstacles dans une liste soignée que nous appellerons à au besoin.

La movefonction devra faire face à tous les nouveaux obstacles et aussi avec le fait que nous traitons avec un objet et non un tas de variables globales.

Et, enfin, la fonction rectRect devra être mis à jour. Pour l'instant, il permet de vérifier si le rouge et le bleu ont été recoupées, mais désormais il doit être en mesure de vérifier pour tout et tous les rectangles. Nous allons le rendre plus neutre et l'utiliser différemment.

Voici le code après ces changements:

//red
Rectangle red;

//all other rectangles
ArrayList <Rectangle> rectList;

float speed = 2;
//float cspeed = 2;

void setup() {
  size(800, 800);
  noStroke();
  noSmooth();
  noCursor();

  // Initializing Red square
  red = new Rectangle(200, 375, 50, 50, color(255, 0, 0));
  // Initializing a bunch of rectangles
  rectList = new ArrayList <Rectangle>();
  rectList.add(new Rectangle(550, 375, 50, 50, color(0, 0, 255)));  // Red
  rectList.add(new Rectangle(300, 500, 50, 50, color(0, 255, 0)));  // Green
  // you can add as many as you want
}

void draw() {
  surface.setTitle(mouseX + ", " + mouseY);
  background(50);
  move();
  display();
}

void display() {
  red.Render();

  // this is a java 'For Each' loop. Research it, it's very useful.
  for ( Rectangle r : rectList) {
    r.Render();
  }
}

void move() {
  //Red square movement
  float moveX = 0;
  float moveY = 0;

  if (keyPressed) {
    // We're going calculate up how much we want to move the red square first
    // Then we'll check for collisions
    // Then we'll move the square (it there are no collisions)
    if (key == 'd' || key == 'D') {moveX += speed;}
    else if (key == 'a' || key == 'A') {moveX -= speed;}
    else if (key == 'w' || key == 'W') {moveY -= speed;}
    else if (key == 's' || key == 'S') {moveY += speed;}

    for (Rectangle r : rectList) {
      if (red.Collision(r.x, r.y, r.w, r.h, moveX, moveY)) {
        // If a collision is detected, we exit this function so there will be no move
        return;
      }      
    }

    red.Move(moveX, moveY);
  }
}

// INTERSECT RECTs
// The old function was nice, but it was really useful only with your specific example. You can re-use this one with any set of rectangles.
// There are many ways to write this function. I wrote this instance back when I was a student, and I still use it to this day.
boolean Intersect(float x1, float y1, float w1, float h1, float x2, float y2, float w2, float h2)
{
  boolean checkX = false;
  boolean checkY = false;

  if ( (x1<=x2 && (x1+w1)>=x2) || (x1<=(x2+w2) && (x1+w1)>=x2+w2) || (x1>=x2 && (x1+w1)<=(x2+w2)) ) {checkX = true;}
  if ( (y1<=y2 && (y1+h1)>=y2) || (y1<=(y2+h2) && (y1+h1)>=y2+h2) || (y1>=y2 && (y1+h1)<=(y2+h2)) ) {checkY = true;}

  if (checkX && checkY) {return true;}

  return false;
}

Maintenant, vous pouvez ajouter un tas d'autres carrés et rectangles de tout et de toutes les tailles et couleurs! Essayez-le! Mais, plus important encore, essayer de le comprendre. Si vous avez des questions, rappelez-vous que je suis là pour vous aider.

S'amuser!

Je suppose que tu aimes

Origine http://43.154.161.224:23101/article/api/json?id=313626&siteId=1
conseillé
Classement