📄 gameframe.java
字号:
package SnakeGame;
/**
*整个游戏的逻辑控制。。。。
*/
import javax.swing.*;
import java.util.*;
import java.awt.event.*;
import javax.swing.event.*;
import java.awt.geom.*;
import java.awt.Toolkit;
import java.awt.color.*;
import java.awt.*;
import java.io.FileOutputStream;
import java.io.FileInputStream;
import java.util.Properties;
public class GameFrame
extends JFrame {
private Toolkit tempKit;
//private int horizontalGrid = 60;
public javax.swing.Timer snakeTimer;
//private int verticalGrid = 40;
private int direction = Global.RIGHT; //贪食蛇初始时的方向为向右
private int horizontalGrid,verticalGrid;
private int singleWidthX ;//= this.getWidth()/horizontalGrid;
private int singleHeightY ;//= this.getHeight()/verticalGrid;
private int cooPos ;//= 5; //画贪食蛇时,单个小圆点的arc大小
//private boolean flag = true;
private int Level = 0; //待扩展功能部分,设置关卡,初始时游戏为第一关,分数达到一定值时进入下一关。
private HashMap delay = new HashMap(); //待扩展功能部分, 设置每一关对应的游戏中贪食蛇移动的速度。
//此处为每一关固定为多少的速度。。
//其实也可以在游戏中 设置加速度这个概念。。。如一直按向右键可以向右加速。
//在此程序没有实现这个功能。。。有时间了考虑扩展一下该功能。
{
delay.put(0,75);
delay.put(1,70);
delay.put(2,65);
delay.put(3,60);
delay.put(4,55);
delay.put(5,10);
}
public static ControlMenu configMenu;
public boolean paused = false; //标记游戏“暂停”或“进行”状态的boolean值。
private int score; //游戏中 得分记录变量
private JLabel scoreLabel; //游戏中 得分记录牌
{
scoreLabel = new JLabel();
}
Snake mainSnake = new Snake(); //游戏中的 贪食蛇
private LinkedList eatedBean; //游戏中 被吃过的小Bean,并且此时该Bean还在蛇身中,
//单独将其记录下来 是为了游戏的过程中,当贪食蛇吃到Bean
//并且蛇身还没有穿过该Bean时,用不同于贪食蛇自身的颜色显示出来。
//数据结构采用LinkedList来实现。
// 可以便于遍历。
{
eatedBean = new LinkedList();
}
/* // 待扩展部分,增加障碍物。
private LinkedList wallBean;
{
wallBean = new LinkedList();
}*/
private Point bean,eatBean; //生成的食物
{
bean = new Point();
}
private Iterator iterator ;
public GameFrame() {
this.paused = false;
this.tempKit = this.getToolkit();
System.out.println(tempKit.getScreenSize().getWidth());
System.out.println(tempKit.getScreenSize().getHeight());
this.setSize(tempKit.getScreenSize());
this.setGrid(Global.GameScreenWidthGrid,Global.GameScreenHeightGrid,Global.SnakePieceCooPos);//(85,63,5);
this.getContentPane().setBackground(Global.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.configMenu = new ControlMenu(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;
}
public class KeyHandler extends KeyAdapter
{
public void keyPressed(KeyEvent e)
{
if(e.getKeyCode() == KeyEvent.VK_ESCAPE) //如果是ESC键时,隐藏的菜单栏出现,
// Timer停止计时
{
snakeTimer.stop();
if(paused)
{
configMenu.menuItem[2].setEnabled(false); //如果此时不是暂停状态,则菜单栏中“暂停”项可用
configMenu.menuItem[3].setEnabled(true); //而菜单栏中的“开始”项不可用
}
else
{
configMenu.menuItem[3].setEnabled(false); //如果此时不是进行状态,则菜单栏中“开始”项可用
configMenu.menuItem[2].setEnabled(true); //而菜单栏中的“暂停”项不可用
}
configMenu.setVisible(true); //隐藏的菜单应在相关状态设置完后,才出现。
/*
if (!paused){
snakeTimer.stop();
configMenu.setVisible(true);
//GameFrame.this.changePausedState();
}
else {
snakeTimer.start();
configMenu.setVisible(false);
//GameFrame.this.changePausedState();
}*/
}
/** 上,下,左,右移动。。 **/
else if(e.getKeyCode() == KeyEvent.VK_LEFT && mainSnake.snakeDirection != Global.RIGHT)
{
direction = Global.LEFT;
}
else if (e.getKeyCode() == KeyEvent.VK_UP && mainSnake.snakeDirection != Global.DOWN)
{
direction = Global.UP;
}
else if(e.getKeyCode() == KeyEvent.VK_RIGHT && mainSnake.snakeDirection != Global.LEFT)
{
direction = Global.RIGHT;
}
else if(e.getKeyCode() == KeyEvent.VK_DOWN && mainSnake.snakeDirection != Global.UP)
{
direction = Global.DOWN;
}
else if(e.getKeyCode() == KeyEvent.VK_SPACE ) //空格键, 只有暂停与继续游戏的作用。
{
if(!paused) //暂停游戏时,要将菜单栏与之相关的状态改变。
{
snakeTimer.stop();
GameFrame.this.changePausedState();
configMenu.menuItem[2].setEnabled(false);
configMenu.menuItem[3].setEnabled(true);
}else //继续游戏时,要将菜单栏与之相关的状态改变。
{
snakeTimer.start();
GameFrame.this.changePausedState();
configMenu.menuItem[3].setEnabled(false);
configMenu.menuItem[2].setEnabled(true);
}
//System.exit(1);
}
}
}
public class TimerHandler implements ActionListener // 监听器
{
public void actionPerformed(ActionEvent e)
{
Point temp = (Point) mainSnake.getLast();
iterator = mainSnake.iterator();
while(iterator.hasNext()) //计算蛇是否自身相遇算法
{ //先取出蛇的头部,
//再取蛇的iterator。然后循环一个一个
//与头部比较,真到取到头部时,如果有重合的。
//则有判断蛇与自身相遇了。。
// 接下来提示游戏结束。。
Point tempPoint = (Point)iterator.next();
if(temp.equals(tempPoint) && iterator.hasNext()!=false)
{
snakeTimer.stop();
stopGame();
JOptionPane.showMessageDialog(null,"Your score is"+score+"\nYou Lost");
GameFrame.this.resultRecord(score); // 积分榜 游戏中 成绩的记录 (见该方法详细说明)
System.exit(1);
}
}
//System.out.println(temp.x+"--"+temp.y); 游戏中上,下,左,右边界的判定
if( (temp.x==0 && direction ==4) || // 左边界
(temp.y==0 && direction ==1) || // 上边界
(temp.x==horizontalGrid-1 && direction ==2)|| //右边界
(temp.y==verticalGrid-1 && direction ==3)) //下边界
{
snakeTimer.stop();
stopGame();
JOptionPane.showMessageDialog(null,"Your score is"+score+"\nYou Lost");
/*积分榜*/
GameFrame.this.resultRecord(score);
System.exit(1);
}
if(direction != mainSnake.snakeReDirection) //当此时方向与原来蛇移动的反方向不同时,
//移动蛇。。
{
moveSnake(direction);
}
//drawBackGround(getGraphics());
mainSnake.drawSnake(getGraphics(),singleWidthX,singleHeightY,cooPos); //在屏幕上画出蛇
//drawWall(getGraphics(),Level);
//drawWall(getGraphics());
drawBeanAndEBean(getGraphics()); //画出生成的Bean(食物)和吃过的Bean
}
}
public void resultRecord(int score) // 积分榜。。。只实现的记录第一名的成绩。。
// 如果当前玩家所得的分数比文件中记录的以前所有玩家中
// 最高得分还高的话,提示当前玩家输入姓名。。
// 并同时记录下玩家的姓名与分数。写入一个文件中。。。。持久保存
{
Properties pp = new Properties();
try
{
pp.load(new FileInputStream("Miracle.ini"));
Enumeration enumt= pp.propertyNames();
if(!enumt.hasMoreElements())
{
String inputName=JOptionPane.showInputDialog("Please Input your Name");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -