贪吃蛇java源代码
2016-04-20 21:03
399 查看
这个贪吃蛇是我学完Java之后的课程设计作业,做了有挺久的,做完这个小游戏,自己对Java的一些知识也更了解了些。其中包括按完按钮后焦点的处理啊,还有就是图形的闪烁问题。我当时做的时候基本是在自己电脑上完成的,后来才放到学校机房测试的。说来也奇怪,这个代码开始在我自己电脑上运行的时候并没有闪烁,所以我也就没想过要处理闪烁的问题,可是后来在学校机房闪烁的十分严重,所以才又用双缓冲来处理闪烁。
双缓冲解决图形闪烁源代码:
运行效果:
下面是贪吃蛇完整源代码:
SnakeBody.java
GameUi.java
Test.java
双缓冲解决图形闪烁源代码:
@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); // 将图形缓冲区绘制到屏幕上 }
运行效果:
下面是贪吃蛇完整源代码:
SnakeBody.java
package com.java.snake; 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; } }
GameUi.java
package com.java.snake;
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 += 10;
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("我的贪吃蛇");
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:
b88e
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;
}
}
});
}
}
Test.java
package com.java.snake; public class Test { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub new GameUi(); } }
相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- Android IPC进程间通讯机制
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- 介绍一款信息管理系统的开源框架---jeecg
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- PropertyChangeListener简单理解
- c++11 + SDL2 + ffmpeg +OpenAL + java = Android播放器
- 插入排序
- 冒泡排序
- 堆排序
- 快速排序
- 二叉查找树