我写了一个Breakout游戏,实际上我已经完成了。是我的第一个“大”java项目。这个游戏在我的电脑上运行得很流畅,没有滞后,也没有问题。但是如果我在我的笔记本电脑上运行它(相同的代码),那么它运行的速度会变慢,并且会滞后。我确信我的笔记本电脑的硬件足以运行这个程序。我是否应该使用另一个游戏循环,或者这只是我的笔记本电脑的问题?它们都安装了Windows10。
我在另一台笔记本电脑(Win 7)上做了一个测试,他们的运行没有延迟,在第三台笔记本电脑(Win 10)上也有同样的问题。
好吧,我发现了些东西。当我启动英特尔图形控制面板,然后启动游戏时,它运行得很完美。当我在没有启动英特尔图形控制面板的情况下运行它时,它会滞后。
希望你能帮助我。
这是我的游戏类。
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.Timer;
public class Gameplay extends JPanel implements ActionListener, KeyListener{
private Timer timer;
private int delay = 5;
//Timer tm= new Timer(5, this);
boolean play = false;
int score = 0;
int totalBricks = 28;
// Paddle
int xbat = 355 , velX = 0;
//Image img;
//Ball
int xball = 395, yball = 450;
int ballXdir = 5;
int ballYdir = -3;
Font f1 = new Font("serif", Font.BOLD, 20);
public BrickMap map;
public Gameplay()
{
map = new BrickMap(4,7);
//tm.start();
addKeyListener(this);
setFocusable(true);
setFocusTraversalKeysEnabled(false);
timer = new Timer(delay,this);
timer.start();
}
public void paint(Graphics g)
{
g.setColor(Color.gray);
g.fillRect(0,0,800,700);
// Paddle
g.setColor(Color.blue);
g.fillRect(xbat, 600, 110, 17);
// Ball
g.setColor(Color.green);
g.fillOval(xball, yball, 22,22);
//Won
if(totalBricks <= 0){
play = false;
ballXdir = 0;
ballYdir = 0;
g.setColor(Color.YELLOW);
g.setFont(f1);
g.drawString("You Won " + score,320 ,350);
g.setFont(f1);
g.drawString("Mit Enter neustarten",350 ,660);
}
// Game Over
if(yball > 605){
play = false;
ballXdir = 0;
ballYdir = 0;
g.setColor(Color.YELLOW);
g.setFont(f1);
g.drawString("Game Over, Score: " + score,320 ,400);
g.setFont(f1);
g.drawString("Mit Enter neustarten",350 ,660);
}
// score
g.setColor(Color.YELLOW);
g.setFont(f1);
g.drawString(""+score,5 ,660);
// Bricks
map.draw((Graphics2D)g);
g.dispose();
}
@Override
public void actionPerformed(ActionEvent e)
{
timer.start();
// Paddle----------------------------
if (xbat < 0) {
velX =0;
xbat = 0;
}
if (xbat > 690) {
velX = 0;
xbat = 690;
}
xbat = xbat + velX;
//----------------------------------
// Ball-----------------------------
//Paddle und ball detection
if(play) {
if(new Rectangle(xball, yball, 22, 22).intersects(new Rectangle(xbat, 600, 110, 17))) {
ballXdir = (int) (Math.random()*5);
if(ballXdir <3){
}
else{
ballXdir = -ballXdir;
}
ballYdir = -ballYdir;
}
//ball und bricks
A: for(int i = 0; i < map.map.length; i++){
for(int j = 0; j < map.map[0].length; j++){
if(map.map[i][j] > 0){
int brickX = j * map.brickWigth + 80;
int brickY = i * map.brickHeight + 50;
int brickWidth = map.brickWigth;
int brickHeight = map.brickHeight;
Rectangle rect = new Rectangle(brickX, brickY, brickWidth, brickHeight);
Rectangle ballRect = new Rectangle(xball, yball, 22, 22);
Rectangle brickRect = rect;
// Der Ball trifft auf die Bricks. Ein Brick wird abgezogen und 10 Punkte zur Score hinzugefügt
if(ballRect.intersects(brickRect)){
map.setBrickValue(0 , i , j);
totalBricks --;
score += 10;
if(xball + 22 <= brickRect.x || xball + 1 >= brickRect.x + brickRect.width){
ballXdir = -ballXdir;
} else {
ballYdir = -ballYdir;
}
break A;
}
}
}
}
xball += ballXdir;
yball += ballYdir;
if(xball < 0){
ballXdir = -ballXdir;
}
if(yball < 0){
ballYdir = -ballYdir;
}
if(xball > 778){
ballXdir = -ballXdir;
}
}
//----------------------------------
repaint();
}
@Override
public void keyPressed(KeyEvent e)
{
//Paddle------------------------------------------
int c = e.getKeyCode();
if (c == KeyEvent.VK_RIGHT){
play = true;
velX = +6;
}
if (c == KeyEvent.VK_LEFT){
play = true;
velX = -6;
}
//-----------------------------------------------
//Wenn Enter gedrückt wird
if(c == KeyEvent.VK_ENTER){
if(!play){
play = true;
xball = 395;
yball = 450;
ballXdir = 5;
ballYdir = -3;
xbat = 355;
score = 0;
totalBricks = 28;
map = new BrickMap(4, 7);
}
}
}
@Override
public void keyReleased(KeyEvent e)
{
//Paddle--------------------------------------
velX= 0;
//--------------------------------------------
}
@Override
public void keyTyped(KeyEvent e)
{
}
}发布于 2017-03-20 04:46:05
一些胡乱猜测:这是由于垃圾收集器的压力造成的。
您创建了许多只存在很短时间的对象,例如在paint():g.setFont(new Font("serif", Font.BOLD, 25));中。您可以为每个paint事件创建一个新的Font实例。
如果不查找它,我会猜测Font是一个非常“大”的对象,因此给内存管理带来了很大的压力。
尝试将字体放入全局变量中:
public class gameplay extends JPanel implements ActionListener, KeyListener{
// ...
public final SCORE_FONT = new Font("serif", Font.BOLD, 25);
// ...
public void paint(Graphics g)
{
// ...
g.setFont(SCORE_FONT);
// ...
}
}顺便说一句: Java约定用CamelCase编写类名,例如public class Gameplay。
https://stackoverflow.com/questions/42890535
复制相似问题