Java - 随着时间的推移改变图像的透明度

时间:2011-10-11 21:07:06

标签: java swing sprite alpha-transparency

我正在尝试制作一个在游戏运行时可以半透明的游戏对象。

当我在进入游戏的计时器循环(在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 个答案:

答案 0 :(得分:1)

我刚才找到了解决问题的方法。我最终使用MediaTracker对象在渲染之前等待更改的图像加载。它现在有效。

以下是使用MediaTrackers的简短教程:http://www.javacoffeebreak.com/articles/mediatracker/index.html

答案 1 :(得分:0)

(靠近底部:)

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

这不应该是(rgb & 0x00FFFFFF) | (alpha << 24)吗?