废话不多说咯,直接上代码,求上墙:
格子类
package engorgesnake;
import java.awt.p_w_picpath.BufferedImage;
/**
* 这是一个小方格类,它可以组成贪吃蛇,也可以是食物 它有row col Image三个属性
* 还重写了toString方法
*
* @author yufeng
*
*/
public class Cell {
private int row;
private int col;
private BufferedImage Image;
public Cell(){}
public Cell(int row, int col, BufferedImage p_w_picpath) {
super();
this.row = row;
this.col = col;
this.Image = p_w_picpath;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + col;
result = prime * result + row;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Cell other = (Cell) obj;
if (col != other.col)
return false;
if (row != other.row)
return false;
return true;
}
public int getRow() {
return row;
}
public void setRow(int row) {
this.row = row;
}
public int getCol() {
return col;
}
public void setCol(int col) {
this.col = col;
}
public BufferedImage getImage() {
return Image;
}
public void setImage(BufferedImage p_w_picpath) {
this.Image = p_w_picpath;
}
public String toString() {
return "(" + row + "," + col /*+","+Image*/+")";
}
}
蛇类和食物类:
package engorgesnake;
import java.awt.p_w_picpath.BufferedImage;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;
/**
* 这时一个描述蛇的类
* @author yufeng
*
*/
public class Snake extends LinkedList<Cell>{
private static final long serialVersionUID = 1L;
private List<Cell> snake=new LinkedList<Cell>();
public Snake(List<Cell> snake) {
this.snake = snake;
}
public List<Cell> getSnake() {
return snake;
}
public void setSnake(List<Cell> snake) {
this.snake = snake;
}
/**
* 可以通过类名调用该方法生成蛇
* @return 一条长度为3的蛇
*/
public static Snake start1(){
Snake snake=new Snake(new LinkedList<Cell>());
snake.add(new Cell(20,2,Game.snakeHead));
snake.add(new Cell(20,1,Game.snakeImage));
snake.add(new Cell(20,0,Game.snakeTail));
return snake;
}
public static Snake start2(){
Snake snake=new Snake(new LinkedList<Cell>());
snake.add(new Cell(20,57,Game.snakeHead));
snake.add(new Cell(20,58,Game.snakeImage));
snake.add(new Cell(20,59,Game.snakeTail));
return snake;
}
/**
* 去掉蛇的尾部元素,并且把蛇集合小标为1的元素图片设置为蛇身图片
* @param snake
*/
public void move(Snake snake){
snake.remove(snake.size()-1);
snake.get(1).setImage(Game.snakeImage);
snake.get(snake.size()-1).setImage(Game.snakeTail);
}
/**
* 蛇左移
* @param snake
*/
public void moveLeft(Snake snake){
snake.add(0,new Cell(snake.get(0).getRow(),snake.get(0).getCol()-1,Game.snakeHead));
snake.move(snake);
}
/**
* 蛇右移
* @param snake
*/
public void moveRight(Snake snake){
snake.add(0,new Cell(snake.get(0).getRow(),snake.get(0).getCol()+1,Game.snakeHead));
snake.move(snake);
}
/**
* 蛇上移
* @param snake
*/
public void moveUp(Snake snake){
snake.add(0,new Cell(snake.get(0).getRow()-1,snake.get(0).getCol(),Game.snakeHead));
snake.move(snake);
}
/**
* 蛇下移
* @param snake
*/
public void moveDown(Snake snake){
snake.add(0,new Cell(snake.get(0).getRow()+1,snake.get(0).getCol(),Game.snakeHead));
snake.move(snake);
}
/**
* 吃食物的方法
* @param snake
* @param str
*/
public void eatFood(Snake snake,String str){
if("up".equals(str)){
snake.add(0,new Cell(snake.get(0).getRow()-1,snake.get(0).getCol(),Game.snakeHead));
snake.get(1).setImage(Game.snakeImage);
}else if("down".equals(str)){
snake.add(0,new Cell(snake.get(0).getRow()+1,snake.get(0).getCol(),Game.snakeHead));
snake.get(1).setImage(Game.snakeImage);
}else if("left".equals(str)){
snake.add(0,new Cell(snake.get(0).getRow(),snake.get(0).getCol()-1,Game.snakeHead));
snake.get(1).setImage(Game.snakeImage);
}else if("right".equals(str)){
snake.add(0,new Cell(snake.get(0).getRow(),snake.get(0).getCol()+1,Game.snakeHead));
snake.get(1).setImage(Game.snakeImage);
}
}
}
/**
* 这是一个描述食物的类
* @author yufeng
*
*/
class Food extends Cell{
private int row;
private int col;
private BufferedImage Image;
public int getRow() {
return row;
}
public void setRow(int row) {
this.row = row;
}
public int getCol() {
return col;
}
public void setCol(int col) {
this.col = col;
}
public BufferedImage getImage() {
return Image;
}
public void setImage(BufferedImage p_w_picpath) {
Image = p_w_picpath;
}
public Food(int row, int col, BufferedImage p_w_picpath) {
super();
this.row = row;
this.col = col;
Image = p_w_picpath;
}
public String toString() {
return "(" + row + "," + col + ")";
}
@Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
result = prime * result + col;
result = prime * result + row;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (!super.equals(obj))
return false;
if (getClass() != obj.getClass())
return false;
Food other = (Food) obj;
if (col != other.col)
return false;
if (row != other.row)
return false;
return true;
}
public Food(){}
/**
* 这个是食物随机生成的方法
* @return
*/
public static Food getFood(){
Food food=new Food();
Random random=new Random();
int x=random.nextInt(Game.ROWS);
int y=random.nextInt(Game.COLS);
food.setRow(x);
food.setCol(y);
return food;
}
}
游戏类:
package engorgesnake;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.p_w_picpath.BufferedImage;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.Timer;
import java.util.TimerTask;
import javax.p_w_picpathio.ImageIO;
import javax.management.RuntimeErrorException;
import javax.swing.JFrame;
import javax.swing.JPanel;
/**
* 游戏类扩展了系统的现实面板
* @author yufeng
*
*/
public class Game extends JPanel{
public static final int ROWS = 40;
public static final int COLS = 60;
public static final int CELL_SIZE = 10;
private Cell[][] wall = new Cell[ROWS][COLS];
private Snake snake1;
private Snake snake2;
private Food food1;
private Food food2;
private int SCORE;
private String str;
private int level=50;
private int index=0;
private boolean gameover=false;
private boolean pause=false;
private Timer timer = new Timer();
public static BufferedImage background;
public static BufferedImage snakeHead;
public static BufferedImage snakeImage;
public static BufferedImage snakeTail;
public static BufferedImage gameOver;
/*
* 获取图片资源
*/
static{
try {
background=ImageIO.read(Game.class.getResource("background.jpg"));
snakeHead=ImageIO.read(Game.class.getResource("SnakeHead.jpg"));
snakeImage=ImageIO.read(Game.class.getResource("SnakeImage.jpg"));
snakeTail=ImageIO.read(Game.class.getResource("SnakeTail.jpg"));
gameOver=ImageIO.read(Game.class.getResource("gameover.png"));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void paint(Graphics g){
/*
* 绘制背景贴图
*/
g.drawImage(background, 0, 0, null);
g.translate(11, 11);
/*
* 绘制墙
*/
paintWall(g);
/*
* 绘制蛇
*/
paintSnake(g);
/*
* 绘制食物
*/
paintFood(g);
/*
* 绘制分数
*/
paintScore(g);
}
/**
* 绘制分数的方法
* @param g
*/
private void paintScore(Graphics g) {
Font font = new Font(getFont().getName(), Font.BOLD, 36);
g.setColor(Color.gray);
g.setFont(font);
String str = "" + this.SCORE;
g.drawString(str, 650, 370);
g.setColor(Color.gray);
g.setFont(font);
str=""+this.str;
g.drawString(str, 670, 115);
if(!pause&&!gameover){
g.setColor(Color.gray);
g.setFont(font);
str="[P]暂停";
g.drawString(str, 635, 242);
}
if(pause&&!gameover){
g.setColor(Color.gray);
g.setFont(font);
str="[C]继续";
g.drawString(str, 635, 242);
}
if(gameover){
g.drawImage(gameOver, 0, 0, null);
font = new Font(getFont().getName(), Font.BOLD, 26);
g.setColor(Color.gray);
g.setFont(font);
str="[R]重新游戏";
g.drawString(str, 625, 242);
}
}
/**
* 绘制食物的方法
* @param g
*/
private void paintFood(Graphics g) {
// TODO Auto-generated method stub
if(food1==null||food2==null){
return;
}
int row1=food1.getRow();
int col1=food1.getCol();
int row2=food2.getRow();
int col2=food2.getCol();
int x1=col1*CELL_SIZE;
int y1=row1*CELL_SIZE;
int x2=col2*CELL_SIZE;
int y2=row2*CELL_SIZE;
g.drawImage(snakeImage,x1,y1,null);
g.drawImage(snakeImage,x2,y2,null);
}
/**
* 绘制蛇的方法
* @param g
*/
private void paintSnake(Graphics g) {
// TODO Auto-generated method stub
if(snake1==null&&snake2==null){
return;
}
for(int i=snake1.size()-1;i>=0;i--){
Cell cells=snake1.get(i);
int row=cells.getRow();
int col=cells.getCol();
int x=col*CELL_SIZE;
int y=row*CELL_SIZE;
g.drawImage(cells.getImage(), x, y, null);
}
for(int i=snake2.size()-1;i>=0;i--){
Cell cells=snake2.get(i);
int row=cells.getRow();
int col=cells.getCol();
int x=col*CELL_SIZE;
int y=row*CELL_SIZE;
g.drawImage(cells.getImage(), x, y, null);
}
}
/**
* 绘制墙,背景图片
* @param g
*/
private void paintWall(Graphics g) {
// TODO Auto-generated method stub
for (int row = 0; row < wall.length; row++) {
Cell[] line = wall[row];
for (int col = 0; col < line.length; col++) {
Cell cell = line[col];
int x = CELL_SIZE * col;
int y = CELL_SIZE * row;
/*g.drawRect(x, y, CELL_SIZE, CELL_SIZE);*/
if (cell != null) {
// 如果有砖块 把砖块的图片贴在x,y的位置上
g.drawImage(cell.getImage(), x, y, null);
}
}
}
}
/**
* 这个是本游戏的流程控制(包括各种功能)的代码
*/
private void action(){
// TODO Auto-generated method stub
startGameAction();
KeyAdapter l = new KeyAdapter() {
public void keyPressed(KeyEvent e) {
final int key = e.getKeyCode();
if (key == KeyEvent.VK_Q) {
System.exit(0);
}
if(gameover){
if(key==KeyEvent.VK_R){
clearAll();
}
return;
}
if(pause){
if(key==KeyEvent.VK_C){
pause=false;
}
return;
}
switch (key) {
case KeyEvent.VK_DOWN:
snake_MoveDown(snake2, snake1, food1, food2);
break;
case KeyEvent.VK_RIGHT:
snake_MoveRight(snake2, snake1, food1, food2);
break;
case KeyEvent.VK_LEFT:
snake_MoveLeft(snake2, snake1, food1, food2);
break;
case KeyEvent.VK_UP:
snake_MoveUp(snake2, snake1, food1, food2);
break;
case KeyEvent.VK_S:
snake_MoveDown(snake1, snake2, food1, food2);
break;
case KeyEvent.VK_D:
snake_MoveRight(snake1, snake2, food1, food2);
break;
case KeyEvent.VK_A:
snake_MoveLeft(snake1, snake2, food1, food2);
break;
case KeyEvent.VK_W:
snake_MoveUp(snake1, snake2, food1, food2);
break;
case KeyEvent.VK_P:
pause=true;
break;
default:
break;
}
repaint();
}
};
this.addKeyListener(l);
this.requestFocus();
/**
* 启动主刷新
*/
timer.schedule(new TimerTask() {
public void run() {
if(!pause&&!gameover){
index++;
if (index % level == 0) {
move(snake1, snake2, food1, food2);
move(snake2, snake1, food1, food2);
}
if(SCORE<200){
str="初级";
level=50;
}else if(SCORE<400){
str="中级";
level=30;
}else if(SCORE<600){
str="高级";
level=15;
}else{
str="终极";
level=5;
}
}
repaint();
}
}, 0, 10);
}
/**
* 重新游戏,需要把游戏结束的画面全部清空,再重新开始游戏
*/
protected void clearAll() {
for(Cell[] cells:wall){
Arrays.fill(cells, null);
}
startGameAction();
pause=false;
gameover=false;
}
/**
* 蛇移动的方法,这里主要是对参数snake1移动
* @param snake1
* @param snake2
* @param food1
* @param food2
*/
protected void move(Snake snake1,Snake snake2,Food food1,Food food2){
if(canDown(snake1)){
snake_MoveDown(snake1, snake2,food1,food2);
}else if(canUp(snake1)){
snake_MoveUp(snake1,snake2,food1,food2);/*}*/
}else if(canLeft(snake1)){
snake_MoveLeft(snake1,snake2,food1,food2);/*}*/
}else if(canRight(snake1) ){
snake_MoveRight(snake1,snake2,food1,food2);/*}*/
}else{
if(gameover){
gameOverAction();
}
}
}
/**
* 这个是游戏结束的方法,停止计时
*/
private void gameOverAction() {
// TODO Auto-generated method stub
timer.cancel();
}
/**
* 判断参数snake是否能够向右移动
* @param snake
* @return 能向右移动 返回true
* 不能则返回false
*/
private boolean canRight(Snake snake) {
if(snake.get(0).getRow()==snake.get(1).getRow()&&snake.get(0).getCol()>snake.get(1).getCol()){
return true;
}
return false;
}
/**
* 判断参数snake能否向左移动
* @param snake
* @return
*/
private boolean canLeft(Snake snake) {
if(snake.get(0).getRow()==snake.get(1).getRow()&&snake.get(0).getCol()<snake.get(1).getCol()){
return true;
}
return false;
}
private boolean canUp(Snake snake) {
if(snake.get(0).getCol()==snake.get(1).getCol()&&snake.get(0).getRow()<snake.get(1).getRow()){
return true;
}
return false;
}
private boolean canDown(Snake snake) {
if(snake==null){
return false;
}
if(snake.get(0).getCol()==snake.get(1).getCol()&&snake.get(0).getRow()>snake.get(1).getRow()){
return true;
}
return false;
}
/**
* 参数snakeA上移的方法
* @param snakeA
* @param snakeB
* @param foodA
* @param foodB
*/
protected void snake_MoveUp(Snake snakeA,Snake snakeB,Food foodA,Food foodB) {
if((snakeA.get(0).getCol()==foodA.getCol()&&(snakeA.get(0).getRow()-1==foodA.getRow()))
||(snakeA.get(0).getCol()==foodB.getCol()&&(snakeA.get(0).getRow()-1==foodB.getRow()))){
snakeA.eatFood(snakeA, "up");
updateFood(foodA,foodB,snakeA,snakeB,"up");
repaint();
SCORE+=10;
}else if (canMove(snakeA,snakeB)&& (snakeA.get(0).getRow() < snakeA.get(1).getRow()
||snakeA.get(0).getRow()==snakeA.get(1).getRow()) ){
snakeA.moveUp(snakeA);
}
if(!canMove(snakeA,snakeB)){
snakeA.remove(0);
snakeB.remove(0);
gameOver();
}
}
/**
* 参数snakeA左移的方法
* @param snakeA
* @param snakeB
* @param foodA
* @param foodB
*/
protected void snake_MoveLeft(Snake snakeA,Snake snakeB,Food foodA,Food foodB) {
if((snakeA.get(0).getCol()-1==foodA.getCol()&&(snakeA.get(0).getRow()==foodA.getRow()))
||(snakeA.get(0).getCol()-1==foodB.getCol()&&(snakeA.get(0).getRow()==foodB.getRow()))){
snakeA.eatFood(snakeA, "left");
updateFood(foodA,foodB,snakeA,snakeB,"left");
repaint();
SCORE+=10;
}
else if(canMove(snakeA,snakeB)&& (snakeA.get(0).getCol() < snakeA.get(1).getCol()
||snakeA.get(0).getCol()==snakeA.get(1).getCol())) {
snakeA.moveLeft(snakeA);
}
if(!canMove(snakeA,snakeB)){
snakeA.remove(0);
snakeB.remove(0);
gameOver();
}
}
/**
* 当食物被吃了,更新食物的方法
* @param foodA
* @param foodB
* @param snakeA
* @param snakeB
* @param str
*/
private void updateFood(Food foodA,Food foodB,Snake snakeA,Snake snakeB,String str) {
/**
* 假如2个食物都被吃了,则生成2个食物
*/
if((foodA.getRow()==snakeA.get(0).getRow()&&foodA.getCol()==snakeA.get(0).getCol())
&&foodB.getRow()==snakeB.get(0).getRow()&&foodB.getCol()==snakeB.get(0).getCol()){
Food food1=getFoods(snakeA, snakeB);
Food food2=getFoods(snakeA, snakeB, food1);
foodA.setRow(food1.getRow());
foodA.setCol(food1.getCol());
foodB.setRow(food2.getRow());
foodB.setCol(food2.getCol());
}
if((foodA.getRow()==snakeB.get(0).getRow()&&foodA.getCol()==snakeB.get(0).getCol())
&&foodB.getRow()==snakeA.get(0).getRow()&&foodB.getCol()==snakeA.get(0).getCol()){
Food food1=getFoods(snakeA, snakeB);
Food food2=getFoods(snakeA, snakeB, food1);
foodA.setRow(food1.getRow());
foodA.setCol(food1.getCol());
foodB.setRow(food2.getRow());
foodB.setCol(food2.getCol());
}
/**
* 假如被吃了一个
*/
if(foodA.getRow()==snakeA.get(0).getRow()&&foodA.getCol()==snakeA.get(0).getCol()){
Food food=getFoods(snakeA,snakeB,foodB);
foodA.setRow(food.getRow());
foodA.setCol(food.getCol());
}
if(foodB.getRow()==snakeA.get(0).getRow()&&foodB.getCol()==snakeA.get(0).getCol()){
Food food=getFoods(snakeA,snakeB,foodA);
foodB.setRow(food.getRow());
foodB.setCol(food.getCol());
}
}
/**
* 参数snakeA右移的方法
* @param snakeA
* @param snakeB
* @param foodA
* @param foodB
*/
protected void snake_MoveRight(Snake snakeA,Snake snakeB,Food foodA,Food foodB) {
if((snakeA.get(0).getCol()+1==foodA.getCol()&&(snakeA.get(0).getRow()==foodA.getRow()))
||(snakeA.get(0).getCol()+1==foodB.getCol()&&(snakeA.get(0).getRow()==foodB.getRow()))){
snakeA.eatFood(snakeA, "right");
updateFood(foodA,foodB,snakeA,snakeB,"right");
repaint();
SCORE+=10;
}else if(canMove(snakeA,snakeB)&& (snakeA.get(0).getCol() > snakeA.get(1).getCol()
||snakeA.get(0).getCol()==snakeA.get(1).getCol())) {
snakeA.moveRight(snakeA);
}
if(!canMove(snakeA,snakeB)){
snakeA.remove(0);
snakeB.remove(0);
gameOver();
}
}
/**
* 参数snakeA下移的方法
* @param snakeA
* @param snakeB
* @param foodA
* @param foodB
*/
protected void snake_MoveDown(Snake snakeA,Snake snakeB,Food foodA,Food foodB) {
if((snakeA.get(0).getCol()==foodA.getCol()&&(snakeA.get(0).getRow()+1==foodA.getRow()))
||(snakeA.get(0).getCol()==foodB.getCol()&&(snakeA.get(0).getRow()+1==foodB.getRow()))){
snakeA.eatFood(snakeA, "down");
updateFood(foodA,foodB,snakeA,snakeB,"down");
repaint();
SCORE+=10;
}
else if(canMove(snakeA,snakeB)&& (snakeA.get(0).getRow() > snakeA.get(1).getRow()
||snakeA.get(0).getRow()==snakeA.get(1).getRow()) ){
snakeA.moveDown(snakeA);
}
if(!canMove(snakeA,snakeB)){
snakeA.remove(0);
snakeB.remove(0);
gameOver();
}
}
/**
* 游戏结束,gameover重新赋值true
*/
private void gameOver() {
gameover=true;
}
private boolean canMove(Snake snakeA,Snake snakeB){
if(outOfBounds(snakeB)||outOfBounds(snakeA)||coincide(snakeA,snakeB)){
return false;
}
return true;
}
private boolean outOfBounds(Snake snake22){
if(snake22.get(0).getCol()>=COLS||snake22.get(0).getCol()<0
||snake22.get(0).getRow()>=ROWS||snake22.get(0).getRow()<0){
return true;
}
return false;
}
private boolean coincide(Snake snakeA,Snake snakeB){
for(int i=snakeA.size()-1;i>2;i--){
if(snakeA.get(0).equals(snakeA.get(i))){
/*
* 重合
*/
return true;
}
}
for(int i=snakeB.size()-1;i>=0;i--){
if(snakeA.get(0).equals(snakeB.get(i))){
/*
* 重合
*/
return true;
}
}
return false;
}
/**
* 这个是游戏开始的方法
*/
private void startGameAction() {
snake1=Snake.start1();
/*snake1.add(0,new Cell(20,3,Game.snakeHead));*/
snake2=Snake.start2();
food1=getFoods(snake1,snake2);
/* System.out.println(food1);*/
food2=getFoods(snake1,snake2,food1);
SCORE=0;
str="初级";
}
/**
* 这个是生成food2的方法
* @param snake1
* @param snake2
* @param food1
* @return
*/
private Food getFoods(Snake snake1, Snake snake2, Food food1) {
Food food=null;
boolean used=true;
do{
food=Food.getFood();
if(food.getRow()!=food1.getRow()||food.getCol()!=food1.getCol()){
used=false;
}else{
continue;
}
for(Cell cells:snake1){
if(food.getRow()!=cells.getRow()||food.getCol()!=cells.getCol()){
used=false;
}else{
used=true;
}
}
if(used){
continue;
}
for(Cell cells:snake2){
if(food.getRow()!=cells.getRow()||food.getCol()!=cells.getCol()){
used=false;
}else{
used=true;
}
}
}while(used);
return food;
}
/**
* 这个是生成food1的方法
* @param snake1
* @param snake2
* @return
*/
private Food getFoods(Snake snake1,Snake snake2) {
Food food=null;
boolean used=true;
do{
food=Food.getFood();
for(int i=snake1.size()-1;i>=0;i--){
if(food.getRow()!=snake1.get(i).getRow()||food.getCol()!=snake1.get(i).getCol()){
used=false;
break;
}
}
if(used){
continue;
}
for(int i=snake2.size()-1;i>=0;i--){
if(food.getRow()!=snake1.get(i).getRow()||food.getCol()!=snake1.get(i).getCol()){
used=false;
break;
}else{
used=true;
}
}
}while(used);
return food;
}
/**
* 主方法,画出面板,让后把墙放在面板上,调用流程控制方法action
* @param args
*/
public static void main(String[] args){
JFrame jframe=new JFrame();
Game game=new Game();
jframe.setSize(815,625);
jframe.setTitle("双龙戏珠");
jframe.add(game);
jframe.setLocationRelativeTo(null);
jframe.setVisible(true);
jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
game.action();
}
}