java图像绘画优化

时间:2013-07-26 03:05:46

标签: java image optimization paintcomponent

我正在开发一款2D java自顶向下飞机游戏。这是一个高中的课程,但我毕业前没有完成它。无论如何,我仍然是Java的初学者,所以我不知道如何扫描我的代码以查看它被挂起的地方。我能够评论出代码并发现我可怕的FPS的原因是我必须绘制的大量图像(飞机,导弹,爆炸和背景)。背景由两个图像组成,这些图像从上到下滚动,然后传送回顶部,让玩家感觉他们正在移动。删除它们会将我的FPS从14跳到45-50左右。我的FPS计算器非常糟糕,只计算当前程序实例的平均FPS。 (我无法弄清楚如何仅计算当前的FPS,抱歉)。

我见过很多人询问如何优化移动背景,但我没有看到任何移动背景的东西。

放一个背景而不是另一个只能将我的FPS提高到20,这是不错的但是我想多一点因为我需要添加更多功能,这可能会减慢它的速度,更不用说看到景观和然后是一个灰色的盒子然后更多的景观。

我相信我正在和Swing一起工作,但你可能想检查一下,正如我所说,我仍然是一个初学者。

修改的 此外,游戏在旧计算机上以更好的FPS运行(即2008年及更早版本) 结束编辑

继承我的主要课程我发表了一个大评论,上面写着“看这里!!!!”关于背景材料的地方。大多数东西都在现场声明和油漆的顶部附近。在ActionPerformed的底部最后几行代码中有实际的运动内容:

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.*;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;

public class runTime extends JPanel implements ActionListener, KeyListener {
    static String pPlane;
    long start = System.currentTimeMillis();
    public static void main(String[] args0) {
        planeSelect ps = new planeSelect();
        while(true){
            if(ps.getPlane()=="f15.png"||ps.getPlane()=="f35.png"||ps.getPlane()=="a10.png"){
                pPlane=ps.getPlane();
                break;
            }
        }
        ps.pullThePlug();
        runTime rt=new runTime(Toolkit.getDefaultToolkit().getScreenSize());
    }
    entity e = new entity();                                    //creates an entity so all other subclasses can initialize
    Timer t = new Timer(5, this);                               // refresh screen
    int count = 0;                                              //used for deceleration
    int aam = 0;                                                //number of active AAMs or Missiles
    final static int ammo = 10;                                 //number of max active missiles
    missile[] fox3 = new missile[ammo];                         // missile array
    BufferedImage[] msl = new BufferedImage[ammo];              //Image array
    final static int maxBaddies = 8;                            //Maximum number of badguys
    badGuy[] baddies = new badGuy[maxBaddies];                  //Badguy array
    BufferedImage[] planes = new BufferedImage[maxBaddies];     //Image array for Baddies
    int plane = 0;                                              //number of flying planes
    badGuyMissile[] bmsl = new badGuyMissile[maxBaddies];       //Array of badGuyMissiles
    BufferedImage[] bmslImg = new BufferedImage[maxBaddies];    //Array of badGuyMissile images
    int[] bgMslUse = new int[maxBaddies];                       //used badGuyMissiles
    final static int speed = 6;                                 //plane speed and basis for other objects
    static int playerSpeed = speed;                             //player speed (can be increased with afterburner)
    final static int decel = 1;                                 //deceleration delay
    playerPlane f15;                                            //Playerplane Object
    int altCount2=-1;                                           //Annother count storage variable for slowing fuel use to less than instantaneous
    final static int fuel = 100;                                //Fuel count for Afterburner
    int remainingFuel = fuel;                                   //Fuel displayed in HUD for Afterburner
    boolean[] checkFire=new boolean[maxBaddies];                //prevents badguys from firing more than one missile
    Image[] ammoCount = new Image[ammo];                        //Images for the Ammo count in the HUD (FIRED)
    Image[] ammoCount2 = new Image[ammo];                       //Images for the Ammo count in the HUD (LIVE)
    int w=0;
    int h=0;
    int array = (maxBaddies*2)+ammo+1;
    //storage in order
        //first maxBaddies is badguy planes
        //second maxBaddies is badguy missiles
        //ammo is player missiles
        //last is player plane
    int velX=0;                                                 //X coordinate modifier for player plane
    int velY=0;                                                 //Y coordinate modifier for player plane
    int score=0;                                                //Player Score
    boolean pause = false;                                      //boolean for pausing the game
    public runTime(Dimension screenSize) {
        w=(int)(screenSize.getWidth()/2);
        h=(int)(screenSize.getHeight()/2);
        f15=new playerPlane(w,h,pPlane);
        JFrame window = new JFrame("AIR ASSAULT");
        window.setBounds(0,0,getWidth(), getHeight());
        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        Container c = window.getContentPane();
        c.add(this);
        t.start();
        window.setVisible(true); 
        System.out.println("start");
        for(int i=0;i<maxBaddies;i++){
            checkFire[i]=false;
        }
        for(int i=0;i<ammo;i++){
            ammoCount[i]=(new ImageIcon("ammo.png")).getImage();
            ammoCount2[i]=(new ImageIcon("AAM.png")).getImage();
        }
        try {
            player = ImageIO.read(new File(pPlane));
        } catch (IOException e1) {
            e1.printStackTrace();
        }
    }
    Image img = (new ImageIcon("tbg.gif")).getImage();      //Background image 1
    Image img2 = (new ImageIcon("tbg.gif")).getImage();     //Background image 2
    int[] test = new int[10];
    //LOOK HERE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    int bgy=0;                                              //Background X coordinate
    int bgx=0;                                              //Background Y coordinate
    long fps;                                               //FPS counter
    static BufferedImage player;                            //Player Image Variable
    Image[] boom = new Image[array];                        //explosion gifs, 1 for each plane
    int[] boomLocX = new int[array];                        //X coordinates for explosion
    int[] boomLocY = new int[array];                        //Y coordinates for explosion
    int[] altCount = new int[array];                        //count storage for explosion gif expiration
    //storage in order
        //first maxBaddies is badguy planes
        //second maxBaddies is badguy missiles
        //ammo is player missiles
        //last is player plane
//FROM SCREEN *****
    public int getWidth(){
        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        double width = screenSize.getWidth();
        if(width>1024){
            width=1024;
        }
        return (int)width;
    }
    public int getHeight(){
        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        double height = screenSize.getHeight();
        if(height>1024){
            height=1024;
        }
        return (int)height;
    }
//RUNTIME RESUME *****
    //PAINT COMPONENT *****
    public void paintComponent(Graphics g){
        //init *****
        addKeyListener(this);
        setFocusable(true);
        setFocusTraversalKeysEnabled(false);
        super.paintComponent(g);
        //BACKGROUND ***** LOOK HERE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        g.drawImage(img, bgx, bgy, null);
        g.drawImage(img2, bgx, bgy-1024, null);
        //HUD MISSILES *****
        for(int i=0;i<aam;i++){
            g.drawImage(ammoCount[i],((ammo-i)*15)-5,getHeight()-120,null);
        }
        for(int i=0;i<ammo-aam; i++){
            g.drawImage(ammoCount2[i],10+i*15,getHeight()-120,null);
        }
        //INITIALIZE TEXT APPERANCE *****
        //int screenRes = Toolkit.getDefaultToolkit().getScreenResolution();
        //int fontSize = (int)Math.round(12.0 * screenRes / 72.0);
        Font font = new Font("Arial", Font.BOLD, 15);
        g.setFont(font);
        //HUD FPS ******
        g.drawString("FPS: "+fps, 20, 20);
        //HUD SCORE *****
        g.drawString("KILL COUNT: "+score, 20, getHeight()-140);
        //HUD FUEL
        g.drawString("FUEL:", 20, getHeight()-155);
        //SET COLOR TO RED
        if(remainingFuel>=fuel/2+fuel/6){
            g.setColor(Color.GREEN);
        }else if(remainingFuel>=fuel/3){
            g.setColor(Color.ORANGE);
        }else{
            g.setColor(Color.RED);
        }
        g.fillRect(70, getHeight()-166, remainingFuel*2, 10);
        g.setColor(Color.BLACK);
        g.drawRect(70, getHeight()-166, fuel*2, 10);
        //MISSILES *****
        for(int i=0;i<aam;i++){ //For Each Missile
            if(i<ammo&&(fox3[i]!=null&&msl[i]!=null)){ //if missile exists
                if(fox3[i].findY()>getHeight()){ //if not on screen
                    //destroy
                    fox3[i]=null;
                    msl[i]=null;
                }else if(fox3[i]!=null&&fox3[i]!=null){
                    g.drawImage(msl[i], fox3[i].findX(), fox3[i].findY(), null);
                    fox3[i].aamMove(speed);
                }
            }
        }
        //PLAYER PLANE *****
        g.drawImage(player,f15.findX(),f15.findY(),null);
        //BAD GUYS *****
        for(int i=0;i<maxBaddies;i++){  //for all badguys
            if(baddies[i]!=null){       //checks weather baddies exists
                g.drawImage(planes[i], baddies[i].findX(), baddies[i].findY(), null);
                baddies[i].move(speed);
            }else{  
                // THESE LINES ARE FOR BADGUY MISSILES (SEE BELOW) (resets the missiles for next plane)
                bgMslUse[i]=0; 
                checkFire[i]=false;
            }
        }
        //BadGuy Missile draw*****
        for(int i=0;i<maxBaddies;i++){ //counts bad guys
            if(planes[i]!=null&&baddies[i]!=null&&checkFire[i]==false&&baddies[i].findY()>50&&f15.findY()-baddies[i].findY()>0&&f15.findX()-baddies[i].findY()<750&&bmslImg[i]==null&&Math.abs(baddies[i].findX()-f15.findX())<=90&&bgMslUse[i]==0){
            //checks whether
                //the plane and baddies exists
                //plane has fired
                //plane is off screen
                //plane is in front of target
                //plane is not too far from the target
                //the missile has not been created
                //the plane is close enough on the X axis
                //the plane has not already fired a missile
                bmsl[i]=new badGuyMissile(baddies[i].findX(),baddies[i].findY());   //intializes missile object
                try {                                                               //initializes image
                    bmslImg[i] = ImageIO.read(new File("badAAM.png"));
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
                checkFire[i]=true;                                                  //prevents an infinite number of missiles
                bgMslUse[i]++;
            }else if(i<maxBaddies&&bmslImg[i]!=null&&bmsl[i]!=null&&checkFire[i]==true){//draws any previously created missiles
                g.drawImage(bmslImg[i],bmsl[i].findX(),bmsl[i].findY(),null);
                bmsl[i].aamMove(speed);                                                 //missile mover
            }
            if(checkFire[i]==false){                                                    //resets all missile variables
                bmsl[i]=null;
                bmslImg[i]=null;
                checkFire[i]=false;
            }
        }
        //collision implementation and explosion paint *****
        for(int i=0;i<array;i++){
            if(altCount[i]!=-1&&count-altCount[i]<=17&&boomLocX[i]!=-1&&boomLocY[i]!=-1){
                g.drawImage(boom[i],boomLocX[i],boomLocY[i],null);
            }else{
                altCount[i]=-1;
            }
            if(altCount[i]==17){
                altCount[i]=-1;
            }
        }
    }
    // BEGIN COLCHECK *****
    //**
    public void colCheck(){
        for(int i=0;i<plane;i++){   //counts existing bad planes
            for(int j=0;j<aam;j++){ //counts player missiles
                if(i<maxBaddies&&j<aam&&baddies[i]!=null&&fox3[j]!=null){ //double check existance
                    Rectangle r1 = baddies[i].getBounds();                    //creates rectangles around both objects
                    Rectangle r2 = fox3[j].getBounds();                       //THIS IS A COLLISION FOR BADGUYS AND PLAYER MISSILES
                    if(r1.intersects(r2)){                                    //checks for overlap on rectangles
                        boomLocX[i]=(baddies[i].findX()+fox3[j].findX())/2;   //Stores X coordinates for explosion (see archive order on declaration of int array)
                        boomLocY[i]=(baddies[i].findY()+fox3[j].findY())/2;   //Stores Y coordinates for explosion
                        altCount[i]=count;                                    //Initializes altCount, the timer for the explosions existance
                        boom[i] = (new ImageIcon("splosion.gif")).getImage(); //Initializes the explosion gif
                        baddies[i]=null;                                      //Nullifies object(s)
                        fox3[j]=null;
                        score++;                                              //only for this collision increments score
                        }
                }
                for(int k=0; k<maxBaddies;k++){                               //counts badguys who fire missiles
                    if(bgMslUse[k]!=0&&bmsl[k]!=null){                        //checks to see if there is a badguy missile
                        if(fox3[j]!=null){
                            Rectangle r1 = fox3[j].getBounds();
                            Rectangle r2 = bmsl[k].getBounds(); //THIS IS A COLLISION FOR BADGUY MISSILES AND PLAYER MISSILES
                            if(r1.intersects(r2)){
                                boomLocX[maxBaddies+k]=bmsl[k].findX()-50;
                                boomLocY[maxBaddies+k]=fox3[j].findY()-50;
                                altCount[maxBaddies+k]=count;
                                boom[maxBaddies+k] = (new ImageIcon("splosion.gif")).getImage();
                                fox3[j]=null;
                                bmsl[k]=null;
                            }
                        }
                        if(f15!=null&&bmsl[k]!=null){
                            Rectangle r1 = bmsl[k].getBounds();
                            Rectangle r2 = f15.getBounds(); //THIS IS A COLLISION FOR BADGUY MISSILES AND THE PLAYER
                            if(r1.intersects(r2)){
                                boomLocX[maxBaddies*2+ammo]=(bmsl[k].findX()+f15.findX())/2;
                                boomLocY[maxBaddies*2+ammo]=(bmsl[k].findY()+f15.findY())/2;
                                altCount[maxBaddies*2+ammo]=count;
                                boom[maxBaddies*2+ammo] = (new ImageIcon("splosion.gif")).getImage();
                                bmsl[k]=null;
                                bmslImg[k]=null;
                                System.out.println("DEAD");
                            }
                        }
                    }
                }
            }
            for(int j=0;j<maxBaddies;j++){
                if(i<maxBaddies&&i!=j&&baddies[i]!=null&&baddies[j]!=null){
                    Rectangle r1 = baddies[i].getBounds();
                    Rectangle r2 = baddies[j].getBounds();//THIS IS A COLLISON FOR MULTIPLE BAD GUYS
                    if(r1.intersects(r2)){
                        baddies[i]=null;
                    }
                }
            }
            if(i<maxBaddies&&baddies[i]!=null&&f15!=null){
                Rectangle r1 = baddies[i].getBounds();
                Rectangle r2 = f15.getBounds(); //THIS IS A COLLISION FOR BADGUYS AND PLAYERS
                if(r1.intersects(r2)){
                    boomLocX[i]=(baddies[i].findX()+f15.findX())/2;
                    boomLocY[i]=(baddies[i].findY()+f15.findY())/2;
                    altCount[i]=count;
                    boom[i] = (new ImageIcon("splosion.gif")).getImage();
                    baddies[i]=null;
                    System.out.println("DEAD");
                }
            }
        }   
    }
    //END COL CHECK *****
    //*/
    /**
    //FINE COL CHECK *****
        //this tests individual pixels for transparency
    public boolean withinBounds(BufferedImage a, BufferedImage b) {
        int z = 225;
        for(int i = a.getWidth(null);i>=0;i--){                     //for a.width
            for(int j = a.getHeight(null);j>=0;j--){                //for a.height
                if(a.getRGB(j,i)<z){
                    for(int k = b.getWidth(null);k>=0;k--){         //for b.width
                        for(int l = b.getHeight(null);l>=0;l--){    //for b.height
                             if(b.getRGB(l,k)<z){ 
                                if(i==k&&j==l){                     //coordinates are the same
                                    System.out.println("TRUE");
                                    return true;                    //collision
                                }
                            }
                        }
                    }
                }
            }
        }
        return false;                                               //no collision
    }
    //rgb = getPixelData(img, i, j);
    // */
    public int inboundsX(){
        if(f15.findX()<0){
            return 1;
        }
        if(f15.findX()>getWidth()-f15.getWidth()){
            return -1;
        }
        return 0;
    }
    public int inboundsY(){
        if(f15.findY()<0){
            return 1;
        }
        if(f15.findY()>(getHeight()-f15.getHeight())-45){
            return -1;
        }
        return 0;
    }
    public void afterburners(){
        if(altCount2!=count){
            altCount2=count;
            if(remainingFuel>0){
                playerSpeed=speed*2;
                remainingFuel--;
            }else{
                playerSpeed=speed;
            }
        }else{
            playerSpeed=speed;
        }
    }
    public void refuel(){
        if(remainingFuel<fuel){
            playerSpeed=speed;
            remainingFuel++;
        }
    }
    boolean fire = true; //allows for the firing of a missile to prevent all from being fired at one time
    boolean mg = false;  //allowss for multiple bullets to be fired in one keypress
    //LISTENER STUFF BELOW HERE *****
    boolean[] acceleration={false,false,false,false}; //allows for independent deceleration in any direction
    public void keyPressed(KeyEvent e) {
        int c = e.getKeyCode();
        if(pause==false){
            //MOVEMENT
            if (c == KeyEvent.VK_A){
                acceleration[0]=true;
                velX=-playerSpeed;
            }
            if (c == KeyEvent.VK_D){
                acceleration[1]=true;
                velX=playerSpeed;
            }
            if (c == KeyEvent.VK_S){
                acceleration[2]=true;
                velY=speed;
            }
            if (c == KeyEvent.VK_W){
                acceleration[3]=true;
                velY=-playerSpeed;
            }
            //MISSILE FIRE
            if (c == KeyEvent.VK_SPACE&&aam<ammo&&fire==true){
                fire=false;
                fox3[aam] = new missile(f15.findX(),f15.findY());
                try {
                    msl[aam] = ImageIO.read(new File("AAM.png"));
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
                aam++;
            }
            //MISSILE RELOAD
            if(c == KeyEvent.VK_R){
                for(int i = 0; i<aam; i++){
                    fox3[i]=null;
                }
                aam=0;
            }
            //AFTERBURNERS
            if(c == KeyEvent.VK_SHIFT){
                mg=true;
            }

        }
        //PAUSE
        if(c == KeyEvent.VK_P){
            if(pause==true){
                pause=false;
            }
        }
        if(c == KeyEvent.VK_O){
            if(pause==false){
                pause=true;
            }
        }
    }
    public void keyReleased(KeyEvent e) {
        if(pause==false){
            int c = e.getKeyCode();
            if(c == KeyEvent.VK_A&&inboundsX()!=1){             //left
                acceleration[0]=false;
            }
            if(c == KeyEvent.VK_D&&inboundsX()!=-1){            //right
                acceleration[1]=false;
            }
            if(c == KeyEvent.VK_S&&inboundsY()!=-1){            //down
                acceleration[2]=false;
            }
            if(c == KeyEvent.VK_W&&inboundsY()!=1){             //up
                acceleration[3]=false;
            }
            if(c == KeyEvent.VK_SPACE&&fire==false){
                fire=true;
            }
            if(c == KeyEvent.VK_SHIFT){
                mg=false;
            }
        }
    }
    public void keyTyped(KeyEvent arg0) {   
    }
    public void actionPerformed(ActionEvent arg0) {
        if(pause==false){
            if(mg==true){
                afterburners();
            }else{
                refuel();
            }
            count++;                                //increments count the game regulator most intervals come from count
            if(f15!=null){
                if(inboundsY()==0&&inboundsX()==0){ //checks weather the new location will be on screen
                    f15.setLoc(velX,velY);          //refreshes F15 location
                }else if(count>5){                              //if any position not on screen set location to be on screen
                    if(inboundsX()==-1){                //right
                        velX-=playerSpeed;
                    }else if(inboundsX()==1){           //left
                        velX+=playerSpeed;
                    }
                    if(inboundsY()==-1){                //bottom
                        velY-=playerSpeed;
                    }else if(inboundsY()==1){           //top
                        velY+=playerSpeed;
                    }
                    f15.setLoc(velX,velY);          //refreshes F15 Location
                }
            }
            if(plane<maxBaddies){                   //if max planes has not been reached
                for(int i=0; i<maxBaddies;i++){     //for all badguys
                    if(baddies[i]==null){           //badguy does not yet exist
                        baddies[i] = new badGuy((int)(Math.random()*w)%1024,h-600-(int)(Math.random()*500));
                        //creates them in random X Y positions above the screen to space them out
                        try {
                            planes[i] = ImageIO.read(new File("Su-27.png"));
                        } catch (IOException e1) {
                            e1.printStackTrace();
                        }
                        plane++;
                    }
                }
            }
            for(int i=0;i<plane;i++){  //nullifies bad planes so they can respawn
                //works for off screen and for collisions
                if(i<maxBaddies&&((baddies[i]!=null&&baddies[i].findY()>1200)||baddies[i]==null||planes[i]==null)){
                    baddies[i]=null;
                    planes[i]=null;
                    plane--;
                }
            }
            for(int i = 0; i<aam; i++){             //For each missile
                if(fox3[i]==null||msl[i]==null){    //if partially null make entirely null
                    fox3[i]=null;
                    msl[i]=null;
                }
            }
            //DECELERATION
            if(count%decel==0&&acceleration[0]==false&&(velX!=0||velY!=0)){
                if(velX<0)
                    velX++;
            }
            if(count%decel==0&&acceleration[1]==false&&(velX!=0||velY!=0)){
                if(velX>0)
                    velX--;
            }
            if(count%decel==0&&acceleration[2]==false&&(velX!=0||velY!=0)){
                if(velY>0)
                    velY--;
            }
            if(count%decel==0&&acceleration[3]==false&&(velX!=0||velY!=0)){
                if(velY<0)
                    velY++;
            }
            //BACKGROUND MOVEMENT !!!!!!!!!!!!!!!!!!LOOK HERE!!!!!!!!!!!!!!!!
            if(bgy>1024){ //if background image is greater than 1024 its entirely off the screen and is moved down
                bgy-=1024;
            }else{ //otherwise it is incrimented
                bgy+=speed+3;
            }
            //COLISIONS
            colCheck(); //checks collisions for badguys and missiles
            //REPAINT
            Toolkit.getDefaultToolkit().sync();
            repaint();  //repaints the screen by calling the repaint method
            //FPS CALCULATE *****
            long deltaTime = System.currentTimeMillis();
            fps=1000/((deltaTime-start)/count);
        }
    }
}

对于大量代码表示歉心,感谢您的帮助。如果我需要发布不同的代码或者我可以删除一些代码,请告诉我。

0 个答案:

没有答案