Java - изменение прозрачности изображения с течением времени - PullRequest
0 голосов
/ 12 октября 2011

Я пытаюсь создать игровой объект, который можно сделать полупрозрачным во время игры.

Мой фильтр полупрозрачности работает нормально, когда я применяю его к изображению моего объекта перед входом в цикл таймера игры (внутри метода loadImages ()). Однако внутри цикла таймера игры (метод timerLoop ()) он не работает и делает изображение моего объекта полностью прозрачным. Что я делаю не так?

Я использую библиотеку java.awt для рисования и использую RGBImageFilter для применения полупрозрачности.

public class MyMainJPanel extends JPanel
{
    // essential members
    private Timer timer;
    private Camera camera;

    // image data

    Image bulletImg;
    Image bulletSemiTransImg;

    MenuBackgroundsSprite menuBg, menuBg2;



    public MyMainJPanel()
    {
        this.setBackground(Color.black);

        this.setFocusable(true);

        // load images

        this.loadImages();

        // set up the timer

        TimerListener timerListener = new TimerListener();

        timer = new Timer(0,timerListener);
        this.setFPS(60);
        timer.start();
    }


    private boolean loadImages()
    {
        ... 

        loads some other graphics

        ...

        // LOAD BULLET GRAPHICS

        // get our default toolkit

        Toolkit tk = Toolkit.getDefaultToolkit();

        // load our bullet images

        Image preImg = tk.getImage("graphics/basicBullet.png");

        bulletImg = ColorFilters.setTransparentColor(preImg, new Color(0xFF00FF)); // pink
    //  bulletSemiTransImg = ColorFilters.setSemiTransparency(bulletImg, 0.5); // My semitransparency works here outside the timer loop


        ...

        loads Camera object

        ...

        return true;
    }


    /** 
    *   setFPS()
    *   Preconditions: fps is a quantity of frames per second
    *   Postconditions: Sets the timer's refresh rate so that it fires fps times per second.
    **/

    public void setFPS(int fps)
    {
        int mspf = (int) (1000.0 /fps + 0.5);
        timer.setDelay(mspf);
    }



    // Event listener for the timer objects

    private class TimerListener implements ActionListener
    {

        public void actionPerformed(ActionEvent e)
        {
            Object source = e.getSource();

            if(source == timer)
            {
                // perform a loop through the game's logic
                timerLoop();        // Enters timer loop step here

            }
        }
    }


    public void timerLoop()
    {

        // bullet dynamic semitransparency test

        bulletSemiTransImg = ColorFilters.setSemiTransparency(bulletImg, 0.5); // This is where I'm having my problem. It makes all the bullets completely transparent 
                                                                                                        // if I try to apply semitransparency to them inside my timer loop.

        // repaint after game logic has completed.
        this.repaint();
    }

    public void paintComponent(Graphics g)
    {
            super.paintComponent(g);

            Graphics2D g2D = (Graphics2D) g;
            // test data

            // Camera transform

            g2D.setTransform(camera.getTransform()); 

            // Draw graphics

            ...

            Draw some stuff before the bullets

            ...

            // Here's where I draw my bullets

            for(int i = 0; i < 10; i++)
            {
                for(int j = 0; j < 10; j++)
                {
                    g2D.translate((i+1)*32,(j+1)*32);

                    g2D.drawImage(bulletSemiTransImg, null, null); 

                    g2D.setTransform(camera.getTransform()); // reset the Graphics context's transform
                }
            }


    }

}



/**
*   ColorFilters.java
*   A class of static methods used to apply color filters to images.
**/

public class ColorFilters
{

    public static Image setTransparentColor(Image srcImg, final Color tColor) // method accepts a transparent color.
                                                                     // It'll transform all pixels of the transparent color to transparent.
    {   
        ImageFilter filter = new RGBImageFilter() // overriding part of the RGBImageFilterClass to produce a specialized filter.
        {
            public int testColor = tColor.getRGB() | 0xFF000000; // establish the transparent color as a hexidecimal value for bit-wise filtering.

            public int  filterRGB(int x, int y, int rgb) // overriden method
            {
                if((rgb | 0xFF000000 ) == testColor) // if transparent color matches the color being tested, make it transparent.
                {
                    return rgb & 0x00FFFFFF; // alpha bits set to 0 yields transparency.
                }
                else // otherwise leave it alone.
                    return rgb;
            }
        };

        ImageProducer ip = new FilteredImageSource(srcImg.getSource(),filter);
        Image result = Toolkit.getDefaultToolkit().createImage(ip);

        return result;
    }


    // Here is the static method used to apply the semitransparency

    public static Image setSemiTransparency(Image srcImg, double semiTrans) // method accepts a transparent color.
                                                                     // It'll transform all pixels of the transparent color to transparent.
    {   
        if(semiTrans > 1.0) 
            semiTrans = 1.0;
        if(semiTrans < 0.0)
            semiTrans = 0.0;
        final int alpha = (int) (255 * (1.0 - semiTrans));

        ImageFilter filter = new RGBImageFilter() // overriding part of the RGBImageFilterClass to produce a specialized filter.
        {
            public int  filterRGB(int x, int y, int rgb) // overriden method
            {
                System.out.println(alpha);
                if((rgb & 0xFF000000) != 0)
                    return (rgb & 0x00FFFFFF) + (alpha << 24); // alpha bits set to 0 yields transparency.  
                else
                    return rgb;
            }
        };

        ImageProducer ip = new FilteredImageSource(srcImg.getSource(),filter);
        Image result = Toolkit.getDefaultToolkit().createImage(ip);

        return result;
    }

}

Ответы [ 2 ]

1 голос
/ 01 декабря 2011

Я нашел решение своей проблемы некоторое время назад. В итоге я использовал объект MediaTracker, чтобы дождаться загрузки измененного изображения перед рендерингом. Это работает сейчас.

Вот краткое руководство по использованию MediaTrackers: http://www.javacoffeebreak.com/articles/mediatracker/index.html

0 голосов
/ 12 октября 2011

(возле дна:)

return (rgb & 0x00FFFFFF) + (alpha << 24); // alpha bits set to 0 yields transparency.

Разве это не должно быть (rgb & 0x00FFFFFF) | (alpha << 24)?

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