以前写的一个贪吃蛇,比较适合初学者,并且里面用到了JDK1.5的很多新的东西,比如枚举,泛型,增强for循环,静态导入等等,希望能对初学者有一定的帮助.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
import static java.lang.Math.*;//静态导入
/*
* 此类是贪吃蛇的简单实现方法
* 自己可以加入在开始时的设置,比如
* 选关,初始的蛇的长度等等
* 作者:千里冰封
* 日期:2006年6月25日15:47
*/
public class Snake extends JPanel{
private Direction dir;//要走的方向
private int blockWidth=10;//块大小
private int blockSpace=2;//块之间的间隔
private long sleepTime;//重画的进间间隔
private MySnake my;
private int total;//代表蛇的长度
private Rectangle food;//代表蛇的食物
private volatile boolean go;
private int round;//表示第几关
public Snake(JFrame jf){
initOther();
//为顶级窗口类JFrame添加事件处理函数
jf.addKeyListener(new KeyAdapter(){
public void keyReleased(KeyEvent ke){
int code=ke.getKeyCode();
if(code==KeyEvent.VK_RIGHT){
if(dir!=Direction.WEST)
dir=Direction.EAST;
}
else if(code==KeyEvent.VK_LEFT){
if(dir!=Direction.EAST)
dir=Direction.WEST;
}
else if(code==KeyEvent.VK_UP){
if(dir!=Direction.SOUTH)
dir=Direction.NORTH;
}
else if(code==KeyEvent.VK_DOWN){
if(dir!=Direction.NORTH)
dir=Direction.SOUTH;
}
else if(code==KeyEvent.VK_ENTER){
if(!go)
initOther();
}
}
});
this.setBounds(300,300,400,400);
this.setVisible(true);
}
//随机生成一个食物的位置
private void makeFood(){
int x=40+(int)(random()*30)*12;
int y=10+(int)(random()*30)*12;
food=new Rectangle(x,y,10,10);
}
//做一些初始化的工作
private void initOther(){
dir=Direction.EAST;
sleepTime=500;
my=new MySnake();
makeFood();
total=3;
round=1;
new Thread(new Runnable(){
public void run(){
go=true;
while(go){
try{
Thread.sleep(sleepTime);
repaint();
}
catch(Exception exe){
exe.printStackTrace();
}
}
}
}).start();
}
//处理多少关的函数
private void handleRound(){
if(total==6){
round=2;
sleepTime=300;
}
else if(total==10){
round=3;
sleepTime=200;
}
else if(total==15){
round=4;
sleepTime=100;
}
else if(total==18){
round=5;
sleepTime=50;
}
else if(total==20){
round=6;
sleepTime=20;
}
else if(total>21){
round=7;
sleepTime=15;
}
}
//把自己的组件全部画出来
public void paintComponent(Graphics g){
g.setColor(Color.PINK);
g.fillRect(0,0,this.getWidth(),this.getHeight());
g.setColor(Color.BLACK);
g.drawRect(40,10,358,360);
if(go){
my.move();
my.draw(g);
g.setFont(new Font("黑体",Font.BOLD,20));
g.drawString("您的得分:"+(total*10)+" 第"+round+"关",40,400);
}
else{
g.setFont(new Font("黑体",Font.BOLD,20));
g.drawString("游戏结束,按回车(ENTER)键重玩!",40,440);
}
g.setColor(Color.RED);
g.fillRect(food.x,food.y,food.width,food.height);
}
private class MySnake{
private ArrayList<Rectangle> list;
public MySnake(){
list=new ArrayList<Rectangle>();
list.add(new Rectangle(160+24,130,10,10));
list.add(new Rectangle(160+12,130,10,10));
list.add(new Rectangle(160,130,10,10));
}
//蛇移动的方法
public void move(){
if(isDead()){
go=false;
return;
}
if(dir==Direction.EAST){
Rectangle rec=list.get(0);
Rectangle rec1=new Rectangle(rec.x+(blockWidth+blockSpace),rec.y,rec.width,rec.height);
list.add(0,rec1);
}
else if(dir==Direction.WEST){
Rectangle rec=list.get(0);
Rectangle rec1=new Rectangle(rec.x-(blockWidth+blockSpace),rec.y,rec.width,rec.height);
list.add(0,rec1);
}
else if(dir==Direction.NORTH){
Rectangle rec=list.get(0);
Rectangle rec1=new Rectangle(rec.x,rec.y-(blockWidth+blockSpace),rec.width,rec.height);
list.add(0,rec1);
}
else if(dir==Direction.SOUTH){
Rectangle rec=list.get(0);
Rectangle rec1=new Rectangle(rec.x,rec.y+(blockWidth+blockSpace),rec.width,rec.height);
list.add(0,rec1);
}
if(isEat()){
handleRound();
makeFood();
}
else{
list.remove(list.size()-1);
}
}
//判断是否吃到了食物
private boolean isEat(){
if(list.get(0).contains(food)){
total++;
return true;
}
else
return false;
}
//判断是否死了,如果碰壁或者自己吃到自己都算死了
private boolean isDead(){
Rectangle temp=list.get(0);
if(dir==Direction.EAST){
if(temp.x==388)
return true;
else{
Rectangle comp=new Rectangle(temp.x+12,temp.y,10,10);
for(Rectangle rec:list){
if(rec.contains(comp))
return true;
}
}
return false;
}
else if(dir==Direction.WEST){
if(temp.x==40)
return true;
else {
Rectangle comp=new Rectangle(temp.x-12,temp.y,10,10);
for(Rectangle rec:list){
if(rec.contains(comp))
return true;
}
}
return false;
}
else if(dir==Direction.NORTH){
if(temp.y==10)
return true;
else{
Rectangle comp=new Rectangle(temp.x,temp.y-12,10,10);
for(Rectangle rec:list){
if(rec.contains(comp))
return true;
}
}
return false;
}
else if(dir==Direction.SOUTH){
if(temp.y==358)
return true;
else{
Rectangle comp=new Rectangle(temp.x,temp.y+12,10,10);
for(Rectangle rec:list){
if(rec.contains(comp))
return true;
}
}
return false;
}
else{
return false;
}
}
//把自己画出来
public void draw(Graphics g){
for(Rectangle rec:list){
g.fillRect(rec.x,rec.y,rec.width,rec.height);
}
}
}
public static void main(String arsg[]){
JFrame jf=new JFrame("贪吃蛇");
Snake s=new Snake(jf);
jf.getContentPane().add(s,BorderLayout.CENTER);
jf.setBounds(300,300,500,500);
jf.setVisible(true);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
//定义一个枚举,在此也可以用接口或者常量值代替
enum Direction{
EAST,
SOUTH,
WEST,
NORTH;
}
尽管千里冰封
依然拥有晴空
你我共同品味JAVA的浓香.
posted on 2007-08-30 10:34
千里冰封 阅读(561)
评论(2) 编辑 收藏 所属分类:
JAVASE