I am wanting to make a game that has each level loaded from an image. I want to draw up the whole level in Photoshop, and then set it as the background and allow the player to walk over it. I want another invisible image to go over top which will be black in all places that I want to collide with.
The reason I don't want to use tiles, which are much easier with rectangle collision and such, is because there will be complex corners and not everything will be rectangle.
Is this a good idea, and is it possible to do easily? Would this be a big CPU hog or is there a better way to do this?
Two forms of collision detection: Continuous: very expensive. Simulate solid objects in real life. Discrete: objects will end up with penetrating each other.
Axis-Aligned Bounding Box One of the simpler forms of collision detection is between two rectangles that are axis aligned — meaning no rotation. The algorithm works by ensuring there is no gap between any of the 4 sides of the rectangles. Any gap means a collision does not exist.
..there will be complex corners and not everything will be rectangle.
This could be achieved by drawing and dealing with Shape
and Area
instances. E.G.
import java.awt.*; import java.awt.event.*; import java.awt.geom.*; import java.awt.image.BufferedImage; import javax.swing.*; class ShapeCollision { private BufferedImage img; private Area[] obstacles = new Area[4]; private Area walls; int x; int y; int xDelta = 3; int yDelta = 2; /** A method to determine if two instances of Area intersect */ public boolean doAreasCollide(Area area1, Area area2) { boolean collide = false; Area collide1 = new Area(area1); collide1.subtract(area2); if (!collide1.equals(area1)) { collide = true; } Area collide2 = new Area(area2); collide2.subtract(area1); if (!collide2.equals(area2)) { collide = true; } return collide; } ShapeCollision() { int w = 400; int h = 200; img = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); final JLabel imageLabel = new JLabel(new ImageIcon(img)); x = w/2; y = h/2; //circle obstacles[0] = new Area(new Ellipse2D.Double(40, 40, 30, 30)); int[] xTriangle = {330,360,345}; int[] yTriangle = {60,60,40}; //triangle obstacles[1] = new Area(new Polygon(xTriangle, yTriangle, 3)); int[] xDiamond = {60,80,60,40}; int[] yDiamond = {120,140,160,140}; //diamond obstacles[2] = new Area(new Polygon(xDiamond, yDiamond, 4)); int[] xOther = {360,340,360,340}; int[] yOther = {130,110,170,150}; // other obstacles[3] = new Area(new Polygon(xOther, yOther, 4)); walls = new Area(new Rectangle(0,0,w,h)); ActionListener animate = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { animate(); imageLabel.repaint(); } }; Timer timer = new Timer(50, animate); timer.start(); JOptionPane.showMessageDialog(null, imageLabel); timer.stop(); } public void animate() { Graphics2D g = img.createGraphics(); g.setRenderingHint( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g.setColor(Color.BLUE); g.fillRect(0, 0, img.getWidth(), img.getHeight()); x+=xDelta; y+=yDelta; int s = 15; Area player = new Area(new Ellipse2D.Double(x, y, s, s)); // Acid test of edge collision; if (doAreasCollide(player,walls)) { if ( x+s>img.getWidth() || x<0 ) { xDelta *= -1; } if(y+s>img.getHeight() || y<0 ) { yDelta *= -1; } } g.setColor(Color.ORANGE); for (Area obstacle : obstacles) { if (doAreasCollide(obstacle, player)) { g.setColor(Color.RED); } else { g.setColor(Color.GREEN); } g.fill(obstacle); } g.setColor(Color.YELLOW); g.fill(player); g.dispose(); } public static void main(String[] args) { Runnable r = new Runnable() { @Override public void run() { new ShapeCollision(); } }; // Swing GUIs should be created and updated on the EDT // http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html SwingUtilities.invokeLater(r); } }
make it detect all the red color and set that as the collision bounds
At start-up, use the source seen in the Smoothing a jagged path question to get an outline of the red pixels (see the getOutline(Color target, BufferedImage bi)
method). Store that Area
as the single obstacle on start-up.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With