Me gustaría solicitar un juego de serpientes escrito en Java, preferiblemente con comentarios y diagramas de flujo.
El juego Snake implementado usando MVC tiene 4 clases. Simplemente ejecuta GreedSnake. Principalmente sobre el uso del patrón de observador, agregué muchos comentarios.
1.
/*
* Nombre del programa: Snake
* Autor original: BigF
* Modificado por: algo
* Nota: He escrito este programa en C antes, pero ahora veo a BigF escribiendo este programa en Java y descubro que, aunque el autor afirma ser un principiante en Java,
* Pero es obvio que soy bueno escribiendo programas. La estructura del programa está escrita de manera muy clara y algunos detalles sutiles también están escritos de manera muy concisa. Lo hice por capricho.
* A continuación, interpreté cuidadosamente el programa y descubrí que los datos y el rendimiento están bien separados, y actualmente estoy aprendiendo el patrón de diseño MVC
* Así que intenté cambiar la estructura del programa y usar el. Patrón MVC para implementarlo, sin realizar muchos cambios en el programa fuente.
* También agregué algunos comentarios al programa que entiendo, espero que sea útil para que todos los lean.
*/
paquete mvcTest;
/**
* @autor WangYu
* @version 1.0
* Descripción:
*
* Crear el :Fecha :2005-6-13 Hora:15:57:16 p>
* Última modificación:
* Historial:
*/
clase pública GreedSnake {
public static void main( String--
//La dirección de ejecución predeterminada es hacia arriba, por lo que nodeArray cambia tan pronto como comienza el juego:
// [10, 14]-[10, 15] -[11,15]-[12,15]~~[19,15]
nodeArray.addLast(new Node(x, y));
matriz[x] [y] = true;
}
// Crear comida
comida = crearComida();
matriz[comida.x ][food .y] = true;
}
public void changeDirection(int newDirection) {
// La dirección del cambio no puede ser la misma o opuesta a la dirección original
if (dirección % 2 != nuevaDirección % 2) {
dirección = nuevaDirección;
}
}
/**
* Ejecutar una vez
* @return
*/
moveOn público booleano () {
p>Nodo n = (Nodo) nodeArray.getFirst();
int x = n.x;
int y = n.y; p>
// Aumenta o disminuye el valor de las coordenadas según la dirección
switch (dirección) {
case UP:
y--;
ruptura;
p>caso ABAJO:
y++;
ruptura;
caso IZQUIERDA:
x--;
romper;
caso DERECHA:
x++;
romper;
}
// Si las nuevas coordenadas están dentro del rango válido, procéselas
if ((0 <= x && x < maxX) && (0 <= y && y < maxY)) {
if (matrix[x][y]) { // Si hay algo (serpiente o comida) en el nuevo punto de coordenadas
if (x == food.x && y = = food.y) { //Comer comida, éxito
nodeArray.addFirst(food); // Dar un regalo desde la cabeza de la serpiente
// Reglas de puntuación y movimiento. cambia de dirección Los tiempos y la velocidad están relacionados con dos elementos
int scoreGet = (10000 - 200 * countMove) / timeInterval;
Score += ScoreGet > 0 ScoreGet : 10;
countMove = 0;
comida = createFood(); // Crear nueva comida
matriz[food.x][food.y] = true; / Establecer ubicación de comida
return true;
} else // No se pudo comer el cuerpo de la serpiente
return false;
} else { // Si no hay nada (cuerpo de serpiente) en el nuevo punto de coordenadas, mueva el cuerpo de la serpiente
nodeArray.addFirst(new Node(x, y));
matriz [x][y] = verdadero;
n = (Nodo) nodeArray.removeLast();
matriz[n.x][n.y] = falso;
countMove++;
return true;
}
}
return false // Tocó el borde, falló
}
public void run() {
corriendo = true;
mientras (corriendo) {
intenta {
Thread.sleep(timeInterval);
} catch (Excepción e) {
break;
}
if (!paused) {
if (moveOn()) {
setChanged(); // El modelo notifica a View que los datos se han actualizado
notifyObservers(); p>
} else {
JOptionPane.showMessageDialog(null,
"fallaste",
"Juego terminado",
JOptionPane .INFORMATION_MESSAGE);
break;
}
}
}
corriendo = false ; p>
}
Nodo privado createFood() {
int x = 0;
int y = 0;
// Obtenga aleatoriamente una posición en el área efectiva que no se superponga con el cuerpo de la serpiente y la comida
do {
Random r = new Random();
x = r.nextInt(maxX);
y = r.nextInt(maxY);
} while (matrix[x][y]); p>
devolver nuevo Nodo(x, y);
}
public void speedUp() {
timeInterval *= speedChangeRate;
}
public void speedDown() {
timeInterval /= speedChangeRate;
}
public void changePauseState() {
pausado = !pausado;
}
public String toString() {
String resultado = "";
for ( int i = 0; i < nodeArray.size(); ++i) {
Nodo n = (Nodo)
nodeArray.get(i);
resultado += "[" + n.x + "," + n.y + "]";
}
devolver resultado ;
}
}
clase Nodo {
int x;
int y;
Nodo(int x, int y) {
this.x = x;
this.y = y;
}
}
-------------------------------------- --------- -----------------------
4.
paquete mvcTest ;
// SnakeView.java
importar javax.swing.*;
importar java.awt.*;
importar java .util.Iterator;
importar java.util.LinkedList;
importar java.util.Observable;
importar java.util.Observer;
/**
* El visor en modo MVC solo es responsable de mostrar datos y no le importa la lógica de control del juego
*/
la clase pública SnakeView implementa Observer {
control SnakeControl = null;
modelo SnakeModel = null;
JFrame mainFrame;
Canvas paintCanvas;
JLabel labelScore ;
public static final int canvasWidth = 200;
public static final int canvasHeight = 300;
public static final int nodeWidth = 10;
public static final int nodeHeight = 10;
public SnakeView(modelo SnakeModel, control SnakeControl) {
this.model = modelo;
this. control = control;
mainFrame = new JFrame("GreedSnake");
Contenedor cp = mainFrame.getContentPane(); p>
// Crea la visualización de puntuación más alta
labelScore = new JLabel("Score:");
cp.add(labelScore, BorderLayout.NORTH); p>
// Crea el programa de juego intermedio
Área de visualización
paintCanvas = new Canvas();
paintCanvas.setSize(canvasWidth + 1, canvasHeight + 1);
paintCanvas.addKeyListener(control);
cp.add(paintCanvas, BorderLayout.CENTER);
// Crea la barra de ayuda debajo
JPanel panelButtom = new JPanel();
panelButtom.setLayout(new BorderLayout());
JLabel labelHelp;
labelHelp = new JLabel("Re Pág, Av Pág para velocidad;", JLabel.CENTER);
panelButtom.add(labelHelp, BorderLayout.NORTH);
labelHelp = new JLabel("ENTER o R o S para inicio;", JLabel.CENTER);
panelButtom.add(labelHelp, BorderLayout.CENTER);
labelHelp = new JLabel("ESPACIO o P para pausa", JLabel.CENTER);
panelButtom.add( labelHelp, BorderLayout.SOUTH);
cp.add(panelButtom, BorderLayout.SOUTH);
mainFrame.addKeyListener(control);
mainFrame.pack( );
mainFrame.setResizable(false);
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainFrame.setVisible(true);
}
void repaint() {
Gráficos g = paintCanvas.getGraphics();
//dibujar fondo
g.setColor(Color.WHITE);
g.fillRect(0, 0, canvasWidth, canvasHeight);
// dibuja la serpiente
g. setColor(Color.BLACK);
LinkedList na = model.nodeArray;
Iterador it = na.iterator();
while (it.hasNext()) {
Nodo n = (Nodo) it.next();
drawNode(g, n);
}
// dibuja la comida
g.setColor(Color.RED);
Nodo n = model.food;
drawNode(g, n);
updateScore();
}
private void drawNode(Gráficos g, Nodo n) {
g.fillRect(n.x * nodeWidth,
n.y * nodeHeight,
nodeWidth - 1,
nodeHeight - 1);
}
public void updateScore() {
String s = "Puntuación: " + model.score;
labelScore.setText(s);
}
actualización nula pública (Observable o, objeto arg) {
repintar();
}
}