package MySnake;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import org.eclipse.jface.text.WhitespaceCharacterPainter;
import javax.swing.JLabel;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.util.Random;
import java.awt.event.ActionEvent;
import java.awt.Color;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class SnakeFrame extends JFrame {
private int xx = 370;//地图宽度
private int yy = 280;//地图长度
int level = 0; //设置游戏难度(改变速度)
JPanel panel;
private File f = new File("data"); //用于存储游戏记录的File对象
private JPanel contentPane; //内容面板
private static Snake snake; //地图里的蛇
private static Body food; //地图里的食物
Thread t1 = null; //蛇行线程
JLabel now_score = new JLabel(""); //当前长度
JLabel best_score = new JLabel(""); //历史记录
public static void main(String[] args) {
new SnakeFrame().setVisible(true);
}
public SnakeFrame() {
super("我的小小贪吃蛇"); //显示窗口标题
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(250, 100, 620, 390); //设置窗口位置及大小
contentPane = new JPanel(); //JFrame的内容面板
setContentPane(contentPane);
contentPane.setLayout(null);
JLabel label = new JLabel("小小贪吃蛇"); //显示标题
label.setBounds(152, 10, 123, 29);
label.setFont(new Font("宋体", Font.BOLD, 20)); //宋体粗体
contentPane.add(label);
//重开按钮
JButton jb1 = new JButton("新游戏");
jb1.setBounds(426, 44, 109, 48);
jb1.setFont(new Font("宋体", Font.BOLD, 16));
jb1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
writeHis(); //写入历史记录
Initial(); //重新初始化
}
});
contentPane.add(jb1);
jb1.addKeyListener(new KeyAdapter() {//KeyAdapter实现了接口KeyListener,用来接收处理键盘事件
public void keyPressed(KeyEvent e) {
changeDirection(e);
}
});
//暂停按钮
JButton jb2 = new JButton("暂停");
jb2.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
changeDirection(e);
}
});
jb2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if(t1!=null) {
if(jb2.getText().equals("暂停")) {
t1.suspend(); //使得线程进入阻塞状态,并且不会自动恢复
jb2.setText("继续");
}
else if(jb2.getText().equals("继续")) {
t1.resume(); //使线程重新进入可执行状态
jb2.setText("暂停");
}
}
}
});
jb2.setBounds(426, 95, 109, 48); //设置“暂停”、“继续”按钮位置及大小
jb2.setFont(new Font("宋体", Font.BOLD, 16)); //宋体加粗
contentPane.add(jb2);
//增加难度
JButton jb3 = new JButton("增加难度");
jb3.setBounds(426, 148, 109, 48); //设置“增加难度”按钮位置及大小
jb3.setFont(new Font("宋体", Font.BOLD, 16)); //宋体加粗
jb3.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
writeHis(); //写入历史记录
level = level + 20 ; //提高速度
Initial(); //重新初始化
}
});
contentPane.add(jb3);
jb3.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
changeDirection(e);
}
});
panel = new JPanel() {
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2 = (Graphics2D) g; //利用Graphics2D类
g2.setColor(new Color(50, 50,50));
//画网格线
for(int i=0;i<=xx;i+=10) {
g2.drawLine(i, 0, i, yy+10);
}//画纵向的线
for(int i=0;i<=yy+10;i+=10) {
g2.drawLine(0, i, xx+10, i);
}//画横线的线
for(int i=0;i<snake.list.size();i++) {
Body body = snake.list.get(i);
if(i==0)
g2.setColor(Color.yellow);//设置蛇头颜色为绿色
else
g2.setColor(Color.green);//设置身体颜色为绿色
g.fillOval(body.x, body.y, 10, 10);
}
g.fillOval(food.x, food.y, 10, 10);//将食物绘制到地图上
}
};
Initial();//初始化函数
panel.setBackground(Color.DARK_GRAY);
panel.setBounds(24, 44, xx, yy); //背景位置大小
panel.setFocusable(true);
panel.requestFocus();
panel.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
changeDirection(e);
}
});
contentPane.add(panel);
//显示当前长度
JLabel label_1 = new JLabel("当前长度");
label_1.setFont(new Font("宋体", Font.PLAIN, 17));
label_1.setBounds(446, 210, 68, 36);
contentPane.add(label_1);
//显示当前长度数值
now_score.setForeground(Color.BLACK);
now_score.setFont(new Font("宋体", Font.PLAIN, 14));
now_score.setBounds(476, 240, 54, 29);
contentPane.add(now_score);
//显示最高长度
JLabel best_scoresd = new JLabel("最高长度");
best_scoresd.setFont(new Font("宋体", Font.PLAIN, 17));
best_scoresd.setBounds(446, 260, 68, 36);
contentPane.add(best_scoresd);
//显示最高长度数值
best_score.setForeground(Color.RED);
best_score.setFont(new Font("宋体", Font.PLAIN, 14));
best_score.setBounds(476, 290, 54, 29);
contentPane.add(best_score);
t1 = new Thread(()->{ //按钮对象注册动作事件侦听者
while(true) {
snake.adjustSnakeDirection(); //蛇调整身体方向
snake.move();
if(isTouch()==true) {
new MyDialog(SnakeFrame.this,"游戏失败!你撞到墙啦!").setVisible(true);
new MyDialog(SnakeFrame.this,"难度为"+ level/20 + "级 " + "最终长度为:" + now_score.getText()).setVisible(true);
writeHis();//写入历史记录
Initial();
}
else if (isBitten()==true) {
new MyDialog(SnakeFrame.this,"游戏失败!你咬到自己啦!").setVisible(true);
new MyDialog(SnakeFrame.this,"难度为" + level/20 + "级 " + "最终长度为:" + now_score.getText()).setVisible(true);
writeHis();//写入历史记录
Initial();
}
else if(isFeeding()==true) {//若蛇头碰到食物
snake.eat(); //吃掉食物
newFood(); //重新生成食物
panel.repaint(); //绘制出食物
now_score.setText(snake.length+"");
if(Integer.valueOf(now_score.getText())>Integer.valueOf(best_score.getText()))//判断是否需要记录为最高值
best_score.setText(now_score.getText());
}
panel.repaint();
try {
Thread.sleep(Snake.timer - level);//每timer毫秒蛇移动一次 同时通过-level来改变难度
} catch (InterruptedException e1) {
e1.printStackTrace();
}
}
});
t1.start();
}
public void Initial() {//生成蛇和食物
snake = new Snake();
newFood();
readHis(); //读取记录
now_score.setText(snake.length+"");
if(best_score.getText()==null)
best_score.setText(now_score.getText());
setResizable(false);
}
public boolean isTouch() { //判断蛇是否撞墙
Body head = snake.list.get(0); //获取蛇头对象
if(head.x<0||head.x>xx-10)
return true;
else if(head.y<0||head.y>yy-10)
return true;
else
return false;
}
public boolean isBitten() { //判断蛇是否咬到自己
Body head = snake.list.get(0); //获取蛇头对象
for(int i=1;i<snake.list.size();i++) {
if(head.x==snake.list.get(i).x&&head.y==snake.list.get(i).y){
return true;
}
}
return false;
}
//随机生成一块新食物
public void newFood() {
while(true) {
Random r1 = new Random();
Random r2 = new Random();
int x = 10*r1.nextInt(( xx + 1)/10); //随机生成食物的坐标
int y = 10*r2.nextInt(( yy + 1)/10);
for(Body body:snake.list) {
if(body.x==x && body.y==y)
continue;
}
food = new Body(x, y); //生成新食物
return;
}
}
//判断蛇是否吃到食物
public boolean isFeeding() {
Body head = snake.list.get(0); //获取蛇头对象
if(head.x==foo
评论1