La creazione di Serpente utilizzando Java

Ho deciso di ri-creare Serpente utilizzando Java, ma mi sento una sorta di bloccato. Al momento, ho un quadrato che l’utente può spostarsi all’interno dello schermo utilizzando i tasti freccia. Quando si premere il tasto SINISTRO una volta, la piazza comincia a spostarsi a sinistra con un timer.. non è necessario tenere premuto il tasto o tenerlo premuto e cambia direzione quando si preme uno qualsiasi degli altri tasti impostati(a Destra, in Alto, in Basso). Il mio obiettivo è quello di utilizzare un ArrayList di tenere i quadrati che compongono il serpente. Al momento, ho creato un ArrayList con un solo Serpente oggetto all’interno, se posso aggiungere un secondo Serpente oggetto alla lista e aggiungere al telaio(con il primo), un solo Serpente l’oggetto è visibile e i tasti per spostarsi non funzione. Sto cercando alcune idee su come posso progredire con questo progetto – per favore, non darmi la risposta completa, perché mi piacerebbe capire di più sulla mia, ho solo bisogno di qualche direzione. Grazie in anticipo – il codice è sotto.

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Snake extends JPanel implements KeyListener, ActionListener
{
int x = 0, y = 0, velx = 0, vely = 0;
Timer t = new Timer(250, this);


public Snake(int num1, int num2)
{
    t.start();
    addKeyListener(this);
    setFocusable(true);
    setFocusTraversalKeysEnabled(true);
    x = num1;
    y = num2;
}
public void paintComponent(Graphics g)
{   
    super.paintComponent(g);

    g.setColor(Color.blue);
    g.fillRect(x, y, 20, 20);
}
public void actionPerformed(ActionEvent e)
{
    repaint();
    x += velx;
    y += vely;
}
public void up()
{
    vely = -20;
    velx = 0;
}
public void down()
{
    vely = 20;
    velx = 0;
}
public void left()
{
    vely = 0;
    velx = -20;
}
public void right()
{
    vely = 0;
    velx = 20;
}
public void keyPressed(KeyEvent e)
{
    int code = e.getKeyCode();

    if(code == KeyEvent.VK_UP)
        up();
    else if(code == KeyEvent.VK_DOWN)
        down();
    else if(code == KeyEvent.VK_RIGHT)
        right();
    else if(code == KeyEvent.VK_LEFT)
        left();

}
public void keyReleased(KeyEvent e)
{

}
public void keyTyped(KeyEvent e)
{

}
}
//Driver Class
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import java.util.*;

public class UserClass
{
private static JFrame frame = new JFrame("Snake");
private static ArrayList<Snake> mySnake = new ArrayList<Snake>();

public static void main(String[] args)
{
    frame.setSize(500,500);
    frame.setBackground(Color.black);
    frame.setVisible(true);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    mySnake.add(new Snake(20,20));
    frame.add(mySnake.get(0));
}
}

P. S Quando ho messo questo stesso codice esatto in Eclipse sul mio Mac, lo sfondo del mio telaio è nero, ma su Windows è grigio chiaro… Qualcuno sa il perché? Grazie.

Sono abbastanza sicuro sovrapposizione di un JPanel per oggetto non è una buona idea …

OriginaleL’autore corecase | 2012-06-09

3 Replies
  1. 5

    Per rispondere alla tua postscript, è possibile impostare un colore di sfondo o fare un JPanel dietro tutto il resto con un colore dipinto.

    Di avanzamento del progetto, in considerazione l’esecuzione di un esercizio nel framework MVC. Quello che sta accadendo ora è che il Modello e la Vista sono collegati nella stessa classe – questo rende difficile seguire la logica dietro a tutto.

    Cosa si può fare è in primo luogo separare il vostro Serpente dal nulla a che fare con la vista un serpente velenoso con un ArrayList<Integer[]> segmentLocations o qualcosa del genere, per rappresentare i (x,y) di ogni segmento posizioni su un consiglio di amministrazione che si definisce – è possibile utilizzare le coordinate assolute o si può fare un arbitrario griglia e il cambiamento di coordinate assolute nel vostro punto di Vista (questo caratterizza l’MVC rapporto migliore). Snake dovrebbe avere anche un campo per la direzione del serpente è di fronte – vorrei utilizzare un enum Direction {N, S, E, W}, ma si dispone di opzioni che, come si potrebbe anche avere un valore intero che rappresenta la direzione, o una varietà di altri modi.

    Il Serpente sarebbe poi anche modi aggiornamento – move(), spostando la posizione di tutti i segmenti, sulla base della attuale direzione per il segmento iniziale e la causa di tutti gli altri segmenti di seguire il movimento di quello di prima (questo è abbastanza facile se si considera che per un paio di minuti).

    Il tuo punto di vista può essere un JFrame con un GridLayout composto di JPanels che sondaggio il vostro Serpente istanza e vedere se c’è un segmento in posizione e se è così, disegnare, o una moltitudine di altre opzioni.

    Il controller potrebbe essere il KeyAdapter che invia gli aggiornamenti di direzione per il vostro Serpente quando i tasti di direzione.

    Piccolo suggerimento, per rendere la vostra vita più facile: quando si aggiunge un nuovo segmento, basta avere la posizione dell’ultimo segmento del Serpente. La prossima volta che si muove, il nuovo segmento sarà nella stessa posizione, e il resto del Serpente dovrebbe avere muoversi di conseguenza.

    Tutti ottimi suggerimenti. +1 voto.
    Vi ringrazio molto.

    OriginaleL’autore

  2. 5

    Tuo paintComponent(...) solo disegna un rettangolo. Invece se si vuole disegnare più rettangoli o ovali, o qualsiasi altra cosa, a dare la tua classe un List<Point> o List<Rectangle2D>, e nel vostro Swing Timer, rimuovere la coda dall’elenco e aggiungere una nuova testa. poi paintComponent() utilizzare un ciclo for per scorrere una lista, il disegno di tutti i rettangoli detenute dalla lista.

    Inoltre, si probabilmente desidera utilizzare key bindings piuttosto che un KeyListener per ottenere la chiave dell’utente preme come questo funziona meglio quando gli altri componenti rubare il fuoco.

    Grazie per il vostro input.

    OriginaleL’autore

  3. 4

    Dato una classe definisce un segmento di geometria,

    class Segment {
        private int x, y, d;
    
        public Segment(int x, int y, int r) {
            this.x = x - r;
            this.y = y - r;
            this.d = 2 * r;
        }
    }

    Considerare una coda di segmenti,

    Queue<Segment> snake = new LinkedList<Segment>();

    Quindi ogni iterazione è semplicemente

    snake.remove();
    snake.add(new Segment(...));

    E paintComponent() include questo ciclo

    @Override
    public void paintComponent(Graphics g) {
        ...
        for (Segment s : snake) {
            g.fillXxxx(s.x, s.y, s.d, s.d);
        }
        ...
    }
    Grazie mille; che sicuramente ha contribuito a chiarire le cose.
    Non l’istanza variabili x, y, d all’interno del Segmento di classe deve essere pubblico per questo tipo di lavoro? Dal paintComponent è l’accesso a tali varibles?
    Basta fare un metodo get, per ciascuna variabile, se non ti piace avere dati pubblici soci. (getX (), ecc.)
    Sì, l’originale è stato private static Segment. Vedere anche Bloch, Efficace Java, 2a ed, “‘Articolo 13: Ridurre al minimo l’accessibilità delle classi e membri”.

    OriginaleL’autore

Lascia un commento