In the development of Java games, we often encounter collision detection problems. As in the tank war, the shell and tank encounter exploded; in the Guardian game, the Guardian Fire Arrows and monsters meet the Monster blood loss; In a plane game, the plane sent bullets and enemy planes met to kill enemy aircraft. These all need to implement collision detection.
We first look at a relatively simple collision detection: Regular graphics collision detection.
Rectangular Collision Detection
As a practiced hand game, the object shape in the game is generally rectangular area, which is the regular graph. Its collision detection can be achieved through the rectangle class in the Java API to detect collisions.
Rectangle refers to a rectangular area that determines the range size by specifying the position x and y of the upper-left corner, as well as the width and height of the rectangle. So the rectangle class construction methods that are often used are:
Constructs a new Rectangle with the coordinates of the upper-left corner (0,0), whose width and height are specified by the parameter with the same name.
public Rectangle (int width, int height)
Constructs a new Rectangle, whose upper-left corner is specified as (x, y), and its width and height are specified by a parameter of the same name.
public Rectangle (int x, int y, int width, int height)
Methods related to collision detection:
Computes the intersection of this Rectangle with the specified Rectangle
Public Rectangle intersection (Rectangle R)
Determines whether this Rectangle intersects with the specified Rectangle
Public boolean intersects (Rectangle R)
If two rectangle objects have intersections, then they collide. Such as:
This method is suitable for collision detection in the case where the object in the map is approximated to be rectangular or not rectangular, but the collision accuracy requirement is not high. Each object records an upper-left corner coordinate and rectangle length width of the smallest rectangle that can frame itself.
Using this method for collision detection needs to be noted that the image of the implementation of the processing should be as far as possible to remove the blank corner of the icon, or the actual effect can be visible to the naked eye error. That is to say rectangle as far as possible to wrap the graphics and rectangle area as small as possible.
Example:
Import Java.awt.Graphics;
Import Java.awt.Image;
Import Java.awt.MediaTracker;
Import Java.awt.Point;
Import Java.awt.Rectangle;
Import Java.awt.Toolkit;
Import Java.awt.image.CropImageFilter;
Import Java.awt.image.FilteredImageSource;
Import Java.awt.image.ImageFilter;
Import Java.awt.image.ImageProducer;
Import Javax.swing.JFrame;
Import Javax.swing.JOptionPane;
/**
* Collision detection test to determine if two tanks moving in the same direction will collide
*
* @author
*
*/
public class intersection extends JFrame implements Runnable {
Private static final long serialversionuid = 156638225301569550L;
Private Mediatracker Mediatracker; Media Tracker
Private image[][] images = new IMAGE[2][4]; Place all the cut images
Private image[] Movetanks = new image[2]; Two tanks moved by the placement interface
Private point[] points = new point[2]; Two tank coordinates
Public intersection () {
Settitle ("Collision Detection");
SetSize (200, 600);
Setlocationrelativeto (NULL);
Setdefaultcloseoperation (Exit_on_close);
Cutimage (); Cutting graphics
/* Add the cut graphics to the media tracker tracking */
Mediatracker = new Mediatracker (this);
for (int i = 0, length = images.length; i < length; i++) {
for (int j = 0, Len = images[i].length; J < Len; J + +) {
Mediatracker.addimage (Images[i][j], I * len + j);
}
}
Wait for all images to finish loading
try {
Mediatracker.waitforall ();
} catch (Interruptedexception e) {
E.printstacktrace ();
}
Initialize two tanks in the form of coordinates
Movetanks[0] = CreateImage (Images[0][0].getsource ());
MOVETANKS[1] = CreateImage (Images[0][0].getsource ());
Points[0] = new Point (80, 200);
POINTS[1] = new Point (80, 100);
SetVisible (TRUE);
}
/**
* Image Segmentation
*/
private void Cutimage () {
Get Source image
Image img = Toolkit.getdefaulttoolkit (). GetImage ("Images/boss.gif");
Looping segmented images
for (int i = 0, length = images.length; i < length; i++) {
for (int j = 0, Len = images[i].length; J < Len; J + +) {
ImageFilter filter = new CropImageFilter (0, 0, 50, 50);
ImageProducer producer = new FilteredImageSource (
Img.getsource (), filter);
IMAGES[I][J] = createimage (producer); Save the segmented image into an array
}
}
}
@Override
public void Paint (Graphics g) {
Image img = createimage (This.getwidth (), This.getheight ());
Graphics graphics = Img.getgraphics ();
Draw two tanks out of the form
for (int i = 0, len = movetanks.length; i < Len; i++) {
Graphics.DrawImage (Movetanks[i], points[i].x, POINTS[I].Y, this);
}
G.drawimage (IMG, 0, 0, this);
G.dispose ();
}
@Override
public void Run () {
while (true) {
Every time the second tank moves farther than the first tank, the second one moves faster.
Points[0].y + = 30;
Points[1].y + = 45;
Redraw
Repaint ();
/* Collision Detection */
Rectangular range of the first tank
Rectangle Tank1 = new Rectangle (points[0].x, POINTS[0].Y,
Movetanks[0].getwidth (NULL), movetanks[0].getheight (null));
Rectangular range of the second tank
Rectangle tank2 = new Rectangle (points[1].x, POINTS[1].Y,
Movetanks[1].getwidth (NULL), movetanks[1].getheight (null));
Determine if the two rectangles have an intersection, there is a collision
if (Tank1.intersects (TANK2)) {
Joptionpane.showmessagedialog (NULL, "hit", "hint",
Joptionpane.information_message);
Break
}
try {
Thread.Sleep (1000);
} catch (Interruptedexception e) {
E.printstacktrace ();
}
}
}
public static void Main (string[] args) {
New Thread (new Intersection ()). Start ();
}
}
Round collision Detection
Circular detection is similar to a rectangle detection method, except that a circle that can contain an object is substituted with a rectangle. The main consideration is that the shape of the object in the game is mainly smooth, such as character. The calculation of whether the collision of two circle is also very simple, is to determine whether the distance between the two centers is less than the sum of two circle radius.
Example:
Import Java.awt.Graphics;
Import Javax.swing.JFrame;
Import Javax.swing.JOptionPane;
/**
* Collision detection test to determine if two circles will collide
*
* @author
*
*/
public class Intersection2 extends JFrame implements Runnable {
/* Define the upper left corner coordinates, RADIUS */
private int x1 = y1 = 45;
private int x2 = y2 = 70;
private int r1 = +, r2 = 18;
Public Intersection2 () {
Settitle ("Collision Detection");
SetSize (200, 600);
Setlocationrelativeto (NULL);
Setdefaultcloseoperation (Exit_on_close);
SetVisible (TRUE);
}
@Override
public void Paint (Graphics g) {
/* Draw Circle */
G.drawoval (x1, y1, 2 * r1, 2 * R1);
G.drawoval (x2, y2, 2 * R2, 2 * R2);
}
@Override
public void Run () {
/* Determine if the two circles intersect */
Center coordinates of two circles
int centerX1 = x1 + R1, centerY1 = y1 + r1;
int centerX2 = x2 + r2, centerY2 = y2 + r2;
Find the center distance of two circles
Double length = math.sqrt (Math.pow (CENTERX1-CENTERX2, 2)
+ Math.pow (Centery1-centery2, 2));
Judging the relationship between the center distance and the radius of two circles
if (length < (r1 + R2)) {
Joptionpane.showmessagedialog (NULL, "center pitch:" + length + ", collision");
} else {
Joptionpane.showmessagedialog (NULL, "center pitch:" + length + ", no Collision");
}
}
public static void Main (string[] args) {
New Thread (New Intersection2 ()). Start ();
}
}
Package state;
Import Java.awt.Graphics;
Import Java.awt.Image;
Import Java.awt.MediaTracker;
Import Java.awt.Point;
Import Java.awt.Rectangle;
Import Javax.swing.ImageIcon;
Import Javax.swing.JFrame;
Import Javax.swing.JOptionPane;
Public class intersection extends JFrame implements runnable{
Private mediatracker mediatracker;
Private image[] images = new IMAGE[2];
Private point[] point = new point[2];
Private image Image;
Public intersection () {
Settitle ("card layout manager");
SetSize (500, 500);
Setlocationrelativeto (NULL);
Setresizable (FALSE);
Setdefaultcloseoperation (exit_on_close);
Mediatracker = new Mediatracker (this);
Images[0] = Imageutils.addimage (Mediatracker, New ImageIcon ("Imges/jian_super.png"). GetImage ());
Point[0] = new Point (30, 100);
Images[1] = Imageutils.addimage (Mediatracker, New ImageIcon ("Imges/xiaoguai.png"). GetImage ());
Point[1] = new Point (400, 100);
SetVisible (true);
}
@Override
public void Paint (Graphics g) {
G.drawimage (image, 0, 0, this);
}
private void Draw () {
image = CreateImage (This.getwidth (), This.getheight ());
Graphics g = image.getgraphics ();
for (int i =0; i<images.length;i++) {
G.drawimage (images[i], point[i].x, POINT[I].Y, this);
}
G.dispose ();
}
Private Boolean intersects () {
Rectangle arrow = new Rectangle (point[0].x, point[0].y,
Images[0].ge Twidth (NULL) -20, images[0].getheight (null));
Rectangle boss = new Rectangle (point[1].x, Point[1].y,
Images[1].getwidth (null), images[1].getheight (null));
Return Arrow.intersects (Boss);
}
@Override
public void Run () {
while (true) {
point[0].x++;
point[1].x--;
if (intersects ()) {
Joptionpane.showmessagedialog (NULL, "collision");
Break
}
Draw ();
Repaint ();
try {
Thread.Sleep (4);
} catch (Interruptedexception e) {
E.printstacktrace ();
}
}
}
public static void Main (string[] args) {
New Thread (new Intersection ()). Start ();
}
}
Collision detection of Java games