Java-Gaming.org    
Featured games (79)
games approved by the League of Dukes
Games in Showcase (477)
Games in Android Showcase (106)
games submitted by our members
Games in WIP (533)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  sprite-collision: how to ignore transparent colors  (Read 2793 times)
0 Members and 1 Guest are viewing this topic.
Offline bauerr

Junior Member




Java!!!!!!!!!!! !!!


« Posted 2005-04-13 10:19:16 »

Hi,

I'm just thinking of sprite-sprite-collisons. How can I detected  a "true collision"? I want to ignore the transparent parts of a sprite.
I've been thinking of defining several Rectangles that fit the size of my sprite, but I think this will be to compllicated if we talk about complex spirtes.

So, what would be the best method?

By the way: If possible I'm interested in doing this without additional jar/API

Best regards.

Ralf
Offline Malohkan

Senior Member




while (true) System.out.println("WOO!!!!");


« Reply #1 - Posted 2005-04-15 18:10:39 »

If you're interested in using any sort of shape (as accurate as you make it) you could use collision detection with polygons via the Area class.  You can see how I do that in the source to my tutorial found here:
http://www.gamelizard.com/JavaGameProgrammingPresentation.htm

Admin and Game Developer at
GameLizard.com
Play Rimscape!    |    Play Conquer!
Offline erikd

JGO Ninja


Medals: 16
Projects: 4
Exp: 14 years


Maximumisness


« Reply #2 - Posted 2005-04-27 14:48:26 »

You could also first detect an image-image collision (disregarding alpha, just detecting if the images overlap), and if such a collision was detected, compare the overlapping pixels of the parts of the 2 images (sprites) that overlap. If both pixels of a compare are not transparent, you have a collision. This way, you'll have pixel perfect collision detection (which BTW is seldom really needed).
Only in the worst case you'll be comparing all pixels of both sprites, but usually you'll just compare a small part.
An additional optimization might be to do the comparing from the 'inner' pixels of the images to the 'outer' pixels (as the transparent pixels are usually on the 'outer' parts of a sprite).
I hope I'm making sense here.

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Jeff

JGO Coder




Got any cats?


« Reply #3 - Posted 2005-04-27 20:29:41 »

Thats how games have tarditionalyl done it when needed (first do a boundign box or bounding speher and then compare the in intersection points pixel by pixel.)

But as already said its almost never done. usually bouding box or bounding spehere is good enough.

Got a question about Java and game programming?  Just new to the Java Game Development Community?  Try my FAQ.  Its likely you'll learn something!

http://wiki.java.net/bin/view/Games/JeffFAQ
Offline bauerr

Junior Member




Java!!!!!!!!!!! !!!


« Reply #4 - Posted 2005-04-28 05:47:10 »

Thanks.

In the meantime I started with a solution as erikd described it. But I will think about all suggestions.

Ralf
Offline Jeff

JGO Coder




Got any cats?


« Reply #5 - Posted 2005-04-28 06:22:28 »

A side note. if you REALLY need pixel perfect inertscetiion then there is an imetrmediate step between bounding-topes and pixel comaprison that cna speed thinsg up.

its sometimes called a "shadow".  What you do is create a 1 dimensional p[rojection of the 2D object ina bit mask.  At any x location where a  pixel is not transparent on any row of pixels, the mathcing bti is sit on the mask.  If you imagine that the obejct was one bit per pixel, then the mask is the binary OR of all the rows

1  
2  
3  
4  
5  
6  
7  
8  
9  
If this is the object:

              XXX    XXX
            XXXX   XXXXX  
          XXX           XXXXX

Then the shadow is this:

        XXXXX    XXXXXXX


Edit: Damn HTMl wont make it line up straight... ghrr.. well I hope you get the idea
What you do is shit the bitstring over the appropriate amount to match the current overlap of the two objects and then binary AND it together.

If the result is clear (all zeros) then there is noi collision. If it is not clear then you just check the columns for each bit position that is 1 to see if there is really an intersection there.

Obviosuly ist not justa  simpel shift and AND because your going to need a wider bit field then you can fit in a single variable (twice the width of your widest object) but the theory is the same, its jus ta bit fancier code to hanbdle the arbitrarily wide bitfield Smiley


Got a question about Java and game programming?  Just new to the Java Game Development Community?  Try my FAQ.  Its likely you'll learn something!

http://wiki.java.net/bin/view/Games/JeffFAQ
Offline kevglass

JGO Kernel


Medals: 120
Projects: 23
Exp: 18 years


Coder, Trainee Pixel Artist, Game Reviewer


« Reply #6 - Posted 2005-04-28 07:09:17 »

Thats neat! So to paraphrase you build a line of pixels for each sprite by either summing up the pixels in each column or row (which I suppose you can cache). Then do a comparison between the two lines.

Double neat!

Kev

Offline bauerr

Junior Member




Java!!!!!!!!!!! !!!


« Reply #7 - Posted 2005-04-28 11:25:35 »

Two questions:

1. If I check the color of a pixel like that:

 private static void printChannels(int pixel) {

   int alpha = (pixel >> 24) & 0xff;  
   int red   = (pixel >> 16) & 0xff;  
   int green = (pixel >>  8) & 0xff;  
   int blue  = (pixel ) & 0xff;  
   
   if(alpha!=255){
    System.out.println(alpha + "/" + red + "/" + green + "/" + blue);
   }
   
   
  }

Which combination is a transparent  color? I can't find a hint about this :(

2. If I use the suggest of Jeff: How would this work for objects with a great amount of transparent color, e.g. somethin like this:


xxxxxx
xxxxxx
ooxxoo
ooxxoo
ooxxoo
oxxxxo
oxxxxo
ooxxoo
ooxxoo
ooxxoo

If I understand it well, this leads to

xxxxxx

This seems no pixel perfect collision to me?

Offline kevglass

JGO Kernel


Medals: 120
Projects: 23
Exp: 18 years


Coder, Trainee Pixel Artist, Game Reviewer


« Reply #8 - Posted 2005-04-28 12:10:45 »

Ah, the thing Jeff suggested wasn't for the final check, just another quick check you can perform before performing the pixel for pixel check.

(Completely) Transpent pixels should have an alpha of zero I believe.

Kev

Offline bauerr

Junior Member




Java!!!!!!!!!!! !!!


« Reply #9 - Posted 2005-04-28 13:08:50 »

Thx.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline K.I.L.E.R

Senior Member




Java games rock!


« Reply #10 - Posted 2005-04-28 14:19:24 »

Why don't you just load the image, create another temporary image, copy the original to the empty temporary image, avoid adding alpha colours?

Then pass the managed image back to your main program.
Whenever you do basic collision it would be pixel perfect.

Vorax:
Is there a name for a "redneck" programmer?

Jeff:
Unemployed. Wink
Offline Jeff

JGO Coder




Got any cats?


« Reply #11 - Posted 2005-04-29 04:39:49 »

Quote
Ah, the thing Jeff suggested wasn't for the final check, just another quick check you can perform before performing the pixel for pixel check.

(Completely) Transpent pixels should have an alpha of zero I believe.

Kev



Right,  if you rotuinely fill all the coluns with at least one pixel its not terribly useufl. OTOH if you have a lot of "surrounding whitespace" or columsn of whitespace  in the middle, it can be.

Its just another potential heuristic.

Got a question about Java and game programming?  Just new to the Java Game Development Community?  Try my FAQ.  Its likely you'll learn something!

http://wiki.java.net/bin/view/Games/JeffFAQ
Offline bauerr

Junior Member




Java!!!!!!!!!!! !!!


« Reply #12 - Posted 2005-04-29 06:21:25 »

@K.I.L.E.R

How should this work? My images are still defined with x/y/widht/height and the collision are still detected by overlapping rectangles. So, I still have to check the pixels, don't I?
Offline K.I.L.E.R

Senior Member




Java games rock!


« Reply #13 - Posted 2005-04-29 06:37:52 »

Quote
@K.I.L.E.R

How should this work? My images are still defined with x/y/widht/height and the collision are still detected by overlapping rectangles. So, I still have to check the pixels, don't I?


Yeh, but at least you wont have to check many pixels. It removes a lot of overhead at the expense of load time.

Vorax:
Is there a name for a "redneck" programmer?

Jeff:
Unemployed. Wink
Offline bauerr

Junior Member




Java!!!!!!!!!!! !!!


« Reply #14 - Posted 2005-04-29 10:20:53 »

Finally I got a solution, but I still have to test it properly. I also thinking about adding some of the suggestions above into my programm.
Nevertheless, here's my solution. It is not called for each collison detection only for some cases.
Any comment would be appreciated.



import java.awt.*;
import java.awt.image.*;


public class CollisionDetector {
 
 static Rectangle s1;
 static Rectangle s2;
 static Rectangle inter;
 static int width;
 static int height;
 public static BufferedImage buf1;
 public static BufferedImage buf2;

 public static CollisionDetector single = new CollisionDetector();
 
 public CollisionDetector getDetector(){
   return single;
 }
 
 public static boolean checkPixelCollision(Image a, int ax, int ay, Image b, int bx, int by){
 
   //Rectangles
   //System.out.println("detector");
   //System.out.println("A = " + ax + "/" + ay + "/" + a.getWidth(null) + "/" + a.getHeight(null));
   //System.out.println("B = " + bx + "/" + by + "/" + b.getWidth(null) + "/" + b.getHeight(null));
   
   //initialize Rectangles
   Rectangle rec1 = new Rectangle();
   Rectangle rec2 = new Rectangle();
   inter = new Rectangle();
   
   //set Bounds and get intersection
   rec1.setRect(ax,ay,a.getWidth(null),a.getHeight(null));
   rec2.setRect(bx,by,b.getWidth(null),b.getHeight(null));
   Rectangle.intersect(rec1,rec2,inter);
   
   //Intersection
   //System.out.println("I = " + inter.x + "/" + inter.y + "/" + inter.getWidth() + "/" + inter.getHeight());
   
   //widht and height must be at least 1 Pixel
   width = (int) inter.width;
   height = (int) inter.height;
   
   if(width<1){
     return false;
   }
   
   if(height<1){
     return false;
   }

   //compute sub-images for image 1
   s1 = getSubRec(rec1,inter);

   //widht and height must be at least 1 Pixel
   width = (int) s1.width;
   height = (int) s1.height;
   
   if(width<1){
     return false;
   }
   
   if(height<1){
     return false;
   }
   
   //compute sub-images for image 2
   s2 = getSubRec(rec2,inter);
   
   //widht and height must be at least 1 Pixel
   width = (int) s2.width;
   height = (int) s2.height;
   
   if(width<1){
     return false;
   }
   
   if(height<1){
     return false;
   }
   
   //SubImages
   //System.out.println("S1 = " + s1.x + "/" + s1.y + "/" + s1.width + "/" + s1.height);    
   //System.out.println("S2 = " + s2.x + "/" + s2.y + "/" + s2.width + "/" + s2.height);    

   buf1 = (BufferedImage)a;
   buf2 = (BufferedImage)b;
   
   buf1 = buf1.getSubimage((int)s1.x,(int)s1.y,(int)s1.width,(int)s1.height);
   buf2 = buf2.getSubimage((int)s2.x,(int)s2.y,(int)s2.width,(int)s2.height);
   
   //System.out.println(buf1.getWidth() + "/" + buf2.getWidth());
   //System.out.println(buf1.getHeight() + "/" + buf2.getHeight());
   
   for(int i=0;i<buf1.getWidth();i++){
     for(int n=0;n<buf1.getHeight();n++){

       //System.out.println(i + "/" + n);
       int rgb1 = buf1.getRGB(i,n);
       int rgb2 = buf2.getRGB(i,n);

       
       if(isOpaque(rgb1)&&isOpaque(rgb2)){
         return true;
       }
       
     }
   }
   
   
   
   return false;
 }

 private static boolean isOpaque(int pixel) {

   int alpha = (pixel >> 24) & 0xff;  
   //int red   = (pixel >> 16) & 0xff;  
   //int green = (pixel >>  8) & 0xff;  
   //int blue  = (pixel ) & 0xff;  
   
   //transparent if alpha = 0
   if(alpha==0){
     return false;
   }
   
   return true;
   
 }

 //computing Rectangles for sub-images
 private static Rectangle getSubRec(Rectangle rec1, Rectangle inter) {
   
   //Rechtecke erzeugen
   Rectangle sub = new Rectangle();
   Rectangle source =  rec1;
   Rectangle part  =  inter;
   
   int absoluteX = 0;
   int absoluteY = 0;
   
   //get X - compared to the Rectangle
   if(source.x>part.x){
     sub.x = 0;
     absoluteX = source.x;
   }else{
     sub.x = part.x - source.x;
     absoluteX = part.x;
   }
   
   if(source.y>part.y){
     sub.y = 0;
     absoluteY = source.y;
   }else{
     sub.y = part.y - source.y;
     absoluteY = part.y;
   }
   
   //same handling with y
   if((source.x+source.width)<(part.x+part.width)){
     sub.width = (source.x+source.width)-absoluteX;
   }else{
     sub.width = (part.x+part.width)-absoluteX;
   }

   if((source.y+source.height)<(part.y+part.height)){
     sub.height = (source.y+source.height)-absoluteY;
   }else{
     sub.height = (part.y+part.height)-absoluteY;
   }

   
   return sub;
 }
 

}


Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

pw (26 views)
2014-07-24 01:59:36

Riven (25 views)
2014-07-23 21:16:32

Riven (19 views)
2014-07-23 21:07:15

Riven (22 views)
2014-07-23 20:56:16

ctomni231 (51 views)
2014-07-18 06:55:21

Zero Volt (46 views)
2014-07-17 23:47:54

danieldean (37 views)
2014-07-17 23:41:23

MustardPeter (40 views)
2014-07-16 23:30:00

Cero (56 views)
2014-07-16 00:42:17

Riven (55 views)
2014-07-14 18:02:53
HotSpot Options
by dleskov
2014-07-08 03:59:08

Java and Game Development Tutorials
by SwordsMiner
2014-06-14 00:58:24

Java and Game Development Tutorials
by SwordsMiner
2014-06-14 00:47:22

How do I start Java Game Development?
by ra4king
2014-05-17 11:13:37

HotSpot Options
by Roquen
2014-05-15 09:59:54

HotSpot Options
by Roquen
2014-05-06 15:03:10

Escape Analysis
by Roquen
2014-04-29 22:16:43

Experimental Toys
by Roquen
2014-04-28 13:24:22
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!