我正在尝试制作一个在游戏运行时可以半透明的游戏对象。
当我在进入游戏的计时器循环(在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;
}
}
答案 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)
吗?