snake 包括几个属性

1.move       移动   

2.draw       画出自己

3.changeDirection  改变方向

4.isEatBody 吃到了自己

5.isEatFood 迟到了食物

6.isEatRock 吃到了石头

-------------------------------------------------------------------------------------------------------------------------------------

Food   包括几个属性

1.draw       画出自己 

2.isSnakeEatFood 蛇迟到了自己

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------

Ground    包括几个属性

1.draw       画出自己

2.isSnakeEatRock 蛇迟到了自己

---------------------------------------------------------------------------------------------------------------------------------------

GamePanel   包括几个属性

1.redisplay    重新画出蛇,食物,石头

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------

自己定义的监听器部分 分为4部分,

1 建立侦听接口,例如下边的snakelistener

2 控制继承接口,后实现接口类中定义的方法 ,例如下边的controller

3 在第三个类中添加监听器,并且定义添加监听器的方法addactivelistener123(snakelistener l),例如下边的snake

4 为其他的类中addactivelistener123(controller)


1.监听接口SnakeListener 

public interface SnakeListener {
void snakeMoveddisplay();                //接口只定义方法,没有方法体
}

2.控制类 controller  SnakeListener 

@Override

public void snakeMoveddisplay() {                    //实现方法体
// TODO Auto-generated method stub
gamepanel.display(snake,food,ground);
}

-------------------------------------------------------------------------------------------------------------------------------------------------------------------
3.Snake


             public void addSnakeListener(SnakeListener l){                                               //定义向监听器集合中添加监听器的方法

                   if(l!=null)
                      this.listeners.add(l);

             --------------------------------------------------------------------------------------------------------------------------------
            for(SnakeListener l :listeners){                                       //遍历监听器集合,如果有就触发,执行如下方法
l.snakeMoveddisplay();
}

-------------------------------------------------------------------------------------------------------------------------------------------------------------

4.GameFrame 主窗体

sanke.addSnakeListener(controller)


------------------------------

snake

-------------------------------


package com;


import java.awt.Graphics;
import java.awt.Point;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Set;

public class Snake {
private Set<SnakeListener> listeners = new HashSet<SnakeListener>();


public void changeDirection(){
System.out.println("snake 's changedirection");
}

public void isEatBody(){
System.out.println("snake's isEatBody");
}

public void eatFood(){
System.out.println("snake's eatfood");
}

public void move(){
System.out.println("snake move");

}

//定义一个线程,让蛇不停的移动
private class SnakeDriver implements Runnable{
public void run(){
while(true){
move();
//触发监听事件
for(SnakeListener l :listeners){
l.snakeMoveddisplay();
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}

public void addSnakeListener(SnakeListener l){
if(l!=null)
this.listeners.add(l);

}

public void draw(){
System.out.println("my name is a snake");
}

//启动线程的方法,让蛇开始走
public void start(){
new Thread(new SnakeDriver()).start();
}

}

------------------------------

food

-------------------------------

package com;




public class Food {




public boolean isSnakeEatFood(Snake snake){


System.out.println("food's issnakeeatfood");


return false;


}




public void draw(){


System.out.println("food draw");


}


}


------------------------------

ground

-------------------------------

package com;




public class Ground {






public boolean isSnakeEatRock(Snake snake){


System.out.println("Ground's issankeeatrock");


return false;


}




public void draw(){


System.out.println("rock 's drawME");


}


}


------------------------------

gamepanel

-------------------------------

package com;




import java.awt.Color;


import java.awt.Graphics;


import java.awt.Image;




import javax.swing.JPanel;


import javax.swing.border.EtchedBorder;




import cn.snake;






/**


 * 游戏的显示界面<BR>


 * 可以用 setBackgroundColor() 设置游戏的背景色


 * 


 * @version 1.0, 15/04/18


 * 


 * @author 刘洋


 * 


 */


public class GamePanel extends JPanel {




   //先定义,然后通过display传参对sanke等赋值,使整个程序的snake food等统一。


private Snake snake;


 

private Food food;


 

private Ground ground;


 



 

//display 后边更的是参数,目的是为了给上边的private snake等赋值,


 

//由于display是在controller中用到,所以通过赢引用参数赋值后的,本类中的snake,food,


 

//就是controller中定义的snake,food


public void display(Snake snake,Food food,Ground ground){


System.out.println("gamepanel's display");




this.snake = snake;



this.food = food;


this.ground = ground;


this.repaint();






@Override


protected void paintComponent(Graphics g) {


// TODO Auto-generated method stub


this.snake.draw();


this.food.draw();


System.out.println("repaint");


this.ground.draw();


}



------------------------------

SnakeListener 

-------------------------------

package com;


public interface SnakeListener {
void snakeMoveddisplay();
}

------------------------------

controller 

-------------------------------

package com;




import com.Food;


import com.GamePanel;


import com.Ground;


import com.Snake;


import com.SnakeListener;




public class controller implements SnakeListener{




//controller这里我们也定义了snake,food等,但是在本类里没有被new,或赋值,我们还需要将已经复制或new的snake,food传进来。


private Snake snake ;


 

private Food food ;


 

private Ground ground ;


GamePanel gamepanel;






@Override


public void snakeMoveddisplay() {


// TODO Auto-generated method stub


gamepanel.display(snake,food,ground);


}




//测试的时候主窗口中new sanke 、new food,而且在主窗口中调用controller(snake,。。)这里就是通过controller进行传参。


public controller(Snake snake, Food food, Ground ground, GamePanel gamepanel) {


super();


this.snake = snake;


this.food = food;


this.ground = ground;


this.gamepanel = gamepanel;


}




public void newgame(){


//定义什么时候为开始游戏呢?蛇开始走的时候。


snake.start();


}






}



------------------------------

gameframe                  测试的窗体,如果不用frame和add(gamepanel,B),那么gamepanel的repain()重绘图就不好使。记住

-------------------------------

package com;




import java.awt.BorderLayout;




import javax.swing.JFrame;




public class

gameframe  {








public static void main(String[] args){




Snake snake = new Snake();


Food food = new Food();


Ground ground = new Ground();


   GamePanel gamepanel= new GamePanel();


controller cont = new controller(snake,food,ground,gamepanel);


snake.addSnakeListener(cont);




javax.swing.JFrame frame= new  JFrame();


frame.setSize(300,300);


frame.add(gamepanel,BorderLayout.CENTER);


frame.setVisible(true);


cont.newgame();


}


}


以上仅是一个简单的思路还需要进一步的扩展,实现效果为

执行gameframe后会打出如下内容

snake move
gamepanel's display
my name is a snake
food draw
repaint
rock 's drawME
my name is a snake
food draw
repaint
rock 's drawME
snake move
gamepanel's display
my name is a snake
food draw
repaint

实现蛇每移动一次,gamepanel就重新显示一遍snake food ground