Hallo Leute, opcorn:
ich dachte mir, ich mache heute einen kleinen "Artikel" zum Thema "Pixel-genaue Kollision" :toll:
[TIPP]
Vorab möchte ich auf die Quelle der folgenden Methode verweisen: Quaxli's Spiele-Tutorial :applaus:
[/TIPP]
Also erstens existiert zu diesem und weiteren Zwecken eine Klasse "Sprite". :rtfm:
Kritik und vor allem Verbesserungsvorschläge sind erwünscht, ebenso weitere "Lösungsmöglichkeiten" :toll:
PS. Im Anhang findet ihr die komplette Library, die ich mir dazu erstellt habe :rtfm:
ich dachte mir, ich mache heute einen kleinen "Artikel" zum Thema "Pixel-genaue Kollision" :toll:
[TIPP]
Vorab möchte ich auf die Quelle der folgenden Methode verweisen: Quaxli's Spiele-Tutorial :applaus:
[/TIPP]
Also erstens existiert zu diesem und weiteren Zwecken eine Klasse "Sprite". :rtfm:
package de.androbin.lib;
import java.applet.Applet;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import javax.imageio.ImageIO;
import com.sun.xml.internal.ws.api.ResourceLoader;
public class Sprite extends Rectangle implements Drawable, Movable {
// Deklarationen
private static final long serialVersionUID = 1L;
protected int x, y, width, height;
protected HashMap<Integer, BufferedImage> tiles;
protected int pic;
protected int speed = 5;
// Konstruktoren
public Sprite() { }
public Sprite( String url, int x, int y, int width, int height ) {
this.x = x; this.y = y; this.width = width; this.height = height;
for ( int i = 0; new File( url + i + ".png" ).exists(); i++ ) {
try { tiles.put( i, ImageIO.read( ResourceLoader.class.getResource( url + i + ".png" ) ) ); }
catch ( IOException e ) { break; }
}
}
public Sprite( String url, Sprite parent ) { this( url, parent.x, parent.y, parent.width, parent.height ); }
// Methoden
@ Override
public void paint( Graphics g ) { if ( pic == tiles.size() ) pic = 0; g.drawImage( tiles.get( pic++ ), x, y, width, height, null ); }
@Override
public boolean checkCollisions( Sprite s ) {
for ( int x = 0; x < tiles.get( pic ).getWidth(); x++ ) {
for ( int y = 0; y < tiles.get( pic ).getHeight(); y++ ) {
int c1 = tiles.get( pic ).getRGB( x, y );
int c2 = s.tiles.get( s.pic ).getRGB( x, y );
if ( ( ( ( c1 >> 24 ) & 0xff ) != 0 ) && ( ( ( c2 >> 24 ) & 0xff ) != 0 ) ) return true;
}
}
return false;
}
public static String dirToString( Direction dir ) {
switch ( dir ) {
case Up : return "U";
case Down : return "D";
case Left : return "L";
case Right : return "R";
}
return "";
}
@ Override
public void moveTo( Direction dir ) { moveBy( dir, speed ); }
@ Override
public void moveBy( Direction dir, int speed ) {
switch ( dir ) {
case Up : y -= speed;
case Down : y += speed;
case Left : x -= speed;
case Right : x += speed;
}
}
@ Override
public void moveAt( int x, int y ) { this.x = x; this.y = y; }
protected void playSound( String url ) { if ( new File( url + ".wav" ).exists() ) { Applet.newAudioClip( ResourceLoader.class.getResource( url + ".wav" ) ).play(); } }
protected void loopSound( String url ) { if ( new File( url + ".wav" ).exists() ) { Applet.newAudioClip( ResourceLoader.class.getResource( url + ".wav" ) ).loop(); } }
protected void playAnimation( String url, Graphics g ) { new Sprite( url, this ).paint( g ); }
}
import java.applet.Applet;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import javax.imageio.ImageIO;
import com.sun.xml.internal.ws.api.ResourceLoader;
public class Sprite extends Rectangle implements Drawable, Movable {
// Deklarationen
private static final long serialVersionUID = 1L;
protected int x, y, width, height;
protected HashMap<Integer, BufferedImage> tiles;
protected int pic;
protected int speed = 5;
// Konstruktoren
public Sprite() { }
public Sprite( String url, int x, int y, int width, int height ) {
this.x = x; this.y = y; this.width = width; this.height = height;
for ( int i = 0; new File( url + i + ".png" ).exists(); i++ ) {
try { tiles.put( i, ImageIO.read( ResourceLoader.class.getResource( url + i + ".png" ) ) ); }
catch ( IOException e ) { break; }
}
}
public Sprite( String url, Sprite parent ) { this( url, parent.x, parent.y, parent.width, parent.height ); }
// Methoden
@ Override
public void paint( Graphics g ) { if ( pic == tiles.size() ) pic = 0; g.drawImage( tiles.get( pic++ ), x, y, width, height, null ); }
@Override
public boolean checkCollisions( Sprite s ) {
for ( int x = 0; x < tiles.get( pic ).getWidth(); x++ ) {
for ( int y = 0; y < tiles.get( pic ).getHeight(); y++ ) {
int c1 = tiles.get( pic ).getRGB( x, y );
int c2 = s.tiles.get( s.pic ).getRGB( x, y );
if ( ( ( ( c1 >> 24 ) & 0xff ) != 0 ) && ( ( ( c2 >> 24 ) & 0xff ) != 0 ) ) return true;
}
}
return false;
}
public static String dirToString( Direction dir ) {
switch ( dir ) {
case Up : return "U";
case Down : return "D";
case Left : return "L";
case Right : return "R";
}
return "";
}
@ Override
public void moveTo( Direction dir ) { moveBy( dir, speed ); }
@ Override
public void moveBy( Direction dir, int speed ) {
switch ( dir ) {
case Up : y -= speed;
case Down : y += speed;
case Left : x -= speed;
case Right : x += speed;
}
}
@ Override
public void moveAt( int x, int y ) { this.x = x; this.y = y; }
protected void playSound( String url ) { if ( new File( url + ".wav" ).exists() ) { Applet.newAudioClip( ResourceLoader.class.getResource( url + ".wav" ) ).play(); } }
protected void loopSound( String url ) { if ( new File( url + ".wav" ).exists() ) { Applet.newAudioClip( ResourceLoader.class.getResource( url + ".wav" ) ).loop(); } }
protected void playAnimation( String url, Graphics g ) { new Sprite( url, this ).paint( g ); }
}
package de.androbin.lib;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import javax.imageio.ImageIO;
import com.sun.xml.internal.ws.api.ResourceLoader;
public class Player extends Sprite {
// Deklarationen
private static final long serialVersionUID = 1L;
protected HashMap<String, BufferedImage> tiles;
protected Direction dir;
// Konstruktoren
public Player( String url, Direction dir, int x, int y, int width, int height ) {
this.dir = dir; this.x = x; this.y = y; this.width = width; this.height = height;
for ( int i = 0; new File( url + dirToString() + i + ".png" ).exists(); i++ ) {
try { tiles.put( dirToString() + i, ImageIO.read( ResourceLoader.class.getResource( url + dirToString() + i + ".png" ) ) ); }
catch ( IOException e ) { break; }
}
}
// Methoden
public String dirToString() { return dirToString( dir ); }
public void turn( Direction dir ) { this.dir = dir; }
@Override
public boolean checkCollisions( Sprite s ) {
for ( int x = 0; x < tiles.get( dirToString() + pic ).getWidth(); x++ ) {
for ( int y = 0; y < tiles.get( dirToString() + pic ).getHeight(); y++ ) {
int c1 = tiles.get( dirToString() + pic ).getRGB( x, y );
int c2 = s.tiles.get( s.pic ).getRGB( x, y );
if ( ( ( ( c1 >> 24 ) & 0xff ) != 0 ) && ( ( ( c2 >> 24 ) & 0xff ) != 0 ) ) return true;
}
}
return false;
}
@ Override
public void moveTo( Direction dir ) { super.moveTo( dir ); this.dir = dir; }
@ Override
public void moveBy( Direction dir, int speed ) { super.moveBy( dir, speed ); this.dir = dir; }
@ Override
public void moveAt( int x, int y ) { super.moveAt( x, y ); dir = Direction.Down; }
@Override
public void paint( Graphics g ) { if ( pic == tiles.size() ) pic = 0; g.drawImage( tiles.get( dirToString() + pic++ ), x, y, width, height, null ); }
}
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import javax.imageio.ImageIO;
import com.sun.xml.internal.ws.api.ResourceLoader;
public class Player extends Sprite {
// Deklarationen
private static final long serialVersionUID = 1L;
protected HashMap<String, BufferedImage> tiles;
protected Direction dir;
// Konstruktoren
public Player( String url, Direction dir, int x, int y, int width, int height ) {
this.dir = dir; this.x = x; this.y = y; this.width = width; this.height = height;
for ( int i = 0; new File( url + dirToString() + i + ".png" ).exists(); i++ ) {
try { tiles.put( dirToString() + i, ImageIO.read( ResourceLoader.class.getResource( url + dirToString() + i + ".png" ) ) ); }
catch ( IOException e ) { break; }
}
}
// Methoden
public String dirToString() { return dirToString( dir ); }
public void turn( Direction dir ) { this.dir = dir; }
@Override
public boolean checkCollisions( Sprite s ) {
for ( int x = 0; x < tiles.get( dirToString() + pic ).getWidth(); x++ ) {
for ( int y = 0; y < tiles.get( dirToString() + pic ).getHeight(); y++ ) {
int c1 = tiles.get( dirToString() + pic ).getRGB( x, y );
int c2 = s.tiles.get( s.pic ).getRGB( x, y );
if ( ( ( ( c1 >> 24 ) & 0xff ) != 0 ) && ( ( ( c2 >> 24 ) & 0xff ) != 0 ) ) return true;
}
}
return false;
}
@ Override
public void moveTo( Direction dir ) { super.moveTo( dir ); this.dir = dir; }
@ Override
public void moveBy( Direction dir, int speed ) { super.moveBy( dir, speed ); this.dir = dir; }
@ Override
public void moveAt( int x, int y ) { super.moveAt( x, y ); dir = Direction.Down; }
@Override
public void paint( Graphics g ) { if ( pic == tiles.size() ) pic = 0; g.drawImage( tiles.get( dirToString() + pic++ ), x, y, width, height, null ); }
}
package de.androbin.lib;
import java.applet.AudioClip;
import java.awt.Graphics;
import java.util.ArrayList;
import java.util.HashMap;
import javax.swing.JPanel;
public class World extends JPanel implements Runnable {
// Deklarationen
private static final long serialVersionUID = 1L;
protected ArrayList<Sprite> objects;
protected HashMap<String, AudioClip> sounds;
// Methoden
public void moveTo( Sprite s, Direction dir ) { for ( int i = 0; i < objects.size(); i++ ) if ( s.checkCollisions( objects.get( i ) ) ) s.moveTo( dir ); }
public void moveBy( Sprite s, Direction dir, int speed ) { for ( int i = 0; i < objects.size(); i++ ) if ( s.checkCollisions( objects.get( i ) ) ) s.moveBy( dir, speed ); }
public void moveAt( Sprite s, int x, int y ) { for ( int i = 0; i < objects.size(); i++ ) if ( s.checkCollisions( objects.get( i ) ) ) s.moveAt( x, y ); }
@Override
public void paint( Graphics g ) { super.paint( g ); for ( int i = 0; i < objects.size(); i++ ) { objects.get( i ).paint( g ); } }
@Override
public void run() {
while ( true ) {
try { Thread.sleep( 500 ); } catch ( InterruptedException e ) { e.printStackTrace(); }
repaint();
}
}
}
import java.applet.AudioClip;
import java.awt.Graphics;
import java.util.ArrayList;
import java.util.HashMap;
import javax.swing.JPanel;
public class World extends JPanel implements Runnable {
// Deklarationen
private static final long serialVersionUID = 1L;
protected ArrayList<Sprite> objects;
protected HashMap<String, AudioClip> sounds;
// Methoden
public void moveTo( Sprite s, Direction dir ) { for ( int i = 0; i < objects.size(); i++ ) if ( s.checkCollisions( objects.get( i ) ) ) s.moveTo( dir ); }
public void moveBy( Sprite s, Direction dir, int speed ) { for ( int i = 0; i < objects.size(); i++ ) if ( s.checkCollisions( objects.get( i ) ) ) s.moveBy( dir, speed ); }
public void moveAt( Sprite s, int x, int y ) { for ( int i = 0; i < objects.size(); i++ ) if ( s.checkCollisions( objects.get( i ) ) ) s.moveAt( x, y ); }
@Override
public void paint( Graphics g ) { super.paint( g ); for ( int i = 0; i < objects.size(); i++ ) { objects.get( i ).paint( g ); } }
@Override
public void run() {
while ( true ) {
try { Thread.sleep( 500 ); } catch ( InterruptedException e ) { e.printStackTrace(); }
repaint();
}
}
}
PS. Im Anhang findet ihr die komplette Library, die ich mir dazu erstellt habe :rtfm: