java 小游戏-贪吃蛇-精简算法-离奇思路
面向对象:
首先确定建立几个类
明确每个类的功能和属性
Food:
import java.util.List;
public class Food {
private Point point;
public Food() {
point = new Point();
}
public void reset(List<Point> points){
//在网格内、随机、不能在蛇身
while (true){
point.row = (int) (Math.random()* Grid.rows);//扩大随机数的产生范围
point.col = (int) (Math.random()* Grid.cols);
if (!points.contains(point)){
break;
}
}
}
public Point getPoint() {
return point;
}
}
Game:
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.LinkedList;
public class Game extends Frame {
public static void main(String[]args){
Game game = new Game();
}
private Snake snake;
private Food food;
private static Canvas canvas;//画布
private static Graphics pen;//画笔
public Game() {
snake = new Snake();
food = new Food();
food.reset(snake.getBody());//获取蛇身
setSize(Grid.getWidth(),Grid.getHeight()+80);//初始化窗口大小
setTitle("玩命贪吃蛇");//设置标题
setVisible(true);//显示界面
setLayout(new FlowLayout());//设置流式布局
//创建一个和棋盘大小一致的画布并添加到界面中
canvas = new Canvas();
canvas.setSize(Grid.getWidth(),Grid.getHeight());
add(canvas);
canvas.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
handleKeyPress(e.getKeyCode());
}
});
//创建一个“开始”按钮并添加到界面中
Button button = new Button("Start");
button.setSize(100,40);
add(button);
button.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent mouseEvent) {
pen = canvas.getGraphics();//获得画笔
start();
super.mouseClicked(mouseEvent);
}
});
}
public void start(){
new Thread(){
@Override
public void run() {
while (true) {
drawGrid();
drawFood();
drawSnake();
snake.move();
if (snake.isEatFood(food.getPoint())){
snake.grow();
food.reset(snake.getBody());
}else{
if (snake.isEatSelf() || snake.isMeetGird()){
System.out.println("游戏结束!!");
System.exit(0);
}
}
try {
sleep(190);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}
private void handleKeyPress(int keyCode) {
switch (keyCode){
case KeyEvent.VK_UP:
snake.turn(Snake.UP);
break;
case KeyEvent.VK_DOWN:
snake.turn(Snake.DOWN);
break;
case KeyEvent.VK_LEFT:
snake.turn(Snake.LEFT);
break;
case KeyEvent.VK_RIGHT:
snake.turn(Snake.RIGHT);
break;
}
}
public void drawGrid(){
pen.setColor(Color.black);
pen.fillRect(0,0,Grid.getWidth(),Grid.getHeight());
pen.setColor(Color.gray);
pen.fillRect(Grid.margin,Grid.margin,Grid.getWidth()-Grid.margin*2,Grid.getHeight()-Grid.margin*2);
}
public void drawFood(){
drawBlock(food.getPoint(),Color.yellow);
}
public void drawSnake(){
LinkedList<Point> points = snake.getBody();
for (Point p:points){
Color c = p.equals(points.getFirst())?Color.red:Color.white;
drawBlock(p,c);
}
}
private void drawBlock(Point p,Color color){
pen.setColor(color);
int x = Grid.margin + p.col*Grid.size;
int y = Grid.margin + p.row*Grid.size;
pen.fillRect(x,y,Grid.size,Grid.size);
}
}
Grid:
public class Grid {
public static int rows = 20;//行数
public static int cols = 20;//列数
public static int size = 30;//格子大小
public static int margin = 40;//边距
public static boolean outOfBound(Point point) {
if (point.row < 0 || point.row >= rows){
return true;
}
if (point.col<0 ||point.col>=cols){
return true;
}
return false;
}
public static int getWidth() {
return size * cols + margin *2;
}
public static int getHeight() {
return size * rows + margin *2;
}
}
Point:
public class Point {
public int row;
public int col;
public Point(int row, int col) {
this.row = row;
this.col = col;
}
public Point() {
this.row = 0;
this.col = 0;
}
public Point(Point p) {
//拷贝构造函数
this.row = p.row;
this.col = p.col;
}
public boolean equals(Object o){
Point p = (Point)o;
return this.row == p.row && this.col == p.col;
}
}
Snake:
import java.util.Iterator;
import java.util.LinkedList;
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 LinkedList<Point> body;
private int direction;
private boolean growing = false;//生长标记
public Snake() {
body = new LinkedList<>();
body.add(new Point(0,3));
body.add(new Point(0,2));
body.add(new Point(0,1));
body.add(new Point(0,0));//这是头
direction = RIGHT;//初始化向右
}
public void move() {
//加头 去尾 中间其实没变
Point oldHead = body.getFirst();
Point newHead = new Point(oldHead);//复制一个新的头
switch (direction) {
case UP:
newHead.row--;
break;
case DOWN:
newHead.row++;
break;
case LEFT:
newHead.col--;
break;
case RIGHT:
newHead.col++;
break;
}
body.addFirst(newHead);
if (!growing) {
body.removeLast();
//growing = false;
}else {
growing = false;
}
}
public void turn(int direction){
if (this.direction + direction == 0 ) {
}else {
this.direction = direction;
}
}
public boolean isEatFood(Point p){
return body.getFirst().equals(p);
}
public boolean isEatSelf(){
Point head = body.getFirst();
Iterator iterator = body.iterator();
iterator.next();
while (iterator.hasNext()){
Point p = (Point)iterator.next();
if (head.equals(p)){
return true;
}
}
return false;
}
public boolean isMeetGird(){
Point head = body.getFirst();
return Grid.outOfBound(head);
}
public void grow(){
//补长 增加一个标记
growing = true;
}
public LinkedList<Point> getBody() {
return body;
}
}
注意:开始游戏前要鼠标点击屏幕框 选中 方向键才有用!
死亡:吃自己 撞墙