1

在 JAVA 中,我使用 Path2D 制作了这个: 之前

我为此使用了这段代码:

// First Bezier curve points
P1 = new Point2D.Double(0, 480); // Start Point
P2 = new Point2D.Double(400, 350); // End Point
ctrl1 = new Point2D.Double(50, 450); // Control Point 1
ctrl2 = new Point2D.Double(200, 260); // Control Point 2
// Second Bezier curve points
P3 = new Point2D.Double(400, 350); // Start Point
P4 = new Point2D.Double(800, 600); // End Point
ctrl3 = new Point2D.Double(600, 440); // Control Point 1
ctrl4 = new Point2D.Double(700, 310); // Control Point 2

// path bezier curve
path = new Path2D.Double();
path.moveTo(P1.x, P1.y);
path.curveTo(ctrl1.x, ctrl1.y, ctrl2.x, ctrl2.y, P2.x, P2.y);
path.lineTo(P2.x, 600);
path.lineTo(0, 600);
path.closePath();
// path2 bezier curve
path2 = new Path2D.Double();
path2.moveTo(P3.x, P3.y);
path2.curveTo(ctrl3.x, ctrl3.y, ctrl4.x, ctrl4.y, P4.x, P4.y);
path2.lineTo(800, 600);
path2.lineTo(400, 600);
path2.closePath();

玩家将在这片土地上移动。我的游戏就像一个射击游戏,如果有人没有击中敌人而是击中了地面,我想摧毁炮弹击中它的地面。像这样: 之后

我怎样才能做到这一点?我认为分割给定的贝塞尔曲线并绘制更多内容很难。所以我想我会用 1x1px 矩形填充这个区域,使用 arrayList 并从 arrayList 中删除外壳击中地面的矩形,但我认为,这不是最好的解决方案,因为 arrayList 会太大并且使用太多资源来刷新绘画区域:(那么您认为,最好的解决方案是什么?

4

1 回答 1

3
  1. 使用BufferedImage保存地面图像。
  2. 直接使用其Raster操作图像的像素值 。
  3. 更新图像的视图。

就这么简单,步骤 2 有很多不同的方法,但我建议创建一个半径为 R 的圆(取决于物体撞击地面的大小,也许是它的高度?),找到所有像素当它撞到地面并简单地将它们变成白色时,它在物体的 R 范围内。

编辑:所以这里的例子是,我试图找到我的游戏的源,但没有运气,所以这里有一个非常简单的例子,一个矩形落在图像上并破坏了它落在的部分。注意我使用的图像是在此处输入图像描述

这是几个矩形掉落后的样子。 在此处输入图像描述

Terrain.java

package explodingimage;

import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.awt.image.WritableRaster;
import java.io.IOException;

import javax.imageio.ImageIO;

public class Terrain {
private FallingRectangle rectangle;
private BufferedImage image;
private WritableRaster raster;
private int centerX, centerY;
private int[][] bitmap;
private int pixelSize;

public Terrain() {
    try {
        this.image = ImageIO.read(getClass().getResourceAsStream(
                "before.png"));
    } catch (IOException e) {
        e.printStackTrace();
    }
    this.rectangle = new FallingRectangle(getBounds());
    this.raster = image.getRaster();
    setupBitmap();
}

public Dimension getBounds() {
    return new Dimension(image.getWidth(), image.getHeight() * 3);
}

public BufferedImage getImage() {
    return image;
}

public int getImageX() {
    return 0;
}

public int getImageY() {
    return image.getHeight() * 2;
}

public FallingRectangle getFallingRectangle() {
    return rectangle;
}

public void update() {
    rectangle.update();
    if (collidesWithRectangle())
        explode();
}

private void explode() {
    int explosionRadius = 100;
    double distance = 0;
    Rectangle r = new Rectangle(centerX - explosionRadius, centerY
            - explosionRadius, 2 * explosionRadius, 2 * explosionRadius);
    for (int x = 0; x < image.getWidth(); x++) {
        for (int y = 0; y < image.getHeight(); y++) {
            distance = Math.sqrt((x - centerX) * (x - centerX)
                    + (y - centerY) * (y - centerY));
            if (r.contains(x, y) && distance < explosionRadius) {
                raster.setPixel(x, y, new int[] { 255, 255, 255 });
            }
        }
    }
    rectangle.reset();
}

// Notice since the image we use as terrain/background doesn't cover the
// entire frame we have to use offsets, it covers the frame in width but not
// height
private boolean collidesWithRectangle() {
    int xOffset = 0;
    int yOffset = (int) (getBounds().getHeight() - image.getHeight());
    for (int x = 0; x < image.getWidth(); x++) {
        for (int y = 0; y < image.getHeight(); y++) {
            if (bitmap[x][y] == 0
                    && rectangle.getRectangle().contains(x + xOffset,
                            y + yOffset)) {
                centerX = x;
                centerY = y;
                return true;
            }
        }
    }
    return false;
}


// Set up the bitmap, check if pixel colorvalue is white or transparent
// 1 = pixel is solid, 0 pixel is transparent to objects
// Assuming length of 3 is RBG and length 4 is RBGA
private void setupBitmap() {
    bitmap = new int[image.getWidth()][image.getHeight()];
    for (int x = 0; x < image.getWidth(); x++) {
        for (int y = 0; y < image.getHeight(); y++) {
            int[] pixel = null;
            pixel = raster.getPixel(x, y, pixel);

            if (pixel.length == 3) {
                pixelSize = 3;
                if(pixel[0]==255 && pixel[1] ==255 && pixel[2]==255)
                    bitmap[x][y] = 1;
            }

            if (pixel.length == 4) {
                pixelSize = 4;
                if (pixel[3] == 0) {
                    bitmap[x][y] = 1;
                }
            }
        }
    }
}

}

Fallingrectangle.java

package explodingimage;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Rectangle;
import java.util.Random;

public class FallingRectangle {
private static final int MAXWIDTH = 150;
private static final int MINWIDTH = 100;
private static final int MAXHEIGHT = 150;
private static final int MINHEIGHT = 100;
private final double MINX, MAXX, MINY, MAXY;
private static final Random rnd = new Random();
private Rectangle rectangle;
private Color color;
private int speed;

public FallingRectangle(Dimension bounds) {
    this.MAXX = bounds.getWidth() * 0.9;
    this.MINX = bounds.getWidth() * 0.1;
    this.MINY = 0;
    this.MAXY = bounds.getHeight();
    setup();
}

private void setup() {
    int x = (int) (rnd.nextInt((int) (MAXX - MINX)) + MINX);
    int y = 0;
    int w = rnd.nextInt(MAXWIDTH - MINWIDTH) + MINWIDTH;
    int h = rnd.nextInt(MAXHEIGHT - MINHEIGHT) + MINHEIGHT;
    int R = rnd.nextInt(256);
    int G = rnd.nextInt(256);
    int B = rnd.nextInt(256);
    speed = rnd.nextInt(3) + 1;

    rectangle = new Rectangle(x, y, w, h);
    color = new Color(R, G, B);
}

public Rectangle getRectangle() {
    return rectangle;
}

public Color getColor() {
    return color;
}

public void update() {
    int x = rectangle.x;
    int y = rectangle.y + speed;
    int w = rectangle.width;
    int h = rectangle.height;
    rectangle = new Rectangle(x, y, w, h);

    if (y >= MAXY)
        reset();
}

public void reset() {
    setup();
}

public void stop() {
    this.speed = 0;
}
}

游戏面板.java

package explodingimage;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.beans.Transient;

import javax.swing.JPanel;

@SuppressWarnings("serial")
public class GamePanel extends JPanel {
private Terrain terrain;

public GamePanel() {
    this.terrain = new Terrain();
}

@Override
@Transient
public Dimension getPreferredSize() {
    return terrain.getBounds();
}

@Override
protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    Graphics2D g2d = (Graphics2D) g.create();

    // Draw background image of terrain
    g2d.drawImage(terrain.getImage(), terrain.getImageX(),
            terrain.getImageY(), null);

    // Draw the rectangular object
    Rectangle r = terrain.getFallingRectangle().getRectangle();
    g2d.setColor(Color.black);
    g2d.drawString(r.x + "," + r.y, r.x, r.y);
    g2d.draw(r);
    g2d.setColor(terrain.getFallingRectangle().getColor());
    g2d.fill(r);
}

public Terrain getTerrain() {
    return terrain;
}
 }

游戏.java

package explodingimage;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JFrame;
import javax.swing.Timer;

public class Game {
private JFrame frame;
private GamePanel panel;

public Game() {
    this.frame = new JFrame();
    this.panel = new GamePanel();

    frame.getContentPane().add(panel);
    frame.pack();
    frame.setLocationRelativeTo(null);
    frame.setResizable(false);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setVisible(true);
}

public void start(){
    new Timer(10, new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent arg0) {
            panel.getTerrain().update();
            panel.repaint();
        }
    }).start();
}

public static void main(String[] args) {
    new Game().start();
}

 }
于 2013-09-20T12:03:01.487 回答