![](/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.