简体   繁体   English

Java-随时间更改图像的透明度

[英]Java - change transparency of image over time

I am trying to make a game object that can be made semitransparent during the game's runtime. 我正在尝试制作一个可以在游戏运行时变成半透明的游戏对象。

My semitransparency filter works fine when I apply it to my object's image before entering the game's timer loop (inside the loadImages() method). 当我在进入游戏的计时器循环(在loadImages()方法内部)之前将其应用于对象的图像时,我的半透明滤镜效果很好。 Inside the game's timer loop (the timerLoop() method), though, it doesn't work and it makes my object's image completely transparent. 但是,在游戏的计时器循环内部(timerLoop()方法),该按钮不起作用,并且使我的对象的图像完全透明。 What am I doing wrong? 我究竟做错了什么?

I am using the java.awt library for drawing and I'm using an RGBImageFilter to apply the semitransparency. 我正在使用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;
    }

}

I found a solution to my problem a while ago. 不久前,我找到了解决问题的方法。 I ended up using a MediaTracker object to wait for the altered image to load before rendering. 我最终使用MediaTracker对象来等待更改后的图像在渲染之前加载。 It works now. 现在可以使用了。

Here's a short tutorial for using MediaTrackers: http://www.javacoffeebreak.com/articles/mediatracker/index.html 这是使用MediaTrackers的简短教程: http : //www.javacoffeebreak.com/articles/mediatracker/index.html

(near bottom:) (靠近底部:)

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

Shouldn't this be (rgb & 0x00FFFFFF) | (alpha << 24) 这不应该是(rgb & 0x00FFFFFF) | (alpha << 24) (rgb & 0x00FFFFFF) | (alpha << 24) ? (rgb & 0x00FFFFFF) | (alpha << 24)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM