用户注册



邮箱:

密码:

用户登录


邮箱:

密码:
记住登录一个月忘记密码?

发表随想


还能输入:200字
云代码 - java代码库

贪吃蛇代码

2017-04-10 作者:云代码会员举报

[java]代码库

import java.awt.*; 
import java.awt.event.*; 
import javax.swing.*; 
import java.util.*; 
//============================================= 
//Main Class 
//============================================= 
public class GreedSnake implements KeyListener 
{ 
JFrame mainFrame; 
Canvas paintCanvas; 
JLabel label得分;//计分牌 
SnakeModel snakeModel=null;// 蛇 
public static final int canvasWidth=200; 
public static final int canvasHeight=300; 
public static final int nodeWidth=10; 
public static final int nodeHeight=10; 
//---------------------------------------------------------------------- 
//GreedSnake():初始化游戏界面 
//---------------------------------------------------------------------- 
public GreedSnake() 
{ 
//设置界面元素 
mainFrame=new JFrame("贪吃蛇"); 
Container cp=mainFrame.getContentPane(); 
label得分=new JLabel("得分:"); 
cp.add(label得分,BorderLayout.NORTH); 
paintCanvas=new Canvas(); 
paintCanvas.setSize(canvasWidth+1,canvasHeight+1); 
paintCanvas.addKeyListener(this); 
cp.add(paintCanvas,BorderLayout.CENTER); 
JPanel panelButtom=new JPanel(); 
panelButtom.setLayout(new BorderLayout()); 
JLabel labelHelp;// 帮助信息 
labelHelp=new JLabel("上下加速;",JLabel.CENTER); 
panelButtom.add(labelHelp,BorderLayout.NORTH); 
labelHelp=new JLabel("确认,R,S开始;",JLabel.CENTER); 
panelButtom.add(labelHelp,BorderLayout.CENTER); 
labelHelp=new JLabel("空格或者P暂停,卢奇",JLabel.CENTER); 
panelButtom.add(labelHelp,BorderLayout.SOUTH); 
cp.add(panelButtom,BorderLayout.SOUTH); 
mainFrame.addKeyListener(this); 
mainFrame.pack(); 
mainFrame.setResizable(false); 
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
mainFrame.setVisible(true); 
begin(); 
} 
//---------------------------------------------------------------------- 
//keyPressed():按键检测 
//---------------------------------------------------------------------- 
public void keyPressed(KeyEvent e) 
{ 
int keyCode=e.getKeyCode(); 
if(snakeModel.running) switch(keyCode) 
{ 
case KeyEvent.VK_UP: 
snakeModel.changeDirection(SnakeModel.UP); 
break; 
case KeyEvent.VK_DOWN: 
snakeModel.changeDirection(SnakeModel.DOWN); 
break; 
case KeyEvent.VK_LEFT: 
snakeModel.changeDirection(SnakeModel.LEFT); 
break; 
case KeyEvent.VK_RIGHT: 
snakeModel.changeDirection(SnakeModel.RIGHT); 
break; 
case KeyEvent.VK_ADD: 
case KeyEvent.VK_PAGE_UP: 
snakeModel.speedUp();// 加速 
break; 
case KeyEvent.VK_SUBTRACT: 
case KeyEvent.VK_PAGE_DOWN: 
snakeModel.speedDown();// 减速 
break; 
case KeyEvent.VK_SPACE: 
case KeyEvent.VK_P: 
snakeModel.changePauseState();// 暂停或继续 
break; 
default: 
} 
//重新开始 
if(keyCode==KeyEvent.VK_R || keyCode==KeyEvent.VK_S 
|| keyCode==KeyEvent.VK_ENTER) 
{ 
snakeModel.running=false; 
begin(); 
} 
} 
//---------------------------------------------------------------------- 
//keyReleased():空函数 
//---------------------------------------------------------------------- 
public void keyReleased(KeyEvent e) 
{ 
} 
//---------------------------------------------------------------------- 
//keyTyped():空函数 
//---------------------------------------------------------------------- 
public void keyTyped(KeyEvent e) 
{ 
} 
//---------------------------------------------------------------------- 
//repaint():绘制游戏界面(包括蛇和食物) 
//---------------------------------------------------------------------- 
void repaint() 
{ 
Graphics g=paintCanvas.getGraphics(); 
//draw background 
g.setColor(Color.YELLOW); 
g.fillRect(0,0,canvasWidth,canvasHeight); 
//draw the snake 
g.setColor(Color.BLUE); 
LinkedList na=snakeModel.nodeArray; 
Iterator it=na.iterator(); 
while(it.hasNext()) 
{ 
Node n=(Node)it.next(); 
drawNode(g,n); 
} 
// draw the food 
g.setColor(Color.RED); 
Node n=snakeModel.food; 
drawNode(g,n); 
update得分(); 
} 
//---------------------------------------------------------------------- 
//drawNode():绘画某一结点(蛇身或食物) 
//---------------------------------------------------------------------- 
private void drawNode(Graphics g,Node n) 
{ 
g.fillRect(n.x*nodeWidth,n.y*nodeHeight,nodeWidth-1,nodeHeight-1); 
} 
//---------------------------------------------------------------------- 
//update得分():改变计分牌 
//---------------------------------------------------------------------- 
public void update得分() 
{ 
String s="得分: "+snakeModel.得分; 
label得分.setText(s); 
} 
//---------------------------------------------------------------------- 
//begin():游戏开始,放置贪吃蛇 
//---------------------------------------------------------------------- 
void begin() 
{ 
if(snakeModel==null||!snakeModel.running) 
{ 
snakeModel=new SnakeModel(this,canvasWidth/nodeWidth, 
this.canvasHeight/nodeHeight); 
(new Thread(snakeModel)).start(); 
} 
} 
//---------------------------------------------------------------------- 
//main():主函数 
//---------------------------------------------------------------------- 
public static void main(String[] args) 
{ 
GreedSnake gs=new GreedSnake(); 
} 
} 
/************************************************************************** 
*要点分析: 
*1)数据结构:matrix[][]用来存储地图上面的信息,如果什么也没有设置为false, 
* 如果有食物或蛇,设置为true;nodeArray,一个LinkedList,用来保存蛇的每 
* 一节;food用来保存食物的位置;而Node类是保存每个位置的信息。 
*2)重要函数: 
* changeDirection(int newDirection) ,用来改变蛇前进的方向,而且只是 
* 保存头部的前进方向,因为其他的前进方向已经用位置来指明了。 其中newDirection 
* 必须和原来的direction不是相反方向,所以相反方向的值用了同样的奇偶性。在测试 
* 的时候使用了direction%2!=newDirection%2 进行判断。 
* moveOn(),用来更新蛇的位置,对于当前方向,把头部位置进行相应改变。如果越界, 
* 结束;否则,检测是否遇到食物(加头部)或身体(结束);如果什么都没有,加上头部, 
* 去掉尾部。由于用了LinkedList数据结构,省去了相当多的麻烦。 
*************************************************************************/ 
 
//---------------------------------------------------------------------- 
//Node:结点类 
//---------------------------------------------------------------------- 
class Node 
{ 
int x; 
int y; 
Node(int x,int y) 
{ 
this.x=x; 
this.y=y; 
} 
} 
//---------------------------------------------------------------------- 
//SnakeModel:贪吃蛇模型 
//---------------------------------------------------------------------- 
class SnakeModel implements Runnable 
{ 
GreedSnake gs; 
boolean[][] matrix;// 界面数据保存在数组里 
LinkedList nodeArray=new LinkedList(); 
Node food; 
int maxX;//最大宽度 
int maxY;//最大长度 
int direction=2;//方向 
boolean running=false; 
int timeInterval=200;// 间隔时间(速度) 
double speedChangeRate=0.75;// 速度改变程度 
boolean paused=false;// 游戏状态 
int 得分=0; 
int countMove=0; 
// UP和DOWN是偶数,RIGHT和LEFT是奇数 
public static final int UP=2; 
public static final int DOWN=4; 
public static final int LEFT=1; 
public static final int RIGHT=3; 
//---------------------------------------------------------------------- 
//GreedModel():初始化界面 
//---------------------------------------------------------------------- 
public SnakeModel(GreedSnake gs,int maxX,int maxY) 
{ 
this.gs=gs; 
this.maxX=maxX; 
this.maxY=maxY; 
matrix=new boolean[maxX][]; 
for(int i=0;i<maxX;++i) 
{ 
matrix[i]=new boolean[maxY]; 
Arrays.fill(matrix[i],false);// 没有蛇和食物的地区置false 
} 
//初始化贪吃蛇 
int initArrayLength=maxX>20 ? 10 : maxX/2; 
for(int i=0;i<initArrayLength;++i) 
{ 
int x=maxX/2+i; 
int y=maxY/2; 
nodeArray.addLast(new Node(x,y)); 
matrix[x][y]=true;// 蛇身处置true 
} 
food=createFood(); 
matrix[food.x][food.y]=true;// 食物处置true 
} 
//---------------------------------------------------------------------- 
//changeDirection():改变运动方向 
//---------------------------------------------------------------------- 
public void changeDirection(int newDirection) 
{ 
if(direction%2!=newDirection%2)// 避免冲突 
{ 
direction=newDirection; 
} 
} 
//---------------------------------------------------------------------- 
//moveOn():贪吃蛇运动函数 
//---------------------------------------------------------------------- 
public boolean moveOn() 
{ 
Node n=(Node)nodeArray.getFirst(); 
int x=n.x; 
int y=n.y; 
switch(direction) 
{ 
case UP: 
y--; 
break; 
case DOWN: 
y++; 
break; 
case LEFT: 
x--; 
break; 
case RIGHT: 
x++; 
break; 
} 
if((0<=x&&x<maxX)&&(0<=y&&y<maxY)) 
{ 
if(matrix[x][y])// 吃到食物或者撞到身体 
{ 
if(x==food.x&&y==food.y)// 吃到食物 
{ 
nodeArray.addFirst(food);// 在头部加上一结点 
//计分规则与移动长度和速度有关 
int 得分Get=(10000-200*countMove)/timeInterval; 
得分+=得分Get>0 ? 得分Get : 10; 
countMove=0; 
food=createFood(); 
matrix[food.x][food.y]=true; 
return true; 
} 
else return false;// 撞到身体 
} 
else//什么都没有碰到 
{ 
nodeArray.addFirst(new Node(x,y));// 加上头部 
matrix[x][y]=true; 
n=(Node)nodeArray.removeLast();// 去掉尾部 
matrix[n.x][n.y]=false; 
countMove++; 
return true; 
} 
} 
return false;//越界(撞到墙壁) 
} 
//---------------------------------------------------------------------- 
//run():贪吃蛇运动线程 
//---------------------------------------------------------------------- 
public void run() 
{ 
running=true; 
while(running) 
{ 
try 
{ 
Thread.sleep(timeInterval); 
}catch(Exception e) 
{ 
break; 
} 
if(!paused) 
{ 
if(moveOn())// 未结束 
{ 
gs.repaint(); 
} 
else//游戏结束 
{ 
JOptionPane.showMessageDialog(null,"你傻逼啊这么简单都会死", 
"傻逼",JOptionPane.INFORMATION_MESSAGE); 
break; 
} 
} 
} 
running=false; 
} 
//---------------------------------------------------------------------- 
//createFood():生成食物及放置地点 
//---------------------------------------------------------------------- 
private Node createFood() 
{ 
int x=0; 
int y=0; 
do 
{ 
Random r=new Random(); 
x=r.nextInt(maxX); 
y=r.nextInt(maxY); 
}while(matrix[x][y]); 
return new Node(x,y); 
} 
//---------------------------------------------------------------------- 
//speedUp():加快蛇运动速度 
//---------------------------------------------------------------------- 
public void speedUp() 
{ 
timeInterval*=speedChangeRate; 
} 
//---------------------------------------------------------------------- 
//speedDown():放慢蛇运动速度 
//---------------------------------------------------------------------- 
public void speedDown() 
{ 
timeInterval/=speedChangeRate; 
} 
//---------------------------------------------------------------------- 
//changePauseState(): 改变游戏状态(暂停或继续) 
//---------------------------------------------------------------------- 
public void changePauseState() 
{ 
paused=!paused; 
} 
}


分享到:
更多

网友评论    (发表评论)

共6 条评论 1/1页

发表评论:

评论须知:

  • 1、评论每次加2分,每天上限为30;
  • 2、请文明用语,共同创建干净的技术交流环境;
  • 3、若被发现提交非法信息,评论将会被删除,并且给予扣分处理,严重者给予封号处理;
  • 4、请勿发布广告信息或其他无关评论,否则将会删除评论并扣分,严重者给予封号处理。