import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.geom.Rectangle2D;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
class GamePanel extends JPanel
{
private int blockNum=4; //蛇的长度(初始为4格长)
private String dir="right"; //蛇的运动方向,初始时为右
private String tempdir=""; //当第一次方向键按下时的临时方向标记
private String tempdir2=""; //当第二次方向键按下时的临时方向标记
private int changeSec=0; //变换方向的时间标志
private int changeSec2=0; //第二次变换方向的时间标志
// private final int panelWidth = 440, panelHeight = 320;
private Timer timer; //蛇速度timer
private int DELAY = 400; //timer 时间间隔
private int x[]=new int[blockNum]; //蛇每个格的x坐标
private int y[]=new int[blockNum]; //蛇每个格的y坐标
private int mx=100,my=100; //产生小方格的坐标
private int moveX, moveY; //格的边长
private boolean IsGameOver=false; //游戏是否结束标记
private ImageIcon image1;
private ImageIcon image2;
private ImageIcon image3;
private ImageIcon image4;
private ImageIcon imageM;
/**
* 面板构造函数,初始化面板
*/
public GamePanel()
{
image1 = new ImageIcon("./ball1.png");
image2 = new ImageIcon("./ball2.png");
image3 = new ImageIcon("./ball3.png");
image4 = new ImageIcon("./ball4.png");
imageM = new ImageIcon("./ballM.png");
timer = new Timer(DELAY, new ReboundListener());
setBackground(Color.BLACK);
for(int i=0;i<blockNum;i++) //游戏初始状态为蛇向右移动
{
x[i] = 40-i*10;
y[i] = 180;
}
moveX = moveY = 10;
// setPreferredSize(new Dimension(panelWidth, panelHeight));
timer.start();
}
public void setDir(String d)
{
if(changeSec==0||changeSec2==0) //当正在转向时,则按下方向键无效!
{
if(tempdir=="")
{
tempdir=d;
}
else
{
tempdir2=d;
}
}
}
public void paintComponent(Graphics page)
{
super.paintComponent(page);
imageM.paintIcon(this, page, mx, my);
image1.paintIcon(this, page, x[0], y[0]);
image2.paintIcon(this, page, x[1], y[1]);
image3.paintIcon(this, page, x[2], y[2]);
image4.paintIcon(this, page, x[3], y[3]);
}
//timer事件
private class ReboundListener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
//IsGameOver为true时结束游戏
if(IsGameOver==true)
timer.stop();
//没按下方向键或按的方向与当前方向在同一直线上
if(tempdir==""||Comp(tempdir,dir))
{
if(move(0,blockNum,dir))
{
DisBlock();
}
}
else if(tempdir2=="")//初次变换方向
{
changeSec++;
if(changeSec<blockNum+1)
{
if(move(0,changeSec,tempdir))
{
DisBlock();
}
if(move(changeSec,blockNum,dir))
{
DisBlock();
}
}
else
{
if(move(0,blockNum,tempdir))
{
DisBlock();
}
dir=tempdir;
tempdir="";
changeSec=0;
}
}
else//在进行方向变换的同时,用户又按下方向键
{
changeSec++;
if(changeSec2==0) //如果值没有被设置过,则执行设置语句
{
changeSec2=changeSec-1;
}
if(changeSec<(changeSec2+4))
{
if(changeSec>blockNum)
{
if(move(0,changeSec-changeSec2,tempdir2))
{
DisBlock();
}
if(move(changeSec-changeSec2,blockNum,tempdir))
{
DisBlock();
}
}
else
{
if(move(0,changeSec-changeSec2,tempdir2))
{
DisBlock();
}
if(move(changeSec-changeSec2,changeSec,tempdir))
{
DisBlock();
}
if(move(changeSec,blockNum,dir))
{
DisBlock();
}
}
}
else
{
if(move(0,blockNum,tempdir2))
{
DisBlock();
}
dir=tempdir2;
tempdir="";
tempdir2="";
changeSec=0;
changeSec2=0;
}
}
repaint();
}
public boolean move(int min,int blockn,String d)
{
boolean flag=false;
int top=20; //蛇移动的上边界20
int bottom=340; //蛇移动的下边界340
int left=20; //蛇移动的左边界20
int right=460; //蛇移动的右边界460
if(d=="right")
{
for(int n=min;n<blockn;n++)
{
x[n] += moveX;
//判断蛇是否吃到了小方格
if(x[n]==mx&&y[n]==my)
flag=true;
else
flag=false;
}
//判断游戏是否结束
if(x[0]>right||y[0]>bottom||x[0]<left||y[0]<top)
{
IsGameOver=true;
}
}
else if(d=="left")
{
for(int n=min;n<blockn;n++)
{
x[n]-=moveX;
if(x[n]==mx&&y[n]==my)
flag=true;
else
flag=false;
}
//判断游戏是否结束
if(x[0]>right||y[0]>bottom||x[0]<left||y[0]<top)
{
IsGameOver=true;
}
}
else if(d=="up")
{
for(int n=min;n<blockn;n++)
{
y[n]-=moveY;
if(x[n]==mx&&y[n]==my)
flag=true;
else
flag=false;
}
//判断游戏是否结束
if(x[0]>right||y[0]>bottom||x[0]<left||y[0]<top)
{
IsGameOver=true;
}
}
else if(d=="down")
{
for(int n=min;n<blockn;n++)
{
y[n]+=moveY;
if(x[n]==mx&&y[n]==my)
flag=true;
else
flag=false;
}
//判断游戏是否结束
if(x[0]>right||y[0]>bottom||x[0]<left||y[0]<top)
{
IsGameOver=true;
}
}
return flag;
}
//用于比较dir1和dir2两个方向是否在同一直线上
public boolean Comp(String dir1,String dir2)
{
if(dir1==dir2)
{
return true;
}
else if(dir1=="right"&&dir2=="left")
{
return true;
}
else if(dir1=="left"&&dir2=="right")
{
return true;
}
else if(dir1=="up"&&dir2=="down")
{
return true;
}
else if(dir1=="down"&&dir2=="up")
{
return true;
}
else
{
return false;
}
}
//产生新的小方格
public void DisBlock()
{
mx=((int)Math.round(Math.random()*25+5))*10;
my=((int)Math.round(Math.random()*35+5))*10;
}
}
}
class GameFrame extends JFrame
{
private final int WIDTH =500;
private final int HEIGHT = 400;
private GamePanel panel;
public GameFrame()
{
Toolkit kit = Toolkit.getDefaultToolkit();
Dimension screenSize = kit.getScreenSize();
int width = screenSize.width;
int height = screenSize.height;
int x = (width - WIDTH)/2;
int y = (height - HEIGHT)/2;
setLocation(x, y);
setSize(WIDTH, HEIGHT);
setTitle("贪吃蛇");
setResizable(false);
requestFocus();
Container con = getContentPane();
panel = new GamePanel();
con.add(panel);
addKeyListener(new KeyAdapter()
{
public void keyPressed(KeyEvent e)
{
if (e.getKeyCode() == 87) //上方向键(w)按下时
{
panel.setDir("up");
}
else if(e.getKeyCode()==83) //下方向键(s)按下时
{
panel.setDir("down");
}
else if(e.getKeyCode()==65) //左方向键(a)按下时
{
panel.setDir("left");
}
else if(e.getKeyCode()==68) //右方向键(d)按下时
{
panel.setDir("right");
}
//System.out.println(e.getKeyCode());
}
});
}
}
public class Snake
{
public static void main(String args[])
{
GameFrame frame = new GameFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.show();
frame.setVisible(true);
}
}