Java 如何为游戏创建2D游戏场?
在JAVA中,我使用Path2D实现了这一点: 我将此代码用于:Java 如何为游戏创建2D游戏场?,java,Java,在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
// 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用1x矩形填充此区域,并从外壳触地的arrayList中删除矩形,但我认为,这不是最佳解决方案,因为arrayList太大,需要使用太多资源来刷新绘制区域:(那么,你认为什么是最好的解决方案
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;
}
}
}
}
}
}
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;
}
}
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;
}
}
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();
}
}
GamePanel.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;
}
}
}
}
}
}
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;
}
}
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;
}
}
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();
}
}
Game.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;
}
}
}
}
}
}
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;
}
}
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;
}
}
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();
}
}
嗯,你能说得更具体一点吗?我用BuffereImage保存图像,但光栅是如何工作的?我有一个运行方法,其中我有一个游戏循环。在这个循环中,我有一个绘制方法,它绘制屏幕上的所有内容。在这里我绘制了两条路径。这就是我以前获得的图片。我的玩家使用该路径在地面上移动。我使用path、 包含()方法,操纵表面上的运动。那么我如何修改我的地面,使我能够操纵地面上的运动,但它应该是可破坏的:SI将处理一个示例,我曾在我制作的类似蠕虫的游戏中使用过这个示例,但我错放了源。您的图像不是完全白色或透明的,在我的示例中,图像是透明的我觉得,这将是我想要的:)但给我一天时间,因为今天我没有时间阅读/尝试,但明天…)