|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Member
Iscritto dal: May 2005
Città: Modena
Messaggi: 276
|
[JAVA] Controllo collisione
Ciao, stavo smanettando con Java volevo creare un'animazione di due oggetti che volano a random per lo schermo e quando si toccano si avvia un'azione...
Il problema è che non riesco a controllare QUANDO si toccano.... Io vorrei che anche se hanno un solo punto in comune si avvii l'azione... I due oggetti in questione sono un Ellipse2D (un cerchio) e una Gif... Riesco a controllare se hanno l'origine in comune ma non se hanno un punto qualsiasi in comune.. per ciò il tutto nziona solo se hanno l'origine uguale.. Non so come fare... Non mi viene in mente nulla.... Uff...
__________________
andrew |
|
|
|
|
|
#2 |
|
Senior Member
Iscritto dal: Nov 2005
Messaggi: 2782
|
Devi fare delle traslazioni, per intenderci la logica da usare è innanzitutto immaginare i rettangoli circoscritti alle due immagini, poi trovare il rettangolo derivante dalla loro intersezione e su questo fare un controllo pixel per pixel. Se non c'è intersezione tra i due rettangoli allora sai già che non c'è sicuramente la collisione e ti risparmi calcoli inutili.
Questo è un codice che avevo scritto per un giochino in java: x1,y1,x2 e y2 sono le coordinate del left,top della prima e della seconda immagine img1 e img2 sono le due immagini Codice:
public static boolean isPixelCollide(double x1, double y1, BufferedImage img1, double x2, double y2, BufferedImage img2){
int offX1=x1>x2?0:(int)x1-(int)x2;
int offX2=x2>x1?0:(int)x2-(int)x1;
int offY1=y1>y2?0:(int)y1-(int)y2;
int offY2=y2>y1?0:(int)y2-(int)y1;
for(int i=0;i-offX1<img1.getWidth()&&i-offX2<img2.getWidth();i++){
for(int j=0;j-offY1<img1.getHeight()&&j-offY2<img2.getHeight();j++){
if((img1.getRGB(i-offX1,j-offY1)& 0xff000000) != 0 && (img2.getRGB(i-offX2,j-offY2)& 0xff000000) != 0){
return true;
}
}
}
return false;
}
|
|
|
|
|
|
#3 |
|
Senior Member
Iscritto dal: Jul 2002
Città: Reggio Calabria -> London
Messaggi: 12112
|
...ma usare l'equazione dell'ellisse e calcolarne l'intersezione?
__________________
|
|
|
|
|
|
#4 | |
|
Senior Member
Iscritto dal: Nov 2005
Messaggi: 2782
|
Quote:
EDIT: Ci ho riflettuto su, adesso ho capito, controlli tutti i punti appartenenti al perimetro dell'ellisse, se uno di questi collide c'è collisione. In effetti dovrebbe essere più efficiente anche se dipende da quali sono le immagini credo... Ultima modifica di wingman87 : 18-06-2008 alle 19:45. |
|
|
|
|
|
|
#5 | |
|
Senior Member
Iscritto dal: Jul 2002
Città: Reggio Calabria -> London
Messaggi: 12112
|
Quote:
__________________
|
|
|
|
|
|
|
#6 |
|
Senior Member
Iscritto dal: Nov 2005
Messaggi: 2782
|
Ah, ma allora forse sono io che non ho capito bene, io pensavo che un'immagine fosse un'ellissi e l'altra qualsiasi altra cosa
|
|
|
|
|
|
#7 | |
|
Senior Member
Iscritto dal: Jul 2002
Città: Reggio Calabria -> London
Messaggi: 12112
|
Quote:
![]() avevo letto un ellispe2d e un cerchio anzichè un ellipse2d (un cerchio)...
__________________
|
|
|
|
|
|
|
#8 | ||
|
Senior Member
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
|
Quote:
-> interface java.awt.Shape -> interface java.awt.geom.PathIterator -> final class java.awt.geom.GeneralPath (implementa Shape, ha metodi per produrre un PathIterator che serve per iterare l'elenco delle "geometrie"[linee del primo secondo e terzo ordine] che descrive la Shape di un'istanza di GeneralPath) Dato che queste classi mettono già a disposizione dei metodi per controllare l'intersezione la tecnica potrebbe essere quella di "inviluppare" l'immagine gif in una Shape che ne "ricalchi" i bordi (qui è neccessario che tu definisca una classe per fare questo lavoro: prende in input una gif e produce in output il GeneralPath relativo). In pratica esisterà un GenerlPath per ogni immagine gif da gestire: i GeneralPath vanno aggiornati (posizone nel mondo virtuale) di pari passo con l'immagine gif e a ogni update controlli se c'è o no collisione. Le immagini gif servono per essere disegnate a video, i GeneralPath servono solo per i calcoli di collisione con il tuo cerchio (che, tra l'altro, essendo una Elipse2D puoi già usarlo per i calcoli di collisione con un altro GeneralPath perchè entrambe le classi estendono Shape). Non mi dilungo ulteriormente sui dettagli implementativi, l'unca cosa che mi sembra un attimo più impegnativa è la realizzazione della classe che presa una gif ne ricalca il perimetro: devi trovare un metodo per farlo agevolmente, producendo semplici linee dritte (mio consiglio) da incapsulare in un GeneralPath. Fatto questo il problema della collisione è molto semplice. P.S.: sto presumendo che la gif possa avere *qualsiasi* forma, perchè anche se alla fine è sempre rettangolare, magari tu la disegni con lo sfondo trasparente e vuoi le collisioni *esattamente* sulla forma dell'oggetto rappresentato dal disegno della gif e non su tutta la gif (il rettangolo). Nel caso contrario, quello cioè in cui ti basta il controllo di collisione con il rettangolo della gif, la cosa è di una banalità disarmante: -> public abstract class Elipse2D (il tuo cerchio) -> public abstract class Rectangle2D (la tua gif) Implementano entrambi un metodo .intersects() del tipo: Quote:
__________________
As long as you are basically literate in programming, you should be able to express any logical relationship you understand. If you don’t understand a logical relationship, you can use the attempt to program it as a means to learn about it. (Chris Crawford) Ultima modifica di banryu79 : 19-06-2008 alle 10:42. |
||
|
|
|
|
|
#9 |
|
Senior Member
Iscritto dal: Jul 2002
Città: Reggio Calabria -> London
Messaggi: 12112
|
fichissimi, non li conoscevo 'sti cosi di java
__________________
|
|
|
|
|
|
#10 |
|
Senior Member
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
|
Sì, molto ben fatti, ma se uno non li ha mai usati debbo testimoniare che non permettono un utilizzo immediato, però con la giusta dose di studio e un paio di prove arrivi a fare quello che ti serve: puoi eseguire hit testing e collision su qualsiasi tipo di perimetro/contorno chiuso, adirittura su forme contenenti fori, dove puoi decidere te se un foro è una regione "vuota" di materiale oppure lo consideri "pieno" (dipende tutto da come ti costruisci il GeneralPath (ovvero la Shape) che descrive la tua forma).
Si possono usare linee dritte, e curve di Bèzier (quadrate e cubiche) per definire il GenerlPath e poi iterarle punto per punto (estremi inizio/fine e punti di controllo nel caso delle Bèzier) grazie al PathIterator. sapendo usare bene queste classi oltre a ottenere la collisione in maniera molto precisa (per esempio sulla forma "opaca" della gif e non su tutta la gif) puoi anche farti restituire la zona di intersezione delle due forme in collisione (il proiettile/cerchio e la gif/bersaglio) se ti interessa per esempio eseguire un'animazione localizzata/condizionata rispetto al punto di collisione. Inoltre c'è anche la classe Area da guardare, ma è più "pesante" ed è orientata alla Computational Geometry e alle operazioni di insieme su forme geometriche per costruire forme complesse tramite intersezioni/unioni e sottrazioni di forme.
__________________
As long as you are basically literate in programming, you should be able to express any logical relationship you understand. If you don’t understand a logical relationship, you can use the attempt to program it as a means to learn about it. (Chris Crawford) Ultima modifica di banryu79 : 19-06-2008 alle 13:14. |
|
|
|
|
|
#11 |
|
Senior Member
Iscritto dal: Jul 2002
Città: Reggio Calabria -> London
Messaggi: 12112
|
really good
si imparano sempre cose nuove
__________________
|
|
|
|
|
|
#12 |
|
Senior Member
Iscritto dal: Oct 2007
Messaggi: 677
|
Wow, mi si è risolto un dubbio leggendo questo post....;
Io sono in una situazione simile...; Magari può essere utile a tutti e due, per cui non apro un altro post....; Devo gestire una animazione di oggetti che vanno collidere (devo ovviamente controllare se si toccano ma questo viene dopo..); Il problema è ce non so in precedenza se i due oggetti sono immagini o Componenti2D di java... Esempio magari si capisce meglio: Si creano due oggetti che "navigano" per lo schermo: Oggetto a: Elipse2D Oggetto b: A scelta dell'user tra un'immagine gif e un Rectangle2D Come gestisco il fatto che a volte l'oggetto b è un'immagine e a volte è un Rectangle2D? Io pensavo con un'interfaccia ma non so come implementare il tutto... Mi sono spiegato male già lo so.... Ma cercate di capire.. Grazie
__________________
Desktop: (In Vendita) iMac (12,2) 27" --> i5 QaudCore 2,7GHz, 8GB RAM, 1TB HDD.. Laptop (In Pensione): MacBook PRO (3,1) 15.4" (Glossy, ma pentito) --> 2.2Ghz, 4GB Ram.. Camera: Nikon D80 with Nikkor 18-55mm 1:3-5.6 GII + Nikkor 55-200mm 1:4-5.6 VR "Mobile": iPhone 5 64Gb MyEbay: 100%! • Mercatino (Green = Good; Red = Bad) UncleSam, Boxi80, Zuckerbaer, lamerone, danidj, maxmax80 |
|
|
|
|
|
#13 |
|
Senior Member
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
|
Ti presento una soluzione che forse non è la migliore, ma è la prima che mi è venuta in mente ed è semplice:
Una soluzione potrebbe essere di gestire l'oggetto bersaglio con una classe che ti scrivi tu che prende in input o un Rectangle2D o l'oggetto scelto dall'utente (immagino si tratti di un'immagine? cmq potrebbe essere qualsiasi cosa). -> Per poter fare questo dovrai dotare la tua classe di costruttori che accettino come parametro di ingresso un Object e lo memorizzino al loro interno. Poi la tua classe dovrà esporre un metodo che restituisca un Rectangle2D in modo da poter fare i calcoli di collisione. -> Per poter fare questo, dentro questo metodo esegui un instanceof [adesso qualcuno inorridirà A questo punto, guardando le cose da fuori e supponendo che la tua classe si chiami Bersaglio, e abbia un metodo pubblic chiamato .getBoundingRectangle() la potrai istanziare così: Codice:
// caso Rectangle2D Rectangle2D rectangle = ...bla bla bla ... Bersaglio b1 = new Bersaglio(rectangle) // caso Image Image image = ...bla, bla, bla ... Bersaglio b1 = new Bersaglio(image) Codice:
Elipse2D bullet // è il proiettile
Bersaglio b1 // è il bersaglio da colpire
boolean collision = false;
...
if (bullet.intersects(b1.getBoundingRectangle()))
{
collision = true;
}
__________________
As long as you are basically literate in programming, you should be able to express any logical relationship you understand. If you don’t understand a logical relationship, you can use the attempt to program it as a means to learn about it. (Chris Crawford) |
|
|
|
|
|
#14 | |||
|
Senior Member
Iscritto dal: Oct 2007
Messaggi: 677
|
Quote:
Avevo pensato di usare la classe Object... Ma mi da errore dicendo che un Objct non può memorizzare un'Image al suo intrno poichè essa è "astratta".... Hehe.. semplice da dire ma non capisco il motivo.. :P Quote:
No, è che ultimamente non sto capendo piu nulla.. sto ricevendo mille informazioni su java.... e ho un po' di confusione.. XD Anzi molta confuzione.... :P Quote:
Codice:
//deve essere così:
public Bersaglio(Rectangle2D rect)
{...}
public Bersaglio(Image img)
{...}
...
//oppure così:
public Bresaglio(Object obj)
{ if (obj.instanceof() == Rectangle2D)
{...}
else if (obj.instanceof() == Image)
{...}
}
__________________
Desktop: (In Vendita) iMac (12,2) 27" --> i5 QaudCore 2,7GHz, 8GB RAM, 1TB HDD.. Laptop (In Pensione): MacBook PRO (3,1) 15.4" (Glossy, ma pentito) --> 2.2Ghz, 4GB Ram.. Camera: Nikon D80 with Nikkor 18-55mm 1:3-5.6 GII + Nikkor 55-200mm 1:4-5.6 VR "Mobile": iPhone 5 64Gb MyEbay: 100%! • Mercatino (Green = Good; Red = Bad) UncleSam, Boxi80, Zuckerbaer, lamerone, danidj, maxmax80 |
|||
|
|
|
|
|
#15 |
|
Senior Member
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
|
1) Image è una classe astratta (abstract class) il che significa che non può essere istanziata: devi cercare delle sotto-classi che la estendano.
Tu, concretamente, userai una di quelle: io parlavo di Image per indicare un'istanza generica, non importa di che tipo, che estende Image. 2) recuperare il Rectangle2D di un Image. Hai due possibilità: a] la classe che usi come estensione di Image implementa già di suo un metodo pubblico che restituisce un Rectangle2D e te non devi fare niente; b] la classe che usi come estensione di Image *non* implementa un metodo che ti restituisca un Rectangle2D, in tal caso devi "spulciare" tra i metodi pubblici della classe per individuare quelli che ti restituiscono delle informazioni a te utili per poi processarle e costrutirti tu il Rectangle2D. 3) costruttore. Per ora basta 1 solo costruttore del tipo: Codice:
...
private Object userObject;
...
public Bersaglio(Object obj)
{
userObject = obj;
}
...
-> Java™ Platform, Standard Edition 6 API Specification Con questo strumento risolverai i punti 1) e 2). A dire il vero il punto 1) denota anche che ancora non ti sei impadronito di alcuni concetti basilari del linguaggio: questi li devi studiare su un buon manuale. Ciao P.S.: prova un po' a documentarti con calma e ad abbozzare un'implementazione quando ti senti un po' più sicuro e hai le idee più chiare. Ti suggerisco di prenderti una giornata per esaminare con calma le possibilità di soluzione e i punti più "oscuri" che ancora rimangono dopo la consultazione dei Javadoc: a quel punto avrà molto più senso chiedere aiuto qui
__________________
As long as you are basically literate in programming, you should be able to express any logical relationship you understand. If you don’t understand a logical relationship, you can use the attempt to program it as a means to learn about it. (Chris Crawford) Ultima modifica di banryu79 : 21-06-2008 alle 13:11. |
|
|
|
|
|
#16 |
|
Senior Member
Iscritto dal: Oct 2007
Messaggi: 677
|
:embarassed:
Si, conosco le API... E' che c'è tamente tanta roba che a volte a leggerle vado in confuzione.. :P
Comunque ti ringrazio, sei sempre molto gentile e disponibile... Il motivo per cui scrivo spesso sul forum è a fretta... Per certe cose leggendo con calma e ragionando i si arriverebbe, ma l'agitazione e la pressione del atto di dover consegnare entro fine mese il pretto mi deconcentrano e non riesco a ragionare come si deve.. Chiedo scusa se a volte domando cose banali o scontate.. Ma la fretta come dicevo... Fa brutti scherzi... Guarda un po' te che ho realizzato una pagina php per creare al tabelle dei risultati scordandomi che il php senza un server di supporto non funziona.. E me ne sn ricordato a lavoro ultimato..
__________________
Desktop: (In Vendita) iMac (12,2) 27" --> i5 QaudCore 2,7GHz, 8GB RAM, 1TB HDD.. Laptop (In Pensione): MacBook PRO (3,1) 15.4" (Glossy, ma pentito) --> 2.2Ghz, 4GB Ram.. Camera: Nikon D80 with Nikkor 18-55mm 1:3-5.6 GII + Nikkor 55-200mm 1:4-5.6 VR "Mobile": iPhone 5 64Gb MyEbay: 100%! • Mercatino (Green = Good; Red = Bad) UncleSam, Boxi80, Zuckerbaer, lamerone, danidj, maxmax80 |
|
|
|
|
|
#17 | |
|
Member
Iscritto dal: May 2005
Città: Modena
Messaggi: 276
|
stavo per mettere in pratica i vostri suggerimenti ma m è sorto un problema a monte.. ovvero non riesco sciegliere l'immagine, che è o un rectangle2d o una gif, tipo con dei radiobutton.. questa è in una classe che estende jframe, ma nn riesco a gestire il tutto..
Quote:
__________________
andrew |
|
|
|
|
|
|
#18 | |
|
Senior Member
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
|
Quote:
1) All'inizio istanziare un Rectangle2D o una sottoclasse di Image in base al valore di default del radiobutton; 2) quindi istanziare un Rectangle2D o una sottoclase di Image ad ogni evento lanciato dalla selezione utente sul radiobutton. Tutto qua credo. Se il tuo problema è avere a che fare con il controllo/componente che implementa un radiobutton: How to Use Buttons, Check Boxes, and Radio Buttons
__________________
As long as you are basically literate in programming, you should be able to express any logical relationship you understand. If you don’t understand a logical relationship, you can use the attempt to program it as a means to learn about it. (Chris Crawford) |
|
|
|
|
|
|
#19 |
|
Member
Iscritto dal: May 2005
Città: Modena
Messaggi: 276
|
Si, mi sono spiegato male scusate...
volevo dire che *NON* ho problemi a selezionare uno dei due.. Ma essendo oggetti totalmente diversi con metodi differenti non riesco a gestirli allo stesso modo.... Per esempio se dovessi creare un oggetto "Bersaglio" che è *sempre* un rettangolo so che metodi posso invocare anche dal'esterno... ma se a volte Bersaglio è un Image.... Non posso gestirli dll'esterno allo stesso modo... Devo utlizzare una Interfaccia? Fin ora ho fatto questo: Codice:
package Project;
import java.awt.*;
import java.io.File;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
public class Aereo {
private Object obj = null;
private File alpha = new File("./Immagini/Statiche/Statico0.gif");
private File bravo = new File("./Immagini/Statiche/Statico1.gif");
private File charlie = new File("./Immagini/Statiche/Statico2.gif");
private File delta = new File("./Immagini/Animate/Animato0.gif");
private File echo = new File("./Immagini/Animate/Animato1.gif");
private File foxtrot = new File("./Immagini/Animate/Animato2.gif");
double x, y = 0;
//crea un oggetto in base all'ID fornito.
public Aereo(int id){
switch(id){
case(1):{
obj = new RectStat(x, y, 170.0, 70.0);
break;
}
case(2):{
obj = new CercStat(x, y, 160.0, 160.0);
break;
}
case(3):{
obj = new RectStat(x, y, 160.0, 160.0);
break;
}
case(4):{
obj = new AereoImmagine(alpha);
break;
}
case(5):{
obj = new AereoImmagine(bravo);
break;
}
case(6):{
obj = new AereoImmagine(charlie);
break;
}
case(7):{
obj = new AereoImmagine(delta);
break;
}
case(8):{
obj = new AereoImmagine(echo);
break;
}
case(9):{
obj = new AereoImmagine(foxtrot);
break;
}
default:{
}
}
}
public void setLocation(Point punct){
x = punct.getX();
y = punct.getY();
}
}
class AereoImmagine extends Image {
private Image img;
/**
* Crea un'immagine dal file indicato
* @param path File dell'imamgine
*/
public AereoImmagine(File path){
try{
img = ImageIO.read(path);
} catch (Exception e) {
System.out.print("Errore:" + e);
JOptionPane.showMessageDialog(null, "File immagine Insistente", "Errore Interno",
JOptionPane.ERROR_MESSAGE);
}
}
@Override
public int getWidth(ImageObserver arg0) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public int getHeight(ImageObserver arg0) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public ImageProducer getSource() {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public Graphics getGraphics() {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public Object getProperty(String arg0, ImageObserver arg1) {
throw new UnsupportedOperationException("Not supported yet.");
}
}
class RectStat extends Rectangle2D.Double{
private Rectangle2D.Double rect;
private Graphics2D gr;
public RectStat(double x, double y, double width, double height){
rect = new Rectangle2D.Double(x, y, width, height);
//gr.fill(rect);
}
@Override
public void setRect(double arg0, double arg1, double arg2, double arg3) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public int outcode(double arg0, double arg1) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public Rectangle2D createIntersection(Rectangle2D arg0) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public Rectangle2D createUnion(Rectangle2D arg0) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public double getX() {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public double getY() {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public double getWidth() {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public double getHeight() {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public boolean isEmpty() {
throw new UnsupportedOperationException("Not supported yet.");
}
}
class CercStat extends Ellipse2D.Double{
private Ellipse2D.Double cerc;
public CercStat(double x, double y, double width, double height){
cerc = new Ellipse2D.Double(x, y, width, height);
}
@Override
public double getX() {
throw new UnsupportedOperationException("Not supported yet.");
}
__________________
andrew Ultima modifica di andrew1988 : 23-06-2008 alle 17:22. |
|
|
|
|
|
#20 | ||
|
Senior Member
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
|
Quote:
Nel caso dell'Image l'idea è che Bersaglio internamente si ricavi il rettangolo dell'Image per istanziare un Rectangle2D. Fatto questo poi tu puoi fare altre operazioni con la classe dotandola di metodi che, per esempio, operino interfacciandosi solo con il Rectangle2D (e questo implicherebbe l'esclusione di operazioni sui pixel di un'immagine) per gestire il posizionamento a video e le collisioni. Questo nell'ottica di per gestire le due-tre operazioni comuni che faresti sia con l'Image che con il Rectangle2D nella loro funzione di "bersagli" (rendering a video, update della loro posizione, calcolo della collisione). Ho detto subito che la soluzione proposta di primo acchito non era la migliore, ma per poche cose poteva andare bene. Se tu vuoi fare cose più complesse con il tuo "Bersaglio" forse è meglio prima capire con precisione cosa devi gestire (che operazioni comuni condividerai a prescindere dall'oggetto scelto dall'utente per rappresentare il "bersaglio") e quali tipi di oggetti l'utente può scegliere come alternativa per la rappresentazione (è lo stesso problema di jj.69kt?) Poi si prova a trovare una soluzione, in considerazione delle classi da usare e delle operazioni da compiere. P.S.: ti avviso già che non conosco bene la libreria per la gestione delle immagini in Java: ho letto varie cose sull'argomento e fatto qualche esercizietto, ma non le conosco come la parte che ho descritto sulle Shape/GenerlPath che invece ho usato per lavoro in un componente software. Quote:
__________________
As long as you are basically literate in programming, you should be able to express any logical relationship you understand. If you don’t understand a logical relationship, you can use the attempt to program it as a means to learn about it. (Chris Crawford) |
||
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 23:01.




















