package SnakeGame;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
import java.awt.geom.*;
public class GameFrame extends JFrame {
private Toolkit tempKit; //这个类是抽象窗口工具包的所有实际实现的抽象超类。 Toolkit的子类用于将各种组件绑定到特定的本地工具包实现。
private int horizontalGrid, verticalGrid;
private int singleWidthX, singleHeightY;
private int cooPos;
private Snake mainSnake; //蛇类的实例化对象
private LinkedList eatedBean;
{
eatedBean = new LinkedList();
}
private Iterator snakeSq; //初始化迭代器
public javax.swing.Timer snakeTimer; //计时器,在没有发生方向改变的情况下,蛇身可以以某一速度不断移动
private int direction = 2; //初始化移动方向
private int score; //记录得分
private String info;
private Point bean, eatBean;
{
bean = new Point();
}
private boolean flag;
private JMenuBar infoMenu;
private JMenu[] tempMenu;
private JMenuItem[] tempMenuItem;
private JRadioButtonMenuItem[] levelMenuItem, versionMenuItem;
private JLabel scoreLabel;
{
scoreLabel = new JLabel();
}
private Graphics2D g;
private ImageIcon snakeHead;
{
snakeHead = new ImageIcon( "LOGO.gif" );
}
private ConfigMenu configMenu;
private boolean hasStoped = true;
public GameFrame()
{
this.tempKit = this.getToolkit();
this.setSize( tempKit.getScreenSize() );
this.setGrid( 60, 40, 5 );
this.getContentPane().setBackground( ColorGroup.COLOR_BACK );
this.setUndecorated( true );
this.setResizable( false );
this.addKeyListener( new KeyHandler() ); //加入键盘监听器
GameFrame.this.snakeTimer = new javax.swing.Timer( 80, new TimerHandler() );
this.getContentPane().add( scoreLabel, BorderLayout.SOUTH );
this.scoreLabel.setFont( new Font( "Fixedsys", Font.BOLD, 15 ) ); //设置分数记录Label的字体和字号
this.scoreLabel.setText( "Pause[SPACE] - Exit[ESC]" ); //空格键暂停,Esc按钮退出
this.configMenu = new ConfigMenu( this );
this.setVisible( true );
}
public void setGrid( int temp1, int temp2, int temp3 ) //设置格的大小,即蛇运动的标准
{
this.horizontalGrid = temp1; //水平格
this.verticalGrid = temp2; //垂直网格
this.singleWidthX = this.getWidth() / temp1;
this.singleHeightY = this.getHeight() / temp2;
this.cooPos = temp3;
}
private class KeyHandler extends KeyAdapter
{
public void keyPressed( KeyEvent e )
{
if( e.getKeyCode() == 27 ) //Esc键的处理方式
{
snakeTimer.stop();
if( JOptionPane.showConfirmDialog( null, "Are you sure to exit?" ) == 0 )
{
System.exit( 0 );
}
snakeTimer.start();
}
else if( e.getKeyCode() == 37 && mainSnake.snakeDirection != 2 )//left
{
direction = 4;
}
else if( e.getKeyCode() == 39 && mainSnake.snakeDirection != 4 )//right
{
direction = 2;
}
else if( e.getKeyCode() == 38 && mainSnake.snakeDirection != 3 )//up
{
direction = 1;
}
else if( e.getKeyCode() == 40 && mainSnake.snakeDirection != 1 )//down
{
direction = 3;
}
else if( e.getKeyCode() == 32 ) //设置space暂停键的处理方式
{
if( !hasStoped )
{
if( !flag ) //暂停
{
snakeTimer.stop();
configMenu.setVisible( true ); //菜单栏显示
configMenu.setMenuEnable( false ); //菜单栏速度、颜色不可修改
flag = true;
}
else //不暂停
{
snakeTimer.start();
configMenu.setVisible( false ); //菜单栏隐藏
configMenu.setMenuEnable( true );
flag = false;
}
}
}
}
}
private class TimerHandler implements ActionListener
{
public synchronized void actionPerformed( ActionEvent e )
{
Point temp = (Point) mainSnake.getLast();
snakeSq = mainSnake.iterator();
while ( snakeSq.hasNext() )
{
Point tempPoint = (Point)snakeSq.next();
if( temp.equals( tempPoint ) && snakeSq.hasNext() != false ) //游戏接下来的点在线性表中而且蛇身还没有结束
{
snakeTimer.stop();
stopGame();
JOptionPane.showMessageDialog( null,
"Your Score is " + score + ", You Loss!" );
}
}
System.out.println( temp.x + " " + temp.y ); //在框里输出
if( (temp.x == 0 && direction == 4) ||
(temp.x == horizontalGrid-1 && direction == 2) ||
(temp.y == 0 && direction == 1) ||
(temp.y == verticalGrid-1 && direction == 3) ) //撞墙
{
snakeTimer.stop();
stopGame();
JOptionPane.showMessageDialog( null,
"Your Score is " + score + ", You Loss!" );
}
if( direction != mainSnake.snakeReDirection )
{
moveSnake( direction );
}
mainSnake.drawSnake( getGraphics(), singleWidthX, singleHeightY, cooPos );
drawBeanAndEBean( getGraphics() );
}
}
public void stopGame()
{
this.hasStoped = true;
this.snakeTimer.stop();
Graphics2D g = (Graphics2D) GameFrame.this.getGraphics();
g.setColor( ColorGroup.COLOR_BACK );
super.paint( g );
configMenu.setVisible( true );
}
public void resetGame() //重置
{
System.gc();
this.hasStoped = false;
Graphics2D g = (Graphics2D) GameFrame.this.getGraphics();
g.setColor( ColorGroup.COLOR_BACK );
super.paint( g );
this.mainSnake = new Snake();
this.createBean( bean );
this.eatedBean.clear();
mainSnake.drawSnake( getGraphics(), singleWidthX, singleHeightY, cooPos );
this.snakeTimer.start();
this.direction = 2;
this.score = 0;
this.scoreLabel.setText( "Pause[SPACE] - Exit[ESC]" );
}
private void moveSnake( int direction ) //蛇的移动
{
if( mainSnake.checkBeanIn( this.bean ) ) //每吃一个豆,分数加一百
{
this.score += 100;
this.scoreLabel.setText( this.info + " Current Score:" + this.score );
this.eatedBean.add( new Point(this.bean) );
this.createBean( this.bean );
}
mainSnake.changeDirection( (Point) mainSnake.getLast(), direction );
Point temp = (Point) mainSnake.getFirst();
if( eatedBean.size() != 0 )
{
if( eatedBean.getFirst().equals( temp ) )
{
eatedBean.remove( 0 );
}
else
{
mainSnake.clearEndSnakePiece( getGraphics(), temp.x, temp.y,
singleWidthX, singleHeightY, cooPos );
mainSnake.removeTail();
}
}
else
{
mainSnake.clearEndSnakePiece( getGraphics(), temp.x, temp.y,
singleWidthX, singleHeightY, cooPos );
mainSnake.removeTail();
}
}
private void drawBeanAndEBean( Graphics g )
{
g.setColor( ColorGroup.COLOR_BEAN );
this.drawPiece( g, this.bean.x, this.bean.y );
g.setColor( ColorGroup.COLOR_EATEDBEAN );
snakeSq = eatedBean.iterator();
while ( snakeSq.hasNext() )
{
Point tempPoint = (Point)snakeSq.next();
this.drawPiece( g, tempPoint.x, tempPoint.y );
}
}
private void drawPiece( Graphics g, int x, int y )
{
g.fillRoundRect( this.singleWidthX * x + 1,
this.singleHeightY * y + 1,
this.singleWidthX - 2,
this.singleHeightY - 2,
this.cooPos,
this.cooPos );
}
private void createBean( Point temp ) //随机产生豆子
{
LP:
while( true )
{
temp.x = (int) (Math.random() * this.horizontalGrid);
temp.y = (int) (Math.random() * this.verticalGrid);
snakeSq = mainSnake.iterator();
while ( snakeSq.hasNext() )
{
if( snakeSq.next().equals( new Point( temp.x, temp.y ) ) )
{
continue LP;
}
}
break;
}
}
}