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();

プレイヤーはこの地面を移動します。私のゲームはシューティングゲームのようなもので、誰かが敵に当たらずに地面にぶつかった場合、砲弾が当たった地面を破壊したいと考えています。このように: その後

これどうやってするの?与えられたベジエ曲線を分割してさらに描画するのは難しいと思います。したがって、arrayList を使用してこの領域を 1x1px の長方形で埋め、シェルが地面に衝突する 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;
}
}

GamePanel.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 に答える