基于Java的指法练习小游戏的设计与实现
2017-12-15张会
张会
摘要:该文利用 Java Swing,多线程,事件处理等技术实现了一个指法练习小游戏。游戏具有设置游戏难度等级,统计游戏成绩等功能。该游戏是一个集Java Swing、多线程、事件处理等知识综合应用实例程序,对《Java程序设计》课程教学有一定的指导作用。
关键词:多线程;事件处理;游戏;Java Swing
中图分类号:TP311 文献标识码:A 文章编号:1009-3044(2017)32-0085-02
Design and Implementation of Fingering Practice Game Based on Java
ZHANG Hui
(School of Mathematics and Computer Science, Panzhihua University, Panzhihua 617000, China)
Abstract: This paper uses Java Swing, multi-thread, event processing and other techniques to complete a fingering practice game. The game has difficulty level settings, statistical game scores and other functions. This game is a comprehensive program, including Java Swing, multi-threaded, event processing and other knowledge. It has some guiding function to the course teaching of Java programming.
Key words: multi-thread; event processing; game; Java Swing
指法练习小游戏是用户在键盘指法练习时经常选择的一款小游戏。在程序设计语言教学中,结合学生熟悉的游戏并利用案例式教学有助于提高学生学习兴趣,促进学生对所学知识掌握吸收,并较好的应用于实际项目中。文中的指法练习小游戏采用Java Swing,线程,事件处理等相关技术进行设计及开发,使学生快速掌握及使用Java中的Java Swing、线程、事件处理等相关技术进行Java程序开发有较大帮助,并对《Java程序设计》课程相关知识点的综合实践教学具有一定指导作用。
1 指法练习小游戏设计
1.1 功能设计
小游戏能够实现以下功能:
1) 字母小球生成:字母小球从窗口顶端的任意位置随机生成并按一定速度向窗口下方滚动。
2) 游戏等级设置:按照游戏设置菜单下的高,中,低,自定义设置界面中字母小球的个数,并在窗口顶部开始随机产生相应个数的滚动字母小球。
3) 计分统计:窗口中字母小球滚动入窗口下方且未敲击中键盘上相应字母按键,score成绩减1分,字母小球未滚动入窗口下方且敲击中键盘上相应字母按键,则score成绩加1分,同时显示score的当前值。
4) 能够通过菜单中的退出功能退出游戏。
1.2 界面设计
Swing是Java的GUI(图形用户界面)工具包,包括了GUI组件,如:菜单栏、菜单项、按钮、面板、文本框等组件。本设计利用了Swing中的相关组件实现了如图1所示的游戏界面。其中JFrame做为顶层窗体容器,在其上添加了JMenuBar(菜单栏),JMenu(游戏设置菜单)及菜单下的JMenuItem(菜单项)组件,另外在JFrame容器中添加了一个JPanel面板,用于在其上显示向下滚动的字母小球及得分情况。
2 指法练习游戏功能实现
2.1 游戏难度设置功能实现
本游戏通过选择“游戏设置”菜单中的高,中,低及自定义选项控制游戏难易度,游戏难易度由游戏中滚动字母小球的个数确定,难度越高则字母小球个数越多,“自定义”选项采用Dialoag方式直接输入滚动字母小球的個数。
游戏等级设置通过java中的事件处理技术实现。当单击菜单中某菜单选项时,会产生一个ActionEvent事件(或者在进行游戏过程中,按键盘上的某个按键时,会产生一个KeyEven事件),然后Java虚拟机检查是否有与该菜单项或按键相关联的事件处理器,事件处理器实质是一个方法,如actionPerformed()方法,keyPressed()方法,如果没有,不做任何处理;若有则将事件对象传递给与之关联的事件处理器方法作为事件处理方法参数,并自动调用事件处理方法。Java虚拟机通过传递过来的ActionEvent,keyEvent对象,获得事件发生时与该事件及事件源相关联的信息。Java组件通过形如addXxxListener()的方法添加事件监听器。一个事件源可以添加多个监听器。
游戏高、中、低及自定义级别的菜单项的事件处理代码如下:
JMenuItem item = (JMenuItem) e.getSource();
if (item == this.lowI) {
init(lowBallCount);
} else if (item == this.midI) {
init(midBallCount);
} else if (item == this.highI) {
init(highBallCount);
} else if (item == this.selfDefineI) {endprint
String str = JOptionPane.showInputDialog("输入字母小球个数:");
ballCount = Integer.parseInt(str);
init(ballCount);}
为各菜单项添加事件监听器代码如下:
lowI.addActionListener(myPanle);
midI.addActionListener(myPanle);
highI.addActionListener(myPanle);
selfDefineI.addActionListener(myPanle);
为面板添加按键事件监听器代码如下:myPanel.addKeyListener(myPanel);
2.2 游戏中字母小球的产生及位置定位
本游戏中向下滚动的字母小球在游戏加载运行时,其生成的位置在JPanel中是随机的,通过为每个字母小球定义(x,y)座标值,使用Math.random()在JPanel中产生随机座标值。同时把小球上的字母通过随机函数产生。由于程序中生成的字母小球是ballCount个,所以程序中字母小球的座标x,y及小球上的字母ch在存储时均采用数组进行存放,且数组元素个数均是ballCount个。代码如下:
public void init(int ballCount) {
x = new int[ballCount];
y = new int[ballCount];
ch = new char[ballCount];
for (int i = 0; i < ballCount; i++) {
x[i] = (int) (Math.random() * width);
y[i] = (int) (Math.random() * height);
ch[i] = (char) ((Math.random() * 26) + 65);}}
界面中的字母下面小球是一张背景图片,是通过读取ball.png图片数据,再通过drawImage()将小球图片绘制在(x[i],y[i])座标位置,由于小球图片大于显示的字母,所以在绘制ball.png图片时,(x[i],y[i])座标值同时向左向上做了些微偏移,因此最终在(x[i]-20,y[i]-30)座标处绘制出ball.png,最后再在(x[i],y[i])座标位置使用drawString()绘制出大写字母ch[i]的值。代码如下:
image = ImageIO.read(new File("ball.png"));
g.drawImage(image, x[i] - 20, y[i] - 30, imWidth, imHeight, this);
g.drawString("" + ch[i], x[i], y[i]);
2.3 线程实现字母小球在屏幕上向下滚动
类 JComponent中的paint()方法通常用于在容器中绘制所需组件,程序中不能直接调用 paint()方法,均是采用自动调用方式调用paint()方法。调用子类重写父类pain()方法通常有两种方式:一是在顶层容器中显示子类组件时会自动调用paint()方法,如果子类组件没有被显示,是不会调用paint();二是调用组件的repaint(),其实质是自动调用Java组件子类中重写的paint()方法以实现刷新重绘。
本游戏在运行过程时需要在JFrame中的JPanel中绘制出向下移动的字母小球,及得分情况,因此本程序通过自定义一个MyPanel类继承于JPanel类,并重写Jpanel类中的paint()方法,以便程序在绘制不断向下滚动的小球时,MyPanel线程调用repaint()方法时能自动调用paint()方法实现小球滚动的效果。代码如下:
public void paint(Graphics g) {
for (int i = 0; i < ballCount; i++) {
Image image;
try {
image = ImageIO.read(new File("ball.png"));
g.drawImage(image, x[i] - 20, y[i] - 30, 50, 50, this);
} catch (IOException e) {
e.printStackTrace();}
g.drawString("" + ch[i], x[i], y[i]);
y[i] += 3;}}
程序通过Thread.sleep(100)控制线程每隔100毫秒,调用repaint()去自动调用paint()方法一次,使字母小球的纵向坐标值y[i]+=3;从而使小球动起来。代码如下:
public void run() {
while (true) {
repaint(); //自动调用重写的paint()方法
Thread.sleep(100);}}
2.4 计分功能实现
在字母小球向下滚动的过程中,用户通过敲击键盘上相应的字母键,触发MyPanel事件源,生成KeyEvent按鍵事件对象,并将该对象传递给按键处理器的keyPressed()方法做为参数,并执行该方法。当按键字母与小球上的字母相等时,字母小球消失,再给该字母小球的座标值重新置值,其中将该小球的y值置为0,x值在窗口宽度范围内产生一个随机值,并重新在小球上生成一个随机字母,以保证窗口中的字母小球的个数始终为ballCount个,同时使score值加1,以实现计分中的加分功能。代码实现如下:endprint
public void keyPressed(KeyEvent e)
{
char c = e.getKeyChar();
for (int i = 0; i < ballCount; i++)
{
if (c == ch[i]) {
x[i] = (int) (Math.random() * width);
y[i] = 0;
ch[i] = (char) ((Math.random() * 26) + 65);
score++;}}}
計分功能中的减分功能的实现:当有字母小球从窗口底部移出,并且用户未敲击键盘上相应的字母键,则score的值减1。程序再在窗口顶部重新产生一个字母小球的座标,并通过调用repaint()方法在下一个100毫秒时进行重绘该字母小球。代码实现如下:
if (y[i] >= height) {
x[i] = (int) (Math.random() * width);y[i] = 0;
ch[i] = (char) ((Math.random() * 26) + 65);
score—;}
3 结束语
本指法练习小游戏通过使用Java Swing呈现出友好的人机交互界面,采用多线程技术实现字母小球在窗口中向下滚动动画及字母小球移出窗口减分功能,采用事件处理技术实现游戏等级设置及在敲击键盘上字母键等同于字母小球上字母时的得分功能,另外通过重写JPanel类的paint()方法来实现重绘等功能。虽然本指法练习小游戏的功能与金山打字类软件的指法练习在功能上相比有所欠缺,但本程序便于初学者理解,为Java初学者掌握事件处理,多线程技术,Java Swing等知识提供了一个综合而有趣的实例,并且在Java程序设计课程教学中有一定的参考作用。
参考文献:
[1] 明日科技. Java从入门到精通 [M]. 3版.北京: 清华大学出版社, 2012.
[2] 传智博客. Java基础入门[M]. 北京: 清华大学出版社, 2014.
[3] 杨建强, 李苗在. 基于Java Swing的计算器的设计与实现[J]. 电脑与电信, 2016(10):61-63.
[4] 马巧梅. 基于Java打砖块游戏的设计与实现[J]. 信息技术, 2016(7):16-19.
[5] 孙佳美. 基于Java飞机大战的设计与实现[J]. 无线互联科技, 2016(1):54-55.
[6] 王改芳, 龚君芳. 基于Java的考试机设计与实现[J]. 实验技术与管理, 2016(33):147-149.endprint