자바 뱀 먹 기 게임 실현
MVC 모드 의 전체 자바 프로젝트 입 니 다.Snake App.java 를 컴 파일 하여 실행 하면 게임 을 시작 할 수 있 습 니 다.
확장 가능 기능:
1.포인트 기능:득점 규칙 의 유형(모델 류 의 일부분)을 만 들 고 GameController 의 run()방법 에서 점 수 를 계산 할 수 있 습 니 다.
2.변속 기능:예 를 들 어 가속 기능,감속 기능 은 GameController 의 keypressed()방법 에서 특정한 버튼 에 대해 매번 이동 사이 의 시간 간격 을 설정 하고 Thread.sleep(Settings.DEFAULTMOVE_INTERVAL);동적 시간 간격 으로 바 꾸 면 됩 니 다.
3.더욱 아름 다운 게임 인터페이스:GameView 의 drawXXX 방법 을 수정 합 니 다.예 를 들 어 음식 을 그림 으로 과장 할 수 있 고 Graphics 는 drawImage 방법 이 있 습 니 다.
View
SnakeApp.java
/*
* View, , 。
*/
public class SnakeApp {
public void init() {
//
JFrame window = new JFrame(" ");
// 500X500 , ,
Grid grid = new Grid(50*Settings.DEFAULT_NODE_SIZE,50*Settings.DEFAULT_NODE_SIZE);
// grid ,
GameView gameView = new GameView(grid);//
//
gameView.initCanvas();
//
GameController gameController = new GameController(grid);
//
window.setPreferredSize(new Dimension(526,548));
// , , paintComponent 。
window.add(gameView.getCanvas(),BorderLayout.CENTER);
//
GameView.draw();
//
window.addKeyListener((KeyListener)gameController);
//
new Thread(gameController).start();
//
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//
window.setResizable(false);
//
window.pack();
window.setVisible(true);
}
// ,
public static void main(String[] args) {
SnakeApp snakeApp = new SnakeApp();
snakeApp.init();
}
}
GameView.java
/*
* View, 、 、
*/
/* Graphics 。 Java 。 :
Component 。
。
。
。
。
(XOR Paint)。
XOR
*/
/* java.awt.Component repaint()
: 。
, repaint ,AWT update 。 。
Component update paint 。 repaint 。 Component super.update(g), update paint(g)。
, (0,0) 。 。
*/
public class GameView {
private final Grid grid;
private static JPanel canvas;// , , 。
public GameView(Grid grid) {
this.grid = grid;
}
// , paintComponent 。
public static void draw() {
canvas.repaint();
}
//
public JPanel getCanvas() {
return canvas;
}
//
public void initCanvas() {
canvas = new JPanel() {
//
//paintComponent() ,Swing , , (callback) 。
public void paintComponent(Graphics graphics) {
super.paintComponent(graphics); // container ,
drawGridBackground(graphics);//
drawSnake(graphics, grid.getSnake());//
drawFood(graphics, grid.getFood());//
}
};
}
//
public void drawSnake(Graphics graphics, Snake snake) {
for(Iterator<Node> i = snake.body.iterator();i.hasNext();) {
Node bodyNode = (Node)i.next();
drawSquare(graphics, bodyNode,Color.BLUE);
}
}
//
public void drawFood(Graphics graphics, Node food) {
drawCircle(graphics,food,Color.ORANGE);
}
// , Snake , 10 50 。
public void drawGridBackground(Graphics graphics) {
graphics.setColor(Color.GRAY);
canvas.setBackground(Color.BLACK);
for(int i=0 ; i < 50 ; i++) {
graphics.drawLine(0, i*Settings.DEFAULT_NODE_SIZE, this.grid.getWidth(), i*Settings.DEFAULT_NODE_SIZE);
}
for(int i=0 ; i <50 ; i++) {
graphics.drawLine(i*Settings.DEFAULT_NODE_SIZE, 0, i*Settings.DEFAULT_NODE_SIZE , this.grid.getHeight());
}
graphics.setColor(Color.red);
graphics.fillRect(0, 0, this.grid.width, Settings.DEFAULT_NODE_SIZE);
graphics.fillRect(0, 0, Settings.DEFAULT_NODE_SIZE, this.grid.height);
graphics.fillRect(this.grid.width, 0, Settings.DEFAULT_NODE_SIZE,this.grid.height);
graphics.fillRect(0, this.grid.height, this.grid.width+10,Settings.DEFAULT_NODE_SIZE);
}
/*
* public abstract void drawLine(int x1,int y1,int x2,int y2)
, (x1, y1) (x2, y2) 。
:
x1 - x 。
y1 - y 。
x2 - x 。
y2 - y 。
*/
// 。
public static void showGameOverMessage() {
JOptionPane.showMessageDialog(null," "," ", JOptionPane.INFORMATION_MESSAGE);
}
// :
private void drawSquare(Graphics graphics, Node squareArea, Color color) {
graphics.setColor(color);
int size = Settings.DEFAULT_NODE_SIZE;
graphics.fillRect(squareArea.getX(), squareArea.getY(), size - 1, size - 1);
}
private void drawCircle(Graphics graphics, Node squareArea, Color color) {
graphics.setColor(color);
int size = Settings.DEFAULT_NODE_SIZE;
graphics.fillOval(squareArea.getX(), squareArea.getY(), size, size);
}
}
ControllerGameController
/*
* SnakeApp , Grid, Grid 。
* SnakeApp
*
*/
public class GameController implements KeyListener, Runnable{
private Grid grid;
private boolean running;
public GameController(Grid grid){
this.grid = grid;
this.running = true;
}
@Override
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();
switch(keyCode) {
case KeyEvent.VK_UP:
grid.changeDirection(Direction.UP);
break;
case KeyEvent.VK_DOWN:
grid.changeDirection(Direction.DOWN);
break;
case KeyEvent.VK_LEFT:
grid.changeDirection(Direction.LEFT);
break;
case KeyEvent.VK_RIGHT:
grid.changeDirection(Direction.RIGHT);
break;
}
isOver(grid.nextRound());
GameView.draw();
}
private void isOver(boolean flag) {
if(!flag) {// , ( flag )
this.running = false;
GameView.showGameOverMessage();
System.exit(0);
}
}
@Override
/*run() (Controller) :
(Model): Grid
(View): GameView */
public void run() {
while(running) {
try {
Thread.sleep(Settings.DEFAULT_MOVE_INTERVAL);
isOver(grid.nextRound());
GameView.draw();
} catch (InterruptedException e) {
break;
}
//
// ,
// ,
}
running = false;
}
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyReleased(KeyEvent e) {
}
}
ModelGrid
/*
* , , SnakeApp 。
*/
public class Grid {
private Snake snake;
int width;
int height;
Node food;
private Direction snakeDirection =Direction.LEFT;
public Grid(int length, int high) {
super();
this.width = length;
this.height = high;
initSnake();
food = creatFood();
}
//
private void initSnake() {
snake = new Snake();
int x = width/2;
int y = height/2;
for(int i = 0;i<5;i++) {
snake.addTail(new Node(x, y));
x = x+Settings.DEFAULT_NODE_SIZE;
}
}
// 。
// , 。
private Node creatFood() {
int x,y;
do {
x =(int)(Math.random()*100)+10;
y =(int)(Math.random()*100)+10;
System.out.println(x);
System.out.println(y);
System.out.println(this.width);
System.out.println(this.height);
}while(x>=this.width-10 || y>=this.height-10 || snake.hasNode(new Node(x,y)));
food = new Node(x,y);
return food;
}
// , 。
public boolean nextRound() {
Node trail = snake.move(snakeDirection);
Node snakeHead = snake.getBody().removeFirst();// ,
if(snakeHead.getX()<=width-10 && snakeHead.getX()>=10
&& snakeHead.getY()<=height-10 && snakeHead.getY()>=10
&& !snake.hasNode(snakeHead)) {//
if(snakeHead.equals(food)) {
// , move
snake.addTail(trail);
food = creatFood();
}
snake.getBody().addFirst(snakeHead);
return true;//
}
return false;
}
public Node getFood() {
return food;
}
public Snake getSnake() {
return snake;
}
public int getWidth() {
return width;
}
public int getHeight() {
return height;
}
//
public void changeDirection(Direction newDirection){
snakeDirection = newDirection;
}
}
Snake
/*
* , ,
*/
public class Snake implements Cloneable{
public LinkedList<Node> body = new LinkedList<>();
public Node move(Direction direction) {
// body
// Node( )
Node n;//
switch (direction) {
case UP:
n = new Node(this.getHead().getX(),this.getHead().getY()-Settings.DEFAULT_NODE_SIZE);
break;
case DOWN:
n = new Node(this.getHead().getX(),this.getHead().getY()+Settings.DEFAULT_NODE_SIZE);
break;
case RIGHT:
n = new Node(this.getHead().getX()+Settings.DEFAULT_NODE_SIZE,this.getHead().getY());
break;
default:
n = new Node(this.getHead().getX()-Settings.DEFAULT_NODE_SIZE,this.getHead().getY());
}
Node temp = this.body.getLast();
this.body.addFirst(n);
this.body.removeLast();
return temp;
}
public Node getHead() {
return body.getFirst();
}
public Node getTail() {
return body.getLast();
}
public Node addTail(Node area) {
this.body.addLast(area);
return area;
}
public LinkedList<Node> getBody(){
return body;
}
//
public boolean hasNode(Node node) {
Iterator<Node> it = body.iterator();
Node n = new Node(0,0);
while(it.hasNext()) {
n = it.next();
if(n.getX() == node.getX() && n.getY() == node.getY()) {
return true;
}
}
return false;
}
}
Direction
/*
*
*/
public enum Direction {
UP(0),
DOWN(1),
LEFT(2),
RIGHT(3); //
//
private final int directionCode;
//
public int directionCode() {
return directionCode;
}
Direction(int directionCode){
this.directionCode = directionCode;
}
}
Node
public class Node {
private int x;
private int y;
public Node(int x, int y) {
this.x = ((int)(x/10))*10;
this.y = ((int)(y/10))*10;
}//
public int getX() {
return x;
}
public int getY() {
return y;
}
@Override
// Node
public boolean equals(Object n) {
Node temp;
if(n instanceof Node) {
temp = (Node)n;
if(temp.getX()==this.getX() && temp.getY()==this.getY())
return true;
}
return false;
}
}
Settings
public class Settings {
public static int DEFAULT_NODE_SIZE = 10;//
public static int DEFAULT_MOVE_INTERVAL = 200;//
}
더 많은 재 미 있 는 클래식 게임 을 통 해 주 제 를 실현 하고 여러분 에 게 공유 합 니 다.C++클래식 게임 모음
python 클래식 게임 모음
python 러시아 블록 게임 집합
JavaScript 클래식 게임 을 계속 합 니 다.
javascript 고전 게임 모음
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Is Eclipse IDE dying?In 2014 the Eclipse IDE is the leading development environment for Java with a market share of approximately 65%. but ac...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.