1.作业基本任务
1.多个小写英文单词及简单的标点符号在多个时间起始阶段,从屏幕上方下落,速度一定,直至屏幕下方横线;
2.监视键盘敲击事件,记录键盘敲击得到的数据;
3.当键盘连续击的英文单词与屏幕上下落的英文单词一致时,消除屏幕下落的单词,并计分;
4.当下落的英文单词下落到屏幕下方横线,部分横线被消除,当所有横线支消除后,游戏结束。
2. 图形界面设计
2.1 主窗口
2.1.1 创建主窗口
主窗口使用`JFrame`创建,设置窗口标题、大小,并定义窗口关闭操作。同时,添加键盘监听器以捕捉用户输入。代码如下:
public TypingGame() {
this.setTitle("键盘盲打游戏");
this.setSize(800, 600);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.addKeyListener(this);
words = new ArrayList<>();
generateNewWord();
timer = new Timer(800, this);
timer.start();
}
2.2 绘制区域
2.2.1 显示区域
使用`JTextArea`创建显示区域,用于显示下落的单词。为了实现双缓冲技术,避免闪烁,使用`Image`和`Graphics`对象进行离屏绘制。
@Override
public void paint(Graphics g) {
if (offScreenImage == null) {
offScreenImage = createImage(this.getWidth(), this.getHeight());
offScreenGraphics = offScreenImage.getGraphics();
}
offScreenGraphics.setColor(getBackground());
offScreenGraphics.fillRect(0, 0, this.getWidth(), this.getHeight());
offScreenGraphics.setColor(getForeground());
for (int i = 0; i < words.size(); i++) {
offScreenGraphics.drawString(words.get(i), wordPositions.get(i).x, wordPositions.get(i).y);
}
offScreenGraphics.drawLine(0, 550, 800 * lineCount / 3, 550);
offScreenGraphics.drawString("得分: " + score, 10, 50);
offScreenGraphics.drawString("剩余横线段数: " + lineCount, 10, 70);
g.drawImage(offScreenImage, 0, 0, this);
}
2.2.2 横线和分数显示
在离屏图像上绘制横线,显示当前得分和剩余的横线段数。横线的初始段数设为3,每当一个单词到达底部横线,减少一段横线。
3. 单词下落和生成
3.1 定时器控制单词下落
3.1.1 初始化定时器
使用`Timer`类创建定时器,设置定时器间隔为800毫秒,控制单词下落速度。定时器每次触发时,单词向下移动,并检测单词是否到达横线位置。代码如下:
@Override
public void actionPerformed(ActionEvent e) {
timeSinceLastWord += 200;
if (timeSinceLastWord >= generateWordInterval && words.size() < MAX_WORDS) {
generateNewWord();
timeSinceLastWord = 0;
}
for (int i = 0; i < wordPositions.size(); i++) {
Point p = wordPositions.get(i);
wordPositions.set(i, new Point(p.x, p.y + 30));
if (p.y >= 550) {
wordPositions.remove(i);
words.remove(i);
lineCount--;
if (lineCount <= 0) {
timer.stop();
JOptionPane.showMessageDialog(this, "游戏结束! 你的得分是: " + score);
System.exit(0);
}
}
}
repaint();
}
3.2 生成新单词
3.2.1 新单词生成逻辑
在定时器触发事件中,每隔一定时间间隔生成一个新单词。单词生成间隔为200毫秒,同时控制屏幕上最多存在5个单词。
3.2.2 单词位置
新生成的单词位置为窗口宽度的三分之一到三分之二范围内的随机位置。代码如下:
private void generateNewWord() {
String[] possibleWords = {"apple", "banana", "cherry", "date", "fig", "grape", "kiwi", "hello", "ojbk"};
Random random = new Random();
String newWord = possibleWords[random.nextInt(possibleWords.length)];
words.add(newWord);
int xPosition = this.getWidth() / 3 + random.nextInt(this.getWidth() / 3 * 2);
wordPositions.add(new Point(xPosition, 50));
}
4. 键盘输入处理
4.1 捕捉键盘事件
4.1.1 监听键盘输入
实现`KeyListener`接口,捕捉用户键盘输入事件。将输入的字符追加到当前输入单词中。代码如下:
@Override
public void keyPressed(KeyEvent e) {
char keyChar = e.getKeyChar();
if (Character.isAlphabetic(keyChar) || keyChar == ' ') {
currentTypedWord += keyChar;
checkTypedWord();
}
}
@Override
public void keyReleased(KeyEvent e) {}
@Override
public void keyTyped(KeyEvent e) {}
4.2 检查输入单词
4.2.1 匹配逻辑
在键盘输入事件中,检查当前输入单词是否与下落单词匹配。如果匹配,消除单词并增加分数,同时清空当前输入单词。代码如下:
private void checkTypedWord() {
boolean wordMatched = false;
for (int i = 0; i < words.size(); i++) {
if (words.get(i).startsWith(currentTypedWord.trim())) {
if (currentTypedWord.trim().equals(words.get(i))) {
words.remove(i);
wordPositions.remove(i);
score++;
currentTypedWord = "";
wordMatched = true;
break;
} else {
wordMatched = true;
}
}
}
if (!wordMatched) {
currentTypedWord = "";
}
repaint();
}
5. 游戏结束处理
5.1 横线消除
5.1.1 单词到达底部
当单词到达底部横线位置时,减少一段横线。当所有横线段数被消除,游戏结束,弹出提示框显示得分,并退出程序。
5.2 游戏重绘
5.2.1 重绘界面
每次定时器触发或键盘事件发生时,重新绘制界面,显示当前单词、得分和剩余横线段数。
@Override
public void paint(Graphics g) {
if (offScreenImage == null) {
offScreenImage = createImage(this.getWidth(), this.getHeight());
offScreenGraphics = offScreenImage.getGraphics();
}
offScreenGraphics.setColor(getBackground());
offScreenGraphics.fillRect(0, 0, this.getWidth(), this.getHeight());
offScreenGraphics.setColor(getForeground());
for (int i = 0; i < words.size(); i++) {
offScreenGraphics.drawString(words.get(i), wordPositions.get(i).x, wordPositions.get(i).y);
}
offScreenGraphics.drawLine(0, 550, 800 * lineCount / 3, 550);
offScreenGraphics.drawString("得分: " + score, 10, 50);
offScreenGraphics.drawString("剩余横线段数: " + lineCount, 10, 70);
g.drawImage(offScreenImage, 0, 0, this);
}
通过上述步骤,实现了一个基本的键盘盲打游戏。玩家需要通过键盘输入与下落单词匹配的字符,消除单词并获得分数,同时避免单词到达底部横线,保持游戏进行。
运行结果如下: