贪吃蛇⼩游戏java项⽬_Java实现贪吃蛇⼩游戏(附完整源
码)
今天我就从零开始来完成这个⼩游戏,完成的⽅式也是⼀步⼀步的添加功能这样的⽅式来实现。
第⼀步完成的功能:写⼀个界⾯
⼤家见到的贪吃蛇⼩游戏,界⾯肯定是少不了的。因此,第⼀步就是写⼀个⼩界⾯。
实现代码如下:
public class SnakeFrame extends Frame{
//⽅格的宽度和长度
public static final int BLOCK_WIDTH = 15 ;
public static final int BLOCK_HEIGHT = 15 ;
//界⾯的⽅格的⾏数和列数
public static final int ROW = 40;
public static final int COL = 40;
public static void main(String[] args) {
new SnakeFrame().launch();
}
public void launch(){
this.setTitle("Snake");
this.setSize(ROW*BLOCK_HEIGHT, COL*BLOCK_WIDTH);
this.setLocation(300, 400);
this.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
}
});
this.setResizable(false);
this.setVisible(true);
}
}
第⼆步完成的功能:在界⾯上画成⼀格⼀格的
我们见过的贪吃蛇游戏,是有⼀个格⼦⼀个格⼦构成,然后蛇在这个⾥⾯运动。
重写paint⽅法,单元格就是横着画⼏条线竖着画⼏条线即可。
代码如下:
@Override
public void paint(Graphics g) {
Color c = g.getColor();
g.setColor(Color.GRAY);
/*
* 将界⾯画成由ROW*COL的⽅格构成,两个for循环即可解决
* */
for(int i = 0;i
g.drawLine(0, i*BLOCK_HEIGHT, COL*BLOCK_WIDTH,i*BLOCK_HEIGHT );
}
for(int i=0;i
g.drawLine(i*BLOCK_WIDTH, 0 , i*BLOCK_WIDTH ,ROW*BLOCK_HEIGHT);
}
g.setColor(c);
}
效果如下:
第三步完成的功能:建⽴另外的线程来控制重画
由于,蛇的运动就是改变蛇所在的位置,然后进⾏重画,就是我们所看到的运动。因此,在这⾥,我们单独⽤⼀个线程来控制重画。
1、新建⼀个MyPaintThread类,实现了Runnable接⼝
private class MyPaintThread implements Runnable{
@Override
public void run() {
//每隔50ms重画⼀次
while(true){
repaint();//会⾃动调⽤paint⽅法
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
2、在SnakeFrame的launchFrame⽅法中添加代码:new Thread(new MyPaintThread()).start();即可。
完成功能:利⽤双缓冲来解决闪烁的问题
private Image offScreenImage = null;
/*
* 重写update⽅法
* */
@Override
public void update(Graphics g) {
if(offScreenImage==null){
offScreenImage = ateImage(ROW*BLOCK_HEIGHT, COL*BLOCK_WIDTH);
}
Graphics offg = Graphics();
//先将内容画在虚拟画布上
paint(offg);
//然后将虚拟画布上的内容⼀起画在画布上
g.drawImage(offScreenImage, 0, 0, null);
}
贪吃蛇的编程代码第四步完成的功能:在界⾯上画⼀个蛇出来
贪吃蛇游戏中的蛇就是⽤⼀系列的点来表⽰,这⾥我们来模拟⼀个链表。链表上的每个元素代表⼀个节点。
⾸先,我们先新建⼀个Node类来表⽰构成蛇的节点,⽤⾯向对象的思想,发现,这个类应该有如下的属性和⽅法:
1、位置
2、⼤⼩,即长度、宽度
3、⽅向
4、构造⽅法
5、draw⽅法
Node类的代码如下:
public class Node {
private static final int BLOCK_WIDTH = SnakeFrame.BLOCK_WIDTH;
private static final int BLOCK_HEIGHT = SnakeFrame.BLOCK_HEIGHT;
/*
* 每个节点的位置
* */
private int row;
private int col;
//⽅向
private Direction dir ;
private Node pre;
private Node next;
public Node(int row, int col, Direction dir) {
this.dir = dir;
}
public void draw(Graphics g){
Color c = g.getColor();
g.setColor(Color.BLACK);
g.fillRect(col*BLOCK_WIDTH, row*BLOCK_HEIGHT, BLOCK_WIDTH, BLOCK_HEIGHT);
g.setColor(c);
}
}
Direction是⼀个enum,具体如下:
public enum Direction {
L,U,R,D
}
⽽在Snake类中,⽤⾯向对象的思维,可以发现,Snake类中应该有如下的属性和⽅法
1、头结点
2、尾结点
3、构造函数
3、draw⽅法
具体代码如下:
public class Snake {
private Node head = null;
private Node tail = null;
private SnakeFrame sf;
//初始化是蛇的位置
private Node node = new Node(3,4,Direction.D);
private int size = 0;
public Snake(SnakeFrame sf) {
head = node;
tail = node;
size ++;
this.sf = sf ;
}
public void draw(Graphics g){
if(head==null){
return ;
}
for(Node node = head;node!=null;node = ){
node.draw(g);
}
}
}
在SnakeFrame类中new⼀个Snake对象,然后调⽤Snake对象的draw⽅法即可。
效果如下:
第五步完成的功能:通过键盘控制蛇的上下左右移动
⾸先想到的是这样:在Snake类中添加⼀个keyPressed⽅法,然后在SnakeFrame的键盘事件中调⽤Snake对象的keyPressed⽅法。
注意:蛇的移动是通过在头部添加⼀个单元格,在尾部删除⼀个单元格这样的思想来实现。
具体如下:
Snake类中添加⼀个keyPressed⽅法,主要是根据键盘的上下左右键来确定蛇的头结点的⽅向,然后move⽅法再根据头结点的⽅向来在头部添加⼀个单元格。
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
switch(key){
case KeyEvent.VK_LEFT :
if(head.dir!=Direction.R){
head.dir = Direction.L;
}
break;
case KeyEvent.VK_UP :
if(head.dir!=Direction.D){
head.dir = Direction.U;
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论