[java]代码库
11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
package game.mysanek.entities;
import game.mysanek.listener.SnakeListener;
import game.mysanek.util.Global;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Set;
public class Snake {
public static final int UP= -1;
public static final int DOWN=1;
public static final int LEFT=2;
public static final int RIGHT= -2;
//设置两个变量来存放原来的蛇头坐标--和--键盘输入的最后一次控制蛇的方向
private int oldDirection, newDirection;
//这个变量用来存放蛇的尾部,当蛇吃掉食物后身体边长。则在蛇的身体添加body.addLast(oldTail),节点的位置坐标
private Point oldTail;
//存放蛇的节点位置坐标。
private LinkedList<Point> body = new LinkedList<Point>();
private Set<SnakeListener> listeners = new HashSet<SnakeListener>();
public boolean life; //这个变量用来判断蛇是否死亡(结速进程)
/**
* 构造方法初始化蛇的body身体、蛇头oldDirection和newDirection运行的方向
*/
public Snake(){
init();
}
public void init(){
//取一个节点作为蛇头的位置坐标
int x=Global.WIDTH/2;
int y=Global.HEIGHt/2;
//蛇的长度初始化为--5个节点的长度
for(int i=0; i<5; i++){
body.addLast(new Point(x--, y));
}
oldDirection = newDirection = RIGHT; //蛇头方向初始化
life=true; //蛇是活的,
}
/**
* 蛇移动
*/
public void move(){
System.out.println("Snake's move");
//1.去尾
oldTail=body.removeLast(); //记录每次去尾时,尾巴的x,y坐标
//获取蛇的蛇头坐标想x,y
int x = body.getFirst().x;
int y = body.getFirst().y;
//当蛇的原来方向oldDirection和键盘输入的最后一个方向newDirection不相反时,再传递蛇最新的方式值
if(!(oldDirection + newDirection ==0)){
oldDirection = newDirection;
}
switch(oldDirection){
case UP:
y--;
if(y <0){ //使蛇在GamePanel的范围内运动
y =Global.HEIGHt - 1;
}
break;
case DOWN:
y++;
if( y > Global.HEIGHt-1){ //使蛇在GamePanel的范围内运动
y = 0;
}
break;
case LEFT:
x--;
if( x<0 ){ //使蛇在GamePanel的范围内运动
x=Global.WIDTH-1;
}
break;
case RIGHT:
x++;
if(x> Global.WIDTH-1){ //使蛇在GamePanel的范围内运动
x=0;
}
break;
}
//蛇变化方向后,蛇头的坐标位置
Point newHead = new Point(x, y);
//2.加头
body.addFirst(newHead);
}
/**
* 蛇改变方向
* @param direction
*/
public void changeDirection(int direction){
newDirection=direction;
}
/**
* 蛇吃食物
* 蛇吃到食物后身体变长
*/
public void eatFood(){
System.out.println("Snake's eatFood");
body.addLast(oldTail); //蛇吃到食物后身体变长
}
/**
* 判断蛇是否吃到了自己的身体,吃到身体蛇死亡(即结束SankeDriver线程)
* @return
*/
public boolean isEatBody(){
System.out.println("Sanek's isEatBody");
//i=0表示蛇头,所以i要从1,2,3。。。开始
for(int i=1; i<body.size(); i++){
//判断蛇头与身体的其中一个坐标是否重贴
if(body.get(i).equals(this.getHead())){
return true;
}
}
return false;
}
/**
* 绘制蛇的图像
* @param g
*/
public void drawMe(Graphics g){
System.out.println("Snake's drawMe");
g.setColor(Color.BLUE); //设置蛇头颜色
for(Point p :body){
g.fill3DRect(p.x * Global.cell_size, p.y * Global.cell_size,
Global.cell_size, Global.cell_size, true);
if(p==body.getFirst()){ //设置蛇的身体颜色
g.setColor(Color.MAGENTA);
}
}
}
//获取蛇头方向
public Point getHead(){
return body.getFirst();
}
/**
* 蛇死亡,即结束进程的方法
*/
public void die(){
life=false;
}
/**
* SnakeDirver类,控制蛇的进程
* @author Administrator
*
*/
public class SnakeDriver implements Runnable{
@Override
public void run() {
// TODO 自动生成的方法存根
while(life){
move(); //蛇运动
//绘制图像--图像显示
for(SnakeListener l : listeners){
l.snakeMoved();
}
try {
//设置线程休息时间
Thread.sleep(200);
} catch (InterruptedException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
System.out.println("##########################################");
}
}
}
/**
* start()方法是启动线程的方法
*/
public void start(){
new Thread(new SnakeDriver()).start();
}
/**
* 往listens中添加 Snake类、Food类、Ground类、GamePnael类的-------类地址
* @param l
*/
public void addSnakeListener(SnakeListener l){
if(l != null){
this.listeners.add(l);
}
}
}
2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222
package game.mysanek.entities;
import game.mysanek.util.Global;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
public class Food extends Point{
//设置食物的x,y坐标
public void newFood(Point p){ //生成食物
this.setLocation(p); //设置食物的坐标
System.out.println("-------------"+p);
}
//比坐标---当蛇头的坐标与食物的坐标重合,则表示食物被蛇吃掉了
public boolean isSnakeEatFood(Snake snake){
System.out.println("Food's isSnakeEatFood");
return this.equals(snake.getHead());
// return false;
}
/**
* 绘制食物的图像
* @param g
*/
public void drawMe(Graphics g){
System.out.println("Food's drawMe");
g.setColor(Color.CYAN);
g.fill3DRect(x*Global.cell_size, y*Global.cell_size,
Global.cell_size, Global.cell_size, true);
}
}
333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333
package game.mysanek.entities;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.util.Random;
import game.mysanek.util.Global;
public class Ground {
//用一个二维数组来存放rocks(障碍物)的坐标
//大小为GamePanel的长宽的小格子数WIDTH和HEIGHT;
private int[][] rocks= new int[Global.WIDTH][Global.HEIGHt];
public Ground(){
for(int x=0; x<Global.WIDTH; x++){
//第一行和最后一行---为rocks(障碍物)
rocks[x][0]=1;
rocks[x][Global.HEIGHt-1]=1;
}
}
//随机生成---newFood()食物的x,y坐标
//而且不能使newFood(食物)的坐标和rocks(障碍物)坐标重合
public Point getPoint(){
Random random =new Random();
int x,y;
//newFood的坐标和rocks坐标重叠,则继续生成新的坐标---直到不重合
do{
x=random.nextInt(Global.WIDTH);
y=random.nextInt(Global.HEIGHt);
}while(rocks[x][y]==1);
return new Point(x,y);
}
/**
* 蛇是否吃到石头(障碍物)
* @param snake
* @return
*/
public boolean isSnakeEatRock(Snake snake){
System.out.println("Ground's isSnakeEatRock");
//判断snake(蛇)是否吃到了rocks(障碍物)
for(int x=0; x<Global.WIDTH; x++){
for(int y=0; y<Global.HEIGHt; y++){
if(rocks[x][y]==1 &&
(x==snake.getHead().x && y==snake.getHead().y) ){//getHead()方法可以获得蛇头的坐标
return true;
}
}
}
return false;
}
/**
* 当rocks[x][y]==1时,绘制石头(障碍物)
* @param g
*/
public void drawMe(Graphics g){
System.out.println("Ground's drawMe");
g.setColor(Color.gray);
for(int x=0; x<Global.WIDTH; x++){
for(int y=0; y<Global.HEIGHt; y++){
if(rocks[x][y] ==1 ){
g.fill3DRect(x*Global.cell_size, y*Global.cell_size,
Global.cell_size, Global.cell_size, true);
}
}
}
}
}
1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
package game.mysanek.view;
import game.mysanek.entities.Food;
import game.mysanek.entities.Ground;
import game.mysanek.entities.Snake;
import game.mysanek.util.Global;
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JPanel;
public class GamePanel extends JPanel{
private Snake snake;
private Food food;
private Ground ground;
/**
* 将蛇、食物、石头(障碍物)显示出来
*snake、food、ground---传递的都是Snaek类、Food类、Ground类的***地址。
* @param snake 传递地址
* @param food
* @param ground
*/
public void display(Snake snake, Food food, Ground ground){//传递各个class的地址
System.out.println("GamePanel's display");
this.snake=snake;
this.food=food;
this.ground=ground;
//绘图----调用下方的--画图功能
this.repaint();
}
@Override
protected void paintComponent(Graphics g) {
// TODO 自动生成的方法存根
//显示
g.setColor(new Color(0xcfcfcf));
//绘制一个GamePnanl大小的--矩形--遮盖掉前一个时间的蛇、食物、石头(障碍物),---相当于橡皮差
g.fillRect(0, 0, Global.WIDTH * Global.cell_size,
Global.HEIGHt *Global.cell_size);
//当snake、food、ground字段----都有对应的Snake类、Food类、Ground类的地址时---画图
if(snake != null && food != null && ground !=null){
this.ground.drawMe(g);
this.snake.drawMe(g);
this.food.drawMe(g);
}
}
}
1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
package game.mysanek.controller;
import game.mysanek.entities.Food;
import game.mysanek.entities.Ground;
import game.mysanek.entities.Snake;
import game.mysanek.listener.SnakeListener;
import game.mysanek.util.Global;
import game.mysanek.view.GamePanel;
import java.awt.Point;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.Random;
public class Controller extends KeyAdapter implements SnakeListener{
//------这时的snake只是个字段,它的值为--null。 没有Snake类的地址
private Snake snake;
private Food food;
private Ground ground;
private GamePanel gamePanel;
/**
* Controller 构造方法----传递Snaek类、Food类、Ground类、GamePanel类--的***地址。
* @param snake
* @param food
* @param ground
* @param gamePanel
*/
public Controller(Snake snake, Food food, Ground ground, GamePanel gamePanel) {
//传递各个class的地址
this.snake = snake;
this.food = food;
this.ground = ground;
this.gamePanel = gamePanel;
}
/**
* 键盘控制-------实现键盘控制-蛇-的方向移动。
*/
@Override
public void keyPressed(KeyEvent e) {
// TODO 自动生成的方法存根
switch(e.getKeyCode()){
case KeyEvent.VK_UP:
snake.changeDirection(Snake.UP);
break;
case KeyEvent.VK_DOWN:
snake.changeDirection(Snake.DOWN);
break;
case KeyEvent.VK_LEFT:
snake.changeDirection(Snake.LEFT);
break;
case KeyEvent.VK_RIGHT:
snake.changeDirection(Snake.RIGHT);
break;
}
}
/**
* 实现SnakeLisener接口中的方法。
*/
@Override
public void snakeMoved() {
//判断食物是否被蛇吃掉,吃掉后产生新的---新食物
if(food.isSnakeEatFood(snake)){
snake.eatFood(); //蛇吃掉食物
food.newFood(ground.getPoint()); //产生新的食物
}
//判断蛇头的位置与石头的位置是否重合---蛇是否吃到石头
if(ground.isSnakeEatRock(snake)){
snake.die(); //蛇蛇死亡---结束SnakeDriver线程
}
//判断蛇是否吃到了自己的身体
if(snake.isEatBody()){
snake.die(); //蛇蛇死亡---结束SnakeDriver线程
}
//绘图-------在GamePanel的面板上绘制蛇、食物、石头(障碍物)。
//snake、food、ground---传递的都是Snaek类、Food类、Ground类的***地址。
gamePanel.display(snake, food, ground);//传递各个class的地址
}
// //随机生成---食物的x,y坐标
// public Point getPoint(){
// Random random =new Random();
// int x=random.nextInt(Global.WIDTH);
// int y=random.nextInt(Global.HEIGHt);
// return new Point(x,y);
// }
/**
* 将Snake类中的start()方法,放在在Controller中
* 逻辑控制
*/
public void newGame(){
snake.start();
food.newFood(ground.getPoint());
}
}
1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
package game.mysanek.listener;
/**
* 设置一个借口----用来存放(Snake snake, Food food, Ground ground) 的类的地址
* @author Administrator
*
*/
public interface SnakeListener {
public void snakeMoved();
}
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
package game.mysanek.util;
public class Global {
//贪吃蛇中的每个小方格的边长--20
public static final int cell_size=20;
//设置游戏界面GameJPanel的大小
public static final int WIDTH=40; //宽度为40个小方格
public static final int HEIGHt =25; //高度为25个小方格
}
11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
package game.mysanek.game;
import java.awt.BorderLayout;
import game.mysanek.controller.Controller;
import game.mysanek.entities.Food;
import game.mysanek.entities.Ground;
import game.mysanek.entities.Snake;
import game.mysanek.util.Global;
import game.mysanek.view.GamePanel;
import javax.swing.JFrame;
public class Game {
public static void main(String[] args) {
Snake snake = new Snake();
Food food = new Food();
Ground ground = new Ground();
GamePanel gamePanel = new GamePanel();
//传递各个class的地址
Controller controller = new Controller(snake, food, ground, gamePanel);
JFrame frame = new JFrame("贪吃蛇游戏");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
gamePanel.setSize(Global.WIDTH * Global.cell_size,
Global.HEIGHt * Global.cell_size);
frame.setSize(Global.WIDTH * Global.cell_size +10,
Global.HEIGHt * Global.cell_size+35);
frame.add(gamePanel, BorderLayout.CENTER);
frame.setLocationRelativeTo(null);
gamePanel.addKeyListener(controller);
snake.addSnakeListener(controller);
frame.addKeyListener(controller);
frame.setVisible(true);
controller.newGame();
}
}
[代码运行效果截图]
中级程序员
by: 陆痴 发表于:2017-03-11 18:13:42 顶(3) | 踩(0) 回复
回复评论