- BufferedImageを使用して地面の画像を保持します。
- Rasterを使用して画像のピクセル値を直接操作します
。
- 画像の表示を更新します。
ステップ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();
}
}