java - 如何在 java swing 上的游戏中添加计时器
问题描述
我制作了一个游戏,可以在键盘上移动玩家并通过吃随机硬币来增加分数。触摸TNT时HP降低,触摸咖啡时HP上升。使用 Graphics g 在屏幕上打印。现在我要添加一个计时器。我想制作一个玩家在规定时间内记录高分的游戏。有很多事情我还不知道。请给我建议,这是我的代码。感谢您阅读。
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.io.File;
import java.io.IOException;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
public class CoinEat1 extends JFrame {
private Image bufferImage;
private Graphics screenGraphic;
private Clip clip;
private Image backgroundImage = new ImageIcon("src/images/배경.jpg").getImage();
private Image player = new ImageIcon("src/images/1P.png").getImage();
private Image coin = new ImageIcon("src/images/코인.png").getImage();
private Image TNT = new ImageIcon("src/images/폭탄.png").getImage();
private Image Coffee = new ImageIcon("src/images/커피.png").getImage();
private int playerX,playerY;
private int playerWidth = player.getWidth(null);
private int playerHeight = player.getHeight(null);
private int coinX,coinY;
private int coinWidth = coin.getWidth(null);
private int coinHeight = coin.getHeight(null);
private int TNTX,TNTY;
private int TNTWidth = TNT.getWidth(null);
private int TNTHeight = TNT.getHeight(null);
private int CoffeeX,CoffeeY;
private int CoffeeWidth = Coffee.getWidth(null);
private int CoffeeHeight = Coffee.getHeight(null);
private int score;
private int HP;
private boolean playerup, down, left, right;
public CoinEat1() {
setTitle("동전JAVA");
setVisible(true);
setSize(Main.SCREEN_WIDTH,Main.SCREEN_HEIGHT);
setLocationRelativeTo(null);
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
addKeyListener(new KeyAdapter(){
public void keyPressed(KeyEvent e) {
switch(e.getKeyCode()) {
case KeyEvent.VK_UP:
playerup=true;
break;
case KeyEvent.VK_DOWN:
down=true;
break;
case KeyEvent.VK_LEFT:
left=true;
break;
case KeyEvent.VK_RIGHT:
right=true;
break;
}
}
public void keyReleased(KeyEvent e) {
switch(e.getKeyCode()) {
case KeyEvent.VK_UP:
playerup=false;
break;
case KeyEvent.VK_DOWN:
down=false;
break;
case KeyEvent.VK_LEFT:
left=false;
break;
case KeyEvent.VK_RIGHT:
right=false;
break;
}
}
});
Init();
while(true){
try {
Thread.sleep(20);
} catch(InterruptedException e) {
e.printStackTrace();
}
keyProcess();
CoinCrashCheck();
TNTCrashCheck();
CoffeeCrashCheck();
}
}
public void Init() {
score = 0;
HP = 100;
playerX = (Main.SCREEN_WIDTH-playerWidth)/2;
playerY = (Main.SCREEN_HEIGHT-playerHeight)/2;
coinX = (int)(Math.random()*(Main.SCREEN_WIDTH+1-playerWidth));
coinY = (int)(Math.random()*(Main.SCREEN_HEIGHT+1-playerHeight-30))+30;
TNTX = (int)(Math.random()*(Main.SCREEN_WIDTH+1-playerWidth));
TNTY = (int)(Math.random()*(Main.SCREEN_HEIGHT+1-playerHeight-30))+30;
CoffeeX = (int)(Math.random()*(Main.SCREEN_WIDTH+1-playerWidth));
CoffeeY = (int)(Math.random()*(Main.SCREEN_HEIGHT+1-playerWidth))+30;
playsound("src/music/BGM.wav",true);
}
public void keyProcess() {
if (playerup && playerY - 3 > 30) playerY-=3;
if (down && playerY + playerHeight + 3 < Main.SCREEN_HEIGHT) playerY+=3;
if (left && playerX -3 > 0) playerX-=3;
if (right && playerX + playerWidth + 3 < Main.SCREEN_WIDTH) playerX+=3;
}
public void CoinCrashCheck(){
if (playerX+playerWidth > coinX && coinX+coinWidth > playerX && playerY+playerHeight > coinY && coinY+coinHeight > playerY){
score += 100;
playsound("src/music/coin.wav",false);
coinX = (int)(Math.random()*(Main.SCREEN_WIDTH+1-playerWidth));
coinY = (int)(Math.random()*(Main.SCREEN_HEIGHT+1-playerHeight-30))+30;
}
}
public void TNTCrashCheck() {
if (playerX+playerWidth > TNTX && TNTX+TNTWidth > playerX && playerY+playerHeight > TNTY && TNTY+TNTHeight > playerY){
HP -= 25;
TNTX = (int)(Math.random()*(Main.SCREEN_WIDTH+1-playerWidth));
TNTY = (int)(Math.random()*(Main.SCREEN_HEIGHT+1-playerHeight-30))+30;
}
}
public void CoffeeCrashCheck() {
if (playerX+playerWidth > CoffeeX && CoffeeX+CoffeeWidth > playerX && playerY+playerHeight > CoffeeY && CoffeeY+CoffeeHeight > playerY){
HP += 25;
CoffeeX = (int)(Math.random()*(Main.SCREEN_WIDTH+1-playerWidth));
CoffeeY = (int)(Math.random()*(Main.SCREEN_HEIGHT+1-playerHeight-30))+30;
}
}
public void playsound(String pathName, boolean isLoop) {
try {
clip = AudioSystem.getClip();
File audioFile = new File(pathName);
AudioInputStream audioStream = AudioSystem.getAudioInputStream(audioFile);
clip.open(audioStream);
clip.start();
if(isLoop)
clip.loop(Clip.LOOP_CONTINUOUSLY);
}catch (LineUnavailableException e) {
e.printStackTrace();
}
catch (UnsupportedAudioFileException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
}
public void paint(Graphics g) {
bufferImage = createImage(Main.SCREEN_WIDTH,Main.SCREEN_HEIGHT);
screenGraphic = bufferImage.getGraphics();
screenDraw(screenGraphic);
g.drawImage(bufferImage,0,0,null);
}
public void screenDraw(Graphics g){//이미지를 출력해줄 paint 메소드
g.drawImage(backgroundImage,0,0,null);
g.drawImage(player,playerX,playerY,null);
g.drawImage(coin,coinX,coinY,null);
g.drawImage(TNT,TNTX,TNTY,null);
g.drawImage(Coffee,CoffeeX,CoffeeY,null);
g.setColor(Color.white);
g.setFont(new Font("Arial",Font.BOLD,35));
g.drawString("SCORE : "+score, 30, 80);
g.drawString("HP : " + HP, 30, 120);
this.repaint();
}
public static void main(String[] args) {
new CoinEat1();
}
}
解决方案
我想制作一个玩家在规定时间内记录高分的游戏。
我认为你需要做一个倒计时。
首先,全局定义这些变量
// Timer Stuff
private Timer mGameTimer;
private int mTimeLeft = 20;
private final int mDelay = 1000; // Start after 1 second
private final int mPeriod = 1000; // Ticks every 1 second
创建一个名为 SetupTimer() 的方法
private void SetupTimer() {
mGameTimer = new Timer();
mGameTimer.scheduleAtFixedRate(new TimerTask() {
public void run() {
if (mTimeLeft == 1) {
mTimeLeft--;
mGameTimer.cancel();
// Handle your game over thing
} else {
mTimeLeft--;
}
}
}, mDelay, mPeriod);
}
在你的构造函数中调用它
public CoinEat1() {
...
SetupTimer();
...
}
最后改变你的 screenDraw 方法
public void screenDraw(Graphics g) {
g.drawImage(backgroundImage, 0, 0, null);
g.drawImage(player, playerX, playerY, null);
g.drawImage(coin, coinX, coinY, null);
g.drawImage(TNT, TNTX, TNTY, null);
g.drawImage(Coffee, CoffeeX, CoffeeY, null);
g.setColor(Color.white);
g.setFont(new Font("Arial", Font.BOLD, 35));
g.drawString("SCORE : " + score, 30, 80);
g.drawString("HP : " + HP, 30, 120);
g.drawString("Time Left : " + mTimeLeft, 30, 160); //Redraws your time
this.repaint();
}
推荐阅读
- visual-studio-code - 在 vscode 中粘贴具有现有文件名的文件会导致它们重命名而不是替换现有文件
- reactjs - Babel 是否可以为整个 React 项目构建一个 AST?
- jsf - 在 Primefaces 中关闭对话框时更新数据表和消息
- reactjs - 将敏感数据从反应发送到节点 js 快递服务器
- python - Pyinstaller 无法完全转换
- r - Pyspark/R:R 的 is.na 是否有 pyspark 等效功能?
- classification - LSTM 分类
- jenkins - 詹金斯:是否可以为詹金斯中的选定参数授予用户访问权限?
- json - Spring Boot 中登录的 Rest/JSON 响应
- linux - 无法将现有的 git 存储库推送到 github