贪吃蛇游戏(Java)
程序员文章站
2023-12-23 19:43:03
...
第一步
package TanCiShe_01;
import java.awt.Color;
public class SnakeBody {
private int x;
private int y;
private Color color;
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 Color getColor() {
return color;
}
public void setColor(Color color) {
this.color = color;
}
}
第二步
package TanCiShe_01;
import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Image;
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.Random;
import javax.swing.*;
public class GameUi extends JFrame{
int flag = 1;
JLabel jl = new JLabel();
JLabel fs = new JLabel();
JButton start = new JButton("开始");
JButton stop = new JButton("暂停");
JButton restart = new JButton("重玩");
JButton exit = new JButton("退出");
boolean p = true;
JPanel pan = new JPanel();
GridLayout grid = new GridLayout(1, 5);
Random r1 = new Random();
Random r2 = new Random();
int a = (r1.nextInt(53) + 1) * 10 - 4;
int b = (r2.nextInt(35) + 6) * 10 - 1;
int score = 0;
int foodNumber = 0;
final int HW = 9;
int x = (r1.nextInt(35) + 10) * 10 - 4;
int y = (r2.nextInt(35) + 6) * 10 - 1;
LinkedList<SnakeBody> snake = new LinkedList<SnakeBody>();
int direction = 1;
SnakeBody tail;
SnakeBody head;
class Mytask implements Runnable{
@Override
public void run() {
// TODO Auto-generated method stub
ALL: while (true) {
head = snake.getFirst();
/*
* 判断蛇是否吃到食物,如果吃到食物则产生一个随机数,若产生的随机数在蛇的身体上则重新再产生一个随机数
*/
if (head.getX() == a && head.getY() == b) {
SnakeBody c = new SnakeBody();
snake.add(c);
++foodNumber;
score += 1;
fs.setText("分数:" + score);
/* 判断生成的食物是不是在蛇的身体里 */
for (int i = 0; i < snake.size(); i++) {
SnakeBody d = snake.get(i);
if (d.getX() == a && d.getY() == b) {
a = (r1.nextInt(53) + 1) * 10 - 4;
b = (r2.nextInt(35) + 6) * 10 - 1;
}
}
}
int x1 = head.getX();
int y1 = head.getY();
/* 判断是否触到边缘 */
if (x1 < 6 || x1 > 536 || y1 < 59 || y1 > 419) {
Gameover();
break ALL;
}
/* 判断是否吃到自己的身体 */
else {
for (int i = 3; i < snake.size(); i++) {
SnakeBody d = snake.get(i);
if (d.getX() == x1 && d.getY() == y1) {
Gameover();
break ALL;
}
}
}
if (p != false) {
moving(direction);
update(getGraphics());
}
try {
//Thread.sleep(500 - foodNumber / 2 * 100);
//可设置等级,等级不同可以有不同的速度
Thread.sleep(100);
} catch (Exception e) {
}
}
}
private void Gameover() {
// TODO Auto-generated method stub
jl.setText("GAME OVER");
jl.setBounds(150, 150, 400, 100);
jl.setForeground(Color.red);
jl.setFont(new Font("宋体", Font.BOLD, 55));
add(jl);
update(getGraphics());
}
}
Thread timer = new Thread(new Mytask());
public GameUi() {
// TODO Auto-generated constructor stub
this.setTitle("我的贪吃蛇666");
this.setSize(552, 435);
this.setResizable(false);
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
initSnakeBody();
initEvent();
fs.setText("分数:" + score);
add(pan, BorderLayout.NORTH);
pan.setLayout(grid);
pan.add(start);
pan.add(stop);
pan.add(restart);
pan.add(exit);
pan.add(fs);
this.requestFocus();
start.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
if (e.getSource() == start) {
p = true;
}
GameUi g = getUi();
g.requestFocus();
}
});
stop.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
if (e.getSource() == stop)
p = false;
}
});
restart.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
if (e.getSource() == restart) {
new GameUi();
dispose();
}
}
});
exit.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
if (e.getSource() == exit)
System.exit(EXIT_ON_CLOSE);
}
});
timer.start();
}
protected GameUi getUi() {
return this;
}
@Override
/* 画边缘,蛇身,食物 */
public void paint(Graphics g) {
// TODO Auto-generated method stub
super.paint(g);
Graphics2D g_2d = (Graphics2D) g;
g_2d.setColor(Color.BLACK);
g_2d.setStroke(new BasicStroke(2f));
g_2d.drawLine(5, 58, 547, 58);// 上面的那根线
g_2d.drawLine(5, 58, 5, 430);// 左边的那根线
g_2d.drawLine(5, 430, 547, 430);// 下面的那根线
g_2d.drawLine(547, 58, 547, 430);// 右边的那根线
g_2d.setColor(Color.black);
for (int i = 0; i < snake.size(); i++) {
SnakeBody b = snake.get(i);
g.fillRect(b.getX(), b.getY(), HW, HW);
}
g.setColor(Color.red);
g.fillRect(a, b, HW, HW);
}
Image ImageBuffer = null;
Graphics GraImage = null;
@Override
public void update(Graphics g) {
// TODO Auto-generated method stub
ImageBuffer = createImage(this.getWidth(), this.getHeight());
GraImage = ImageBuffer.getGraphics(); // 获取图形缓冲区的图形上下文
paint(GraImage); // 用paint方法中编写的绘图过程对图形缓冲区绘图
GraImage.dispose(); // 释放图形上下文资源
g.drawImage(ImageBuffer, 0, 0, this); // 将图形缓冲区绘制到屏幕上
}
/* 初始化蛇身 */
public void initSnakeBody() {
// TODO Auto-generated method stub
for (int i = 0; i < 5; i++) {
SnakeBody b = new SnakeBody();
b.setX(x + i * HW + i);
b.setY(y);
snake.add(b);
}
tail = snake.getLast();
head = snake.getFirst();
}
/* 蛇移动的时候身体的变化 */
public void moving(int direction) {
tail = snake.removeLast();
head = snake.getFirst();
switch (direction) {
// 1:左;2:上;3:右;4:下
case 1:
tail.setX(head.getX() - HW - 1);
tail.setY(head.getY());
break;
case 2:
tail.setX(head.getX());
tail.setY(head.getY() - HW - 1);
break;
case 3:
tail.setX(head.getX() + HW + 1);
tail.setY(head.getY());
break;
case 4:
tail.setX(head.getX());
tail.setY(head.getY() + HW + 1);
break;
}
snake.addFirst(tail);
}
/* 方向控制 */
public void initEvent() {
this.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent event) {
// TODO Auto-generated method stub
switch (event.getKeyCode()) {
case KeyEvent.VK_UP:
if (direction == 2 || direction == 4) {
break;
}
direction = 2;
break;
case KeyEvent.VK_DOWN:
if (direction == 2 || direction == 4) {
break;
}
direction = 4;
break;
case KeyEvent.VK_LEFT:
if (direction == 1 || direction == 3) {
break;
}
direction = 1;
break;
case KeyEvent.VK_RIGHT:
if (direction == 1 || direction == 3) {
break;
}
direction = 3;
break;
}
}
});
}
}
第三步
package TanCiShe_01;
public class Test {
public static void main(String[] args) {
new GameUi();
}
}