Jeu de serpent de problème! java-swing-Jframe


Je suis un lycéen qui travaille actuellement sur un jeu snake (eating the food version) sur java swing (JFrame); dans NetBeans ID 8.0.2. Jusqu'à présent, j'ai pu déplacer le serpent et générer aléatoirement la nourriture; le serpent mange cependant la nourriture et s'arrête lorsqu'il entre en collision avec les frontières/limites autour du tableau. Mais pour être honnête, je ne sais vraiment pas comment faire pousser le serpent à partir de là. Les gens m'ont suggéré d'utiliser une ArrayList afin que je puisse ajouter des morceaux du même bloc(Jpanel). De dites la vérité, je ne suis pas trop familier à ArrayList. Alors voulez - vous m'aider sur la façon dont je fais cette ArrayList et l'utiliser pour faire pousser le serpent. De plus, lorsque le serpent avance(dans n'importe quelle direction), comment puis-je empêcher le serpent de reculer(à l'opposé du bouton Avant), ne devrait-il pas seulement pouvoir se déplacer à gauche, à droite et en avant. J'espère que vous comprendrez ce que je veux dire. Enfin, puisque ma nourriture est générée aléatoirement, elle chevauche parfois le serpent et comment puis-je arrêter la nourriture se chevauchant sur le corps des serpents.

Ce lien vous montrera à quoi ressemble mon jeu (le bloc rouge est mon serpent): http://i.stack.imgur.com/xko2n.jpg

Dans le lien ci-dessus, le bloc rouge est mon serpent, les blocs jaunes sont ma nourriture et la pièce supplémentaire est le bloc que je veux ajouter au serpent et le faire pousser. Les lignes bleues il y a mes frontières / limites.

Voici mon code jusqu'à présent:

package culminating;

import java.util.Random;
import javax.swing.JLabel;
import javax.swing.Timer;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.Rectangle;
import javax.swing.JOptionPane;

public class Visual extends javax.swing.JFrame {
 JLabel[] food = new JLabel[10];
 JLabel[] border = new JLabel[4];
 Timer s_timer;
 boolean[] keys = new boolean[525];
 boolean up = false, down = false;
 int count;
 static int X,Y, lcount;
  public Visual() {
    initComponents();
}


@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">                          
private void initComponents() {

    jPanel1 = new javax.swing.JPanel();
    snake = new javax.swing.JLabel();
    jLabel8 = new javax.swing.JLabel();
    jLabel2 = new javax.swing.JLabel();
    jLabel10 = new javax.swing.JLabel();
    jLabel7 = new javax.swing.JLabel();
    jLabel4 = new javax.swing.JLabel();
    jLabel5 = new javax.swing.JLabel();
    jLabel9 = new javax.swing.JLabel();
    jLabel3 = new javax.swing.JLabel();
    jLabel6 = new javax.swing.JLabel();
    jLabel1 = new javax.swing.JLabel();
    jLabel11 = new javax.swing.JLabel();
    jLabel12 = new javax.swing.JLabel();
    jLabel13 = new javax.swing.JLabel();
    jLabel14 = new javax.swing.JLabel();
    jLabel15 = new javax.swing.JLabel();
    jLabel18 = new javax.swing.JLabel();

    setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
    addComponentListener(new java.awt.event.ComponentAdapter() {
        public void componentShown(java.awt.event.ComponentEvent evt) {
            formComponentShown(evt);
        }
    });
    addKeyListener(new java.awt.event.KeyAdapter() {
        public void keyPressed(java.awt.event.KeyEvent evt) {
            formKeyPressed(evt);
        }
    });

    jPanel1.setBackground(new java.awt.Color(0, 0, 0));
    jPanel1.addKeyListener(new java.awt.event.KeyAdapter() {
        public void keyPressed(java.awt.event.KeyEvent evt) {
            jPanel1KeyPressed(evt);
        }
    });
    jPanel1.setLayout(null);

    snake.setBackground(new java.awt.Color(255, 51, 0));
    snake.setOpaque(true);
    jPanel1.add(snake);
    snake.setBounds(230, 230, 20, 20);

    jLabel8.setBackground(new java.awt.Color(255, 255, 0));
    jLabel8.setOpaque(true);
    jPanel1.add(jLabel8);
    jLabel8.setBounds(100, 184, 10, 10);

    jLabel2.setBackground(new java.awt.Color(255, 255, 0));
    jLabel2.setOpaque(true);
    jPanel1.add(jLabel2);
    jLabel2.setBounds(225, 137, 10, 10);

    jLabel10.setBackground(new java.awt.Color(255, 255, 0));
    jLabel10.setOpaque(true);
    jPanel1.add(jLabel10);
    jLabel10.setBounds(419, 305, 10, 10);

    jLabel7.setBackground(new java.awt.Color(255, 255, 0));
    jLabel7.setOpaque(true);
    jPanel1.add(jLabel7);
    jLabel7.setBounds(301, 137, 10, 10);

    jLabel4.setBackground(new java.awt.Color(255, 255, 0));
    jLabel4.setOpaque(true);
    jPanel1.add(jLabel4);
    jLabel4.setBounds(158, 325, 10, 10);

    jLabel5.setBackground(new java.awt.Color(255, 255, 0));
    jLabel5.setForeground(new java.awt.Color(51, 0, 51));
    jLabel5.setOpaque(true);
    jPanel1.add(jLabel5);
    jLabel5.setBounds(412, 381, 10, 10);

    jLabel9.setBackground(new java.awt.Color(255, 255, 0));
    jLabel9.setOpaque(true);
    jPanel1.add(jLabel9);
    jLabel9.setBounds(503, 325, 10, 10);

    jLabel3.setBackground(new java.awt.Color(255, 255, 0));
    jLabel3.setOpaque(true);
    jPanel1.add(jLabel3);
    jLabel3.setBounds(410, 220, 10, 10);

    jLabel6.setBackground(new java.awt.Color(255, 255, 0));
    jLabel6.setOpaque(true);
    jPanel1.add(jLabel6);
    jLabel6.setBounds(432, 99, 10, 10);

    jLabel1.setBackground(new java.awt.Color(255, 255, 0));
    jLabel1.setOpaque(true);
    jPanel1.add(jLabel1);
    jLabel1.setBounds(510, 400, 10, 10);

    jLabel11.setBackground(new java.awt.Color(51, 51, 255));
    jLabel11.setOpaque(true);
    jPanel1.add(jLabel11);
    jLabel11.setBounds(0, 0, 20, 460);

    jLabel12.setBackground(new java.awt.Color(51, 51, 255));
    jLabel12.setOpaque(true);
    jPanel1.add(jLabel12);
    jLabel12.setBounds(0, 450, 560, 0);

    jLabel13.setBackground(new java.awt.Color(51, 51, 255));
    jLabel13.setOpaque(true);
    jPanel1.add(jLabel13);
    jLabel13.setBounds(0, 0, 560, 20);

    jLabel14.setBackground(new java.awt.Color(51, 51, 255));
    jLabel14.setOpaque(true);
    jPanel1.add(jLabel14);
    jLabel14.setBounds(540, 0, 20, 460);

    jLabel15.setBackground(new java.awt.Color(51, 51, 255));
    jLabel15.setOpaque(true);
    jPanel1.add(jLabel15);
    jLabel15.setBounds(0, 450, 560, 14);

    jLabel18.setIcon(new   javax.swing.ImageIcon(getClass().getResource("/culminating/snake body.jpg"))); // NOI18N
    jLabel18.setText("jLabel17");
    jPanel1.add(jLabel18);
    jLabel18.setBounds(150, 350, 20, 20);

    javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
    getContentPane().setLayout(layout);
    layout.setHorizontalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, 556, Short.MAX_VALUE)
    );
    layout.setVerticalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, 463, Short.MAX_VALUE)
    );

    pack();
}// </editor-fold>                        

private void formComponentShown(java.awt.event.ComponentEvent evt) {                                    
  this.requestFocusInWindow();
    food[0]=jLabel1;
    food[1]=jLabel2;
    food[2]=jLabel3;
    food[3]=jLabel4;
    food[4]=jLabel5;
    food[5]=jLabel6;
    food[6]=jLabel7;
    food[7]=jLabel8;
    food[8]=jLabel9;
    food[9]=jLabel10;

    Random h = new Random();
    Random v = new Random();

    border[0]=jLabel11;
    border[1]=jLabel13;
    border[2]=jLabel14;
    border[3]=jLabel15;

    System.out.println(jLabel1.getX());
    System.out.println(jLabel1.getY());
    this.setBounds(0, 0, 570, 500);

    food[0].setLocation(h.nextInt(490)+20, v.nextInt(412)+20);
    food[1].setLocation(h.nextInt(490)+20, v.nextInt(412)+20);
    food[2].setLocation(h.nextInt(490)+20, v.nextInt(412)+20);
    food[3].setLocation(h.nextInt(490)+20, v.nextInt(412)+20);
    food[4].setLocation(h.nextInt(490)+20, v.nextInt(412)+20);
    food[5].setLocation(h.nextInt(490)+20, v.nextInt(412)+20);
    food[6].setLocation(h.nextInt(490)+20, v.nextInt(412)+20);
    food[7].setLocation(h.nextInt(490)+20, v.nextInt(412)+20);
    food[8].setLocation(h.nextInt(490)+20, v.nextInt(412)+20);
    food[9].setLocation(h.nextInt(490)+20, v.nextInt(412)+20);

   s_timer = new Timer(50, new SnakeAction());
   s_timer.start();
   X=snake.getX();
   Y=snake.getY();

}                                   

private void jPanel1KeyPressed(java.awt.event.KeyEvent evt) {                                   

}                                  

private void formKeyPressed(java.awt.event.KeyEvent evt) {                                
    System.out.println(evt.getKeyCode());
      switch( evt.getKeyCode()){
    case 37:
    case 39:
    case 32:
    case 38:
    case 40:
    if (keys[evt.getKeyCode()]==false){
         keys[37]=false;
         keys[39]=false;
         keys[32]=false;
         keys[38]=false;
         keys[40]=false;
        keys[evt.getKeyCode()] = true;
    }
    break;
}           
}                               




 class SnakeAction implements ActionListener {
    public void actionPerformed(ActionEvent e) {
    String infoMessage, titleBar;
    if(keys[37]){       //left arrow
    up =false;
    down = false;
    checkCollision();
        if(!borderCollision(snake.getX()-10,snake.getY(),snake.getWidth(),snake.getHeight())){
    X-=10;
    snake.setLocation(X, Y);
    }

    }

    if(keys[39]){       //right arrow
    up = false;
    down = false;
    checkCollision();
    if(!borderCollision(snake.getX()+10,snake.getY(),snake.getWidth(),snake.getHeight())){
    X+=10;
    snake.setLocation(X, Y);
    }
    }

    if(keys[38]){       // up
    up=true;
    checkCollision();
    if(!borderCollision(snake.getX(),snake.getY()-7,snake.getWidth(),snake.getHeight())){
    Y-=10;
    snake.setLocation(X, Y);
    }
    }

    if(keys[40]){       //down
    down=true;
    checkCollision();
    if(!borderCollision(snake.getX(),snake.getY()+7,snake.getWidth(),snake.getHeight())){
    Y+=10;
    snake.setLocation(X, Y);
    }

  }

    }
  }
public void checkCollision(){
boolean collision=false;
Rectangle c1,c2=snake.getBounds();
for(int i=0;i<=9;i++){
c1=food[i].getBounds();
if(c1.intersects(c2))food[i].setVisible(false);
}

}
public boolean borderCollision(int x, int y, int w, int h){
boolean collide = false;
Rectangle r1,r2=snake.getBounds();
r2.x=x;
r2.y=y;
r2.width=w;
r2.height=h;
for(int c=0; c<=3;c++){
r1=border[c].getBounds();
if(r1.intersects(r2)){
collide=true;
}
}
return collide;
}
public static void main(String args[]) {

    java.awt.EventQueue.invokeLater(new Runnable() {
        public void run() {
            new Visual().setVisible(true);
        }
    });
}

// Variables declaration - do not modify                     
private javax.swing.JLabel jLabel1;
private javax.swing.JLabel jLabel10;
private javax.swing.JLabel jLabel11;
private javax.swing.JLabel jLabel12;
private javax.swing.JLabel jLabel13;
private javax.swing.JLabel jLabel14;
private javax.swing.JLabel jLabel15;
private javax.swing.JLabel jLabel18;
private javax.swing.JLabel jLabel2;
private javax.swing.JLabel jLabel3;
private javax.swing.JLabel jLabel4;
private javax.swing.JLabel jLabel5;
private javax.swing.JLabel jLabel6;
private javax.swing.JLabel jLabel7;
private javax.swing.JLabel jLabel8;
private javax.swing.JLabel jLabel9;
private javax.swing.JPanel jPanel1;
private javax.swing.JLabel snake;
// End of variables declaration                   

}

Explication du code: j'ai fait deux tableaux pour ma nourriture et des frontières. Chaque aliment est généré aléatoirement à différents endroits. De Jlabel 1 à 10, est ma nourriture et Jlabel 11, 13, 14 et 15 est mon frontières. J'ai une minuterie pour mes serpents mouvement. J'ai utilisé les flèches vers le haut[touche 38], vers le bas[touche 40], vers la gauche[touche 37] et vers la droite[touche 39] pour le mouvement. La nourriture est générée aléatoirement à différents endroits. Lorsque le serpent entre en collision avec un aliment, j'ai utilisé la fonction setvisible pour cacher la nourriture et lorsque le serpent entre en collision avec le frontières / limites, il cesse de bouger.

Author: Qwerty6501, 2016-01-13

2 answers

Eh bien, votre code est tout à fait... Intéressant.

Pour utiliser ArrayList, vous devriez essayer quelque chose comme ceci :

JLabel snakeBody = new JLabel();

snakeBody.setBackground(new java.awt.Color(255, 255, 0));
snakeBody.setOpaque(true);
snakeBody.setBounds(510, 400, 10, 10);

ArrayList<JLabel> snake = new ArrayList<>();
snake.add(snakeBody);

Et chaque fois que le serpent mange vous ajoutez un élément de corps (au bon endroit):

snake.add(snakeBody);

Pour afficher le serpent une boucle foreach devrait faire l'affaire

for(JLabel body : snake){
    jPanel.add(body);
}

Pour empêcher le serpent de revenir en arrière, vous devez simplement supprimer les écouteurs key up et key down et utiliser une boucle pour le faire avancer (selon sa propre perspective). Sinon désactivez simplement le auditeur en fonction de la direction dans laquelle le serpent se déroule. Vous pouvez créer une méthode pour déterminer la direction dans laquelle se trouve le serpent.

class SnakeAction implements ActionListener{
    public void actionPerformed(ActionEvent e) {
        if(key[37] && snakeDirection()!="right"){
            //some code
        }
    }
}

Pour éviter que la nourriture ne chevauche le serpent, vous devez vérifier chaque fois que vous générez votre nombre aléatoire si ces nombres ne correspondent pas à l'emplacement du serpent (et de son corps). S'il ne génère un autre numéro.

 2
Author: YounesM, 2016-01-13 02:43:19

Sur le point de faire pousser le serpent, je suggérerai d'utiliser le code ci-dessous au lieu de ArrayList, car vous n'avez pas besoin de l'utiliser.

Tout d'abord, setVisible ne fonctionne pas dans ce jeu. Vous le cachez, mais il est toujours là. Cela signifie que vous continuerez à manger la nourriture cachée pendant que vous la passerez. Mais vous pouvez utiliser setBounds pour le déplacer.

public void checkCollision()
{
    boolean collision=false;
    Rectangle c1,c2=snake.getBounds();
    for(int i=0;i<=9;i++)
    {
        c1=food[i].getBounds();
        if(c1.intersects(c2))
        {   // it cause the problem
            food[i].setVisible(false);
            // add 
            food[i].setBounds(0,0,0,0);
        }
    }
}

Et de la même manière, pour faire pousser le serpent

//A variable to save direction
String direction = "";
//A variable to save how long you will grow
int grow = 5;

Switch(direction)
{
     case N:

     snake.setBounds(X, Y,(int)snake.getSize().getWidth() ,(int)snake.getSize().getHeight()+grow);
     break;

     case E:

     snake.setBounds(X, Y,(int)snake.getSize().getWidth()+grow ,(int)snake.getSize().getHeight());
     break;

     case W:

     snake.setBounds(X, Y,(int)snake.getSize().getWidth()+grow ,(int)snake.getSize().getHeight());
     break;

     case S:

     snake.setBounds(X, Y,(int)snake.getSize().getWidth() ,(int)snake.getSize().getHeight()+grow);
     break;
}

En détail, notez que si vous voulez un meilleur effet, contrôlez la partie croissante et la position du serpent dans le code aura de l'aide.

Et comme l'a dit @Younes Mgharfaoui, vous ne pouvez pas laisser snake revenir. Alors faites la direction dans une variable. Si vous allez à gauche, vous ne pouvez pas aller à droite immédiatement comme un serpent.

 1
Author: TomN, 2016-01-13 02:52:41