java 简单版贪吃蛇小游戏
程序员文章站
2023-12-23 21:06:27
...
在利用java编程的时候,我们应该用面向对象的编程思想来写。
贪吃蛇游戏中,你应该要知道有几个对象,每个对象中应该有森马方法和属性。
GamePanel类 //显示类
Void display(); //显示
Food类 //食物类
boolean isSnakeEatFood(Snake); //判断蛇是否吃到食物
void drawMe(); //显示食物
Snake类 //蛇
void move(); //移动
void changeDirection(); //改变方向
void eatFood(); //吃食物
boolean isEatBody(); //判断是否吃到自己
void drawMe(); //显示自己
Ground类 //障碍物类
boolean isSnakeEatRock(Snacke); //判断蛇是否吃到石头
void drawMe(); //显示自己
Controller类 //业务逻辑来类
Controller.java
package cn.itcast.snake.controller;
import java.awt.Point;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.Random;
import cn.itcast.snake.entities.Food;
import cn.itcast.snake.entities.Ground;
import cn.itcast.snake.entities.Snake;
import cn.itcast.snake.listener.SnakeListener;
import cn.itcast.snake.util.Global;
import cn.itcast.snake.view.GamePanel;
//控制器
//处理逻辑,处理按钮
public class Controller extends KeyAdapter implements SnakeListener {
private Snake snake;
private Food food;
private Ground ground;
private GamePanel gamePanel;
public Controller(Snake snake, Food food, Ground ground, GamePanel gamePanel) {
this.snake = snake;
this.food = food;
this.ground = ground;
this.gamePanel = gamePanel;
}
//利用键盘来控制蛇的方向
@Override
public void keyPressed(KeyEvent e) {
switch(e.getKeyCode()){
case KeyEvent.VK_UP:
snake.changeDirection(snake.UP);
break;
case KeyEvent.VK_DOWN:
snake.changeDirection(snake.DOWN);
break;
case KeyEvent.VK_LEFT:
snake.changeDirection(snake.LEFT);
break;
case KeyEvent.VK_RIGHT:
snake.changeDirection(snake.RIGHT);
break;
}
}
@Override
public void snakeMoved(Snake snake) {
//判断蛇吃到食物否?
if(food.isSnakeFood(snake)){
snake.eatFood();
food.newFood(ground.getPoint());
}
//吃到石头就结束游戏
if(ground.isSnakeEatRock(snake)){
snake.die();
}
//吃到自己的身体结束游戏
if(snake.isEatBody()){
snake.die();
}
gamePanel.display(snake, food, ground);
}
public void newGame(){
snake.start();
food.newFood(ground.getPoint());
}
}
Food.java
package cn.itcast.snake.entities;
import java.awt.Graphics;
import java.awt.Point;
import cn.itcast.snake.util.Global;;
public class Food extends Point{
//显示新的食物
public void newFood(Point p){
this.setLocation(p);
}
//判断是否迟到食物
public boolean isSnakeFood(Snake snake){
return this.equals(snake.getHead());
}
//显示食物
public void drawMe(Graphics g){
g.fill3DRect(x*Global.CELL_SIZE, y*Global.CELL_SIZE,
Global.CELL_SIZE, Global.CELL_SIZE, true);
}
}
Ground.java
package cn.itcast.snake.entities;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.util.Random;
import javax.xml.bind.annotation.XmlElementDecl.GLOBAL;
import cn.itcast.snake.util.Global;
//石头类
public class Ground {
private int[][] rocks = new int[Global.WIDTH][Global.HEIGHT];
//利用构造函数产生石头
public Ground(){
for(int x = 0; x<Global.HEIGHT; x++){
rocks[x][0] = 1;
rocks[x][Global.WIDTH-1] = 1;
}
}
//判断是否吃到了石头
public boolean isSnakeEatRock(Snake snake){
for(int x = 0; x<Global.WIDTH; x++){
for(int y = 0; y<Global.HEIGHT; y++){
if(rocks[x][y] ==1 &&
(x == snake.getHead().x && y==snake.getHead().y)){
return true;
}
}
}
return false;
}
//随机产生食物的坐标
public Point getPoint(){
int x = 0, y = 0;
Random random = new Random();
do{
x = random.nextInt(Global.WIDTH);
y = random.nextInt(Global.HEIGHT);
}while(rocks[x][y]==1);
return new Point(x,y);
}
//显示石头
public void drawMe(Graphics g){
g.setColor(Color.DARK_GRAY);
for(int x = 0; x<Global.WIDTH; x++){
for(int y = 0; y<Global.HEIGHT; y++){
if(rocks[x][y] == 1){
g.fill3DRect(x*Global.CELL_SIZE, y*Global.CELL_SIZE,
Global.CELL_SIZE,Global.CELL_SIZE, true);
}
}
}
}
}
Snake.java
package cn.itcast.snake.entities;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Set;
import cn.itcast.snake.listener.SnakeListener;
import cn.itcast.snake.util.Global;
public class Snake {
public static final int UP = -1;
public static final int DOWN = 1;
public static final int LEFT = 2;
public static final int RIGHT = -2;
private int oldDirection,newDirection;
private Point oldTall; //最后的尾巴
private boolean life;
private LinkedList<Point> body = new LinkedList<Point>();
private Set<SnakeListener> listeners = new HashSet<SnakeListener>();
public Snake(){
init();
}
public void die(){
life = false;
}
//初始化蛇的长度
public void init(){
life = true;
int x = Global.WIDTH/2;
int y = Global.HEIGHT/2;
for(int i=0; i<3; i++){
body.addLast(new Point(x--,y));
}
oldDirection =newDirection= RIGHT;
}
//移动
public void move(){
//判断老方向和新方向是否是相反的方向
if(!(oldDirection+newDirection == 0)){
oldDirection = newDirection;
}
//1.去尾
oldTall = body.removeLast();
int x = body.getFirst().x;
int y = body.getFirst().y;
switch(oldDirection){
case UP:
y--;
if(y<0){
y = Global.HEIGHT-1;
}
break;
case DOWN:
y++;
if(y>=Global.HEIGHT){
y = 0;
}
break;
case LEFT:
x--;
if(x<0){
x = Global.WIDTH-1;
}
break;
case RIGHT:
x++;
if(x>=Global.WIDTH){
x = 0;
}
break;
}
Point newHead = new Point(x, y);
//2.加头
body.addFirst(newHead);
}
//改变方向
public void changeDirection(int direction){
newDirection = direction;
}
//吃食物
public void eatFood(){
//吃到食物后蛇的的身子变长
body.addLast(oldTall);
}
//判断是否吃到自己
public boolean isEatBody(){
//从第一个元素开始,排除蛇头
for(int i=1; i<body.size(); i++){
if(body.get(i).equals(this.getHead())){
return true;
}
}
return false;
}
//显示蛇
public void drawMe(Graphics g){
g.setColor(Color.blue);
for(Point p : body){
g.fill3DRect(p.x*Global.CELL_SIZE, p.y*Global.CELL_SIZE,
Global.CELL_SIZE,Global.CELL_SIZE, true);
}
}
//获取蛇的头节点
public Point getHead(){
return body.getFirst();
}
//线程来让蛇一直运动
private class SnakeDriver implements Runnable{
@Override
public void run() {
while(life){
move();
for(SnakeListener l : listeners){
l.snakeMoved(Snake.this);
}
try {
Thread.sleep(300);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
public void start(){
new Thread(new SnakeDriver()).start();
}
//添加监听器
public void addSnakeListener(SnakeListener l){
if(l!=null){
this.listeners.add(l);
}
}
}
Game.java
package cn.itcast.snake.game;
import java.awt.BorderLayout;
import javax.swing.JFrame;
import cn.itcast.snake.controller.Controller;
import cn.itcast.snake.entities.Food;
import cn.itcast.snake.entities.Ground;
import cn.itcast.snake.entities.Snake;
import cn.itcast.snake.util.Global;
import cn.itcast.snake.view.GamePanel;
public class Game {
public static void main(String[] args) {
Snake snake = new Snake();
Food food = new Food();
Ground ground = new Ground();
GamePanel gamePanel = new GamePanel();
Controller controller = new Controller(
snake,food,ground,gamePanel);
JFrame frame = new JFrame();
//关闭时退出程序
frame.setTitle("简单版贪吃蛇@清凉");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
gamePanel.setSize(Global.WIDTH*Global.CELL_SIZE, Global.HEIGHT*Global.CELL_SIZE);
frame.setSize(Global.WIDTH*Global.CELL_SIZE+10, Global.HEIGHT*Global.CELL_SIZE+35);
frame.add(gamePanel,BorderLayout.CENTER);
frame.addKeyListener(controller);
gamePanel.addKeyListener(controller);
snake.addSnakeListener(controller);
frame.setVisible(true);
controller.newGame();
}
}
SnakeListener.java
package cn.itcast.snake.listener;
import cn.itcast.snake.entities.Snake;
public interface SnakeListener {
//蛇移动
void snakeMoved(Snake snake);
}
Global.java
package cn.itcast.snake.util;
public class Global {
public static final int CELL_SIZE = 20;
public static final int WIDTH = 15;
public static final int HEIGHT = 15;
}
GamePanel.java
package cn.itcast.snake.view;
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JPanel;
import cn.itcast.snake.entities.Food;
import cn.itcast.snake.entities.Ground;
import cn.itcast.snake.entities.Snake;
import cn.itcast.snake.util.Global;
//画板类
public class GamePanel extends JPanel{
private Snake snake;
private Food food;
private Ground ground;
//显示
public void display(Snake snake, Food food, Ground ground){
this.snake = snake;
this.food = food;
this.ground = ground;
this.repaint();
}
//重绘
@Override
public void paint(Graphics g) {
super.paint(g);
g.setColor(new Color(0xcfcfcf));
//g.setColor(new Color(0xcfcfcf));
g.fillRect(0, 0, Global.WIDTH*Global.CELL_SIZE,
Global.HEIGHT*Global.CELL_SIZE);
this.ground.drawMe(g);
this.snake.drawMe(g);
this.food.drawMe(g);
}
}
运行结果: