package snack;
import javax.swing.*;
import javax.swing.event.MenuEvent;
import javax.swing.event.MenuListener;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.LinkedList;
import java.util.Timer;
import java.util.TimerTask;
public class MainJFram extends JFrame {
public static Font font1=new Font("宋体",Font.BOLD,20);
private Snake snake;//蛇
private JPanel jPanel,jPanel1;//游戏棋盘
private Timer tiner;//定时器,在规定的时间内调用蛇移动的方法
private Node food;
private MainJFram(){
//初始化窗体参数
inFrame();
//初始化游戏棋盘
GamePanel();
//初始化蛇
initSnake();
//初始化食物
initFood();
//添加菜单栏
MEnu();
// initTimer();
//设置一个键盘监听,让蛇随着上下左右方向移动
setKeyListener();
}
private void initFood() {
food=new Node();
food.random();
}
private void setKeyListener() {
addKeyListener(new KeyAdapter() {
//当键盘按下时,会自动调用此方法
@Override
public void keyPressed(KeyEvent e) {
//键盘中的每一个键都有一个编号
switch(e.getKeyCode()){
case KeyEvent.VK_UP://上键
if (snake.getDirection()!=Direction.DOWN){
//修改蛇的运动方向
snake.setDirection(Direction.UP);
}
break;
case KeyEvent.VK_DOWN://下键
if (snake.getDirection()!=Direction.UP) {
snake.setDirection(Direction.DOWN);
}
break;
case KeyEvent.VK_LEFT://左键
if (snake.getDirection()!=Direction.RIGHT) {
snake.setDirection(Direction.LEFT);
}
break;
case KeyEvent.VK_RIGHT://右键
if (snake.getDirection()!=Direction.LEFT) {
snake.setDirection(Direction.RIGHT);
}
break;
}
}
});
}
private void MEnu(){
JMenuBar menBar=new JMenuBar();
JMenu buton=new JMenu("开始游戏");
// JMenu buton1=new JMenu("暂停");
// Menu buton2=new JMenu("继续游戏");
JMenu buton3=new JMenu("退出游戏");
buton.addMenuListener(new MenuListener() {
@Override
public void menuSelected(MenuEvent e) {
//初始化定时器开始运行
initTimer();
}
@Override
public void menuDeselected(MenuEvent e) {
}
@Override
public void menuCanceled(MenuEvent e) {
}
});
buton3.addMenuListener(new MenuListener() {
@Override
public void menuSelected(MenuEvent e) {
//初始化定时器开始运行
System.exit(0);
}
@Override
public void menuDeselected(MenuEvent e) {
}
@Override
public void menuCanceled(MenuEvent e) {
}
});
menBar.add(buton);
menBar.add(buton3);
setJMenuBar(menBar);
}
//初始化定时器
private void initTimer() {
//创建定时器对象
tiner=new Timer();
//初始化,定时任务
TimerTask tinerTask=new TimerTask() {
@Override
public void run() {
snake.move();
//判断蛇头和食物是否重合
Node head=snake.getBody().getFirst();
if(head.getX()==food.getX()&&head.getY()==food.getY()) {
snake.eat(food);
food.random();
}
//重绘游戏棋盘
jPanel.repaint();
}
};
//每100毫秒执行一次
tiner.scheduleAtFixedRate(tinerTask,0,200);//(定时任务,延迟时间)
}
private void initSnake() {
snake=new Snake();
}
//初始化游戏棋盘
private void GamePanel() {
jPanel=new JPanel(){ //JPanel(){pa}
// 绘制游戏棋盘中的内容
@Override
public void paint(Graphics g) {
//清空棋盘
g.clearRect(0,0,600,600);
//Graphics g可以看作是一个画笔,提供了很多方法,可以绘制很多的图形
//绘制40条横线
for (int i = 0; i <= 40; i++) {
g.drawLine(0,i*15,600,i*15);//设置x坐标的起始坐标和结束坐标
}
// 绘制40条横线
for (int i = 0; i <= 40; i++) {
g.drawLine(i*15,0,i*15,600);//设置y坐标的起始坐标,和结束坐标
}
//绘制蛇
LinkedList<Node> body=snake.getBody();//通过这个集合获得蛇的身体
for(Node node:body){
g.setColor(Color.green);
g.fillRect(node.getX()*15,node.getY()*15,15,15);//填充颜色
}
//绘制食物
g.fillRect(food.getX()*15,food.getY()*15,15,15);
//g.setColor(Color.green);
}
};
//把棋盘添加到窗体
add(jPanel);
}
//初始化窗体参数
private void inFrame() {
Toolkit tk = Toolkit.getDefaultToolkit();
java.awt.Image img = tk.getImage ("src/img.png");
setIconImage(img);
// 给窗体设置图标方法
setTitle("贪吃蛇");
//设置窗体的大小
setSize(610,640);
//设置窗体的位置
setLocation(400,200);
//关闭窗口
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//设置窗体大小不可变
setResizable(false);
}
public static void main(String[] args) {
//创建窗体对象,并显示
new MainJFram().setVisible(true);
}
}
package snack;
//enum 枚举:枚举就是几个固定的常量
public enum Direction {
UP,DOWN,LEFT,RIGHT;
}
package snack;
import java.util.Random;
//节点类:每一条蛇是由若干节点组成,每一个节点由横纵坐标来确定位置
public class Node {
private int x;
private int y;
//空参构造,有参与构造,和get set方法
public Node(){
}
public Node(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
//随机生成位置的方法
public void random(){
//创建random对象
Random r=new Random();
//随机x,y生成坐标
this.x=r.nextInt(40);
this.y=r.nextInt(40);
}
}
package snack;
import javax.swing.*;
import java.util.LinkedList;
//一条蛇由多个节点使用LinkedLIstanbul集合存储N哦的节点,蛇出生的时候有3给节点
public class Snake {
//蛇的身体
private LinkedList<Node> body;
//定义一个蛇的运动方向,默认左移
private Direction direction=Direction.LEFT;
//蛇是否活着
public boolean isLiving=true;
public Snake(){
//初始化蛇身体
initSnake();
}
//初始化身体
private void initSnake() {
//创建集合
body=new LinkedList<>();
//创建6个节点,添加的集合中
body.add(new Node(16,20));
body.add(new Node(17,20));
body.add(new Node(18,20));
body.add(new Node(19,20));
body.add(new Node(20,20));
body.add(new Node(21,20));
body.add(new Node(22,20));
body.add(new Node(23,20));
}
//绘制沿着蛇头的方向移动
//控制蛇移动,在蛇头的运动方向添加一个节点,然后把蛇尾的节点删除
public void move(){
if(isLiving){
//获取蛇头
Node head=body.getFirst();
switch (direction){
case UP:
//在蛇头的上边添加一个节点
body.addFirst(new Node(head.getX(), head.getY()-1));
break;
case DOWN:
body.addFirst(new Node(head.getX(), head.getY()+1));
break;
case LEFT:
body.addFirst(new Node(head.getX()-1, head.getY()));
break;
case RIGHT:
body.addFirst(new Node(head.getX()+1, head.getY()));
break;
}
//删除最后一个节点
body.removeLast();
//判断这个蛇是否撞墙
head=body.getFirst();
if(head.getX()<0||head.getY()<0||head.getX()>=40||head.getY()>=40){
isLiving=false;
JOptionPane.showMessageDialog(null, "游戏结束!");
}
//判断蛇是否碰到自己身体
for (int i = 0; i < body.size(); i++) {
Node node=body.get(i);
if((head.getX()==node.getX())&&(head.getY()== node.getY())){
// isLiving=false;
}
}
}
}
public LinkedList<Node> getBody() {
return body;
}
public void setBody(LinkedList<Node> body) {
this.body = body;
}
public Direction getDirection() {
return direction;
}
public void setDirection(Direction direction) {
this.direction = direction;
}
//沿着蛇头的移动方向添加一个节点
public void eat(Node food) {
Node head=body.getFirst();
switch (direction){
case UP:
//在蛇头的上边添加一个节点
body.addFirst(new Node(head.getX(), head.getY()-1));
break;
case DOWN:
body.addFirst(new Node(head.getX(), head.getY()+1));
break;
case LEFT:
body.addFirst(new Node(head.getX()-1, head.getY()));
break;
case RIGHT:
body.addFirst(new Node(head.getX()+1, head.getY()));
break;
}
}
}
总的代码量并不算多,创建四个类
MainJFram类:主要用于创建一些能够调用的方法
Direction类:使用键盘来控制蛇的移动(枚举)
Node类:节点类:每一条蛇是由若干节点组成,每一个节点由横纵坐标来确定位置
Snake类:一条蛇由多个节点使用LinkedLIstanbul集合存储N哦的节点,蛇出生的时候有3给节点