java做贪吃蛇小游戏_《Java小游戏实现》:贪吃蛇

《Java小游戏实现》:贪吃蛇

在完成坦克大战之后,就想到了贪吃蛇这个小游戏,因为这两个游戏太像了,因此,就决定把这个游戏来尝试的写下。接下来的几篇博文就是来记录这个小游戏实现的全过程。

突然,想起,一年前(时间是2015年7月3日),我刚学习Java的时候看过别人写的这个游戏源代码,还专门写了篇博文,连接如下:http://www.voidcn.com/article/p-mfgogccw-zu.html

确实好巧,今天我自己就从零开始来完成这个小游戏,完成的方式也是一步一步的添加功能这样的方式来实现。

第一步完成的功能:写一个界面

大家见到的贪吃蛇小游戏,界面肯定是少不了的。因此,第一步就是写一个小界面。

实现代码如下:

public class SnakeFrame extends Frame{

public static void main(String[] args) {

SnakeFrame s = new SnakeFrame();

s.launchFrame();

}

private void launchFrame() {

this.setLocation(300, 400);

this.setSize(400, 400);

this.setBackground(Color.WHITE);

this.setTitle("Snake");

//添加关闭的处理事件

this.addWindowListener(new WindowAdapter() {

@Override

public void windowClosing(WindowEvent e) {

System.exit(0);

}

});

//禁止改变窗的大小

this.setResizable(false);

this.setVisible(true);

}

}

第二步完成的功能:在界面上画成一格一格的

我们见过的贪吃蛇游戏,是有一个格子一个格子构成,然后蛇在这个里面运动。

重写paint方法,单元格就是横着画几条线竖着画几条线即可。

代码如下:

@Override

public void paint(Graphics g) {

Color c = g.getColor();

g.setColor(Color.GRAY);

/* * 画线 * */

int col = GAME_WIDTH/squareSize;

int row = GAME_HEIGHT/squareSize;

for(int i=0;i

g.drawLine(i*squareSize, 0, i*squareSize, GAME_HEIGHT);

}

for(int i=0;i

g.drawLine(0, i*squareSize, GAME_WIDTH, i*squareSize);

}

g.setColor(c);

}

效果如下:

0818b9ca8b590ca3270a3433284dd417.png

第三步完成的功能:建立另外的线程来控制重画

由于,蛇的运动就是改变蛇所在的位置,然后进行重画,就是我们所看到的运动。因此,在这里,我们单独用一个线程来控制重画。

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();即可。

第四步完成的功能:在界面上画一个蛇出来

贪吃蛇游戏中的蛇就是用一个“点”来表示。

这里,我们将蛇新建一个类,用面向对象的思想,发现,这个类应该有如下的属性和方法:

1、位置

2、大小,即长度、宽度

3、方向

4、构造方法

5、draw方法

Snake类的代码如下:

public class Snake {

//位置

private int x;

private int y;

//大小

private static final int WIDTH = 10 ;

private static final int HEIGHT = 10 ;

private SnakeFrame snakeFrame ;

//方向

private Direction dir =Direction.D;

private SnakeFrame snakeFrame ;

public Snake(int x, int y, SnakeFrame snakeFrame) {

this.x = x;

this.y = y;

this.snakeFrame = snakeFrame;

}

public Snake(int x, int y,Direction dir, SnakeFrame snakeFrame) {

this(x,y,snakeFrame);

this.dir = dir ;

}

public void draw(Graphics g){

Color c = g.getColor();

g.setColor(Color.BLACK);

g.fillRect(x, y, WIDTH, HEIGHT);

g.setColor(c);

}

}

Direction是一个enum,具体如下:

public enum Direction {

L,U,R,D

}

在SnakeFrame类中new一个Snake对象,然后调用Snake对象的draw方法即可。

效果如下:

0818b9ca8b590ca3270a3433284dd417.png

第五步完成的功能:通过键盘控制蛇的上下左右移动

首先想到的是这样:在Snake类中添加一个keyPressed方法,然后在SnakeFrame的键盘事件中调用Snake对象的keyPressed方法。

具体如下:

Snake类中添加一个keyPressed方法

public void keyPressed(KeyEvent e) {

int key = e.getKeyCode();

switch(key){

case KeyEvent.VK_LEFT :

this.x = x - WIDTH;

break;

case KeyEvent.VK_UP :

this.y = y - HEIGHT;

break;

case KeyEvent.VK_RIGHT :

this.x = x + WIDTH;

break;

case KeyEvent.VK_DOWN :

this.y = y + WIDTH;

break;

}

//处理蛇的边界

if(x<=0){

x = 0;

}

else if(x>SnakeFrame.GAME_WIDTH - WIDTH){

x = SnakeFrame.GAME_WIDTH - WIDTH;

}

if(y<=0){

y = 0;

}

else if(y>SnakeFrame.GAME_HEIGHT - HEIGHT){

y = SnakeFrame.GAME_HEIGHT - HEIGHT ;

}

}

在SnakeFrame中完整代码如下:

public class SnakeFrame extends Frame{

//游戏界面的大小

public static final int GAME_WIDTH =400;

public static final int GAME_HEIGHT =400;

//游戏中方格的大小

private static final int squareSize = 10;

Snake s = new Snake(40,40,Direction.D,this);

public static void main(String[] args) {

SnakeFrame s = new SnakeFrame();

s.launchFrame();

}

private void launchFrame() {

this.setLocation(300, 400);

this.setSize(GAME_WIDTH, GAME_HEIGHT);

this.setBackground(Color.WHITE);

this.setTitle("Snake");

//添加关闭的处理事件

this.addWindowListener(new WindowAdapter() {

@Override

public void windowClosing(WindowEvent e) {

System.exit(0);

}

});

//禁止改变窗的大小

this.setResizable(false);

this.setVisible(true);

new Thread(new MyPaintThread()).start();

this.addKeyListener(new MyKeyListener());

}

@Override

public void paint(Graphics g) {

Color c = g.getColor();

g.setColor(Color.GRAY);

/* * 画线 * */

int col = GAME_WIDTH/squareSize;

int row = GAME_HEIGHT/squareSize;

for(int i=0;i

g.drawLine(i*squareSize, 0, i*squareSize, GAME_HEIGHT);

}

for(int i=0;i

g.drawLine(0, i*squareSize, GAME_WIDTH, i*squareSize);

}

g.setColor(c);

s.draw(g);

}

/* * 重画线程类 * */

private class MyPaintThread implements Runnable{

@Override

public void run() {

//每隔50ms重画一次

while(true){

repaint();//会自动调用paint方法

try {

Thread.sleep(50);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

}

/* * 键盘监听类 * */

private class MyKeyListener extends KeyAdapter{

@Override

public void keyPressed(KeyEvent e) {

s.keyPressed(e);

}

}

}

以上就完成了通过键盘来控制着蛇的上下左右移动。

第六步完成的功能:改善Snake类,如果没有按键,则按照原来的方向移动

由于上面的Snake类中的keyPressed方法实现的是:每按键一次,蛇就移动一次,完全没有把方向加入进去,即我们没有完成这样的功能,如果我们没有按键,则按照原来的方向移动。

为了解决这个问题,则需要对Snake类来进行改善。

public class Snake {

//位置

private int x;

private int y;

//大小

private static final int WIDTH = 10 ;

private static final int HEIGHT = 10 ;

//方向

private Direction dir =Direction.D;

private SnakeFrame snakeFrame ;

public Snake(int x, int y, SnakeFrame snakeFrame) {

this.x = x;

this.y = y;

this.snakeFrame = snakeFrame;

}

public Snake(int x, int y,Direction dir, SnakeFrame snakeFrame) {

this(x,y,snakeFrame);

this.dir = dir ;

}

public void draw(Graphics g){

Color c = g.getColor();

g.setColor(Color.BLACK);

g.fillRect(x, y, WIDTH, HEIGHT);

g.setColor(c);

move();

}

/* * 函数功能:根据按键来确定蛇的移动方向 * */

public void keyPressed(KeyEvent e) {

int key = e.getKeyCode();

switch(key){

case KeyEvent.VK_LEFT :

this.dir = Direction.L;

break;

case KeyEvent.VK_UP :

this.dir = Direction.U;

break;

case KeyEvent.VK_RIGHT :

this.dir = Direction.R;

break;

case KeyEvent.VK_DOWN :

this.dir = Direction.D;

break;

default:

this.dir = Direction.STOP;

}

}

/* * 根据方向的具体移动 * */

public void move(){

if(dir == Direction.L){

x = x - WIDTH;

}

else if(dir == Direction.U){

y = y - HEIGHT;

}

else if(dir == Direction.R){

x = x + WIDTH;

}

else if(dir == Direction.D){

y = y + HEIGHT;

}

//处理蛇的边界

if(x<=0){

x = 0;

}

else if(x>SnakeFrame.GAME_WIDTH - WIDTH){

x = SnakeFrame.GAME_WIDTH - WIDTH;

}

if(y<=0){

y = 0;

}

else if(y>SnakeFrame.GAME_HEIGHT - HEIGHT){

y = SnakeFrame.GAME_HEIGHT - HEIGHT ;

}

}

}

SnakeFrame的代码与上面贴出来一致。

这样,就实现了,当我们没有按方向键时,则按照原来的方向移动。

未完,待续!!!!

接下来要实现的功能有: 1、随机产生其他的蛇; 2、蛇吃其他的蛇变大

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值