贪吃蛇小游戏

开始写第一篇博客。

先从Java的基础开始,写的这个贪食蛇小游戏只是一个最简化的,利用Java自带的图形来构建的,所以比较简陋一些。

主要是运用了Swing里面的一些知识,Swing相对awt来说,兼容性以及对于画面的呈现等方面都有优势,因此,大多数图形界面都是用Swing去编写。

贪吃蛇,可以用几个部分去写,先构造界面、蛇身、球的属性,然后对三个部分详细写,增加事件监听,用画板画出来。最难的部分在于蛇的移动的判定以及撞墙的判定,这里在蛇的移动上面是先把界面分成一个一个的小格,每一个小格代表蛇的一部分,这样移动起来就是在表格中移动,相对好理解一些。撞墙的判定是头碰到边缘就会结束。

package Game;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Random;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;

@SuppressWarnings("serial")
public class Game extends JFrame {
    //首先设置好界面 以及 蛇 球的各个属性 让他们线呈现出来 之后在进行移动 吃东西等的判断


    //面板的长和宽
    private int WIDTH = 800;
    private int HEIGHT = 800;
    
    //每个格子长宽
    private int size = 20;
    
    //多少个格子
    private int rate = WIDTH/size;
    //蛇的属性  在蛇的属性这个方面也可以用面向对象的思想
    private int[] snake_x;//蛇的横坐标  用数组的形式储存
    private int[] snake_y;//蛇的纵坐标
    private int length;//蛇的长度
    private int Direction ;
    private int speed= 1;//一次移动一格
    private int[] move_x ={speed,-speed,0,0};
    private int[] move_y ={0,-0,speed,-speed};    
    //初始化
    public void inital() {
        snake_x = new int[rate];
        snake_y = new int[rate];
         length = 3;

        //蛇的初始坐标,一开始显示的位置
         snake_x[0] = 5;
         snake_y[0] = 5;
         snake_x[1] = 4;
         snake_y[1] = 5;
         snake_x[2] = 3;
         snake_y[2] = 5;
    }
    
    //球的属性
    private int ball_x = random.nextInt(rate)*size;
    private int ball_y = random.nextInt(rate)*size;
    private int ball_size = 20;
    
    boolean flag = true;
    Timer time = null;
    
    
    
    //画板
    class Mycanvas extends JPanel{
        
        @Override
        public void paint(Graphics g) {
            // TODO Auto-generated method stub
            super.paint(g);
            if (flag) {//存活状态下设置各个物体的属性
                g.setColor(Color.GREEN);
                g.fillOval(ball_x, ball_y, ball_size, ball_size);
                for(int i = 0; i < length; i++) {
                    g.setColor(Color.blue);
                    g.fillRect(snake_x[i] * size, snake_y[i] * size, size, size);
                }
            }else {//游戏结束时各个物体的属性
                g.setColor(Color.RED);
                g.setFont(new Font("宋体", Font.ITALIC, 60));
                g.drawString("GAME OVER", 300, 300);
            }
            
        }
    }
    
    private Mycanvas mycanvas = new Mycanvas();

    
    Game(){
        super("贪吃蛇");
        this.inital();
        mycanvas.setPreferredSize(new Dimension(WIDTH, HEIGHT));
        this.add(mycanvas);

        //增加监听事件
        ActionListener al = new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                
                if(flag) {
                    for(int i = length -1; i >0; i--) {//蛇的移动的条件 后一个变成前一个,位置的改变
                        snake_x[i] = snake_x[i-1];
                        snake_y[i] = snake_y[i-1];
                    }
                    snake_x[0] += move_x[Direction];//在判定蛇往哪移动后,蛇进行相应的移动
                    snake_y[0] += move_y[Direction];
                }
                //撞到边缘
                if(snake_x[0] < 0 || snake_x[0] > (WIDTH - size)/size  ||snake_y[0] < 0 || snake_y[0] >(HEIGHT -size)/size ) {
                    flag = false;
                }
                //撞到自己
                for(int i =1; i <length ;i++) {
                if(snake_x[0] == snake_x[i] && snake_y[0] == snake_y[i]) {
                    flag = false;
                }
                }
                //吃到食物
            
                if(snake_x[0]*size == ball_x && snake_y[0]*size == ball_y) {
                    length++;
                    snake_x[length-1] = ball_x/size;
                    snake_y[length-1] = ball_y/size;
                    ball_x=random.nextInt(rate)*size;
                    ball_y=random.nextInt(rate)*size;
                }
            
            mycanvas.repaint();
            }
            
        };
        this.addKeyListener(new KeyListener() {
            
            @Override
            public void keyTyped(KeyEvent arg0) {
                // TODO Auto-generated method stub
                
            }
            
            @Override
            public void keyReleased(KeyEvent arg0) {
                // TODO Auto-generated method stub
                
            }
            //键盘监听事件 上下左右分别对应不用的Direction 而Direction又决定了蛇的移动方向

            //这样就能通过上下左右来控制蛇的移动了
            @Override
            public void keyPressed(KeyEvent e) {
                // TODO Auto-generated method stub
                switch(e.getKeyCode()) {
                case KeyEvent.VK_UP :   
                    if(Direction !=2 ) {
                    Direction = 3;
                    }
                    break;
                case KeyEvent.VK_DOWN :
                    if(Direction !=3) {
                    Direction = 2;
                    }
                    break;
                case KeyEvent.VK_LEFT :
                    if(Direction !=0 ) {
                    Direction = 1;
                    }
                    break;
                case KeyEvent.VK_RIGHT :
                    if(Direction !=1) {
                    Direction = 0;
                    }
                    break;
                default :
                break;
                }

                //画板的重绘
                mycanvas.repaint();
            }
        });

        //设置刷新时间 也就是闪烁频率
        time = new Timer(200, al);
        time.start();

        this.setVisible(true);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.pack();
        
    }
    //主类 执行
    public static void main(String[] args) {
        new Game();
    }
    
    
    
}
不管是写贪吃蛇还是别的小游戏,写代码都应从简到繁,先写出大体的轮廓,然后对相应的功能进行一步一步的完善,这个贪吃蛇写的简单了一点,所以一些东西是直接定义拿过来用的。很多时候面向对象很好用,特别是东西多了之后,一个对象一个类,这样逻辑就会很清晰,然后到最后直接调用就可以。

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值