package snake.game;



 

import java.awt.CardLayout;

import java.awt.Color;

import java.awt.Graphics;

 

import java.awt.Image;

import java.awt.Insets;

import java.awt.Point;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import java.awt.event.KeyEvent;

import java.awt.event.KeyListener;

import java.awt.event.MouseEvent;

import java.awt.event.MouseListener;

import java.io.File;

import java.io.IOException;

import java.util.ArrayList;

import java.util.Timer;



import javax.imageio.ImageIO;

import javax.swing.JButton;

import javax.swing.JFrame;

import javax.swing.JLabel;

import javax.swing.JOptionPane;

import javax.swing.JPanel;



public class SnakeGame implements ActionListener,KeyListener,MouseListener{



private long initTime ;

SnakeGame.InterClassSnake innerSnake;

boolean signal=false;

private Timer  tim;

int douX=120,douY=120,direct;

private ArrayList<Point>  snake = new ArrayList<Point>();

JFrame jf = new JFrame("贪吃蛇游戏");

JPanel  mainPane = new JPanel();

//欢迎界面、开始界面、游戏界面

WelcomPanel  wp = new WelcomPanel();

StartPanel  sp = new StartPanel();

JPanel  gamePane= new JPanel();

 

BallDemo bd ;


JButton [] btns = {new JButton("下一步"),new JButton("上一步"),new JButton("开始")};

Color[] yanse = {Color.black,Color.blue,Color.cyan,Color.green};

CardLayout gld= new CardLayout();

{

snake.add(new Point(90,150));

snake.add(new Point(90,120));

snake.add(new Point(90,90));

snake.add(new Point(90,60));

snake.add(new Point(90,30));


wp.setLayout(null);

wp.setBounds(0, 0, 500, 450);

btns[0].setMargin(new Insets(0,0,0,0));

btns[0].setBounds(350, 350, 50, 30); 

wp.add(btns[0]);



sp.setLayout(null);

sp.setBounds(0, 0, 500, 450);

btns[1].setMargin(new Insets(0,0,0,0));

btns[1].setBounds(300, 350, 50, 30);

btns[2].setMargin(new Insets(0,0,0,0));

btns[2].setBounds(350, 350, 50, 30);

sp.add(btns[1]);

sp.add(btns[2]);

 

btns[0].addActionListener(this);

btns[1].addActionListener(this);

btns[2].addActionListener(this);


gamePane.addMouseListener(this);

jf.addKeyListener(this);

mainPane.setLayout(gld); 

mainPane.add(wp,"1"); 

mainPane.add(sp, "2");

mainPane.add(gamePane, "3");

bd=new BallDemo(500,450,gamePane);

mainPane.setSize(500,450);

mainPane.setVisible(true);

}

public SnakeGame(){

innerSnake =this. new InterClassSnake();

jf.add(mainPane);

jf.setSize(500, 450);

jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

jf.setVisible(true);

}

/**

* @param args

*/

public static void main(String[] args) { 

     

       

        

SnakeGame sg=new SnakeGame();


 

@Override

public void actionPerformed(ActionEvent e) {

if(e.getSource()==btns[0]){

gld.show(mainPane, "2");

}

if(e.getSource()==btns[1]){

gld.show(mainPane, "1");

}

if(e.getSource()== btns[2]){

gld.show(mainPane, "3");

initTime=System.currentTimeMillis();

tim = new Timer();

tim.scheduleAtFixedRate(new TimerCounts(initTime), 0,50000); //间隔大概10分钟提醒一次 

innerSnake.setDaemon(true);

innerSnake.start();

}


}


    class InterClassSnake extends Thread {

   

        int tempDouX,tempDouY;

        

    public void run(){

    while(true){

   

    this.displaySnake(gamePane.getGraphics());

    this.displayDou(gamePane.getGraphics());

       if(signal){moveSnake();signal=false;gamePane.repaint();  }

           if(this.isEatDou()){

            snake.add(0, new Point(douX,douY));System.out.println("hello world 1");

            makeDou();          

           }

           if(this.isEatSelf() || this.isOverBounds()){System.out.println("hello world 2");

            JOptionPane.showMessageDialog(null, "你玩完了");

            System.exit(0);

           }

    }

    }

   /*造豆和造蛇、显示蛇、显示豆子函数*/ 

  public void makeDou(){

 douX=(int)((int)(Math.random()*10));

 douY=(int)((int)(Math.random()*8));

     if(douX>15)douX=douX-4;

     if(douY>14)douY=douY-4;

     douX=douX*30;douY=douY*30;

     for(Point x:snake){

    int tempX=x.x;

    int tempY=x.y;

    if(tempX==douX&&tempY==douY){   

   makeDou(); 

    }

       }

   }

   public void displaySnake(Graphics g){

  for(Point pos:snake){

  if(pos==snake.get(0)){

  g.setColor(Color.green);  

  g.fillRect(pos.x, pos.y, 30, 30);  

  }  

  else

      g.setColor(Color.red);  

      g.fillRect(pos.x, pos.y, 30, 30);

   }

   }

   public void displayDou(Graphics g){

       g.setColor(gamePane.getBackground());

       g.drawRect(tempDouX, tempDouY, 30, 30);

      g.setColor(Color.blue);

       g.fillRect(douX, douY, 30, 30);

       tempDouX=douX;tempDouY=douY;

   }

   //eat the bean ,return true if eat successfully,otherwise return false;

   public boolean  isEatDou(){

   if(douX==snake.get(0).x && douY==snake.get(0).y){

     return true;

    }

    return false;

   }

        public boolean isEatSelf(){

       int x=snake.get(0).x , y =snake.get(0).y;

        for(int i=snake.size()-1;i>1;i--){

      if(x==snake.get(i).x && y==snake.get(i).y)

        return true;

       }

     return false;

       }

       public boolean isOverBounds(){

         int x=snake.get(0).x,y=snake.get(0).y;

       if(x<0 || x>480 || y<0 ||y>450)

        return true;

       return false;

       }

 public void moveSnake(){ 

for(int i =snake.size()-1;i>0;i--){

snake.get(i).x=snake.get(i-1).x;

snake.get(i).y=snake.get(i-1).y;

int tx=snake.get(0).x  ,  ty=snake.get(0).y;

switch(direct){

case  1:  if(snake.get(1).y<snake.get(0).y){System.out.println("不能往上");}

         else ty -=30;

          break;

case  2: if(tx-snake.get(1).x==0){

        tx=tx-30;   

        }

        else{

        ty=ty+30;  

        }         

        break;

case  3: if(tx-snake.get(1).x==0){

               tx=tx+30;   

                }

                else{

               ty=ty-30;    

                }        

                break;

case 4: if(snake.get(1).y>snake.get(0).y){System.out.println("不能往下");} 

       else  ty += 30;

case  5: 

                     break;

}

snake.remove(snake.size()-1);  

snake.add(0, new Point(tx,ty));

 

  }

    }

@Override

public void keyTyped(KeyEvent e) {

}

@Override

public void keyPressed(KeyEvent e) {

signal = true; 

switch(e.getKeyCode()){

   case  KeyEvent.VK_UP:   direct=1;                      

                      break;

   case  KeyEvent.VK_LEFT: direct =2;

                      break;

   case  KeyEvent.VK_RIGHT: direct =3;

                      break;

   case  KeyEvent.VK_DOWN: direct =4;

                           break;

   default :direct=5;

     

}


}

@Override

public void keyReleased(KeyEvent e) {

 


}

@Override

public void mouseClicked(MouseEvent e) {

// TODO Auto-generated method stub


}

@Override

public void mousePressed(MouseEvent e) {

// TODO Auto-generated method stub


}

@Override

public void mouseReleased(MouseEvent e) {

// TODO Auto-generated method stub


}

@Override

public void mouseEntered(MouseEvent e) {

// TODO Auto-generated method stub


}

@Override

public void mouseExited(MouseEvent e) {

// TODO Auto-generated method stub


}

class BallDemo {  //小球运动,

   private   int  x=50;  //初始位置

   private   int  y=50;

   private  final int  XSIZE=30;

   private  final int  YSIZE=30;

   private    int  dx=2;

   private    int  dy=2;

   private  int  tempX=50;

   private  int  tempY=50;

   private  final int retangleX;

   private  final int retangleY;

   private  JPanel pane; //用于得到背景面板

   private  Color  c=new Color(5);

   public BallDemo(int x,int y,JPanel jtp){

   retangleX=x;

   retangleY=y;

   this.pane=jtp;

   }

 

   public void left(){

       x -= dx;

   }

   public void right(){

       x += dx;

   }

   public void  up(){

       y -= dy;

   }

   public void  down(){

       y += dy;

   }

   public void move(){

       x += dx;

       y += dy;

       if(x<2){

          dx = -dx;

       }

       if(x+XSIZE>retangleX){

           dx = -dx;

       }

       if(y<YSIZE){  

           dy =  -dy;

       }

       if(y+YSIZE>=retangleY){            

          dy = -dy;

       }

   }

   protected void setColor(Color co){

   this.c=co;

   }

   public void paint(Graphics g){

       g.setColor(pane.getBackground());  //这条语句用于擦除小球轨迹,让这条语句不起作用你就知道了

       g.fillOval(tempX, tempY, XSIZE, YSIZE);

       g.setColor(c);       

       g.fillOval(x, y, XSIZE, YSIZE);

       tempX=x;tempY=y;

        

   }  

   

}

//定时器类,工作任务类

class  TimerCounts extends  java.util.TimerTask{


private long init;

private JFrame jf=new JFrame("游戏时间提示框");

private JLabel label = new JLabel ();

public TimerCounts(long i){

this.init=i;

jf.setSize(200, 100);

jf.add(label);

jf.setVisible(true);

}

@Override

public  void run(){

long j=System.currentTimeMillis();

byte tim =(byte)( (j-init)/6000); //minutes

if(tim>=20){

JOptionPane.showMessageDialog(null,"你已经玩了很久了,要退出游戏休息了");

System.exit(0);

}

else{

   label.setText("游戏时间已经过了"+tim+"分钟");

}


}

}



//欢迎界面

class  WelcomPanel extends JPanel{


private static final long serialVersionUID = 1L;

Image img;

WelcomPanel(){

try{

img = ImageIO.read(new File("e:\\ok1.jpg"));

}catch(IOException e){

System.out.println("welcompanel");

}

}

@Override

public void paintComponent(Graphics g){

super.paintComponent(g);

g.drawImage(img, getX(), getY(), null);

}

}

//开始界面

class  StartPanel extends JPanel{


private static final long serialVersionUID = 1L;

Image img;

StartPanel(){

try{

img = ImageIO.read(new File("e:\\ok2.jpg"));

}catch(IOException e){

System.out.println("startpanel");

}

}

@Override

public void paintComponent(Graphics g){

super.paintComponent(g);

g.drawImage(img, getX(), getY(), null);

}

}