自学制作贪吃蛇

来源:互联网 发布:淘宝跳转play商店 编辑:程序博客网 时间:2024/04/28 14:28


在学习的过程中,特别是学习程序,如果看懂了一个程序,但是你如果不亲自去写一遍这个程序,你还是不算是真正会制作这个程序的,本人利用闲暇时间,参考别人的程序,自己做出了一个贪吃蛇游戏的程序:

程序设计的过程是:

一:抽象出:贪吃蛇游戏中的各个对象(界面,游动的蛇,)

二.一步一步的理顺游戏的逻辑,从设计对象开始,

三,修改自己的程序,使其尽量少地bug出现


总结:我自己制作的贪吃蛇程序,没有运用到缓存技术所以有时候会看到屏闪,同时因为没有考虑到frame的边框效果,导致frame的边框挡住了游戏的边界部分!

从游戏的界面部分开始设计起:

设计游戏的格子->游动的蛇->被吃的豆豆->再回过头来实现游戏的主题逻辑部分,以下是设计出来后的程序代码,本人才疏学浅,如有错误,请不吝赐教!


游戏的主题逻辑部分(包括界面对象的设计)

/** * @Title: Aboard.java * @Package com.csdn.ranplus.snake * @Description: TODO * @author: Rainplus * @date: Feb 15, 2014 9:46:41 PM * @version: V1.0    */package com.csdn.ranplus.snake;import java.awt.Color;import java.awt.Font;import java.awt.Frame;import java.awt.Graphics;import java.awt.event.KeyAdapter;import java.awt.event.KeyEvent;import java.awt.event.WindowAdapter;import java.awt.event.WindowEvent;/** * @author: Rainplus * @Description: 游戏活动的界面; * @date: Feb 15, 2014 9:46:41 PM */public class Aboard extends Frame {public static final int ROWS = 30;public static final int COLS = 30;public static final int BLOCK_SIZE = 15;private static Aboard singleton;private static Snake s = new Snake();private static Bean b = new Bean();private MoveThread moveThread = new MoveThread();private static boolean gameOver = false;private static int score;/** * @Title: start * @Description: 使用单例模式的入口点      * @throws: */public static void start() {if (singleton == null) {singleton = new Aboard();}singleton.draw();}/** * @Title: draw * @Description: 画出贪吃蛇的界面大小; * @throws: */private void draw() {this.setTitle("Rainplus自学版 贪吃蛇");this.setSize(ROWS * BLOCK_SIZE, COLS * BLOCK_SIZE);this.setLocation(200, 200);this.addWindowListener(new WindowAdapter() {@Overridepublic void windowClosing(WindowEvent e) {System.exit(0);}});this.setVisible(true);this.addKeyListener(new KeyMonitor());new Thread(moveThread).start();}/** * @Title: paint * @Override: * @Description: 画出贪吃蛇的格子界面,得分注释,描述蛇的行动过程; * @throws: */@Overridepublic void paint(Graphics g) {Color c = g.getColor();g.setColor(Color.GRAY);g.fillRect(0, 0, COLS * BLOCK_SIZE, ROWS * BLOCK_SIZE);g.setColor(Color.BLACK);for (int i = 1; i < ROWS; i++) {g.drawLine(0, BLOCK_SIZE * i, COLS * BLOCK_SIZE, BLOCK_SIZE * i);}for (int i = 1; i < COLS; i++) {g.drawLine(BLOCK_SIZE * i, 0, BLOCK_SIZE * i, BLOCK_SIZE * ROWS);}g.setColor(Color.YELLOW);g.setFont(new Font("宋体", Font.BOLD, 16));g.drawString("score:" + score, ROWS * BLOCK_SIZE- 100, 60);g.setColor(Color.RED);if (gameOver) {g.setFont(new Font("宋体", Font.BOLD, 50));g.drawString("GameOver", 120, 180);moveThread.pause();}g.setColor(c);s.eat(b);b.draw(g);s.draw(g);}/** * @author: Rainplus * @Description: 使用分线程重绘刷新游戏界面 * @date: Feb 15, 2014 11:44:45 PM */private class MoveThread implements Runnable {private boolean running = true;private boolean pause = false;public void run() {while (running) {if (pause)continue;elserepaint();try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}}}public void pause() {this.pause = true;}public void reStart() {this.pause = false;s = new Snake();gameOver = false;}}public static void stop() {gameOver = true;}/** * @author: Rainplus * @Description: 使用键盘对游戏进行控制 * @date: Feb 15, 2014 11:45:19 PM */private class KeyMonitor extends KeyAdapter {@Overridepublic void keyPressed(KeyEvent e) {int key = e.getKeyCode();if (key == KeyEvent.VK_F2) {moveThread.reStart();}s.keyPressed(e);}}public static int getScore() {return score;}public static void setScore(int score) {score = score;}public static void main(String[] args) {start();}}

游戏主角设计--对象蛇的设计

 * @Title: snake.javapackage com.csdn.ranplus.snake;import java.awt.Color;import java.awt.Graphics;import java.awt.Rectangle;import java.awt.event.KeyEvent;/** * @author: Rainplus * @Description: 蛇由结点构成,拥有吃的方法,和相应的处理的办法 (添加结点和删除移动的后端) * @date: Feb 15, 2014 10:19:30 PM *//** * @author: Rainplus * @Description: TODO * @date: Feb 15, 2014 10:53:38 PM */public class Snake {private static Node head = null;private static Node tail = null;private static int size = 0;private Node first = new Node(15, 15, Dir.L);/** * Title: Description: 构造初始结点 */public Snake() {head = first;tail = first;size++;}public void addToTail() {Node node = null;switch (tail.dir) {case L:node = new Node(tail.row, tail.col + 1, tail.dir);break;case U:node = new Node(tail.row + 1, tail.col, tail.dir);break;case R:node = new Node(tail.row, tail.col - 1, tail.dir);break;case D:node = new Node(tail.row - 1, tail.col, tail.dir);break;}tail.next = node;node.prev = tail;tail = node;size++;}public void addToHead() {Node node = null;switch (head.dir) {case L:node = new Node(head.row, head.col - 1, head.dir);break;case U:node = new Node(head.row - 1, head.col, head.dir);break;case R:node = new Node(head.row, head.col + 1, head.dir);break;case D:node = new Node(head.row + 1, head.col, head.dir);break;}node.next = head;head.prev = node;head = node;size++;}/** * @Title: draw * @Description: 画出蛇游动的效果; * @param g * @throws: */public void draw(Graphics g) {move();for (Node n = head; n != null; n = n.next) {n.draw(g);}}/** * @Title: move * @Description: 蛇的游动 * @throws: */private void move() {addToHead();deleteFromTail();checkDead();}private void checkDead() {if (head.row < 2 || head.col < 0 || head.row > Aboard.ROWS|| head.col > Aboard.COLS) {Aboard.stop();}for (Node n = head.next; n != null; n = n.next) {if (head.row == n.row && head.col == n.col) {Aboard.stop();}}}/** * @Title: deleteFromTail * @Description: 删除移动后留下的尾部结点,使其看起来有动态效果 * @throws: */private void deleteFromTail() {if (size == 0)return;tail = tail.prev;tail.next = null;}/** * @Title: keyPressed * @Description: 用键盘A,S,D,W和上,下,左,右键,控制蛇的游动方向 * @param e * @throws: */public void keyPressed(KeyEvent e) {int key = e.getKeyCode();switch (key) {case KeyEvent.VK_LEFT:case KeyEvent.VK_A:if (head.dir != Dir.R)head.dir = Dir.L;break;case KeyEvent.VK_UP:case KeyEvent.VK_W:if (head.dir != Dir.D)head.dir = Dir.U;break;case KeyEvent.VK_RIGHT:case KeyEvent.VK_D:if (head.dir != Dir.L)head.dir = Dir.R;break;case KeyEvent.VK_DOWN:case KeyEvent.VK_S:if (head.dir != Dir.U)head.dir = Dir.D;break;}}/** * @Title: eat * @Description: 贪吃蛇吃豆的动作 * @param b      * @throws: */public void eat(Bean b) {if (this.getRect().intersects(b.getRect())) {b.reAppear();this.addToHead();Aboard.setScore(Aboard.getScore() + 5);}}private Rectangle getRect() {return new Rectangle(Aboard.BLOCK_SIZE * head.col, Aboard.BLOCK_SIZE* head.row, head.weight, head.hight);}/** * @author: Rainplus * @Description: 构成贪吃蛇的结点,其拥有画出结点的方法draw(); * @date: Feb 15, 2014 10:22:52 PM */private class Node {private int weight = Aboard.BLOCK_SIZE;private int hight = Aboard.BLOCK_SIZE;private int row, col;private Node prev = null;private Node next = null;private Dir dir = null;/** * Title: Node() Description:用字段构造结点; *  * @param row * @param col * @param dir */public Node(int row, int col, Dir dir) {this.row = row;this.col = col;this.dir = dir;}/** * @Title: draw * @Description: 画出结点 * @param g * @throws: */public void draw(Graphics g) {Color c = g.getColor();g.setColor(Color.BLACK);g.fillRect(col * Aboard.BLOCK_SIZE, row * Aboard.BLOCK_SIZE,weight, hight);g.setColor(c);}}}

 * @Title: Dir.javapackage com.csdn.ranplus.snake;/** * @author: Rainplus * @Description: 结点在下一步行走的方向的定义 * @date: Feb 15, 2014 10:28:25 PM */public enum Dir {L, R, U, D;}

游戏中的豆豆设计:

 * @Title: Bean.javapackage com.csdn.ranplus.snake;import java.awt.Color;import java.awt.Graphics;import java.awt.Rectangle;import java.util.Random;/** * @author: Rainplus * @Description: 贪吃蛇所有吃的豆类,利用随机算法在游戏界面中随机生成豆豆的位置; * @date: Feb 15, 2014 10:57:44 PM */public class Bean {    private int weight = Aboard.BLOCK_SIZE;    private int hight = Aboard.BLOCK_SIZE;    private int row, col;    private static Random r = new Random();    private Color color = Color.GREEN;    public Bean(int row, int col) {        this.row = row;        this.col = col;    }    public Bean() {        this(r.nextInt(Aboard.ROWS-2) + 2, r.nextInt(Aboard.COLS));    }    /**     * @Title: reAppear     * @Description: 当豆豆被吃到后,重新绘制出一颗豆豆          * @throws:     */    public void reAppear() {        this.row = r.nextInt(Aboard.ROWS - 2) + 2;        this.col = r.nextInt(Aboard.COLS);    }    public Rectangle getRect() {        return new Rectangle(Aboard.BLOCK_SIZE * col, Aboard.BLOCK_SIZE * row, weight, hight);    }    /**     * @Title: draw     * @Description: 画出豆豆的位置     * @param g          * @throws:     */    public void draw(Graphics g) {        Color c = g.getColor();        g.setColor(color);        g.fillOval(Aboard.BLOCK_SIZE * col, Aboard.BLOCK_SIZE * row, weight, hight);        g.setColor(c);        if (color == Color.GREEN)            color = Color.RED;        else            color = Color.GREEN;    }    public int getCol() {        return col;    }    public void setCol(int col) {        this.col = col;    }    public int getRow() {        return row;    }    public void setRow(int row) {        this.row = row;    }}


本程序的原工程文件可以从此处下载:http://download.csdn.net/detail/u012332962/6925679

0 0
原创粉丝点击