4

I'm currently implementing a little game in java that allows for a player to drive a car around a track.

I want the car to slow if it deviates from the track. However, because the track is rounded, using rectangles doesn't seem to be the best idea.

One idea that popped into my head was somehow using the colors of the pixels the car is on. If all the pixels of the car happen to be where the map is green, as opposed to black for the track, then I slow the car down.

Is this a good approach? If so, how do I go about doing it? Searches have just yielded the same rectangle intersection approach to collision detection.

oadams
  • 3,019
  • 6
  • 30
  • 53
  • How is the rounded track defined? You may also want to have a look on http://gamedev.stackexchange.com/ if you haven't already. – YXD May 13 '11 at 00:58

4 Answers4

3

If your cars and track can be drawn using classes that implement the Shape interface, one of the assorted contains() methods may solve the problem. There's a scale and rotate example here and a more elaborate example here.

Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • Can you shine some light on how the contains() method would be implemented? – Dhaivat Pandya May 13 '11 at 11:56
  • @Dhaivat Pandya: That's the best part—all the implementing classes already have concrete methods. Here's an [example](https://sites.google.com/site/drjohnbmatthews/point-in-polygon) using `Polygon`. – trashgod May 13 '11 at 19:46
  • @Dhaivat Pandya: Thanks! I up-voted the other two answers, as they represent useful approaches for some cases. – trashgod May 13 '11 at 21:32
  • Ok so the spec of my program has changed a bit. The car must avoid rectangular obstacles. I thought I could just test for intersection between the obstacle and the cars, but because the car turns using an AffineTransformation, it no longer inherits from the shape class. How would I test for intersection with the AffineTransformation? – oadams May 15 '11 at 02:31
  • Use [`createTransformedShape()`](http://download.oracle.com/javase/6/docs/api/java/awt/geom/AffineTransform.html#createTransformedShape%28java.awt.Shape%29), as shown in each of the three examples cited. – trashgod May 15 '11 at 04:59
1

You could do collision detection sort of like bit-blit'ing. Make the 'mask' for the car with 1's for foreground and 0's for the transparent or outside pixels. 'AND'ing the mask with the background where the car is located results in the background pixels that the car is on. Of course this 'AND' operation isn't doesn't operate on bits but rather pixel values of the background. Searching for Raster-Ops or PixBlt might lead to some solutions.

karmakaze
  • 34,689
  • 1
  • 30
  • 32
  • This can be done with [`getRaster()`](http://download.oracle.com/javase/6/docs/api/java/awt/image/BufferedImage.html#getRaster%28%29), but it scales poorly. – trashgod May 13 '11 at 02:07
  • This makes sense. How do I go about making this mask? What data structure should I use? – oadams May 13 '11 at 07:01
  • Having the whole screen as a multidimensional array seems like a bad idea to me, because on high resolutions every operation will be very slow. – Dhaivat Pandya May 13 '11 at 11:55
1

These are all good answers. If you wanted to go more with your idea of color detection, check out the Robot class in the Java API; It has a lot of cool lower level functions like getting a color value of a point on the screen (px,px), moving the cursor independent of the user, etc..

xdevient
  • 56
  • 3
  • Here's an [example using `createScreenCapture()`](http://stackoverflow.com/questions/3742731/java-how-to-draw-constantly-changing-graphics/3742841#3742841). – trashgod May 13 '11 at 02:31
  • This isn't a good idea. This like trying to have a program write to file by making a robotic arm. You can just do it on the backend. – Dhaivat Pandya May 13 '11 at 20:46
  • Your own backend? How would you do that in Java? I don't see the analogy; A low level access is a low level access. I'm not saying the algorithm is a good idea however. – xdevient May 13 '11 at 21:34
0

I like trashgod's answer the best, but, if you're not using the Shape class, then you may have problems.

So, here is my answer.

Firstly, anything you can draw on the screen has some granularity, so take advantage of that. You have not provided many details on how you're blitting to the screen, but, this is what I would suggest.

Use Bezier Curves. Since they are mathematically defined (and very simple to plot), you can easily, pick, say 100 points on a Bezier curve and check if the edges of your car are inside the Bezier Curve. This is probably the most accurate solution.

If you don't like math for some reason, I would suggest keeping track of a variable that contains how close the nearest patch of dirt is, and when that goes to zero, you can slow down the car.

Or (the worst solution), you can compare two patches of what is being shown on the screen (the car and the dirt), and check if the car is on the dirt. This is what the Shape.contains() method does, but, it has been written by professionals and your version is probably going to be significantly slower.

Dhaivat Pandya
  • 6,499
  • 4
  • 29
  • 43