- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
所以,我创建了一个横向的“太空入侵者”类型的游戏,我使用了 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/
我正在尝试将 JFrame (bar) 添加到 JFrame (foo),这会强制 bar 在之前关闭foo 可以再次集成。 例如,在我可以再次编写代码之前,必须关闭“About Eclipse”框架
我有一个名为 User 的 JFrame,在其中声明一个名为 id 的变量,并根据某些条件将其设置为特定值。 我需要在称为输出的第二个 JFrame 中使用此变量。 这是我的代码 class Inpu
我有这个问题:我有一个 ArrayList,其中包含一些我想在特定框架中使用的项目,问题是数组列表通过在主类中初始化而变满我的项目。在本类(class)中,我还启动了与其他框架链接的起始框架(登录框架
如何在隐藏一个 Swing 程序的同时将一个 javax.Swing 程序移动到另一个 Swing 程序,以及如何制作可滚动的 JFrame。请帮助我。 最佳答案 在这里你可以找到一个非常good e
所以基本上我有一个 2D 游戏(基本上是过去的仿制品的链接),当你按 e 键时,库存会打开,关闭时会隐藏。问题是,每次我按 e 键时,它都会打开一个包含所有初始值的新库存,我希望它在初始值之后打开一个
我有一个 JFrame(1,主框架),它延续了 JPanel 和 JTable 以及数据。用户可以编辑数据。因此,一个新的 JFrame (2) 打开,用户可以输入新数据。如果他们在第二帧中单击“确定
我有一个新的netbeans“Java应用程序”项目,我试图从主JFrame添加第二个JFrame,用户可以从中加载文件。 所以我有主要的 JFrame main 方法 public static v
我的程序应该在单击按钮时启动第二个 JFrame 并打印一条语句,但它总是启动三个 JFrame 并打印三个语句。我只需要它来打印出一份声明并启动一个 Jframe。这是代码: import java
我目前已经构建了一个使用多个框架的应用程序。但如果我能在 1 帧中使用所有我用过的帧,那就太好了。如下图所示。 因此,如果您按左侧按钮“Speler Overzicht”,它将在右侧面板中向用户显示,
我目前有一个按钮,单击该按钮时,会执行一种方法,该方法创建一个带有加载多个图像的面板的 jframe。如果多次单击此按钮,图像将继续添加到加载到 jframe 上的现有图像上。我应该使用什么代码,以便
为什么无法将JFrame添加到JFrame中?它只是将一个组件添加到容器中。 Java 如何禁止我这样做?是的,我知道这样做没有意义,但我的问题的重点是了解 Swing 机制 - 它在幕后是如何工作的
我创建了一个生成 StartUpWindow 对象的类。其中一个 JButton 组件关闭 JFrame,然后调用一种新类型的框架进行实例化,AdminMainWindow。但是,当 AdminMai
我试图在不显示 JFrame 本身的情况下将 JFrame 渲染为图像(类似于 this 问题所问的内容)。我试过使用这段代码: private static BufferedImage getScr
我正在使用 XFCE 4 桌面的 Debian 8 上编译并运行以下代码。 import javax.swing.JFrame; import javax.swing.JComponent; impo
我有 14 个 JFrame 类和一个 JFrame 类,其中包含一个充当日历的 JTable。我希望当用户从 JTable 日历中选择日期时,更改 14 个 JFrame 类中任何一个文本字段或任何
我有 3 个扩展 JFrame 的对象让我们调用他们 FrameA FrameB FrameC . FrameA是我的主应用程序窗口。来自 FrameA的构造函数如果应用程序未注册我创建 FrameB
我试图简单地创建四个 jtextfields 和一个 jbutton。按下按钮后,我希望输入到 jtextfields 的文本作为参数(p、var、s、f)传递到另一个窗口,该窗口使用给定的参数显示数
这个问题已经有答案了: Close one JFrame without closing another? (2 个回答) 已关闭 6 年前。 我制作了一个程序,其中存在三个jframe。但问题是,当
我正在用 java 构建一个桌面学生管理应用程序。所以我需要关闭当前的 JFRAME,同时另一个 JFRAME 可见(关闭新的 jframe 后,旧的 jframe 应该可见)。你能帮我一下吗? 最佳
我正在开发的应用程序包含一个主 JFrame,用户最终可能会从中打开另一个补充框架。我正在尝试实现应用程序的这种行为,其中一旦主框架最小化,补充框架就会最小化(图标化)。 我正在考虑重写主框架的 se
我是一名优秀的程序员,十分优秀!