Snake ...Problem

  • Themenstarter Themenstarter Thorse
  • Beginndatum Beginndatum
T

Thorse

Gast
Ich bin gerade dabei eine Art Snake zu programmieren, dabei habe ich folgendes Problem :
Eigentlich soll zuerst das Spielfeld gezeichnet werden und dann die Punkte.
Doch dadurch das die Punkte gezeichnet werden wird das Spielfeld (das Rechteck) "gelöscht".
Sieht vll jmd vion euch den Fehler:
Java:
import java.awt.Color;
import java.awt.Graphics; //x+8 //y+28
import java.awt.event.*;
import java.util.Random;

import javax.swing.JFrame;




public class Snake extends JFrame implements KeyListener
{
	
	private static final long serialVersionUID = 3800165321162121122L;
 
	Color schwarz = new Color( 0, 0, 0 );
	Random rand = new Random();

	String pcom;
	String com;
	String comnext=new String("r");
	int lifes = 4;
	int s = 100;
	int dots = 3; 
	int points=0;
	Boolean equal=false;
	Boolean got=true;
	
	int[]xvals=new int[20];
	int[]yvals=new int[30];
	
	int i;
	int e=0;
	
	int x1 = 13;
	int y1 = 33;
	int xl = 4000;
	int yl = 4000;
	int xg;
	int yg;
	int fx=0;
	int fy=0;
 Snake()
 {
	  	setSize(425,360); //x + 2x8Framerand + 2x5Spielfeld
	 					  //y+28+8 Framerand + 2x5 Spielfeld
	 	setVisible(true);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBackground(schwarz);
	    addKeyListener(this);
	    
 }

 public void keyPressed(KeyEvent ev)
 {
	 if(ev.getKeyCode()==KeyEvent.VK_LEFT && com.equals("r")==false)
		{comnext = "l";}
	 if(ev.getKeyCode()==KeyEvent.VK_RIGHT && com.equals("l")==false)
	    {comnext = "r";}
	 if(ev.getKeyCode()==KeyEvent.VK_UP && com.equals("d")==false)
	 	{comnext = "u";}
	 if(ev.getKeyCode()==KeyEvent.VK_DOWN && com.equals("u")==false)
	 	{comnext = "d";}

	 
 }
 public void keyTyped (KeyEvent ev)
 {
	 if(ev.getKeyCode()==KeyEvent.VK_LEFT && com.equals("r")==false)
		{comnext = "l";}
	 if(ev.getKeyCode()==KeyEvent.VK_RIGHT && com.equals("l")==false)
	    {comnext = "r";}
	 if(ev.getKeyCode()==KeyEvent.VK_UP && com.equals("d")==false)
	 	{comnext = "u";}
	 if(ev.getKeyCode()==KeyEvent.VK_DOWN && com.equals("u")==false)
	 	{comnext = "d";}
 }
 public void keyReleased (KeyEvent ev){}

 public void paint( Graphics g )
 {
	 if(pcom.equals("flash"))
	 {
		 g.setColor(new Color(0,0,0));
		 g.fillRect(8, 28, 450, 350);
		 g.setColor(Color.GRAY);
		 g.drawRect(8, 28, 408, 303);
		 g.drawRect(9, 29, 406, 301);
		 g.drawRect(10, 30, 404, 299);
	 }
	 if(pcom.equals("score"))
	 {
		 g.setColor(Color.WHITE);
		 g.drawString("Score "+points,30,345);
	 }
	 
	 if(pcom.equals("loop"))
	 {
		 g.setColor(new Color(255,0,0));
		 g.fillRect(xg, yg, 5, 5);
		 g.setColor(new Color(0,0,0));
		 g.fillRect(xvals[0], yvals[0], 5, 5);
		 g.setColor(new Color(rand.nextInt(256),rand.nextInt(256),rand.nextInt(256)));
		 g.fillRect( x1, y1, 5, 5);
	 }
 }
 void draw(String c)
 {
	pcom=c;
	repaint();
 }
 public void start()throws Exception
 {
	 
	 draw("flash");
	 draw("score");
	 

	 while(lifes!=0)
	 {
	   while(dots<=15)
	   {
       Thread.sleep(s);
       xvals[dots]=x1;
       yvals[dots]=y1;
       
	   com = comnext;
	   if(com.equals("l"))
		   x1=x1-7;
	   if(com.equals("r"))
		   x1=x1+7;
	   if(com.equals("u"))
		   y1=y1-7;
	   if(com.equals("d"))
		   y1=y1+7;
	   
	   if(x1==xg&&y1==yg)
	   {
		   got=true;
		   dots++;
	   }
	   
	   i = 0;
	   while(i<dots)
	   {
		   xvals[i]=xvals[i+1];
		   yvals[i]=yvals[i+1];
		   i++;
	   }
	   if(got==true)
	   {	
		   equal=true;
		   while(equal==true)
		   {	
			   equal=false;
			   xg=13+(rand.nextInt(57)*7);
			   yg=33+(rand.nextInt(42)*7);
			   while(e<=dots)
			   {
				   if(xg==xvals[e]&&yg==yvals[e])
					   equal=true;
				   e++;
			   }
			   e=0;
			   
		   }
		   got=false;
		   points++;
		   draw("score");
	   }
	   draw("loop");
	   }
	   dots=3;
	   s-=50;
	   x1=13;
	   y1=33;
	   comnext="r";
	   draw("flash");
	   
	 }

 }
 
}
 
Zwei sachen:
- in Swing die paintComponent methode überschreiben, nicht die paint.
- die paintComponent Methode des JFrames nicht überschreiben, mal dein Zeug besser in nen JPanel

Evtl. löst das auch schon dein problem.

PS:
Ich würde die Punkte nicht unbedingt reinmalen per drawString.
Pack dir oben nen JPanel rein wo du JLabels drin hast die die scores anzeigen.
 
ich versteh jetzt nicht ganz was mit "mal dein zeug lieber in ein Jpanel" gemeint ist?

dass ich am anfagng ein großes jpanel zeichnen soll ??
 
was ist das allererste was einem Lehrbuch zum Zeichnen in JFrame einfällt zu sagen?
Galileo Computing :: Java ist auch eine Insel – 20 Grafikprogrammierung

20.1.2 Zeichnen von Inhalten auf ein JFrame Zur nächsten Überschrift
Wenn Swing eine Komponente zeichnet, ruft es automatisch die Methode paint() auf. Um eine Grafik selbst in ein Fenster zu zeichnen, ließe sich von JFrame eine Unterklasse bilden und paint() überschreiben – das ist jedoch nicht der übliche Weg.

Stattdessen wählen wir einen anderen Ansatz, der sogar unter AWT eine gute Lösung ist. Wir bilden eine eigene Komponente, eine Unterklasse von JPanel [..]
die Formulierung ist noch geschönt, einfach 'paint in JFrame == bäh', fertig, und genau das hast du eingebaut,
wie es immer nur zu sowas kommt?

gleich noch den anderen noch häufigeren Merksatz: nie getGraphics() aufrufen!
 
Also ich hab jetzt mal ein Panel eingefügt das einfach mal Schwarz ist.
Das hat schon mal den Fehler behoben das manchmal bei Starten der Programms der Hintergrund nicht schwarz sondern grau war.

Aber leider passiert außer einem schwarzen Frame auch weiter nix.

Könnte mir vielleicht mal ganz grob jemand erklären wie das mit paintComponent() und @overwrite funktioniert?
Ich hab echt schon viel gegooglet aber nicht wirklich was gefunden.
 
ich habe doch einen Link zu einem Lehrbuch gepostet, eines der ersten Code-Spiele für JFrame (nach dem von mir zitierten wichtigen Text) enthält dort
Java:
class DrawPanel extends JPanel
{
  @Override
  protected void paintComponent( Graphics g )
  {
    super.paintComponent( g );
    g.drawLine( 10, 10, 100, 50 );
  }
}
?!?!

wenn was bei dir nicht funktioniert, dann weichst du bestimmt vom Standard ab,
z.B. könnte das Panel ganz klein sein wenn es nicht BorderLayout maximiert wird,
setPreferredSize() könnte dann helfen,
immer Code posten
 
Das habe ich mir ja auch angesehen, aber ich weiß nicht was ich dann mit dieser Klasse machen soll, wie ich sie dem Frame hinzufüge und wie ich sie dann neu zeichne ...
 
oh, nach 2 Min. eine Antwort und von mir jetzt erst nach 7 Stunden,
sonst meist andersrum 😉

also Einfügen an sich wäre logischerweise das nächste Codebeispiel nur wenige Zeilen darunter,
aber repaint(), komplette Steuerung usw., das findet man natürlich nicht überall, das stimmt

wobei deine Variante erstmal bestimmt passt, repaint() ist repaint(), egal wo nun die paintComponent() überschrieben ist,
noch ein Link:
http://www.ralf-bauer.org/java/tutorial/Tutorial.zip
 
Ja erst nach 7 Stunden.. schäm dich was!
😀

Danke für das tolle Tutorial.
Und... Thanks for your support. 😉
 

Zurück
Oben