Java: Как я могу нарисовать эти изображения быстрее? - PullRequest
0 голосов
/ 05 ноября 2011

Хорошо, поэтому я создаю игру, в которой пользователь перемещает изображение (называемое «карта» в моем коде) позади персонажа в игре, поэтому создается впечатление, что персонаж движется.

Во время работы программы наблюдаются умеренные падения производительности, а фоновое изображение («карта») отстает и не всегда перерисовывается.

Вот класс, который мой основной класс призывает нарисовать картины:

public graphics(int z,int s, int f)
{
    x = z;
    y = s;
    d = f;
    try {
    map = ImageIO.read(new File("background.png"));
    //br = ImageIO.read(new File("blackrectangle.jpg"));
    s0 = ImageIO.read(new File("spriteshoot0.png"));
    s10 = ImageIO.read(new File("spriteshoot10.png"));
    s20 = ImageIO.read(new File("spriteshoot20.png"));
    s30 = ImageIO.read(new File("spriteshoot30.png"));
    s40 = ImageIO.read(new File("spriteshoot40.png"));
    s50 = ImageIO.read(new File("spriteshoot50.png"));
    s60 = ImageIO.read(new File("spriteshoot60.png"));
    s70 = ImageIO.read(new File("spriteshoot70.png"));
    s80 = ImageIO.read(new File("spriteshoot80.png"));
    s90 = ImageIO.read(new File("spriteshoot90.png"));
    s100 = ImageIO.read(new File("spriteshoot100.png"));
    s110 = ImageIO.read(new File("spriteshoot110.png"));
    s120 = ImageIO.read(new File("spriteshoot120.png"));
    s130 = ImageIO.read(new File("spriteshoot130.png"));
} catch (IOException e) {}
}
public void moveZ(int a,int b)
{
    xz+=a;
    yz+=b;
}

public void move(int a,int b)
{
    x+=a;
    y+=b;
}

public void angle(int t)
{
    q=t;

}



public void paintComponent(Graphics g) {

        g.drawImage(map,x,y,this);

        if (q==1)
        g.drawImage(s0,599,340,null);

        if (q==2)
        g.drawImage(s10,599,340,null);

        if (q==3)
        g.drawImage(s20,599,340,null);

        if (q==4)
        g.drawImage(s30,599,340,null);

        if (q==5)
        g.drawImage(s40,599,340,null);

        if (q==6)
        g.drawImage(s50,599,340,null);

        if (q==7)
        g.drawImage(s60,599,340,null);

        if (q==8)
        g.drawImage(s70,599,340,null);

        if (q==9)
        g.drawImage(s80,599,340,null);

        if (q==10)
        g.drawImage(s90,599,340,null);

        if (q==11)
        g.drawImage(s100,599,340,null);

        if (q==12)
        g.drawImage(s110,599,340,null);

        if (q==13)
        g.drawImage(s120,599,340,null);

        if (q==14)
        g.drawImage(s130,599,340,null);
   }}

Поэтому мне интересно, как я могу быстрее отобразить изображение "карты" или найти альтернативный маршрут для решения этой проблемы производительности.

Примечание ** Этот код создается как объект в моем основном классе, и BufferedImages не читаются из файлов каждый раз, когда это выполняется (насколько я знаю). Кроме того, перекрасить (); метод вызывается каждые 16 миллисекунд в моей программе (и да, я пытался увеличить это время, и проблемы все еще остаются). Вот фрагмент таймера, использованного для перекраски кадра:

TimerTask task = new TimerTask () {

    public void run()       {

        if (onU)
            g.move(0,3);

        if (onL)
            g.move(3,0);

        if (onD)
            g.move(0,-3);

        if (onR)
            g.move(-3,0);
        //System.out.println(ze.getX(650,400,650,0,xZ,yZ));
        //System.out.println(ze.getY(650,400,650,0,xZ,yZ));
        if(onR||onL||onD||onU)
        gameSurface.repaint();
    }};

Любая помощь очень ценится, спасибо.

Ответы [ 4 ]

1 голос
/ 05 ноября 2011

Если вы пишете игру, вы должны использовать игровой движок. Написание качественных игр - трудная задача, и перерисовка всего, что происходит на экране, не поможет. Другие умные люди уже решили эти проблемы, и вы можете воспользоваться их накопленной работой, а не пытаться изобретать велосипед.

Я не специалист по игровым движкам, но первое попадание в Google по запросу "java game engine" - jmonkeyengine.com . Может тебе стоит попробовать.

1 голос
/ 05 ноября 2011

Вы можете кэшировать часто используемые изображения через ResourceBundle. Следующий код обеспечивает доступ к кэшу для изображений, хранящихся в банке или по абсолютному пути как ImageIcons. При первом доступе с помощью изображение будет сохранено в Hashtable. Последующие вызовы к тому же изображению будут поисковыми. Этот класс должен быть установлен в пакете «по умолчанию»:

import java.util.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.net.*;

import javax.imageio.ImageIO;
import javax.swing.*;

/**
 * ImageBundle is a ResourceBundle that retrieves the content of an image from an image file with supported extension.
 */
public class ImageBundle extends ResourceBundle {
    private static final String RESOURCE = "MyApp";
    private String __fileSuffix;
    /**
     * @uml.property  name="__KEYS"
     */
    private static final Vector<String> __KEYS;
    private static Hashtable<String, ImageIcon> __TABLE;

    static {
        __KEYS  = new Vector<String>();
        __KEYS.addElement(RESOURCE);
        __TABLE = new Hashtable<String, ImageIcon>();
    }

    /**
     * Load image file stored in a JAR classpath
     * @param imageName the filename of the image
     * @return the ImageIcon of the image file
     */
    private ImageIcon __loadImageFromJar(String imageName) {
        String path = ""; //define the file path of the image file in imageName itself

        String imagePath = path + imageName + __fileSuffix;
        ImageIcon icon;
        URL url;

        icon = (ImageIcon)__TABLE.get(imageName);

        if(icon != null)
            return icon;

        url = ImageBundle.class.getResource(imagePath);

        icon = new ImageIcon(url);
        __TABLE.put(imageName, icon);

        return icon;
    }

    /**
     * Load image file stored in a given path
     * @param imageName the filename of the image
     * @return the ImageIcon of the image file
     */
    @SuppressWarnings("unused")
    private ImageIcon __loadImageFromExternalSource(String imageName) {
        String path = System.getenv("MY_APP_HOME_PATH");

        String imagePath = ((path != null) ? (path + imageName + __fileSuffix) : (imageName + __fileSuffix));
        ImageIcon value;

        value = (ImageIcon)__TABLE.get(imageName);

        if(value != null){
            //Outils.debugMessage("Cached " + imagePath + "> " + imageName + ": " + value);
            return value;
        }
        else {
            //Outils.debugMessage("New " + imagePath + "> " + imageName + ": " + value);
        }

        ImageIcon property = null;
        BufferedImage image = null;
        try {
            image = ImageIO.read(new File(imagePath));
        } catch (IOException e) {
            e.printStackTrace();
        }
        property = new ImageIcon(image);

        value = property;
        __TABLE.put(imageName, value);

        return value;
    }

    protected ImageBundle(String suffix) {
        __fileSuffix = suffix;
    }

    public ImageBundle() {
        this("");
    }

    /**
     * @return
     * @uml.property  name="__KEYS"
     */
    public Enumeration<String> getKeys() {
        return __KEYS.elements();
    }

    protected final Object handleGetObject(String key) {
        return __loadImageFromJar(key);
    }
}

Использование:

ResourceBundle rsc = ResourceBundle.getBundle("ImageBundle"); //call rsc only once
...
ImageIcon icon = (ImageIcon) rsc.getObject("picture/plus.png");
1 голос
/ 05 ноября 2011

Подумайте об ограничении перекраски (...) небольшой областью графического интерфейса, которую необходимо перекрасить. Кроме того, не утилизируйте объект Graphics, переданный вам JVM, в методе paint или paintComponent. Избавляйся только от того, кого создал сам.

Редактировать 1
Если производительность графики является ключевым фактором, вам лучше оставить Swing и перейти к библиотеке, оптимизированной для игр, анимации и графики.

0 голосов
/ 05 ноября 2011

У меня была проблема с производительностью интерактивного движущегося JComponent внутри контейнера, и я обнаружил, что вызов repaint () для parent , а не для движущегося компонента, дал огромное увеличение скорости.Понятия не имею, почему - кто-нибудь знает?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...