GameFace类主要实现主游戏界面。
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.*;
public class GameFace {
public static Dimension getSize(){ //设置所需窗体大小
return new Dimension(1024,590);
}
public static Point getLocation(){ //计算居窗体左上角坐标
Toolkit toolKit=Toolkit.getDefaultToolkit(); //获得Toolkit实例
Dimension screenSize=toolKit.getScreenSize(); //获得显示器大小
//当显示器小于窗体时报错并结束程序
if((screenSize.width<getSize().width)||(screenSize.height<getSize().height)){
JOptionPane.showMessageDialog(null,"显示器分辨率至少为"+getSize().width+"*"+getSize().height,"",JOptionPane.WARNING_MESSAGE);
System.exit(0); //终止程序
}
int x=(screenSize.width-getSize().width)/2; //计算左上角坐标
int y=(screenSize.height-getSize().height)/2;
return new Point(x,y); //返回计算好的坐标
}
public static void run() {
JFrame frame=new JFrame("狙击坦克(不区分大小写版)"); //游戏窗体
frame.setLocation(getLocation()); //设置窗体位置居中
frame.setSize(1024,590); //设置窗体大小
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); //设置关闭窗体为销毁窗体
frame.setResizable(false); //设置窗体大小不可变
//设置窗体图标
frame.setIconImage(Toolkit.getDefaultToolkit().getImage(GameFace.class.getResource("char_bg.png")));
GameJPanel pan=new GameJPanel(); //绘画面板(自定义画布)
pan.go(); //开始游戏,启动定时任务
frame.addKeyListener(pan); //绑定键盘事件
frame.add(pan); //向窗体添加面板
frame.setVisible(true); //显示窗体
}
}
class GameJPanel extends JPanel implements KeyListener{
private static final long serialVersionUID = 1L;
private Image background=Toolkit.getDefaultToolkit().getImage(GameJPanel.class.getResource("background.jpg")); //背景图片
private Image bong0=Toolkit.getDefaultToolkit().getImage(GameJPanel.class.getResource("bong0.png")); //爆炸图片
private Image bong1=Toolkit.getDefaultToolkit().getImage(GameJPanel.class.getResource("bong1.png"));
private Image bong2=Toolkit.getDefaultToolkit().getImage(GameJPanel.class.getResource("bong2.png"));
private Image bong3=Toolkit.getDefaultToolkit().getImage(GameJPanel.class.getResource("bong3.png"));
private Image bong4=Toolkit.getDefaultToolkit().getImage(GameJPanel.class.getResource("bong4.png"));
private Image bong5=Toolkit.getDefaultToolkit().getImage(GameJPanel.class.getResource("bong5.png"));
private Image bong6=Toolkit.getDefaultToolkit().getImage(GameJPanel.class.getResource("bong6.png"));
private Image char_bg=Toolkit.getDefaultToolkit().getImage(GameJPanel.class.getResource("char_bg.png")); //字母背景图片
SqlLink sql=new SqlLink(); //链接数据库
boolean firstStart =true; //游戏启动标记
int num=4; //游戏启动倒计时
private static long start=0; //用于存放游戏开始时间
private static long end =0; //用于存放游戏结束时间
private static int score=1000; //初始分数1000分
private static int highscore=1000; //用于存放本局最高分数
private static int level=1; //用于存放等级
private static int number=1; //用于存放屏幕出现字数
private static int count=0; //用于存放打对字数
private static int upcount=5; //用于存放升级所需打字数
private static int speed=100; //用于存放游戏速度
private static int bonus=10; //用于存放加分
private static int minus=120; //用于存放扣分
private static int[] changeLevel=new int[2];
private static int[] changeGame=new int[4];
private static char[] c=new char[106]; //用于存放屏幕中字母以及所对应的坐标
private static int[] x=new int [106];
private static int[] y=new int[106];
private static Timer timer=null; //定义定时任务对象
private static int xx=0; //被打掉字母坐标,被打掉标记
private static int yy=0;
boolean playflag=true;
public GameJPanel(){ //构造时初始化
firstStart=true; //画板实例时,将第一次启动标志改变
for(int i=0;i<c.length;i++){ //初始化字符数组
c[i]=‘0‘;
}
}
public void init(){ //生成一组随机字母
for(int i=0;i<number;i++){
setChar(i);
}
}
public void setChar(int i){ //获得随机26个字母之一及其位置
c[i]=(char)(Math.random()*26+65);
x[i]=(int)(Math.random()*600+200);
y[i]=-20;
}
public void paint(Graphics g){ //绘图
super.paint(g); //获得父类的绘图功能
g.drawImage(background,0, 0, this); //绘制背景图片
if(firstStart){ //启动游戏时,倒计时3秒
g.setColor(Color.red);
g.setFont(new Font("方正舒体",Font.BOLD,50));
switch(num){
case 3:
g.drawString("坦克来袭!", 390, 275);
break;
case 2:
g.drawString("请做好准备!", 365, 275);
break;
case 1:
g.drawString("迎战!", 440, 275);
break;
default:
break;
}
num--;
try {
Thread.sleep(1000); //画1次休息1秒
} catch (InterruptedException e) {
e.printStackTrace();
}
if(num<0){ //倒计时结束,初始化,获得游戏开始时间
firstStart=false;
init();
start=System.currentTimeMillis();
}
}
if(playflag){ //如果有打掉字母,则显示爆炸效果
g.drawImage(bong0,xx-33, yy-60, this);
g.drawImage(bong1,xx-33, yy-60, this);
g.drawImage(bong2,xx-33, yy-60, this);
g.drawImage(bong3,xx-33, yy-60, this);
g.drawImage(bong4,xx-33, yy-60, this);
g.drawImage(bong5,xx-33, yy-60, this);
g.drawImage(bong6,xx-33, yy-60, this);
playflag=false;
}
if(score<0){ //分数已负,游戏结束
end=System.currentTimeMillis(); //获得结束时间
//游戏结束时,打印本局最高分,打印累计打字数,打印等级,打印存活时间
Image list_bg=Toolkit.getDefaultToolkit().getImage(GameJPanel.class.getResource("list_bg.jpg")); //背景图片
g.drawImage(list_bg,310,0,this);
g.setColor(Color.black);
g.setFont(new Font("Beurk",Font.BOLD,60));
g.drawString("Game Over",344,152);
g.setFont(new Font("华文行楷",Font.PLAIN,30));
g.drawString("您共存活了:"+(end-start)/1000+"秒", 330, 280);
g.drawString("您的最高分为:"+highscore+"分", 330, 330);
g.drawString("您共打对了"+count+"个字母", 330, 380);
g.drawString("您的等级为:"+level, 330, 430);
g.setColor(Color.red);
g.setFont(new Font("Beurk",Font.BOLD,60));
g.drawString("Game Over",340,150);
sql.setHistory(LoginFace.username, highscore, count, (end-start)/1000);
timer.cancel(); //关闭定时任务
return ; //停止此次绘图
}
//设置屏幕字母基本属性
g.setFont(new Font("Vivian",Font.BOLD,22));
for(int i=0;i<c.length;i++){ //绘制字母及其背景图片
if(c[i]!=‘0‘){
g.drawImage(char_bg,x[i]-31, y[i]-21, this);
g.setColor(new Color(255,255,255,80));
g.fillOval(x[i]-14, y[i]-22, 45, 30);
g.setColor(Color.yellow);
g.drawString(c[i]+"",x[i]+2,y[i]+1);
g.setColor(Color.red);
g.drawString(c[i]+"",x[i],y[i]);
}
}
//绘制游戏数据(等级、分数、打对字母数、升级条件)
g.setColor(Color.black);
g.setFont(new Font("楷体",Font.BOLD,25));
g.drawString("等级:"+level,22,32);
g.drawString("分数:"+score,22,67);
g.setFont(new Font("楷体",Font.BOLD,35));
g.drawString("战",937,347);
g.drawString("绩",922,382);
g.setFont(new Font("楷体",Font.BOLD,20));
g.drawString("已经消灭坦克"+count+"辆",822,422);
g.drawString("升级还需消灭",854,452);
g.drawString(upcount+"辆坦克",907,482);
g.setColor(Color.green);
g.setFont(new Font("楷体",Font.BOLD,25));
g.drawString("等级:"+level,20,30);
g.drawString("分数:"+score,20,65);
g.setFont(new Font("楷体",Font.BOLD,35));
g.drawString("战",935,345);
g.drawString("绩",920,380);
g.setFont(new Font("楷体",Font.BOLD,20));
g.drawString("已经消灭坦克"+count+"辆",820,420);
g.drawString("升级还需消灭",852,450);
g.drawString(upcount+"辆坦克",905,480);
}
public void go(){ //定义一个方法,启动游戏
timer=new Timer(); //制定定时任务
timer.schedule(new TimerTask(){
//new TimerTask(){}匿名内部类,重写run方法
public void run() {
try{
Thread.sleep(speed); //每执行一次休息speed毫秒
}catch(Exception ex){
ex.printStackTrace();
}
for(int i=0;i<c.length;i++){ //字母下落
y[i]++;
if(y[i]>590&&c[i]!=‘0‘){ //如果已经掉落到底边界,则扣分,并重新生成字母
score-=minus;
setChar(i);
}
}
repaint(); //重画
}
},0,5) ; //现在就启动,以后每5毫秒执行一次上述代码
}
//键盘监听
public void keyPressed(KeyEvent key) { //按下键盘某个键时,,监听键盘输入的字符
char ckey=key.getKeyChar(); //获得键盘录入字母
if(ckey!=65535){
if (97<=ckey&&ckey<123){ //将小写字母转换成大写字母
ckey=Character.toUpperCase(ckey);
}
int index=-1;
for(int i=0;i<c.length;i++){ //遍历屏幕字母,是否有相同的
if(ckey==c[i]&&y[i]>10&&ckey!=‘0‘){
index=i;
break;
}
}
if(index!=-1){ //如果有相同的,则加分,并消除掉此字母,生成一个新的字母
score+=bonus;
xx=x[index]; //保存被打掉的字母坐标,并将playflag 置 true
yy=y[index];
playflag=true;
count++; //打字数加一,升级条件减一
upcount--;
setChar(index);
if(upcount==0){ //升级,并重新计算下次升级需要的打字数
changeLevel=sql.getLevel(count);
level=changeLevel[0];
upcount=changeLevel[1];
changeGame=sql.getGame(level);
number=changeGame[0];
speed=changeGame[1];
bonus=changeGame[2];
minus=changeGame[3];
setChar(level-1); //升级时,字母多生成一个
}
if(score>highscore){ //当当前分数大于本局最高分时,刷新最高分
highscore=score;
}
}else{
score-=minus; //否则录入的字母并不存在,扣分
}
}
}
//以下两个监听事件,并未用到,置空
public void keyReleased(KeyEvent arg0) {}
public void keyTyped(KeyEvent arg0) {}
}
windows端打字游戏——游戏进行