![](/img/trans.png)
[英]How do you draw the Mandelbrot Set in Java using SWING/AWT?
[英]How do you solve lagging in Java awt/swing image printing?
我试图用Java swing / awt做一个简单的游戏。 在屏幕上打印和移动图像时出现滞后问题。
这是我的代码如下:
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.io.File;
import java.util.ArrayList;
import javax.imageio.ImageIO;
import javax.swing.*;
public class StarDef extends JFrame implements Runnable, KeyListener{
private BufferedImage back;
private boolean start = false, end = false;
public int w = 1500, h = 800, commandx = 200, commandy = 100, ground = 500, mineral = 100;
private int mineralx = 0, mineraly = commandy + 104;
private int dronecnt = 0;
private ArrayList<Drone> DrList = null;
private ArrayList<Enemy> EnList = null;
private ArrayList<Building> BuildList = null;
private ArrayList<Allies> AlyList= null;
public Image imagearr[] = new Image[10];
private boolean makedrone = false, NeedMinerals = false;
public int picnum = 1;
private int OrderBuild = 0;
public static void main(String[] args){
Thread t = new Thread(new StarDef());
t.start();
}
public StarDef(){
back = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
DrList = new ArrayList<>();
BuildList = new ArrayList<>();
EnList = new ArrayList<>();
AlyList = new ArrayList<>();
this.addKeyListener(this);
this.setSize(w,h);
this.setTitle("Starcraft");
this.setResizable(false);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
try {
imagearr[0] = ImageIO.read(new File("Char/Command.png"));
imagearr[1] = ImageIO.read(new File("Char/droneleft.png"));
imagearr[2] = ImageIO.read(new File("Char/droneright.png"));
imagearr[3] = ImageIO.read(new File("Char/Mineral.png"));
imagearr[4] = ImageIO.read(new File("Char/barracks.png"));
} catch (Exception e){
e.printStackTrace();
}
}
public void initGame(){
DrList.clear();
mineral = 100;
}
public void draw(){
Graphics gs = back.getGraphics();
gs.setColor(Color.white);
gs.fillRect(0,0,w,h);
gs.setColor(Color.DARK_GRAY);
gs.fillRect(0,ground,w,200);
if (!end) {
gs.drawImage(imagearr[0], commandx, commandy, null); // First Image-Command Center
gs.drawImage(imagearr[3], mineralx,mineraly,null); // Second Image-Mineral
for (int i = 0; i < DrList.size(); i++) { //Printing Drones
Drone m = DrList.get(i);
gs.drawImage(imagearr[m.state], m.x, m.y, null); //Drawing Drones
m.moveDr(); // Moving the Drone
}
for (int i = 0; i < BuildList.size(); i++){ //Printing Building
Building bd = BuildList.get(i);
if(bd.buildingtype == 'R'){
gs.drawImage(imagearr[4], bd.x, bd.y, null); // Drawing Building-Problem starts..?
}
}
gs.drawImage(imagearr[0], commandx, commandy, null);
}
gs.setColor(Color.black);
gs.drawString("mineral : " + mineral, 10,50);
gs.drawString("Drones : " + DrList.size(), 10, 70);
Graphics ge = this.getGraphics();
ge.drawImage(back, 0,0,w,h,this);
}
public void run(){
try{
int timer = 10;
while (true){
Thread.sleep(timer);
if(start){
if (makedrone) {
makedrone();
}
if (OrderBuild>0){
makeBuilding(OrderBuild);
}
}
draw();
}
} catch (Exception e){
e.printStackTrace();
}
}
public void makeBuilding(int buildingnumber){
int bdx, bdy;
char BuildingType;
if(buildingnumber == 1){
bdx = 500;
bdy = 100;
BuildingType = 'R';
Building barracks = new Building(this, bdx, bdy, BuildingType);
BuildList.add(barracks);
}
}
public void makedrone() {
if (mineral >= 50) {
int dronex = commandx;
int droney = commandy+129;
Drone dr = new Drone(this ,dronex, droney);
DrList.add(dr);
dronecnt++;
mineral -= 50;
makedrone = false;
} else if (mineral < 50) {
NeedMinerals = true;
makedrone = false;
}
}
public void keyPressed(KeyEvent ke){
switch (ke.getKeyCode()){
case KeyEvent.VK_ENTER:
start = true;
end = false;
break;
case KeyEvent.VK_D:
makedrone = true;
break;
case KeyEvent.VK_R:
OrderBuild = 1;
break;
}
}
public void keyReleased(KeyEvent ke){
switch ((ke.getKeyCode())){
}
}
public void keyTyped(KeyEvent ke) {
}
}
当您编译代码时,前几个固定图像看起来很好。
在运动图像(无人机)看起来不错之后,但是当您召唤下一个静止图像(建筑物)时,严重的滞后开始出现并且运动无人机的速度明显降低。
建筑物约为300 * 150像素,无人机为40 * 30像素。
这个问题是什么原因造成的? 是因为代码(召唤图像的方式),图片的大小,还是计算机(我正在使用笔记本电脑(LG Gram 14in))造成的?
首先不使用Graphics ge = this.getGraphics();
。
因为您还使用自己的Thread
,所以冒着线程竞争情况的风险,这可能会导致读取/绘制不干净。
首先了解Swing绘画在API功能中的实际工作方式和工作方式。
首先看一下执行自定义绘画 , AWT中的绘画以及Swing中的Swing和并发
对于监听器的键盘输入, KeyListener
也是一个糟糕的选择,您应该使用Key Bindings API-有关更多详细信息,请参见如何使用键绑定 。
将内容添加到ArrayList
可能会导致ArrayList
经历一个增长周期,这可能会消耗时间并迫使更长的GC周期。 考虑使用初始容量为ArrayList
种子,这将有助于缩短增长周期之间的间隔。
专注于将“更新”逻辑与“绘制”逻辑分开,它可以帮助您发现性能问题
您也可以看看
这证明了提高Swing渲染性能的技术的真实性。
如果这些仍然不能使您达到所需的水平,那么您将需要使用BufferStrategy
探索
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.