2015-05-19 89 views
2

我在我的java程序中有一个圆圈。它只是一个这样的简单圆:Java插入椭圆形图像

private BufferedImage img; 
Graphics2D g = img.createGraphics(); 
g.fill(new Area(new Ellipse2D.Double(x, y, diam, diam))); 

现在我想插入一个图像到圈子里。我知道我可以如何使用drawImage创建一个图像,如下所示:

image = Toolkit.getDefaultToolkit().getImage(url); 
g2.drawImage(image, x, y, WIDTH, HEIGHT, null); 

但是,如何在圈内创建图像?

编辑: 我试图做ControlAltDel建议的剪辑,但它不工作,我不知道为什么。我的代码是波纹管。 我的程序只用简单的黄色圆圈就可以正常工作。在文件Pang.java中,我试图替换下面的代码: g.fill(bubbles [i] .getBubbleArea());通过: Image image = new ImageIcon(“bubble.png”)。getImage(); g .clip(新的Ellipse2D.Double(100,100,50,5)); g.drawImage(image,150,180,null); 但它不工作,我donst得到任何错误。 我在做什么错?

Pang.java:

package pang.gui; 
 

 
import java.awt.*; 
 
import java.awt.event.*; 
 
import java.awt.geom.*; 
 
import java.awt.image.BufferedImage; 
 
import java.awt.TexturePaint; 
 
import java.io.File; 
 
import java.io.IOException; 
 

 
import javax.imageio.ImageIO; 
 
import javax.swing.*; 
 

 
class ShapeCollision { 
 

 
\t private BufferedImage img; 
 
\t private Area limits; 
 

 
\t private int w = 800;// width of the game window 
 
\t private int h = 400;// heigth of the game window 
 

 
\t // private Bubble bubble = new Bubble(w, h); 
 
\t private Bubble[] bubbles = new Bubble[4]; 
 

 

 

 
\t ShapeCollision() { 
 

 
\t \t img = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); 
 
\t \t /** 
 
\t \t * global image of the game shown in the window. This image will be 
 
\t \t * added to the JLabel (imageLabel) 
 
\t \t */ 
 

 
\t \t final JLabel imageLabel = new JLabel(new ImageIcon(img)); 
 
\t \t /** 
 
\t \t * JLabel that contains the global image of the game 
 
\t \t */ 
 

 

 

 
\t \t for (int i = 0; i < bubbles.length; i++) { 
 
\t \t \t bubbles[i] = new Bubble(40 + i * 80, 40 + i * 80,i); 
 
\t \t } 
 

 
\t \t limits = new Area(new Rectangle(0, 0, w, h)); 
 
\t \t /** 
 
\t \t * game limits or painted area 
 
\t \t */ 
 

 
\t \t ActionListener animate = new ActionListener() { 
 

 
\t \t \t @Override 
 
\t \t \t public void actionPerformed(ActionEvent e) { 
 
\t \t \t \t animate(); 
 
\t \t \t \t imageLabel.repaint(); 
 
\t \t \t } 
 
\t \t }; 
 
\t \t Timer timer = new Timer(50, animate); 
 
\t \t /** 
 
\t \t * Repaint rate 
 
\t \t */ 
 

 
\t \t timer.start(); 
 
\t \t JOptionPane.showMessageDialog(null, imageLabel); 
 
\t \t timer.stop(); 
 
\t } 
 

 
\t public void animate() { 
 
\t \t Graphics2D g = img.createGraphics(); 
 
\t \t /** 
 
\t \t * Creates a Graphics2D, which can be used to draw into this 
 
\t \t * BufferedImage (img). 
 
\t \t */ 
 

 
\t \t g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 
 
\t \t \t \t RenderingHints.VALUE_ANTIALIAS_ON); 
 
\t \t /** 
 
\t \t * removes edges from the shape, makes rounder objects 
 
\t \t */ 
 

 
\t \t g.setColor(Color.BLUE); 
 
\t \t /** 
 
\t \t * color of the game windows background 
 
\t \t */ 
 

 
\t \t g.fillRect(0, 0, img.getWidth(), img.getHeight()); 
 
\t \t /** 
 
\t \t * size of the Graphics2D object (g). In this case the game window is 
 
\t \t * filled 
 
\t \t */ 
 

 
\t \t for (Bubble bubble : bubbles) { 
 
\t \t \t bubble.IncrementPos(); 
 
\t \t \t bubbleWallCollision(bubble); 
 

 
\t \t } 
 

 
\t \t for (Bubble bubble : bubbles) { 
 
\t \t \t detectBubblesCollisions(bubble); 
 
\t \t } 
 

 
\t \t g.setColor(Color.YELLOW); 
 

 
\t \t for (int i = 0; i < bubbles.length; i++) { 
 
//Image image = new ImageIcon("bubble.png").getImage(); 
 
//g.clip(new Ellipse2D.Double(100, 100, 50, 
 
// \t \t 5)); 
 
//g.drawImage(image, 150, 180, null); 
 
\t \t \t g.fill(bubbles[i].getBubbleArea()); 
 
\t \t \t /** 
 
\t \t \t * the bubble is filled *after* the obstacles, so the bubble is 
 
\t \t \t * allways shown. If the bubble is on top of an abstacle that 
 
\t \t \t * obstacle is covered by the bubble 
 
\t \t \t */ 
 
\t \t } 
 

 
\t \t g.dispose(); 
 
\t } 
 

 

 

 
\t private void detectBubblesCollisions(Bubble bubble1) { 
 
\t \t for (Bubble bubble : bubbles) { 
 
\t \t \t if (bubble1 != bubble) { 
 
\t \t \t \t if (bubble1.getX() + bubble1.getBubbleDiam()/2 
 
\t \t \t \t \t \t + bubble.getBubbleDiam()/2 > bubble.getX() 
 
\t \t \t \t \t \t && bubble1.getX() < bubble.getX() 
 
\t \t \t \t \t \t \t \t + bubble1.getBubbleDiam()/2 
 
\t \t \t \t \t \t \t \t + bubble.getBubbleDiam()/2 
 
\t \t \t \t \t \t && bubble1.getY() + bubble1.getBubbleDiam()/2 
 
\t \t \t \t \t \t \t \t + bubble.getBubbleDiam()/2 > bubble.getY() 
 
\t \t \t \t \t \t && bubble1.getY() < bubble1.getY() 
 
\t \t \t \t \t \t \t \t + bubble1.getBubbleDiam()/2 
 
\t \t \t \t \t \t \t \t + bubble.getBubbleDiam()/2) { 
 
\t \t \t \t \t if (PangUtilities.areasDistance(bubble1, bubble) < bubble1 
 
\t \t \t \t \t \t \t .getBubbleDiam()/2 + bubble.getBubbleDiam()/2) { 
 
\t \t \t \t \t \t calculateNewVelocities(bubble1, bubble); 
 
\t \t \t \t \t } 
 
\t \t \t \t } 
 
\t \t \t } 
 

 
\t \t } 
 

 
\t } 
 

 
\t private void calculateNewVelocities(Bubble bubble1, Bubble bubble) { 
 
\t \t double mass1 = bubble1.getBubbleDiam()/2; 
 
\t \t double mass2 = bubble.getBubbleDiam()/2; 
 
\t \t double velX1 = bubble1.get_xDelta(); 
 
\t \t double velX2 = bubble.get_xDelta(); 
 
\t \t double velY1 = bubble1.get_yDelta(); 
 
\t \t double velY2 = bubble.get_yDelta(); 
 
    
 
\t \t double newVelX1 = (velX1 * (mass1 - mass2) + (2 * mass2 * velX2))/(mass1 + mass2); 
 
\t \t double newVelX2 = (velX2 * (mass2 - mass1) + (2 * mass1 * velX1))/(mass1 + mass2); 
 
\t \t double newVelY1 = (velY1 * (mass1 - mass2) + (2 * mass2 * velY2))/(mass1 + mass2); 
 
\t \t double newVelY2 = (velY2 * (mass2 - mass1) + (2 * mass1 * velY1))/(mass1 + mass2); 
 
\t 
 
\t 
 
\t bubble1.set_xDelta(newVelX1); 
 
\t 
 
\t bubble.set_xDelta(newVelX2); 
 
bubble1.set_yDelta(newVelY1); 
 
\t 
 
\t bubble.set_yDelta(newVelY2); 
 
    
 
    bubble1.setX(bubble1.getX() + newVelX1); 
 
    bubble1.setY(bubble1.getY() + newVelY1); 
 
\t 
 
    bubble.setX(bubble.getX() + newVelX2); 
 
    bubble.setY(bubble.getY() + newVelY2); 
 

 

 
\t } 
 

 
\t private void bubbleWallCollision(Bubble bubble) { 
 
\t \t if (bubble.getX() + bubble.getBubbleDiam()/2 >= w 
 
\t \t \t \t && bubble.get_xDelta() > 0) 
 
\t \t \t bubble.invert_xDelta(); 
 
\t \t if (bubble.getX()-bubble.getBubbleDiam()/2 <= 0 && bubble.get_xDelta() < 0) 
 
\t \t \t bubble.invert_xDelta(); 
 
\t \t if (bubble.getY() + bubble.getBubbleDiam()/2 >= h 
 
\t \t \t \t && bubble.get_yDelta() > 0) 
 
\t \t \t bubble.invert_yDelta(); 
 
\t \t if (bubble.getY()-bubble.getBubbleDiam()/2 <= 0 && bubble.get_yDelta() < 0) 
 
\t \t \t bubble.invert_yDelta(); 
 

 
\t } 
 

 
\t public static void main(String[] args) { 
 
\t \t Runnable r = new Runnable() { 
 

 
\t \t \t @Override 
 
\t \t \t public void run() { 
 
\t \t \t \t new ShapeCollision(); 
 
\t \t \t } 
 
\t \t }; 
 
\t \t SwingUtilities.invokeLater(r); 
 
\t } 
 
}

Bubble.java:

package pang.gui; 
 

 
import java.awt.Shape; 
 
import java.awt.geom.Area; 
 
import java.awt.geom.Ellipse2D; 
 

 
public class Bubble { 
 
\t private Area bubbleArea = new Area(); 
 
\t private double bubbleDiam = 20, bubbleSpeed = 2;// bubble diameter 
 
private Shape shape; 
 
\t private double x; 
 
\t private double y; 
 

 
\t private int initialDirectionX, initialDirectionY; 
 
\t private double xDelta = bubbleSpeed;// bubble move increments 
 
\t private double yDelta = bubbleSpeed;// bubble move increments 
 

 
\t public Bubble(int x, int y,int i) { 
 

 
\t \t this.x = x;// Bubble position 
 
\t \t this.y = y;// Bubble position 
 
\t \t this.bubbleDiam *=i+1; 
 
\t \t System.out.println(bubbleDiam); 
 

 
\t \t genDirection(); 
 

 
\t } 
 

 
\t public void IncrementPos() { 
 
\t \t x += xDelta;// new position of the bubble 
 
\t \t y += yDelta;// new position of the bubble 
 
\t \t this.bubbleArea = new Area(new Ellipse2D.Double(x-bubbleDiam/2, y-bubbleDiam/2, bubbleDiam, 
 
\t \t \t \t bubbleDiam));// bubble area definition 
 
\t \t shape=new Ellipse2D.Double(x-bubbleDiam/2, y-bubbleDiam/2, bubbleDiam, 
 
\t \t \t \t bubbleDiam); 
 
\t } 
 

 
\t 
 
\t 
 
\t public Shape getShape() { 
 
\t \t return shape; 
 
\t } 
 

 
\t public void setX(double d) { 
 
\t \t this.x = d; 
 
\t } 
 

 
\t public void setY(double d) { 
 
\t \t this.y = d; 
 
\t } 
 

 
\t public Area getBubbleArea() { 
 
\t \t return bubbleArea; 
 
\t } 
 

 
\t public double getBubbleDiam() { 
 
\t \t return bubbleDiam; 
 
\t } 
 

 
\t public double get_xDelta() { 
 
\t \t return xDelta; 
 
\t } 
 

 
\t public double get_yDelta() { 
 
\t \t return yDelta; 
 
\t } 
 

 
\t public void set_xDelta(double d) { 
 
\t \t this.xDelta = d; 
 
\t } 
 

 
\t public void set_yDelta(double d) { 
 
\t \t this.yDelta = d; 
 
\t } 
 

 
\t public void invert_yDelta() { 
 
\t \t yDelta *= -1; 
 

 
\t } 
 

 
\t public void invert_xDelta() { 
 
\t \t xDelta *= -1; 
 

 
\t } 
 

 
\t public double getX() { 
 
\t \t return x; 
 
\t } 
 

 
\t public double getY() { 
 
\t \t return y; 
 
\t } 
 

 
\t private void genDirection() { 
 
\t \t do { 
 
\t \t \t initialDirectionX = PangUtilities.genRandomInt(-3, 3); 
 
\t \t } while (initialDirectionX == 0); 
 

 
\t \t do { 
 
\t \t \t initialDirectionY = PangUtilities.genRandomInt(-3, 3); 
 
\t \t } while (initialDirectionX == initialDirectionY 
 
\t \t \t \t || initialDirectionY == 0); 
 

 
\t \t xDelta *= initialDirectionX; 
 
\t \t yDelta *= initialDirectionY; 
 
\t } 
 

 
}

PangUtilities.java:

package pang.gui; 
 

 
import java.util.Random; 
 

 
public class PangUtilities { 
 

 
\t public static int genRandomInt(int min, int max) { 
 

 
\t \t Random rand = new Random(); 
 

 
\t \t return min + rand.nextInt((max - min) + 1); 
 

 
\t } 
 

 
\t public static double areasDistance(Bubble b1, Bubble b2) { 
 

 
\t \t double distance = Math 
 
\t \t \t \t .sqrt(((b1.getX() - b2.getX()) * (b1.getX() - b2.getX())) 
 
\t \t \t \t \t \t + ((b1.getY() - b2.getY()) * (b1.getY() - b2.getY()))); 
 
\t \t return distance; 
 
\t } 
 

 
}

回答

1

有两种方法可以做到这

  1. (容易)设置裁剪您Graphics对象上与你的圈子Shape
  2. 把你ImageTexturePaint,然后做

Graphics2D g = ...; 
g.setPaint(myImagePaint); 
g.fill(yourCircle); 
+0

是否像这样剪贴?:Image image = new ImageIcon(“image.png”)。getImage(); g.clip(new Ellipse2D.Double(x,y,d, \t \t d)); g.drawImage(image,x,y,null); – user2880113

+0

是的,你就是这么做的,虽然我建议你保持你的裁剪形状,而不是每次都做一个新形状 – ControlAltDel