# Mein erstes Game



## oyo (10. Sep 2009)

Hi leute !
ich habe ein ganz krasses problem und es mag euch lächerlich erscheinen.
ich bin gerade dabei ein java applet game zu schreiben und bin bisher gut weitergekommen:
http://www2.inf.fh-brs.de/~dkrueg2s/funky/bin/mygame.html

als nächsten schritt wollte ich ein auswahlmenü machen, dass mann vorher den charakter wählt. Das funktioniert aus irgendeinem grund nich so wie ich mir das vorstelle. hab schon viel probiert und ich dachte ich poste hier mal meinen stuff vllt. sieht ja jemand direkt was da falsch ist: http://www2.inf.fh-brs.de/~dkrueg2s/funky/funky.rar


```
import java.applet.*;
import java.awt.*;



public class funkymain extends Applet implements Runnable
{
	weapon[]w;
	weapon[]w2;
	player player1;
	player player2;
	player ritter;
	player koenig;
	weapon p1weapon1;
	weapon p2weapon1;
	Transparentfilter T;
	Hmenu HM;
	private Image dbImage;
	private Thread th;
	private Graphics dbg;
	private Image pimg;
	private Image pimg2;
	private Image pimg3;
	private Image pimg4;
	private Image wimg1;
	private Image p2img;
	private Image p2img2;
	private Image p2img3;
	private Image p2img4;
	private Image w2img1;
	private boolean activeH;
	private static int speed = 10;
	public void init()
	{
		setBackground(Color.BLACK);
		w = new weapon[4];
		w2 = new weapon[4];
		
		ritter = new player (50, 50, 20,200,100,w);
		koenig = new player (400,400,10,200,200,w2);
		T = new Transparentfilter(Color.WHITE);
		HM = new Hmenu(100,100);
		p1weapon1 = new fireball(2);
		p2weapon1 = new Sword(2);
		w2[0]=p1weapon1;
		w[0]= p2weapon1;
		activeH=true;
		// fetch images
		getImages();
		
		HM.setImages(pimg2,p2img2,pimg3,pimg4,wimg1);
		ritter.setImages(pimg,pimg2,pimg3,pimg4,wimg1);
		 koenig.setImages(pimg,pimg2,pimg3,pimg4,wimg1);
	}
		
	private void getImages()
	{
		MediaTracker tracker = new MediaTracker(this);

			pimg = getImage(getCodeBase(), "images/up1.gif");
			tracker.addImage(pimg, 1);
			pimg2 = getImage(getCodeBase(), "images/down1.gif");
			tracker.addImage(pimg2, 2);
			pimg3 = getImage(getCodeBase(), "images/left1.gif");
			tracker.addImage(pimg3, 3);
			pimg4 = getImage(getCodeBase(), "images/right1.gif");
			tracker.addImage(pimg4, 4);
			wimg1 = getImage(getCodeBase(), "images/Sword.gif");
			tracker.addImage(wimg1, 5);
			p2img = getImage(getCodeBase(), "images/Kup1.gif");
			tracker.addImage(p2img, 6);
			p2img2 = getImage(getCodeBase(), "images/Kdown1.gif");
			tracker.addImage(p2img2, 7);
			p2img3 = getImage(getCodeBase(), "images/Kleft1.gif");
			tracker.addImage(p2img3, 8);
			p2img4 = getImage(getCodeBase(), "images/Kright1.gif");
			tracker.addImage(p2img4, 9);
			w2img1 = getImage(getCodeBase(), "images/dark-fireball.gif");
			tracker.addImage(w2img1, 10);
		
		try
		{
			tracker.waitForAll();
		}
		catch (Exception exception)
		{

		}
	}

	/** Methode starts Thread */
	public void start ()
	{
		// create new thread
		th = new Thread (this);
		// start thread
		th.start ();
	}

	public void run ()
	{
		Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
		
		while (true)
		{
		while(activeH){
		HM.move();
		HM.leftm=false;
		HM.rightm=false;
		repaint();
		getImages();
			if(HM.chosen1){
				switch(HM.getcur()){
					case '1':
//kann ich dass so machen oder liegt der fehler hier ?
						player1 = ritter.clone();
					break;
					case '2':
						player1 = koenig.clone();
					break;
				}
			}
			if(HM.chosen2){
					switch(HM.getcur()){
					
						case '1':;
							player2 = ritter.clone();
							break;
						case '2':
							player2 = koenig.clone();
							break;
					}
			}
			if(HM.chosen1&&HM.chosen2){
			activeH=false;
			}
		}
		while(!activeH){
		player1.move();	
		player2.move();	
		w[0].dodmg(player2);
		w2[0].dodmg(player1);
		repaint();
		player1.set_right(false);	
		player1.set_up(false);	
		player1.set_down(false);	
		player1.set_left(false);
		player1.setUsew1(false);
		player2.set_right(false);	
		player2.set_up(false);	
		player2.set_down(false);	
		player2.set_left(false);
		player2.setUsew1(false);
		}
		try
		{
			// Stoppen des Threads für in Klammern angegebene Millisekunden
			Thread.sleep (speed);
		}
		catch (InterruptedException ex)
		{
			// do nothing
		}

		// Zurücksetzen der ThreadPriority auf Maximalwert
		Thread.currentThread().setPriority(Thread.MAX_PRIORITY);

		}
		
	}
	

	// event handling for keys down
	public boolean keyDown (Event e, int key)
	{
		
	if(key == Event.LEFT&& activeH){
		HM.leftm= true;
		}
	if(key == Event.RIGHT&& activeH){
		HM.rightm= true;
		}
	if(key == 107&& activeH){
		HM.chosen1=true;
		}
	if(key == 102&& activeH){
		HM.chosen2=true;

		}
	if(key == Event.LEFT&& !activeH)	{
		player1.set_left(true);
		player1.lookleft = true;
		player1.looktop = false;
		player1.lookdown = false;
		player1.lookright = false;
	}
	if(key == Event.UP&& !activeH)	{
		player1.set_up(true);
		player1.lookleft = false;
		player1.looktop = true;
		player1.lookdown = false;
		player1.lookright = false;
		
	}
	if(key == Event.DOWN&& !activeH)	{
		player1.set_down(true);
		player1.lookleft = false;
		player1.looktop = false;
		player1.lookdown = true;
		player1.lookright = false;

	}
	if(key == Event.RIGHT&& !activeH)	{
		player1.set_right(true);
		player1.lookleft = false;
		player1.looktop = false;
		player1.lookdown = false;
		player1.lookright = true;
	}
	if(key == 107&& !activeH){
		player1.setUsew1(true);
	}
	//player2
	if(key == 97&& !activeH)	{
		player2.set_left(true);
		player2.lookleft = true;
		player2.looktop = false;
		player2.lookdown = false;
		player2.lookright = false;
	}
	if(key == 119&& !activeH)	{
		player2.set_up(true);
		player2.lookleft = false;
		player2.looktop = true;
		player2.lookdown = false;
		player2.lookright = false;
		
	}
	if(key == 115&& !activeH)	{
		player2.set_down(true);
		player2.lookleft = false;
		player2.looktop = false;
		player2.lookdown = true;
		player2.lookright = false;

	}
	if(key == 100&& !activeH)	{
		player2.set_right(true);
		player2.lookleft = false;
		player2.looktop = false;
		player2.lookdown = false;
		player2.lookright = true;
	}
	if(key == 102&& !activeH){
		player2.setUsew1(true);
	}
	return true;
	}

	// event handling for keys up
	

	// Stop Thread
	public void stop()
	{
		th.stop();
	}

	// Stop Thread
	public void destroy()
	{
		th.stop();
	}

	public void update (Graphics g)
	{
		if (dbImage == null)
		{
			dbImage = createImage (this.getSize().width, this.getSize().height);
			dbg = dbImage.getGraphics ();
		}

		dbg.setColor (getBackground ());
		dbg.fillRect (0, 0, this.getSize().width, this.getSize().height);

		dbg.setColor (getForeground());

		paint(dbg);

		g.drawImage (dbImage, 0, 0, this);
	}

	/** draw game */
	public void paint (Graphics g)
	{
			if(activeH){
				HM.drawp(g);
			}
			if(!activeH){
			player2.drawp(g);
			player1.drawp(g);
			g.setColor(Color.WHITE);
			g.fillRect(0,V_safe.appletB,V_safe.appletH, 10);
			g.setColor(Color.RED);
				if(player1.gethp()>0){
					g.draw3DRect(20, 360,player1.maxhp, 5, false);
					g.fillRect(20, 360,player1.gethp(), 5);
				}
				if(player2.gethp()>0){
					g.fillRect(300, 360,player2.gethp(), 5);
					g.draw3DRect(300, 360,player2.maxhp, 5, false);
				}
			g.setColor(Color.BLUE);
			g.draw3DRect(20, 370,player1.maxmagic, 5, false);
			g.fillRect(20, 370,player1.getmagic(), 5);
			g.fillRect(300, 370,player2.getmagic(), 5);
			g.draw3DRect(300, 370,player2.maxmagic, 5, false);
				for(int i=0;i<V_safe.appletH;i++){
					for(int j=0;j<V_safe.appletB;j++){	
			
					T.filterRGB(j,i,Color.TRANSLUCENT);
					}
				}
			}
		}	
}
```
sorry für die nich kommentierung und wenn ihr noch anregungen habt oder wenn ihr noch was code von unterklassen braucht...POSTEN ;D 
mfg OyO


----------



## andre111 (10. Sep 2009)

Grundsätzlich solltest du dich an die Codingconventions halten, das macht das ganze wesentlich schöner und übersichtlicher.


----------



## Quaxli (11. Sep 2009)

Es gibt verschiedene Möglichkeiten, wie Du das Lösen könntest. Du könntest auch einen Startbidlschirm basteln, wo die Figuren angezeigt werden und je nach Tastendruck startet das Spiel mit unterschiedlichen Spielerfiguren (F1 = Ritter, F2 = ...).

ABER: Bevor Du Dich an so Schnickschnack versuchst, würde ich Dir doch raten, erstmal die Basics gebacken zu kriegen. 



> ich bin gerade dabei ein java applet game zu schreiben und bin bisher gut weitergekommen



Das bist Du nämlich eigentlich nicht oder Du stellst keine sehr hohen Ansprüche an Dein Spiel. Zum Beispiel ruckelt Deine Figur sehr und wird bei mir überhaupt erst nach einem ersten Tastendruck angezeigt. Außerdem vermisse ich eine Animation der Figur. Du hast Dir da ein schönes Tileset aus dem Internet rausgesucht und nutzt es nicht, was ich schade finde.
Wenn ich so ein Applet im Internet finden würde, wäre es mir egal ob ich die Spielfigur auswählen kann, weil das Spiel an sich keinen Spaß macht (ruckeln, etc. ).


----------



## oyo (11. Sep 2009)

hey vielen dank für eure anregungen und das mit dem anzeigen animieren usw krieg ich schon noch hin bzw hatte ich noch vor... ich mach erst immer so happen und dann mit dem spiel an sich weiter, damit das grundgerüst steht 
ich habe ja auch schon ein auswahlmenu, welches du dir ansehen könntest wenn du das die rar datei runterlädst, jedoch zeigt er mir nicht die figuren im spiel an, bzw. im moment kommt er gar nich in das spiel rein. muss also iwas mit den grafiken sein, weil ich was beim objekt klonen nich richtig gemacht hab !?! oder mann objekte nur in der init methode deklarieren ?!? jedem nochmal danke, der sich zeit nimmt mir ne antwort zu schreiben...


----------



## hdi (12. Sep 2009)

Zu den Bildern kann ich nichts sagen, aber es sei mir erlaubt dir einen allgemeinen Hinweis zu geben: Threads sollte man niemals per stop() o.ä. Methoden beenden, weil das nicht "sauber" ist.

Ein Thread sollte eine Lebensvariable haben, in der er läuft:


```
while(isRunning) // statt while(true) {
 ...
}
```

und in der stop bzw. destroy Methode:


```
isRunning = false; // statt th.stop()
```

Damit verlässt der Thread nach dem momentanen Schleifendurchlauf seine run-Methode, und beendet sich "sauber".

Ich hoffe mal das trifft auf Applets auch zu, damit kenn ich mich nämlich nicht aus. Aber ich denke nicht dass es da einen Unterschied bei Threads gibt.


----------



## Developer_X (12. Sep 2009)

andre111 hat gesagt.:


> Grundsätzlich solltest du dich an die Codingconventions halten, das macht das ganze wesentlich schöner und übersichtlicher.



wenn er sein spiel vermarkten will, sollte er das ganze so schrecklich wie möglich machen, damit kein anderer den Code lesen kann, sogar er selbst nicht.

:lol:


----------



## oyo (12. Sep 2009)

jaja is ja alles ganz witzig aber helfen kann mir keiner ><


----------



## andre111 (12. Sep 2009)

Hey, DevX, an deiner Stelle würde ich mich mal an das "Tutorial" von Ark halten und nicht wo anders blöde Sprüche klopfen. Das kann sich zwar jemand erlauben der von der ganzen Sache eine Ahnung hat, aber nicht der größte Anfänger überhaupt (du).
@Oyo: In der Signatur von Quaxli steht ein Link zu seinem Spieletutorial, da steht auch was über Bilder laden usw. drin.

lg André


----------



## oyo (15. Sep 2009)

also bitte hier noch einmal: 
ich habe 2 figuren, ritter und könig, die ich in der init() methode deklariere:

```
ritter = new player (50, 50, 20,200,100,w);
	  koenig = new player (400,400,10,200,200,w2);
```
in meiner run() methode möchte ich nun mit hilfe einer switch anweisung alle werte z.b des ritter objektes KOPIEREN (!), so dass auch 2 mal der ritter ausgewählt werden kann:

```
while(activeH){
		HM.move();
		HM.leftm=false;
		HM.rightm=false;
		repaint();
		getImages();
			if(HM.chosen1){
				switch(HM.getcur()){
					case '1':
						player1 =ritter.clone();
					break;
					case '2':
						player1 =koenig.clone();
					break;
				}
			}
```
nun erhalte ich an den stellen, wo player1 methoden aufruft null pointer exeptions -->
mein problem ist, dass das clonen von meinem player objekt wohl nicht funktioniert.
Meine frage nun.. IST das überhaupt so möglich oder gibt es für so etwas vllt noch andere möglichkeiten ?
mfg oyo


----------



## Landei (15. Sep 2009)

Ich glaube, das solltest du anders machen (ich hoffe, ich habe den Code oben richtig verstanden):


```
abstract class Player {
   public Player(viele, viele, viele, Argumente) {
      ...
  }
}

public class King extends Player {
   public King() {
       super(400,400,10,200,200,w2); //<--hier setzt du die Startwerte
   }
   //<-- hier wäre noch ganz ganz viel Platz für besondere "königliche" Verhaltensweisen
}

public class Knight extends Player {
   public Knight () {
       super(50, 50, 20,200,100,w); //<--hier setzt du die Startwerte
   }
   //<-- hier wäre noch ganz ganz viel Platz für besondere "ritterliche" Verhaltensweisen
}

//im case
case '1' : player1 = new King();
```

Clone sollte man meiner Meinung nach nur einsetzen
- wenn man das letzte Zipfelchen Performance braucht
- wenn es keine andere passende Lösung gibt
- und man ganz genau weiß, was man da eigentlich tut


----------



## oyo (15. Sep 2009)

ok danke ich versuchs mal was so hinzubekommen


----------

