Hi!
Ich hab mal angefangen Qualxis Tutorial, recht eigen abgeändert, nachzubauen.
Sehr sehr coole Sache - danke!!
Das funkt recht gut, man hat Beschleunigung statt Geschwindigkeit und "Luftwiderstand" etc. pp.
Ich hab auch die zum Spiel gehörigen Funktionen und Variablen in eine Klasse "Engine" ausgelagert. Genau wie eine Library für geladene Bilder (die von der Engine im Konstruktor erzeugt wird, und dort werden Bilder und fps geladen).
Jedenfalls is alles soweit gut bis zur Pixelgetreuen Kollision:
Ich lasse stille raketen erzeugen, fliege mit 1 Pixel pro Knopfdruck hin und schaue nach.
Von schräg unten klappt das manchmal, von hinten aber gar nicht: es die OpaquCollisionsCheck gibt immer aus, dass alles passt - obwohl ich knapp in der Bombe (hinten) drin bin (mit meiner Seite).
Bei etwa 2,3 Pixel überlappen kommt:
[Java]
sub_me: breite und höhe: 1.0015870000000575 10.03
sub_him: breite und höhe: 1.0015870000000575 10.0
Exception in thread "Thread-4" java.awt.image.RasterFormatException: (y + height) is outside of Raster
at sun.awt.image.ByteInterleavedRaster.createWritableChild(ByteInterleavedRaster.java:1273)
at java.awt.image.BufferedImage.getSubimage(BufferedImage.java:1166)
at Sprite.notOpaqueCollision(Sprite.java:120)
at Rocket.collidedWith(Rocket.java:102)
at Engine.doLogic(Engine.java:53)
at Engine.update(Engine.java:23)
at GamePanel.run(GamePanel.java:66)
at java.lang.Thread.run(Thread.java:680)[/code]
Es schaut für mich auch etwas komisch aus, dass da steht:
if( isOpaque(rgb1) && isOpaque(rgb2) ){return true;}
Das sagt doch, dass er aufhören soll zu suchen, wenn irgend welche Pixel alphakanäle haben?!
[Java]
public boolean notOpaqueCollision(Sprite s){
Rectangle2D.Double cut = (Double) this.createIntersection(s);
System.out.println("Intersection created!");
if ((cut.width < 1) || (cut.height < 1)){
return false;
}
//Rectangle relative to images
Rectangle2D.Double sub_me = getSubRec(this, cut);
Rectangle2D.Double sub_him = getSubRec(s, cut);
System.out.println("I: breite ud höhe: " + sub_me.width +" "+ sub_me.height +s.currentPic);
System.out.println("ER:breite ud höhe: " + sub_him.width +" "+ sub_him.height);
BufferedImage img_me = pics[currentPic].getSubimage((int)sub_me.x, (int)sub_me.y,
(int)sub_me.width, (int)sub_me.height);
BufferedImage img_him = pics[s.currentPic].getSubimage((int)sub_him.x, (int)sub_him.y,
(int)sub_him.width, (int)sub_him.height);
for (int i = 0; i < img_me.getWidth(); i++){
for(int k = 0; k < img_him.getHeight(); k++){
int rgb1 = img_me.getRGB(i, k);
int rgb2 = img_him.getRGB(i, k);
System.out.println(rgb1 + "-1 / 2- " + rgb2);
if( isOpaque(rgb1) && isOpaque(rgb2) ){
return true;
}
}
}
return false; //wegen return missing eingefügt...
}
[/code]
und
Und die Einbindung in der Rakete:
Ich hab mal angefangen Qualxis Tutorial, recht eigen abgeändert, nachzubauen.
Sehr sehr coole Sache - danke!!
Das funkt recht gut, man hat Beschleunigung statt Geschwindigkeit und "Luftwiderstand" etc. pp.
Ich hab auch die zum Spiel gehörigen Funktionen und Variablen in eine Klasse "Engine" ausgelagert. Genau wie eine Library für geladene Bilder (die von der Engine im Konstruktor erzeugt wird, und dort werden Bilder und fps geladen).
Jedenfalls is alles soweit gut bis zur Pixelgetreuen Kollision:
Ich lasse stille raketen erzeugen, fliege mit 1 Pixel pro Knopfdruck hin und schaue nach.
Von schräg unten klappt das manchmal, von hinten aber gar nicht: es die OpaquCollisionsCheck gibt immer aus, dass alles passt - obwohl ich knapp in der Bombe (hinten) drin bin (mit meiner Seite).
Bei etwa 2,3 Pixel überlappen kommt:
[Java]
sub_me: breite und höhe: 1.0015870000000575 10.03
sub_him: breite und höhe: 1.0015870000000575 10.0
Exception in thread "Thread-4" java.awt.image.RasterFormatException: (y + height) is outside of Raster
at sun.awt.image.ByteInterleavedRaster.createWritableChild(ByteInterleavedRaster.java:1273)
at java.awt.image.BufferedImage.getSubimage(BufferedImage.java:1166)
at Sprite.notOpaqueCollision(Sprite.java:120)
at Rocket.collidedWith(Rocket.java:102)
at Engine.doLogic(Engine.java:53)
at Engine.update(Engine.java:23)
at GamePanel.run(GamePanel.java:66)
at java.lang.Thread.run(Thread.java:680)[/code]
Es schaut für mich auch etwas komisch aus, dass da steht:
if( isOpaque(rgb1) && isOpaque(rgb2) ){return true;}
Das sagt doch, dass er aufhören soll zu suchen, wenn irgend welche Pixel alphakanäle haben?!
[Java]
public boolean notOpaqueCollision(Sprite s){
Rectangle2D.Double cut = (Double) this.createIntersection(s);
System.out.println("Intersection created!");
if ((cut.width < 1) || (cut.height < 1)){
return false;
}
//Rectangle relative to images
Rectangle2D.Double sub_me = getSubRec(this, cut);
Rectangle2D.Double sub_him = getSubRec(s, cut);
System.out.println("I: breite ud höhe: " + sub_me.width +" "+ sub_me.height +s.currentPic);
System.out.println("ER:breite ud höhe: " + sub_him.width +" "+ sub_him.height);
BufferedImage img_me = pics[currentPic].getSubimage((int)sub_me.x, (int)sub_me.y,
(int)sub_me.width, (int)sub_me.height);
BufferedImage img_him = pics[s.currentPic].getSubimage((int)sub_him.x, (int)sub_him.y,
(int)sub_him.width, (int)sub_him.height);
for (int i = 0; i < img_me.getWidth(); i++){
for(int k = 0; k < img_him.getHeight(); k++){
int rgb1 = img_me.getRGB(i, k);
int rgb2 = img_him.getRGB(i, k);
System.out.println(rgb1 + "-1 / 2- " + rgb2);
if( isOpaque(rgb1) && isOpaque(rgb2) ){
return true;
}
}
}
return false; //wegen return missing eingefügt...
}
[/code]
und
Java:
protected Rectangle2D.Double getSubRec
(Rectangle2D.Double source, Rectangle2D.Double part){
Rectangle2D.Double sub = new Rectangle2D.Double();
if (source.x > part.x){
sub.x = 0;
}else{
sub.x = part.x - source.x;
}
if (source.y > part.y){
sub.y = 0;
}else{
sub.y = part.y - source.y;
}
sub.width = part.width;
sub.height = part.height;
return sub;
}
protected boolean isOpaque(int rgb){
// Bits 24-31 = alpha, below are red, green, blue
int alpha = (rgb >> 24) & 0xff;
if(alpha == 0){
return false;
}else{ return true; }
}
Und die Einbindung in der Rakete:
Java:
@Override
public boolean collidedWith(Sprite s) {
if(remove){return false;}
if(this.intersects(s) && (s instanceof Player | s instanceof Rocket)){
System.out.println("Rakete Kollidierte!");
if(!notOpaqueCollision(s)){System.out.println("noch nicht");return false;}
remove = true;
s.remove = true;
eng.createExplosion((int) getX(),(int) getY());
eng.createExplosion((int) s.getX(),(int) s.getY());
return true;
}else{
return false;
}
}