Rennspiel, Kollision

Vik08090809

Mitglied
Hallo,

Ich muss von der Schule aus ein Rennspiel in der Programmiersprache Java im Team entwickeln. Meine Aufgabe ist es, mich um die Kollision zu kümmern. Dazu nehme ich als Ansatz die Vorlage von: Java BufferedImage - how to get the RGB value of each image pixel | devdaily.com

Jetzt zu meiner Frage:
In unserem Projekt haben wir die Klassen: Ball, Rennstrecke(Main Class), Steuerung, Zeit und eben meine Klasse: Collision_Domain. In der Klasse Rennstrecke ist u.a das BufferedImage Rennstrecke definiert und in ihr wird u.a diese auf ein Panel gezeichnet. In der Klasse Ball wird genauso u.a das BufferedImage Ball definiert und gezeichnet. Jetzt möchte ich aber das BufferedImage Rennstrecke von der Klasse Rennstrecke erben, jedoch bekomme ich das mit public class Collision_Domain extends Rennstrecke nicht hin, weil ich- um die Funktionen aus der o.g. Vorlage nutzen zu können - schon von Component erben (public class Collision_Domain extends Component).

Wie kann ich dennoch die Klasse Rennstrecke in der Klasse Collision_Domain erben?

Vielen Dank
 
Zuletzt bearbeitet von einem Moderator:

Marco13

Top Contributor
Wie kann ich dennoch die Klasse Rennstrecke in der Klasse Collision_Domain erben?

Nicht von Component erben. Da gibt's nicht viele Alternativen, außer einer Grundsätzlich anderen Struktur - was aber angebracht sein könnte. Wie auch immer die Kollisionserkennung umgesetzt wird: Einen Grund von Component zu erben, sehe ich nicht. CollisionDomain (ohne Unterstrich) könnte (und sollte vermutlich) auch ein Interface sein...
 

Vik08090809

Mitglied
ok thx. Du hattest recht: von Component zu erben war unnötig. Also habe ich es geschafft von Rennstrecke zu erben. Allerdings komme ich nicht weiter mit der Kollisionsabfrage. Meiner Überlegung nach sollte es doch funktionieren, indem man den Farbcode des Bildes Rennstrecke.png ausliest und eine Abfrage erstellt, ob die Farbe ungleich oder gleich Farbcode entspricht. Falls der Farbcode der Farbe rot oder weiß entspricht(Wand) soll die Bewegung des Balls in die jeweilige Richtung gestoppt werden.

Hier der komplette Quelltext:

Klasse Ball:

Java:
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.net.URL;
import javax.imageio.ImageIO;

public class Ball 
 {
public int xPos = 300;
public int yPos = 700;
public BufferedImage ball = null;

public  int a;
public int b;

    public Ball() {
        load();
    }



    private void load()
    {
        try {
            URL picUrl = getClass().getClassLoader().getResource("Ball.png");
            if (picUrl == null) {
                System.out.println("Could not find file");
            }
            ball = ImageIO.read(picUrl);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    public void paint(Graphics g)
    {
        g.drawImage(ball,xPos,yPos,null);
    }

  
    public void up()
    {
        yPos -= 5;
    }
    public void down()
    {
        yPos +=6;
    }
    public void left()
    {
        xPos-=4;
    }
    public void right()
    {
        xPos+=7;
    }

    public void Pos_best()
    {
        a = xPos;
        b = yPos;
    }

}


Klasse Rennstrecke:

Java:
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
import java.awt.*;
import java.awt.image.BufferedImage;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
/**
 *
 * @author GerlachAnd
 */

public class Rennstrecke extends JFrame implements Runnable
{
    
    JPanel pnl;
    Ball ball;
    Steuerung s;
    CollisionDomain cd;
   public BufferedImage Rennstrecke = null;
    
    public Rennstrecke ()    
    {
        setTitle("Trabirace 10");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setPreferredSize(new Dimension(809,825));
        pack();
        setVisible(true);
        load();
        ball = new Ball();
        s = new Steuerung();
        cd = new CollisionDomain();
        add(createPanel());
        addKeyListener(s);
        new Thread(this).start();
        
        
    }   
    
    public void load()
    {
        try
        {
            URL picUrl = getClass().getClassLoader().getResource("Rennstrecke.png");
            if (picUrl == null) {
                System.out.println("Could not find file");
            }
            Rennstrecke = ImageIO.read(picUrl);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
      
    
    }
        public void paintStrecke(Graphics g)
        {
        g.drawImage(Rennstrecke,0,0,null);  
        }
        
    public static void main(String[] args)
      {
        new Rennstrecke();

      }


    public JPanel createPanel()
    {
        pnl = new JPanel() {
                
                protected void paintComponent(Graphics g) {
                    super.paintComponent(g);
                    paintStrecke(g);
                    ball.paint(g);
                    g.drawString((float)(s.getZeit().getTime() / 1000f) + "s", 20, 20);
                }

        };
        pnl.setSize(getHeight(), getWidth());
        pnl.setBackground(Color.black);
        return pnl;
    }

    public void run() {
        while(true)
        {
            checkKeys();
            pnl.repaint();
            
            try {
                Thread.sleep(50);
            } catch (InterruptedException ex) {
                ex.printStackTrace();
            }
        }
    }


    public void checkKeys()
    {
        if (s.up)
        {
            ball.up();
        }
        
        if(s.down)
        {
            ball.down();
        }
        
        if (s.left)
        {
            ball.left();
        }
        
        if (s.right)
        {
            ball.right();
        }
    }        
}


Klasse Steuerung:

Java:
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
import java.awt.event.*;
/**
 *

public class Steuerung extends KeyAdapter
{
	
	private boolean started = false;
	public boolean up = false;
	protected boolean down = false;
	protected boolean left = false;
        protected boolean right = false;
        private Zeit z = new Zeit();

    @Override
    public void keyPressed(KeyEvent e)
    {
        if (e.getKeyCode() == KeyEvent.VK_UP) {
            up = true;
        }
        if (e.getKeyCode() == KeyEvent.VK_DOWN) {
            down = true;
        }
            if (e.getKeyCode() == KeyEvent.VK_LEFT) {
           left = true;
        }
        
            if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
            right = true;
            z.start();
        }
            if (e.getKeyCode() ==KeyEvent.VK_SPACE)
            {
            z.stopp();     
            }
        
    }

    @Override
    public void keyReleased(KeyEvent e) 
    {
        if (e.getKeyCode() == KeyEvent.VK_UP) {
            up = false;
        }
           if (e.getKeyCode() == KeyEvent.VK_DOWN) {
            down = false;
        }
           if (e.getKeyCode() == KeyEvent.VK_LEFT) {
            left = false;
        }
           if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
            right = false;
        }
    }
    
    public Zeit getZeit()
    {
        return z;
    }
    
}

Klasse Zeit:

Java:
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */



    public class Zeit
    { 
   
    private long startZeit; 
    private long endZeit; 
    private boolean laeuft; 

    public Zeit() 
    { 
        laeuft = false; 
        startZeit = 0; 
    } 

    public void start()
    {
        if (!laeuft)
        {
            laeuft = true;
            startZeit = System.currentTimeMillis(); 
        }
        
    } 

    public void stopp() 
    { 
        if(laeuft) 
        { 
            laeuft = false; 
            endZeit = System.currentTimeMillis();
        } 
    }
    
    public long getTime() 
    {
        if (laeuft) 
        {
        return  System.currentTimeMillis() - startZeit;     
        }
        return  endZeit - startZeit; 
    }
}


Klasse CollisionDomain:

Java:
import java.awt.Component;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;

public class CollisionDomain extends Component
{
     public CollisionDomain()
  {

   
 Kollision k;

k = new Kollision();

  }
   public class Kollision extends Rennstrecke
   {
  

  public void printPixelARGB(int pixel) {
    int alpha = (pixel >> 24) & 0xff;
    int red = (pixel >> 16) & 0xff;
    int green = (pixel >> 8) & 0xff;
    int blue = (pixel) & 0xff;
    System.out.println("argb: " + alpha + ", " + red + ", " + green + ", " + blue);
  }

public void marchThroughImage(BufferedImage Rennstrecke)
{

    int w = Rennstrecke.getWidth();
    int h = Rennstrecke.getHeight();
    System.out.println("width, height: " + w + ", " + h);

    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
        System.out.println("x,y: " + j + ", " + i);
        int pixel = Rennstrecke.getRGB(j, i);
        printPixelARGB(pixel);
        System.out.println("");
      }
    }
  }

public Kollision()
{
     try {
      // get the BufferedImage, using the ImageIO class
      BufferedImage Rennstrecke =
        ImageIO.read(this.getClass().getResource("Rennstrecke.png"));
      marchThroughImage(Rennstrecke);
    } catch (IOException e) {
      System.err.println(e.getMessage());
    }
  }

}

 

}

so wie die Klasse CollisionDomain jetzt aufgebaut ist, öffnet es in einer endlosschleife das Applet, nichts wird jedoch gezeichnet!
 

Marco13

Top Contributor
Ja, ich sehe schon, dass sich das jetzt wieder beliebig lange hinziehen kann :(

Du redest von Applet und postest einen JFrame, du redest von Kollisionserkennung und sagst das nichts gezeichnet wird, postest komplett auskommentierte Klassen und setzt offenbar voraus, dass jeder das Vorwissen zur Aufgabenstellung hat, das du hast, und wenn ich etwas sehe wie [c]class Kollision extends Rennstrecke[/c] frage ich mich, welche ... "logische" oder auch "natürlichsprachliche" Rechtfertigung da dahinter steht ???:L

Beschreibe, was deine Klasse machen soll, wie du bisher versucht hast, sie dazu zu bringen, das zu machen, und was daran nicht funktioniert.
 

Vik08090809

Mitglied
Ok du hast recht: ich habe einige Fehler in meiner Beschreibung.

Hier also mal eine sehr genau Beschreibung des Projektes:
Also wie schon gesagt müssen wir in einer 2er Gruppe ein Rennspeil in der Programmiersprache Java entwickeln. Da wir für die Entwicklung des Projektes wenig Zeit haben, wollten wir es erst einmal erreichen, dass eine einzige Kugel(BufferedImage ball) auf einer Rennstrecke(BufferedImage Rennstrecke) sich bewegt und natürlich nicht durch die Wände oder durch das Bild fahren kann. Erst später wollten wir eventuell eine zweite Kugel einfügen.

Damit das mit einer Kugel Sinn macht, haben wir die Klasse Zeit entworfen, die die Zeit nach Betätigung einer Taste, misst und anzeigt. So können dann der Anwender die Zeiten in den jeweiligen Durchläufen miteinander vergleichen.

Die Kugel lässt sich bereits bewegen, was in der Steuerungsklasse realisiert wurde. In ihr wird überprüft, ob die Taste nach oben, unten, links, rechts gedrückt wurde. Falls dies geschah, setzt er die jeweilige boolsche Variable (up, down, left, right) auf true. Hier der Code dazu:
Java:
@Override
public void keyPressed(KeyEvent e)
    {
        if (e.getKeyCode() == KeyEvent.VK_UP) {
            up = true;
        }
        if (e.getKeyCode() == KeyEvent.VK_DOWN) {
            down = true;
        }
            if (e.getKeyCode() == KeyEvent.VK_LEFT) {
           left = true;
        }
        
            if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
            right = true;
            z.start();
        }
            if (e.getKeyCode() ==KeyEvent.VK_SPACE)
            {
            z.stopp();     
            }
        
    }

    @Override
    public void keyReleased(KeyEvent e) 
    {
        if (e.getKeyCode() == KeyEvent.VK_UP) {
            up = false;
        }
           if (e.getKeyCode() == KeyEvent.VK_DOWN) {
            down = false;
        }
           if (e.getKeyCode() == KeyEvent.VK_LEFT) {
            left = false;
        }
           if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
            right = false;
        }
    }

In der Hauptklasse Rennstrecke wird dann überprüft, ob die jeweilige boolsche Variable true ist. Falls diese true ist, wird die jeweilige Funktion (up, down, left, right) ausgeführt. Hier der Code hierzu:
Java:
  public void checkKeys()
    {
        if (s.up)
        {
            ball.up();
        }
        
        if(s.down)
        {
            ball.down();
        }
        
        if (s.left)
        {
            ball.left();
        }
        
        if (s.right)
        {
            ball.right();
        }

Diese 4 Funktionen beinhalten die Bewegungsgeschwindigkeiten. Sie werden in der Klasse Ball beschrieben.
Code:
Java:
 public void up()
    {
        yPos -= 5;
    }
    public void down()
    {
        yPos +=6;
    }
    public void left()
    {
        xPos-=4;
    }
    public void right()
    {
        xPos+=7;
    }

Die Rennstrecke und der Ball werden in den Klassen Rennstrecke und Ball durch folgenden Code gezeichnet:

Balldeklarationen:
Java:
public int xPos = 300;
public int yPos = 700;
public BufferedImage ball = null;

Ballbild einlesen:
Java:
  private void load()
    {
        try {
            URL picUrl = getClass().getClassLoader().getResource("Ball.png");
            if (picUrl == null) {
                System.out.println("Could not find file");
            }
            ball = ImageIO.read(picUrl);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

Ball zeichnen:
Java:
public void paint(Graphics g)
    {
        g.drawImage(ball,xPos,yPos,null);
    }

Rennstreckendeklaration:
Java:
 public BufferedImage Rennstrecke = null;

Bild Rennstrecke einlesen (funktioniert gleich wie Ballbild):
Java:
 public void load()
    {
        try
        {
            URL picUrl = getClass().getClassLoader().getResource("Rennstrecke.png");
            if (picUrl == null) {
                System.out.println("Could not find file");
            }
            Rennstrecke = ImageIO.read(picUrl);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
      
    
    }

Rennstreckenbild zeichnen (funktioniert gleich wie Ballbild):
Java:
 public void paintStrecke(Graphics g)
        {
        g.drawImage(Rennstrecke,0,0,null);  
        }

Beide Bilder werden auf ein Panel (namens pnl) gezeichnet, das ständig neu gezeichnet wird. Dieses Panel wird in der Rennstreckenklasse erzeugt.
Code:
Java:
 public JPanel createPanel()
    {
        pnl = new JPanel() {
                
                protected void paintComponent(Graphics g) {
                    super.paintComponent(g);
                    paintStrecke(g);
                    ball.paint(g);
                    g.drawString((float)(s.getZeit().getTime() / 1000f) + "s", 20, 20);
                }

        };
        pnl.setSize(100, 100);
        pnl.setBackground(Color.black);
        return pnl;
    }

das Ständige neu zeichnen des Panels wird auch in der Rennstreckenklasse durch folgenden Code realisiert:
Java:
public void run() {
        while(true)
        {
            checkKeys();
            pnl.repaint();
            
            try {
                Thread.sleep(50);
            } catch (InterruptedException ex) {
                ex.printStackTrace();
            }
        }
    }

--------------------------------------------------------------------------------------------------------------------------

Das alles bisher also ist das, was funktioniert (Ballbild zeichnen, Rennstreckenbild zeichnen, Ball über Pfeiltasten bewegen). Jetzt kommt der Teil, der noch nicht funktioniert, also die Kollisionserkennung.

Meine Überlegungen:
Den Hintergrund des Bildes Rennstrecke an der jeweiligen Ball position auslesen und abfragen, ob diese ungleich schwarz (Strecke, auf der er sich nur bewegen darf) ist. Falls diese ungleich schwarz sein sollte, dann soll der Ball gestoppt werden, indem die eingestellten Bewegungswerte in den oben schon beschriebenen 4 Funktionen (up, down, left, right) auf den Wert 0 gesetzt werden.

Zuerst einmal dachte ich, ich könnte ganz einfach mit rennstrecke.getBackground() die Hintergrundfarbe des Bildes abfragen und die Farben mit einer if abfrage vergleichen.

Jedoch habe ich auf der Seite: Java BufferedImage - how to get the RGB value of each image pixel | devdaily.com gelesen, dass hier die einzelnen Pixelfarben ausgelesen werden müssen.
Hierzu wird die Größe des Bildes ermittelt:
Java:
int w = image.getWidth();
    int h = image.getHeight();

...die rgb werte an den einzelnen pixeln/Positionen ausgelesen:
Java:
 for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
        System.out.println("x,y: " + j + ", " + i);
        int pixel = image.getRGB(j, i);
        printPixelARGB(pixel);
        System.out.println("");
      }
    }

...und das Bildimage eingelesen, das durch die Übergabe des Imagenamens an die vorherige Funktion, die rgb werte ständig ausliest.
Java:
 public JavaWalkBufferedImageTest1() {
    try {
      // get the BufferedImage, using the ImageIO class
      BufferedImage image = 
        ImageIO.read(this.getClass().getResource("WhiteSpot.jpg"));
      marchThroughImage(image);
    } catch (IOException e) {
      System.err.println(e.getMessage());
    }
  }

Zusammenfassung, was die Klassen, alles können / können müssen:

Zeit: liest die Zeit aus und zeigt sie an
Steuerung: Abfragen, ob Pfeiltasten gedrückt, Zeit anhalten/starten
Rennstrecke: Bild einlesen, Zeichnen, Panel pnl erzeugen, auf Panel Ball und Rennstrecke zeichnen
Ball: Ball einlesen, Ball zeichnen, Bewegungsfunktionen, Startwert festgelegt
CollisionDomain: Abfrage des Hintergrunds des Bildes Rennstrecke an der jeweiligen Ballposition. Wenn ungleich schwarz: Ball stoppen, ansonsten: Ball bewegen


Hier noch die Zusammenhänge der einzelnen Klassen...
Steuerung -> Zeit
Rennstrecke -> Ball, Steuerung, Collisondomain

...und hier noch ein Bild des Programms:

http://img571.imageshack.us/img571/2668/projekt.png


...da kommt noch die Ausgabe auf der Console, wenn ich die rgb-Werte des Balls auslese (Ausschnitt):
width, height: 40, 40
x,y: 0, 0
argb: 0, 0, 0, 0

x,y: 1, 0
argb: 0, 0, 0, 0

x,y: 2, 0
argb: 0, 0, 0, 0

x,y: 3, 0
argb: 0, 0, 0, 0

x,y: 4, 0
argb: 0, 0, 0, 0

x,y: 5, 0
argb: 0, 0, 0, 0

x,y: 6, 0
argb: 0, 0, 0, 0

x,y: 7, 0
argb: 0, 0, 0, 0

x,y: 8, 0
argb: 0, 0, 0, 0

x,y: 9, 0
argb: 0, 0, 0, 0

x,y: 10, 0
argb: 0, 0, 0, 0

x,y: 11, 0
argb: 0, 0, 0, 0

x,y: 12, 0
argb: 0, 0, 0, 0

x,y: 13, 0
argb: 0, 0, 0, 0

x,y: 14, 0
argb: 0, 0, 0, 0

x,y: 15, 0
argb: 0, 0, 0, 0

x,y: 16, 0
argb: 0, 0, 0, 0

x,y: 17, 0
argb: 0, 0, 0, 0

x,y: 18, 0
argb: 0, 0, 0, 0

x,y: 19, 0
argb: 0, 0, 0, 0

x,y: 20, 0
argb: 255, 112, 89, 33

x,y: 21, 0
argb: 0, 0, 0, 0

x,y: 22, 0
argb: 0, 0, 0, 0

x,y: 23, 0
argb: 0, 0, 0, 0

x,y: 24, 0
argb: 0, 0, 0, 0

x,y: 25, 0
argb: 0, 0, 0, 0

x,y: 26, 0
argb: 0, 0, 0, 0
 
Zuletzt bearbeitet:

Marco13

Top Contributor
Ja, sorry, vieles davon konnte man sich schon denken, es ging eher darum, was nun genau die Frage ist. Man hat als BufferedImage ein Bild von dem Ball und von der Strecke. Der Ball hat eine Position (x,y). Mit
int rgb = streckenBild.getRGB(x,y)
kann man die Farbe des Pixels an der Ballposition abfragen. Und wenn diese Farbe nicht schwarz ist, soll die Bewegung gestoppt werden. Man liest also alles aus, und dort, wo bisher
printPixelARGB
aufgerufen wird macht man stattdessen sowas wie
Code:
if (pixel==0) // Alpha ggf. beachten
{
    stoppeBall();
}

Wenn der Ball noch richtig abprallen soll und so kann das natürlich beliebig aufwändig werden. Da kommt man um vorheriges Nachdenken kaum drumrum...
 

Vik08090809

Mitglied
achso die Farbe weiß, oder? Dann müsste rot 255 sein, oder?

dann sieht das doch so aus:

if (pixel == 0 && pixel == 255)
{
stoppeball();
}

Methode stoppeball:

public void stoppeball()
{
xPos += 0;
...
}

aber die kugel ist nicht zu bremsen ;)
 

Vik08090809

Mitglied
Wieso wird hier weder etwas auf der Konsole angezeigt, noch der Ball gebremst?;(

public void Kollision(BufferedImage Rennstrecke)
{
int pixel = r.Rennstrecke.getRGB(b.xPos,b.yPos);


if (pixel==0) // Alpha ggf. beachten
{
System.out.println("g");
// b.stoppeball();
}
else
{
System.out.println("h");

}


}
 

Vik08090809

Mitglied
Bitte helft mir. Ich bin grad echt am verzweifeln. Er liefert mir zwar jetzt einen vordefinierten Text wenn das pixel!=0 ist, aber 1. geht das bei mir nur mit Textausgabe und 2. Ist das Pixel nie 0 bzw. 255 ;(;(;(;(
 

Vik08090809

Mitglied
ich habs schon im Konstrukter versucht, in anderen Klassen usw. der Ball ist einfach nicht zu bremsen und das Pixel ist nie 0, da immer "h" ausgegeben wird mit:
if(pixel==0)
{
System.out.println("g");
}
else
{
System.out.println("h");
}
 

Marco13

Top Contributor
Mal wieder die Erkenntnis, dass es viel zu einfach ist, mit Java zu Programmieren. Man schreibt einfach irgendwas hin, und wenn die IDE nichts rot unterstreicht, ist's schon alles richtig... :noe:

In der "Rennstrecke" ein
private CollisionDomain cd;
einfügen, das dann im Konstruktor (nach "load" und dem erstellen des Balls) mit
cd = new CollisionDomain(this, ball);
erstellen, und in der "run"-Methode nach dem checkKeys ein
System.out.println("colliding: "+cd.isColliding());
einfügen. Die CollisionDomain würde dann erstmal so aussehen:
Java:
public class CollisionDomain extends Component
{
    Ball b;
    Rennstrecke r;
    
    public CollisionDomain(Rennstrecke rennstrecke, Ball ball)
    {
        this.r = rennstrecke;
        this.b = ball;
    }
    
    public boolean isColliding()
    {
        int rgb = r.Rennstrecke.getRGB(b.xPos, b.yPos);
        int red = (rgb >> 16) & 0xff;
        int green = (rgb >> 8) & 0xff;
        int blue = (rgb) & 0xff;
        return red > 190 || green > 190 || blue > 190;
    }
}

"Und wie geht's weiter?" - Tja.
 

Vik08090809

Mitglied
also die Wände sind reinfarbig. Rot & weiß und die Strecke ist nun auch komplett schwarz. Ich habe es in der zwischenzeit geschafft die rgb werte der farben auszulesen und auszugeben. Diese Prüfe ich dann ab. Das klappt auch. Allerdings klappt das Ball stoppen nicht. Hierzu habe ich die boolsche Variable started genommen und abgefragt, ob diese true ist....Quellcode ist besser wie erklären

Java:
 public void checkForCollision() {
        Color c =  new Color(imgRennstrecke.getRGB(ball.xPos,ball.yPos), true);
        System.out.println("red:" + c.getRed() + " | green: " + c.getGreen() + " | blue: " + c.getBlue());

        if(c == Color.BLACK)
        {
            s.started = false;
        }
        else
        {
            s.started = true;
        }
    }


Java:
 public void up()
    {
       if(s.started == true)
       {
        yPos -= 5;
       }
       else
       {
           not_up();
       }
    }
    public void down()
     {
       if(s.started == true)
       {
        yPos += 6;
       }
       else
       {
           not_down();
       }
    }
    public void left()
    {
       if(s.started == true)
       {
        xPos-= 4;
       }
       else
       {
           not_left();
       }
    }
    public void right()
    {
       if(s.started == true)
       {
        xPos+= 7;
       }
       else
       {
           not_right();
       }


    }

    public void not_up()
       {
           yPos -= 0;
       }
    public void not_down()
       {
           yPos += 0;
       }

    public void not_left()
    {
        xPos-= 0;
    }

    public void not_right()
    {
        xPos+= 0;
    }

Java:
public void checkKeys()
    {
        if (s.up && s.started == true)
        {
            ball.up();
        }
        else
        {
            ball.not_up();
        }
        
        if(s.down && s.started == true)
        {
            ball.down();
        }
        else
        {
            ball.not_down();
        }

        
        if (s.left)
        {
            ball.left();
        }
        else
        {
            ball.not_left();
        }
        
        if (s.right)
        {
            ball.right();
        }
        else
        {
            ball.not_right();
        }
    }
 

eRaaaa

Top Contributor
Java:
	public static void main(String[] args) throws Exception {
		Color c = Color.BLACK;
		Color c2 = new Color(0,0,0);
		System.out.println(c == c2);
		System.out.println(c.equals(c2));
	}

Soll heißen, überprüfe mal deine if-Abfrage :)
 

Vik08090809

Mitglied
Statt c = Color.BLACK habe ich es folgendermaßen geändert:

Java:
   if(c.equals(Color.BLACK))
        {
            s.started = true;
        }
        else
        {
            s.started = false;
        }
    }

Jedoch bewegt sich der Ball nur nach links und rechts und hält auch noch nicht bei einer Wand
 

Marco13

Top Contributor
Nimm' die Variable
Steuerung#started
wieder raus

Die ganzen "not_left", "not_right"- usw. Methoden in der Klasse "Ball" sind überflüssig. Der braucht nur
Code:
    public void up()
    {
        yPos -= 5;
    }
    public void down()
     {
        yPos += 6;
    }
    public void left()
    {
        xPos-= 4;
    }
    public void right()
    {
        xPos+= 7;
    }


Die checkForCollision-Methode im CollisionDomain kann ein boolean zurückgeben, das angibt, ob eine Kollision vorliegt:
Code:
    public boolean checkForCollision() {
        Color c =  new Color(imgRennstrecke.getRGB(ball.xPos,ball.yPos), true);
        System.out.println("red:" + c.getRed() + " | green: " + c.getGreen() + " | blue: " + c.getBlue());

        
        if(c.equals(Color.BLACK))
        {
            return false;
        }
        return true;
    }


Die run- und checkKeys-Methoden in der Steuerung könnten so aussehen:
Code:
    public void run() 
    {
        while(true)
        {
            int oldX = ball.xPos;
            int oldY = ball.yPos;
            checkKeys();
            boolean colliding = collisionDomain.checkForCollision();
            if (colliding)
            {
                // Don't go there
                ball.xPos = oldX;
                ball.yPos = oldY;
            }

            pnl.repaint();
            
            try {
                Thread.sleep(50);
            } catch (InterruptedException ex) {
                ex.printStackTrace();
            }
            
        }
    }


    public void checkKeys()
    {
        if (s.up)
        {
            ball.up();
        }
        if(s.down)
        {
            ball.down();
        }
        if (s.left)
        {
            ball.left();
        }
        if (s.right)
        {
            ball.right();
        }
    }

Die Idee ist einfach: Man merkt sich, wo der Ball gerade ist. Dann bewegt man ihn, je nachdem, welche Taste gedrückt ist. Und das ganze ohne irgendwelche flags und Abfragen. Man bewegt ihn einfach, ganz brutal, egal, ob er kollidiert oder nicht.
AAAAber: DANN prüft man, OB er an dieser neuen Position kollidiert. Und WENN er dort kollidiert, dann bewegt man ihn auf die alte Position zurück.

Das ist nicht perfekt, hat seine Grenzen (bei sehr schnellen Bewegungen kann man durch dünne Wände laufen etc), aber für alles andere brächte man kontinuierliche Kollisionserkennung, und die macht Pixelbasiert noch weniger Spaß als wenn man das ganze algebraisch lösen darf :autsch:

Im Momen hat man auch noch ein kleines Problemchen bei dem Versuch, über die Startlinie zu fahren, aber vielleicht soll man das ja gar nicht ;)
 

Ähnliche Java Themen

Neue Themen


Oben