Java弹跳DVD Logo碰撞边缘变色失效,求类似JS tint()的实现方法
解决Java弹跳DVD Logo碰撞变色问题
Java中没有JavaScript那样直接的tint()方法,但可以通过图像滤镜实现类似的染色效果。结合你的现有代码,只需两步就能实现碰撞边缘时Logo变色:
1. 碰撞时更新随机颜色
在actionPerformed方法中,检测到Logo碰撞边缘时生成新的RGB随机值,避免无意义的颜色刷新:
public void actionPerformed(ActionEvent e) { boolean collided = false; if (x >= PANEL_WIDTH - dvd.getWidth(null) || x < 0) { xVelocity *= -1; collided = true; } x += xVelocity; if (y >= PANEL_HEIGHT - dvd.getHeight(null) || y < 0) { yVelocity *= -1; collided = true; } y += yVelocity; // 仅在碰撞触发时更新颜色 if (collided) { r = (int)(Math.random() * 255); g = (int)(Math.random() * 255); b = (int)(Math.random() * 255); } repaint(); }
2. 使用RGB滤镜给Logo染色
替换原有的paint方法为Swing标准的paintComponent(避免层次绘制问题),通过RGBImageFilter实现染色效果:
@Override protected void paintComponent(Graphics g) { super.paintComponent(g); // 绘制背景 Graphics2D gr = (Graphics2D) g; // 创建颜色滤镜:保留原图像透明度,替换RGB通道 RGBImageFilter colorFilter = new RGBImageFilter() { @Override public int filterRGB(int x, int y, int rgb) { int alpha = (rgb >> 24) & 0xFF; // 提取原像素的透明度 return (alpha << 24) | (r << 16) | (g << 8) | b; // 组合新颜色 } }; // 生成带滤镜的图像并绘制 Image filteredDvd = createImage(new FilteredImageSource(dvd.getSource(), colorFilter)); gr.drawImage(filteredDvd, x, y, null); }
关键说明
- 用
paintComponent的原因:这是Swing组件绘制的标准方法,能确保背景和组件内容正确分层渲染,避免paint方法可能带来的绘制异常。 - 滤镜逻辑:
RGBImageFilter会遍历图像每个像素,保留原Logo的透明区域,将非透明像素的颜色替换为随机生成的RGB值,完全模拟JavaScript中tint()的染色效果。
修改后的完整代码:
import javax.swing.*; import java.awt.event.*; import java.awt.*; import java.awt.image.RGBImageFilter; import java.awt.image.FilteredImageSource; public class MyPanel extends JPanel implements ActionListener{ final int PANEL_WIDTH = 500; final int PANEL_HEIGHT = 500; Image dvd; Timer timer; int xVelocity = 1; int yVelocity = 1; int x = 0; int y = 0; int r = (int)(Math.random() * 255); int g = (int)(Math.random() * 255); int b = (int)(Math.random() * 255); MyPanel(){ this.setPreferredSize(new Dimension(PANEL_WIDTH, PANEL_HEIGHT)); this.setBackground(Color.BLACK); dvd = new ImageIcon("dvdlogo-01.png").getImage(); timer = new Timer(10, this); timer.start(); } @Override protected void paintComponent(Graphics g){ super.paintComponent(g); Graphics2D gr = (Graphics2D) g; RGBImageFilter colorFilter = new RGBImageFilter() { @Override public int filterRGB(int x, int y, int rgb) { int alpha = (rgb >> 24) & 0xFF; return (alpha << 24) | (r << 16) | (g << 8) | b; } }; Image filteredDvd = createImage(new FilteredImageSource(dvd.getSource(), colorFilter)); gr.drawImage(filteredDvd, x, y, null); } public void actionPerformed(ActionEvent e){ boolean collided = false; if(x >= PANEL_WIDTH - dvd.getWidth(null) || x < 0){ xVelocity = xVelocity * -1; collided = true; } x = x + xVelocity; if(y >= PANEL_HEIGHT - dvd.getHeight(null) || y < 0){ yVelocity = yVelocity * -1; collided = true; } y = y + yVelocity; if(collided){ r = (int)(Math.random() * 255); g = (int)(Math.random() * 255); b = (int)(Math.random() * 255); } repaint(); } }
内容的提问来源于stack exchange,提问作者gloomyside3
相关产品推荐
相关产品推荐

