gpt4 book ai didi

Java 游戏(箭头控制)速度减慢,鼠标在 JFrame 外部移动期间除外

转载 作者:行者123 更新时间:2023-12-01 12:22:50 25 4
gpt4 key购买 nike

所以,我创建了一个横向的“太空入侵者”类型的游戏,我使用了 Swing、JFrame、JPanel、计时器、图形等。

我已将控件设置为箭头键和空格键,因此不需要鼠标。

但是我遇到的问题是,在玩游戏时,游戏似乎“变慢了”,并且仅在鼠标移动时加速到正常速度在 JFrame 之外,并在我停止移动它后持续 1 或 2 秒。

例如,如果其他人正在玩游戏,游戏将以减慢的速度开始。如果我开始将鼠标移动到 JFrame 之外,则当我继续移动鼠标时,游戏会加速到正常速度。当我停止移动它后,速度还会有几秒钟的提高,然后又减慢。

我不知道它可能是什么,因为我没有知道可能会监听鼠标和/或影响性能的代码。运行它的计算机是一个非常干净的系统,有 8 个千兆位和一个 i7。 Eclipse Luna 4.4,Java 1.8。 (8 u 25),因此任何 CPU 性能问题都不太可能发生。

--

这是我的键盘、 Action 监听器和移动相关的代码:

主类:

public class Iniciar extends JFrame{

private static final long serialVersionUID = 1L;
JPanel panel;
JPanel splash;
JButton botonStart;
JButton botonExit;
Board b;
Timer timer;
BufferedImage splashimg;

public Iniciar () throws IOException
{
splash = new JPanel();
panel = new JPanel();

botonStart = new JButton("START");
botonExit = new JButton("EXIT");

panel.setLayout(new BorderLayout());
botonStart.addActionListener(new ActionListener() {


public void actionPerformed(ActionEvent e) {
if (botonStart.getText() == "RESTART")
{
dispose();
try {
new Iniciar();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
panel.setVisible(true);
try {
b = new Board(botonStart,panel);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
panel.add(b);
splash.setVisible(false);
botonStart.setVisible(false);
}
});

botonExit.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent e) {
System.exit(EXIT_ON_CLOSE);
}
});

JPanel panelBotonStart = new JPanel();
panelBotonStart.add(botonStart);
panelBotonStart.add(botonExit);
botonStart.setBorderPainted(false);
botonStart.setBackground(Color.white);
botonExit.setBorderPainted(false);
botonExit.setBackground(Color.white);

splashimg = ImageIO.read(getClass().getResource("splash.jpg"));
ImageIcon splashicon = new ImageIcon(splashimg);
JLabel splashlabel = new JLabel();
splashlabel.setIcon(splashicon);
splash.add(splashlabel);

add(panel,"Center");
panel.add(panelBotonStart,"South");
panelBotonStart.setBackground(Color.black);
panel.add(splash,"North");

setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(1200, 700);
setLocationRelativeTo(null);
setTitle("Forgia Invaders");
setResizable(false);
setVisible(true);
}

public static void main(String [] args) throws IOException
{
new Iniciar();

}
}

我的绘制图形的板:

public class Board extends JPanel implements ActionListener {

private static final long serialVersionUID = 7017738498086742491L;
private Timer timer;
private Craft craft;
private int vidas = 5;
private BufferedImage fondoimg, fondoimg2, fondoimg3;
private ImageIcon fondoicon, fondoiconwin, fondoiconlose;
private ArrayList<Alien> aliens;
private boolean ingame;
private boolean victory;
private int B_WIDTH;
private int B_HEIGHT;
private int puntaje;
boolean nivel2 = false;
boolean nivel3 = false;
boolean nivel4 = false;
boolean bombas = false;
boolean boss = false;
int bossHealth = 200;
private JLabel fondolabel;

private int cantaliens;

JButton restart;
JPanel p;


public Timer getTimer()
{
return timer;
}
public Board(JButton start, JPanel p) throws IOException {





addKeyListener(new TAdapter());
setFocusable(true);
setBackground(Color.BLACK);
setDoubleBuffered(true);
ingame = true;
this.restart = start;
this.p = p;
setSize(1200,700);
craft = new Craft();
timer = new Timer(5, this);
timer.start();

fondoimg = ImageIO.read(getClass().getResource("space3.jpg"));
fondoicon = new ImageIcon(fondoimg);

fondoimg2 = ImageIO.read(getClass().getResource("youlose2.png"));
fondoiconlose = new ImageIcon(fondoimg2);

fondoimg3 = ImageIO.read(getClass().getResource("youwin2.png"));
fondoiconwin = new ImageIcon(fondoimg3);

setLayout(new BorderLayout());
fondolabel = new JLabel();
fondolabel.setIcon(fondoicon);
add(fondolabel,"Center");

//ALIENSINICIALES
aliens = new ArrayList<Alien>();

for (int i = 0; i < 10; i++) {
int xR;
int yR;
xR = 1200 + ((int) (Math.random()*300));
yR = (int) ((Math.random()*550));
aliens.add(new Alien2 (xR, yR));
}
for (int i = 0; i < 10; i++) {
int xR;
int yR;
xR = 1200 + ((int) (Math.random()*500));
yR = (int) ((Math.random()*550));
aliens.add(new Alien3 (xR, yR));
}
for (int i = 0; i < 15; i++) {
int xR;
int yR;
xR = 1200 + ((int) (Math.random()*800));
yR = (int) ((Math.random()*550));
aliens.add(new Alien4 (xR, yR));
}

cantaliens = aliens.size();
}

public int getCantaliens() {
return cantaliens;
}

public void addNotify() {
super.addNotify();
B_WIDTH = getWidth();
B_HEIGHT = getHeight();
}


public void paint(Graphics g) {
super.paint(g);
Graphics2D g2d = (Graphics2D)g;

String msg4 = "Score: "+puntaje;
Font small = new Font("Press Start 2P", Font.BOLD, 54);
FontMetrics metr = this.getFontMetrics(small);
Font small2 = new Font("Press Start 2P", Font.BOLD, 24);

// if (ingame) {
if (ingame && !victory) {
if (craft.isVisible() && vidas >4)
g2d.drawImage(craft.getImage(), craft.getX(), craft.getY(), this);

if (craft.isVisible() && vidas >=0 && vidas <=4)
g2d.drawImage(craft.getImage2(), craft.getX(), craft.getY(), this);

ArrayList<Missile> ms = craft.getMissiles();

for (int i = 0; i < ms.size(); i++) {
Missile m = (Missile)ms.get(i);
g2d.drawImage(m.getImage(), m.getX(), m.getY(), this);
}

for (int i = 0; i < aliens.size(); i++) {
Alien a = aliens.get(i);
if (a.isVisible())
g2d.drawImage(a.getImage(), a.getX(), a.getY(), this);
}

g2d.setColor(Color.WHITE);
g2d.setFont(new Font("Press Start 2P", Font.PLAIN, 15));
g2d.drawString("Enemigos: " + aliens.size()+ " Score: " + puntaje, 90 , 20);

if (vidas > 2)
g2d.setColor(Color.green);
else
if (vidas >1)
g2d.setColor(Color.yellow);
else
{
g2d.setColor(Color.red);
}
g2d.drawString("Vidas: "+vidas, B_WIDTH/2 -30 ,20);

if (boss){

if (bossHealth > 130)
g2d.setColor(Color.green);
else
if (bossHealth > 75)
g2d.setColor(Color.yellow);
else
g2d.setColor(Color.red);

g2d.drawString("Vida Jefe: " + bossHealth, B_WIDTH/2 - 70 , 620);
}

}

if (!ingame && !victory) {

timer.stop();
restart.setText("RESTART");
restart.setVisible(true);
g.setFont(small);
g.setColor(Color.WHITE);
String msg = "Game Over";
g.drawString(msg, (B_WIDTH - metr.stringWidth(msg)) / 2,B_HEIGHT / 2);
g.setFont(small2);
g.drawString(msg4, (B_WIDTH - metr.stringWidth(msg4)) / 2 + 100, B_HEIGHT / 2 +140);

fondolabel.setIcon(fondoiconlose);

}

//GANASTE
if (!ingame && victory) {
String msg = "You Win";
g.setColor(Color.cyan);
g.setFont(small);
g.setColor(Color.white);
g.drawString(msg, (B_WIDTH - metr.stringWidth(msg)) / 2 , B_HEIGHT / 2 );

fondolabel.setIcon(fondoiconwin);
//DISPAROS
final int dispfinal = Craft.getCounter();
String msg2 = "Disparos: "+dispfinal;

g.setColor(Color.white);
g.setFont(small2);
g.drawString(msg2, (B_WIDTH - metr.stringWidth(msg2)) / 2 +180, B_HEIGHT / 2 +60);

//EFECTIVDAD&SCORE
double numerin = Math.round((402 / ((double)dispfinal) * 10)*10) ;
String msg3 = "Efectividad: "+numerin+"%";

g.drawString(msg3, (B_WIDTH - metr.stringWidth(msg3)) / 2 +280, B_HEIGHT / 2 +100);
g.drawString(msg4, (B_WIDTH - metr.stringWidth(msg4)) / 2 +180 , B_HEIGHT / 2 +140);
}

// Toolkit.getDefaultToolkit().sync();
g.dispose();
}
public boolean gamover()
{
return !ingame && !victory;
}

public int getBossHealth() {
return bossHealth;
}
public void setBossHealth(int bossHealth) {
this.bossHealth = bossHealth;
}

public void actionPerformed(ActionEvent e) {

//NIVELES
if (aliens.size()<5 && !nivel2) {

for (int i = 0; i < 5; i++) {
int xR;
int yR;
xR = 1200 + ((int) (Math.random()*1500));
yR = (int) ((Math.random()*550));
aliens.add(new Alien3 (xR, yR));
}
for (int i = 0; i < 15; i++) {
int xR;
int yR;
xR = 1200 + ((int) (Math.random()*1500));
yR = (int) ((Math.random()*550));
aliens.add(new Alien4 (xR, yR));
}
for (int i = 0; i < 5; i++) {
int xR;
int yR;
xR = 1200 + ((int) (Math.random()*1500));
yR = (int) ((Math.random()*550));
aliens.add(new Alien5 (xR, yR));
}

for (int i = 0; i < 5; i++) {
int xR;
int yR;
xR = 1200 + ((int) (Math.random()*1500));
yR = (int) ((Math.random()*550));
aliens.add(new Alien5bis (xR, yR));
}

nivel2 = true;
}

if (aliens.size()<4 && nivel2 && !nivel3) {

for (int i = 0; i < 8; i++) {
int xR;
int yR;
xR = 1200 + ((int) (Math.random()*1500));
yR = (int) ((Math.random()*550));
aliens.add(new Alien5 (xR, yR));
}

for (int i = 0; i < 8; i++) {
int xR;
int yR;
xR = 1200 + ((int) (Math.random()*1500));
yR = (int) ((Math.random()*550));
aliens.add(new Alien5bis (xR, yR));
}

for (int i = 0; i < 18; i++) {
int xR;
int yR;
xR = 1200 + ((int) (Math.random()*1500));
yR = (int) ((Math.random()*550));
aliens.add(new Alien6 (xR, yR));
}

nivel3 = true;
}

if (aliens.size()<3 && nivel3 && !bombas) {

for (int i = 0; i < 10; i++) {
int xR;
int yR;
xR = 1200 + ((int) (Math.random()*1500));
yR = (int) ((Math.random()*550));
aliens.add(new Alien5 (xR, yR));
}
for (int i = 0; i < 10; i++) {
int xR;
int yR;
xR = 1200 + ((int) (Math.random()*1500));
yR = (int) ((Math.random()*550));
aliens.add(new Alien6 (xR, yR));
}

for (int i = 0; i < 30; i++) {
int xR;
int yR;
xR = 1200 + ((int) (Math.random()*50));
yR = (int) ((Math.random()*550));
aliens.add(new Bomba (xR, yR));
}

bombas = true;
}

if (aliens.size()<3 && bombas && !boss) {

for (int i = 0; i < 30; i++) {
int xR;
int yR;
xR = 1200 + ((int) (Math.random()*50));
yR = (int) ((Math.random()*550));
aliens.add(new Slime (xR, yR));
}

aliens.add(new Forgio (1250, 350));
boss = true;
}

if (bossHealth==0) {
ingame = false;
victory = true;
for (int i = 0; i < aliens.size(); i++ )
{
aliens.get(i).setVisible(false);
}
}

ArrayList<Missile> ms = craft.getMissiles();

for (int i = 0; i < ms.size(); i++) {
Missile m = (Missile) ms.get(i);
if (m.isVisible())
m.move();
else ms.remove(i);
}

for (int i = 0; i < aliens.size(); i++) {
Alien a = (Alien) aliens.get(i);
if (a.isVisible())
a.move();
else aliens.remove(i);
}

craft.move();
checkCollisions();
repaint();
}


public void checkCollisions() {

if (bossHealth < 75 && !nivel4)
{
for (int i = 0; i < 20; i++) {
int xR;
int yR;
xR = 1200 + ((int) (Math.random()*50));
yR = (int) ((Math.random()*550));
aliens.add(new Bomba (xR, yR));
}

for (int i = 0; i < 15; i++) {
int xR;
int yR;
xR = 1200 + ((int) (Math.random()*250));
yR = (int) ((Math.random()*550));
aliens.add(new Slimebis (xR, yR));
}

for (int i = 0; i < 15; i++) {
int xR;
int yR;
xR = 1400 + ((int) (Math.random()*250));
yR = (int) ((Math.random()*550));
aliens.add(new Slime (xR, yR));
}

nivel4 = true;
}

Ellipse2D.Double navecita = (Double) craft.getBounds();

for (int j = 0; j<aliens.size(); j++) {
Alien enemigo = (Alien) aliens.get(j);
Rectangle areaEnemigo = enemigo.getBounds();

if (navecita.intersects(areaEnemigo)) {
if (vidas == 0)
{
craft.setVisible(false);
enemigo.setVisible(false);
new FinWav().playSound();
ingame = false;
victory = false;

for (int i = 0; i < aliens.size(); i++ )
{
aliens.get(i).setVisible(false);
}

}
else
{
enemigo.setVisible(false);
vidas--;
new FinWav().playSound();
if (enemigo instanceof Forgio)
{
aliens.add(new ExplosionGde (enemigo.x, enemigo.y));
enemigo.x = 1300;
enemigo.setVisible(true);
}
else
{
aliens.add(new Explosion (enemigo.x, enemigo.y));
}
}
}
}

ArrayList<Missile> listaMisiles = craft.getMissiles();

for (int i = 0; i < listaMisiles.size(); i++) {
Missile misil = (Missile) listaMisiles.get(i);

Rectangle areaMisil = misil.getBounds();

for (int j = 0; j<aliens.size(); j++) {
Alien enemigo = (Alien) aliens.get(j);
Rectangle areaEnemigo = enemigo.getBounds();

if (areaMisil.intersects(areaEnemigo)) {
if (enemigo instanceof Forgio)
if (bossHealth > 0)
{
bossHealth--;
puntaje = puntaje + 100;
}
else
{
puntaje = puntaje + enemigo.getPuntitos();
enemigo.setVisible(false);

}
else {
enemigo.setVisible(false);
puntaje = puntaje + enemigo.getPuntitos();
}
misil.setVisible(false);
new ExplosWAV().playSound();
}
}
}
}


private class TAdapter extends KeyAdapter {

public void keyReleased(KeyEvent e) {
craft.keyReleased(e);
}

public void keyPressed(KeyEvent e) {
craft.keyPressed(e, ingame);
}
}
}

最后,我的工艺课使用了按键/释放:

public class Craft {

private int dx;
private int dy;
private int x;
private int y;
private Image image, image2;
private ArrayList<Missile> missiles;
private int width;
private int height;
private boolean visible;
private static int counter;

public Craft() {

ImageIcon ii = new ImageIcon(this.getClass().getResource("nabe6.png"));
ImageIcon ii2 = new ImageIcon(this.getClass().getResource("nabe7.png"));

image = ii.getImage();
image2 = ii2.getImage();
width = image.getWidth(null)-25;
height = image.getHeight(null)-20 ;
missiles = new ArrayList<Missile>();
visible = true;
x = 77;
y = 241;
}

public void move() {
x += dx*2;
y += dy*2;

if (x < 1) {
x = 1;
}

if (y < 1) {
y = 1;
}
}

public int getX() {
return x;
}

public int getY() {
return y;
}

public static int getCounter() {
return counter;
}

public void setCounter(int counter) {
Craft.counter = counter;
}

public Image getImage() {
return image;
}

public Image getImage2() {
return image2;
}

public ArrayList<Missile> getMissiles() {
return missiles;
}

public void setVisible(boolean visible) {
this.visible = visible;
}

public boolean isVisible() {
return visible;
}

public Ellipse2D getBounds() {
return new Ellipse2D.Double(x, y, width, height);
}

public void keyPressed(KeyEvent e, boolean x) {

int key = e.getKeyCode();

if (key == KeyEvent.VK_SPACE && x) {

fire();
}

if (key == KeyEvent.VK_LEFT) {
dx = -1;
}

if (key == KeyEvent.VK_RIGHT) {
dx = 1;
}

if (key == KeyEvent.VK_UP) {
dy = -1;
}

if (key == KeyEvent.VK_DOWN) {
dy = 1;
}
}


public void fire() {
missiles.add(new Missile(x + width-40, y + height/12));
new LaserWAV().playSound();
counter++;
}

public void keyReleased(KeyEvent e) {
int key = e.getKeyCode();

if (key == KeyEvent.VK_LEFT) {
dx = 0;
}

if (key == KeyEvent.VK_RIGHT) {
dx = 0;
}

if (key == KeyEvent.VK_UP) {
dy = 0;
}

if (key == KeyEvent.VK_DOWN) {
dy = 0;
}
}
}

最佳答案

问题不在于您的代码。问题在于没有多个线程。在制作游戏时,尤其是横向卷轴游戏时,EventQueue 中的所有操作最终都会压垮队列。尝试使用线程缓解队列,您的游戏应该会变得更快。

关于Java 游戏(箭头控制)速度减慢,鼠标在 JFrame 外部移动期间除外,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26548944/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com