Du verwendest einen veralteten Browser. Es ist möglich, dass diese oder andere Websites nicht korrekt angezeigt werden. Du solltest ein Upgrade durchführen oder ein alternativer Browser verwenden.
BlueJ - Fragen zu dem Spiel Pacman (Nachprogrammieren)
Dann erstelle soviel Instanzen von Geist wie du brauchst.
Mache doch eine Liste der du die Objekte hinzugefügtst.
Das sollte doch so sein das du das alles in den Level Klassen machst. Geister keine Punkte, Dreiecke,Diamanten....
Und was du sonst noch so zum einsammeln anbieten willst.
Das sollte doch so sein das du das alles in den Level Klassen machst. Geister keine Punkte, Dreiecke,Diamanten....
Und was du sonst noch so zum einsammeln anbieten willst.
Einfach soviel Objekte von Geist erstelken wie du willst.
Natürlich musst du auch prüfen ob der Geist den pacman Frist.
Oder hast das fressen in der Geist Klasse machen. Dazu natürlich dem Geist die Instanz von pacman mitgeben dein Instanziren des Geistes mit new.
Einfach soviel Objekte von Geist erstelken wie du willst.
Natürlich musst du auch prüfen ob der Geist den pacman Frist.
Oder hast das fressen in der Geist Klasse machen. Dazu natürlich dem Geist die Instanz von pacman mitgeben dein Instanziren des Geistes mit new.
Aber ich will dass es erst 2 geister sind, später dann ab einem bestimmten Level 3 und so weiter. Wie kann ich das machen?
und dann wenn man stirbt soll es ja wieder von level 1 losgehen, also müssen geister wieder weg
Einfach soviel Objekte von Geist erstelken wie du willst.
Natürlich musst du auch prüfen ob der Geist den pacman Frist.
Oder hast das fressen in der Geist Klasse machen. Dazu natürlich dem Geist die Instanz von pacman mitgeben dein Instanziren des Geistes mit new.
//Warum funktioniert folgendes nicht? Ich will dass wenn man diese Methode aufruft man true bekommt, wenn der Kleinepunkt ein Wandstück schneidet
//In klasse LEVEL
Java:
public boolean Schneidet(Raum raum){
return beruehrt(raum);
}
public boolean SchneidetKleinerPunktWand(LEVEL kleinepunkte){
for(RECHTECK r: this.wandstück){
if(kleinepunkte.Schneidet(r)){
return true;
}
}
}
Ich hatte die Entwicklung im Thread nicht weiter verfolgt und habe auch keine aktuellen Sourcen des Projekts. Aber wenn Du mir die gibst (gerne auch per PM), dann kann ich da gerne auch einmal im Detail drauf schauen.
Das Problem muss auch nicht zwingend in der Methode sein sondern kann auch im Bereich des Aufrufes sein. Wenn z.B. auf einer falschen Instanz diese Methode aufgerufen würde, dann wäre das eine Möglichkeit.
Aber wie gesagt: Wenn Du mir den Code einmal als Ganzes gibst, dann kann ich mir das gerne im Detail ansehen (und Dir dann auch gerne generell etwas Feedback geben).
Ich hatte die Entwicklung im Thread nicht weiter verfolgt und habe auch keine aktuellen Sourcen des Projekts. Aber wenn Du mir die gibst (gerne auch per PM), dann kann ich da gerne auch einmal im Detail drauf schauen.
Das Problem muss auch nicht zwingend in der Methode sein sondern kann auch im Bereich des Aufrufes sein. Wenn z.B. auf einer falschen Instanz diese Methode aufgerufen würde, dann wäre das eine Möglichkeit.
Aber wie gesagt: Wenn Du mir den Code einmal als Ganzes gibst, dann kann ich mir das gerne im Detail ansehen (und Dir dann auch gerne generell etwas Feedback geben).
1. Labyrinth Objekt ertellen
2. Methode SpielStarten() aufrufe, dann öffnet sich die darstellung (nicht wundern: zuerst kommt ein verunglückter text, der hinweisen soll wie das spiel funktioniert - 5s) danach gehts los.
Wenn man die Punkte gegessen hat (probeweise nur 5 oben links), soll das neue Level aufgerufen werden. (wandstücke werden verschoben).
Pacman kann aber dann nicht mehr bewegt werden.
//Warum funktioniert folgendes nicht? Ich will dass wenn man diese Methode aufruft man true bekommt, wenn der Kleinepunkt ein Wandstück schneidet
//In klasse LEVEL
Java:
public boolean Schneidet(Raum raum){
return beruehrt(raum);
}
public boolean SchneidetKleinerPunktWand(LEVEL kleinepunkte){
for(RECHTECK r: this.wandstück){
if(kleinepunkte.Schneidet(r)){
return true;
}
}
}
Beim Layout würde ich es so machen allse was in jedem Level gleich ist erstelkst du in der Klasse Level. Level1 zb Erbt ja von Level. In Level1 setzt du die Wände die anders sind als in allen Leveln.
Vileicht ist es auch besser nicht für jedes Raum Objekt ein Array zubenutzen. Wie ich schon am Anfang sagte würde ich ein 2d Array benutzen was vom Datentyp Raum ist. Jetzt hast du ein Array mit 27 Felder in x und 21 Felder in y Richtung. Nun kannst du auch deine Raum Objekte auf den Feldern Speichen. Wand Punkte. Diamanten und was es sonst so in den original Spiel zum sammel gab.
Ps bin die nechsten Wochen nur am Handy und da ist Code schreiben schlecht.
Die Methode berührt wird immer auf ein Raum Objekt aufgerufen und ihr wird das zu prüfende Raum Objekt übergeben. Siehe Doku Alpha Lib.
Das tust du nicht, ein nur berührt aufrufen geht nicht.
Also in etwa so.
Ja stimmt. Jedoch wollte ein Freund eine Methode schreiben, die automatisch überall punkte setzt wo kein Wandstück ist außer an den Pacman und Geister spawnpunkten
Also ich würde Dir dringend raten immer eine Sache nach der andern anzugehen. So baust Du immer mehr Code, es wird immer unübersichtlicher und am Ende blickt niemand mehr durch.
So erstellst Du alle Mauerstücke an einer Position. Der Konstruktor bekommt aber nur die Größe und die Position ist einfach im Konstruktor gesetzt. Bei den Punkten ist es nicht anders - da sind alle Punkte übereinander.
Wenn man sich die Klasse RECHTECK anschaut, dann fällt auf, dass die Koordinate dort als float gespeichert wurde, aber das Setzen wird über int Werte vorgenommen.
Die Positionen sind auch nicht richtig gesetzt - nach dem "fressen" der Punkte statete Level 2 und Pacman war teilweise in der Mauer und konnte sich daher nicht bewegen!
Daher wäre aus meiner Sicht wichtig, dass man sich wirklich genau überlegt, welches Feature man implementieren möchte und dies sollte man dann richtig machen und abschließen, ehe man etwas neue startet.
Bezüglich des Codes, an dem Du gerade dran bist: Du solltest erst einmal überlegen, was Du da überhaupt machen willst. Wenn es Dir z.B. beim Setzen von Punkten darum geht, dass ein neu gesetzter Punkt nicht in einer Wand ist: Ich würde generell anders vorgehen:
Das Spielfeld besteht aus Feldern. Dann können Felder besetzt werden, z.B. durch ein Wandstück (RECHTECK) oder durch einen Kreis, der in der Mitte des Feldes seinen Mittelpunkt hat und kleiner als das Feld ist. Dann wäre die Prüfung einfach nur, ob der der Mittelpunkt des Kreises in einem Rechteck ist.
So ein Level sollte dann auch recht gut beschrieben werden:
Es gibt eine Anzahl Wandstücke und jedes Wandstück bekommt ein Feld zugewiesen.
Es gibt eine Anzahl Punkte und auch hier wird jedem Punkt ein Feld zugewiesen.
Es gibt eine Anzahl Geister - auch jedem wird ein Startpunkt zugewiesen.
Und es gibt ein Startpunkt für den Pacman.
Und generell kann man die Geister auch in einem Array vorhalten.
Dann ist unklar, die die Level vorgehalten werden sollen. Wenn man das als Felder vorstellt, dann kann man den Inhalt der Felder beschreiben
W steht für Wand, . für ein Punkt, P für Pacman und G für ein Geist.
Das ist recht klein gehalten, aber ich will nur das Prinzip aufzeigen.
Den Text liest Du einfach ein, dann zählst Du die Anzahl des "W", "." und "G" und hast damit die Array Größen um diese anzulegen.
Dann gehst Du Zeile für Zeile durch. Und zählst dabei x pro Zeichen hoch und y pro Zeile. Angefangen bei 0.
Die Position einer Wandposition kann man dann berechnen um dann das Rechteck zu erstellen für die Wand. Bei den anderen Elementen muss man ggf. noch einen Offset dazu nehmen. Bei einem Kreis ist der Mittelpunkt halt denn noch jeweils 1/2 Feld in jede Richtung dazu zu nehmen.
Und durch die Startpunkte kann man sicher stellen, dass:
Nichts in einer Wand steckt (Da pro Feld immer nur ein Objekt möglich ist, ist das so auch kein Problem.)
Die Level kann man so auch Problemlos aufbauen mit einem Texteditor.
Das nur einmal kurz als Rückmeldung von meiner Seite.
@Jw456
Ich schaffe folgendes nicht: (Will mit dem Projekt langsam abschließen)
1. Irgendwie bewegen sich die Geister sehr komisch mit der verfolgen Methode. Probier es bitte mal aus.
2. Außerdem bringe ich es nicht hin, dass der Pacman, nachdem er oben oder unten an eine Wand stoßt, wieder umkehren kann.
3. Ich will außerdem, dass in Labyrinth eine Methode ist (nächstesLevel()), die in tick() immer das neue Level aufruft, wenn die Anzahl der kleinen Punkte 0 sind. Das heißt, es soll wenn man gerade level2() in LEVEL geschafft hat, level.level3() aufgerufen werden.
4. Eine Methode die püft ob ein kleinerpunkt (Array) ein Wandstück (Array) schneidet, und dann überall wo keine Wand ist einen Punkt setzt. Außer beim Pacman spawnpunkt, und geister box
das heißt:
Java:
(In Klasse LEVEL) so ungefähr:
public boolean schneidetWandstücke(){
if ......{
return true....
}
}
public void setzePunkeÜberallWoKeinWandstück(){
for(int i;i<this.AnzahlKleinePunkte;i++){
int counter = 0;
if(this.kleinepunkte[i].schneidetWandstücke == false){
this.kleinepunkte[counter].setzeMittelpunkt(..,..);
}
}
}
So ungefähr, funktioniert halt nicht
//xGoast ist die x position des Geistes yGoast yPos.
if (Math.abs(xGoast) < 30 || Math.abs(yGoast) < 30)
// Math.abs gibt den absulutwet zurück ohne Vorzeichen.
{ if (Math.abs(xGoast) > Math.abs(yGoast)) { Richtung = xGoast <= 0 ? "rechts" : "links" ; // ist eine kompakte if Anweisungn
// der Variablen Richtung wird je nachdem wie der die Bedingung in der Klammer vor dem Fragezeichen ausfällt true das vor dem Doppelpunkt oder bei false nach dem Doppeltpunkt zugewiesen.
Das mit dem Pacman der nicht oben oder unten nicht zurück geht.
Da habe ich dir schon einen Tipp gegen. Schaue dir fue virzeiche bei oben und unten an für das ruvhwerts gehen.
Ich bin die nechsten Tage nicht an einem Rechner kann erst später mal testen.
@Jw456
Ich schaffe folgendes nicht: (Will mit dem Projekt langsam abschließen)
1. Irgendwie bewegen sich die Geister sehr komisch mit der verfolgen Methode. Probier es bitte mal aus.
2. Außerdem bringe ich es nicht hin, dass der Pacman, nachdem er oben oder unten an eine Wand stoßt, wieder umkehren kann.
3. Ich will außerdem, dass in Labyrinth eine Methode ist (nächstesLevel()), die in tick() immer das neue Level aufruft, wenn die Anzahl der kleinen Punkte 0 sind. Das heißt, es soll wenn man gerade level2() in LEVEL geschafft hat, level.level3() aufgerufen werden.
4. Eine Methode die püft ob ein kleinerpunkt (Array) ein Wandstück (Array) schneidet, und dann überall wo keine Wand ist einen Punkt setzt. Außer beim Pacman spawnpunkt, und geister box
das heißt:
Java:
(In Klasse LEVEL) so ungefähr:
public boolean schneidetWandstücke(){
if ......{
return true....
}
}
public void setzePunkeÜberallWoKeinWandstück(){
for(int i;i<this.AnzahlKleinePunkte;i++){
int counter = 0;
if(this.kleinepunkte[i].schneidetWandstücke == false){
this.kleinepunkte[counter].setzeMittelpunkt(..,..);
}
}
}
So ungefähr, funktioniert halt nicht
Keine Ahnung wo du genau bist.
Wie wir dir schon sagten brauchst du zum Testen immer auc die bei Instanzen der Objekte die du testen willst. Wenn sie nicht beide in der gleichen Klasse erstellt wurden must du die der Methode mitgeben als Parameter.
Du scheinst noch sehr große Probleme beim verständnis von OOP zu haben.
Grundlagen Oop würde ich sagen könnte helfen. Daten Kaselung.
Was willst du denn hier vergleichen?
Sinnlos
Du wist doch die Differenz der pos von pacman und Geist haben.
Großer Wert weit weg kleiner Wert ziemlich nach. Das Vorzeichen gibt die Richtung an.
So nun schaue in die Alpha Doku wie du zu der Differenz von zwei Raum Objekten kommst.
Was willst du denn hier vergleichen?
Sinnlos
Du wist doch die Differenz der pos von pacman und Geist haben.
Großer Wert weit weg kleiner Wert ziemlich nach. Das Vorzeichen gibt die Richtung an.
So nun schaue in die Alpha Doku wie du zu der Differenz von zwei Raum Objekten kommst.
Wichtig sind hier die ersten beiden Zeilen: xGoast ist der horizontale Abstand zwischen Geist und Pacman. In der if-Bedingung wird dann abefragt, ob dieser horizontale Abstand kleiner als 30 ist.
Wichtig sind hier die ersten beiden Zeilen: xGoast ist der horizontale Abstand zwischen Geist und Pacman. In der if-Bedingung wird dann abefragt, ob dieser horizontale Abstand kleiner als 30 ist.
Dann setze den Abstand größer. So das der geist bei seinen random laufen den pacman früher einfängt.
Natürlich ist beim verfolgen auch immer noch dein Labyrinth im wege. Wenn der Abstand zb nur 10 ist in x Richtung und Eine Wand dazwischen wird er so nicht zum Pacman kommen.
Da musst du schon einen besseren Algorithmus schrieben das das Labyrint mit berücksichtigt.
Ich sagte ja auch einen sehr einfache Art. In dem Layout ohne viel Wände auch geht.
Ich denke in den alten Spielen da kannte der Geist den Weg duch das Labyrint. Also konnte er recht schnell von seiner pos zu der pos des pacman kommen. Die pos des pacman war sicherlich auch immer bekannt.
Dann setze den Abstand größer. So das der geist bei seinen random laufen den pacman früher einfängt.
Natürlich ist beim verfolgen auch immer noch dein Labyrinth im wege. Wenn der Abstand zb nur 10 ist in x Richtung und Eine Wand dazwischen wird er so nicht zum Pacman kommen.
Da musst du schon einen besseren Algorithmus schrieben das das Labyrint mit berücksichtigt.
Ich sagte ja auch einen sehr einfache Art. In dem Layout ohne viel Wände auch geht.
Ich denke in den alten Spielen da kannte der Geist den Weg duch das Labyrint. Also konnte er recht schnell von seiner pos zu der pos des pacman kommen. Die pos des pacman war sicherlich auch immer bekannt.
Aber wie baue ich den Algorithmus aus, damit er die Wände berücksichtigt? Soweit bin ich leider mit Java noch nicht. Das muss mir einer zeigen wie ich das mache, damit ich es dann später nochmal anwenden kann. Außerdem funktioniert die RandomMoves ja auch nicht wirklich. Der geist flieht durch wände, bleibt stecken oder ist aif einmal aus dem sichtbaren bereich geflogen.
Zeigen nicht unbedingt. Du solltest dir ein Strategie Prinzip bilden wie du verfolgen kannst wenn du deine Position und die des pacman kennst.
Meunedwegen merke dir auch die letzten Wege Tasten Klicks vom User...
Und ziehe daraus deine Rückschlüsse.
Zur Steuerung der Geister.
Ein Prinzip dazu solltest du schon selber entwickeln bei der umstzung in java wird dir sicher geholfen werden.
Aber das Grund Prinzip sollte von dir kommen.
Eine Möglichkeit mit der Differenz den Abstand der beiden Figuren habe ich gezeigt.
Zeige die Klasse in der Geister mit Steuerung.
Schaue dir mein Beispiel an was du schon hast da geht kein Geist durch die Wand. Mache doch erst mals eins fertig und versuche zu verstehen was du da tust. Auch das lesen der Doku hilft. Und Grundlagen oop.
Zeige die Klasse in der Geister mit Steuerung.
Schaue dir mein Beispiel an was du schon hast da geht kein Geist durch die Wand. Mache doch erst mals eins fertig und versuche zu verstehen was du da tust. Auch das lesen der Doku hilft. Und Grundlagen oop.
Hallo habe deine Geiste mal angepasst so sollten sie sich sinnvoller bewegen.
Nicht wie bei dir immer den Weg nach oben zum Rand suchen . Warum das so bei dir so solltest du selber erkennen .
Denn wenn eine Wand in Laufrichtung erkannt wurde, wurde immer als erster aufweicht der Weg nach oben genommen.
Dem Konstruktor der Klasse musst du jetzt auch das Layout was in der LABYRINTH Klasse erstellt wird mitgeben. Somit hat der Geist auch die richtige Labyrinth Instanz und keine neue.
Java:
import ea.*;
/**
* Beschreiben Sie hier die Klasse GEIST.
*
* @author (Ihr Name)
* @version (eine Versionsnummer oder ein Datum)
*/
public class GEIST {
private BILD geist;
private LEVEL Levelprüfung;
private String Richtung;
//Benötigt für Prüfung der Schneidungen
int tickSteps = 0;
public BILD getGeist() {
return geist;
}
public GEIST(LEVEL level) {
this.geist = new BILD(285, 225, "GEIST.gif");
this.Levelprüfung = level;
// Gibt dem Geist eine Random Anfangsrichtung
setRandomRichtung();
}
public int RandomZahl(int maxZahl) {
int zahl = (int) ((Math.random()) * maxZahl + 1);
return zahl;
}
public void setRandomRichtung() {
int Zahl1 = this.RandomZahl(4);
if (Zahl1 == 1) {
this.Richtung = "rechts";
} else if (Zahl1 == 2) {
this.Richtung = "links";
} else if (Zahl1 == 3) {
this.Richtung = "oben";
} else if (Zahl1 == 4) {
this.Richtung = "unten";
}
}
public void DrehenAuf(int Winkel) {
this.geist.setzeDrehwinkel(Winkel);
}
public void RandomMoves() {
if (tickSteps > 30) {
setRandomRichtung();
tickSteps = 0;
}
tickSteps++;
if (Richtung == "oben") {
DrehenAuf(90);
geist.verschiebenUm(0, -3);
if (testSchneiden(geist)) {
geist.verschiebenUm(0, +3);
geist.verschiebenUm(4, 0);
if (testSchneiden(geist) == false) {
Richtung = "rechts";
geist.verschiebenUm(-4, 0);
} else {
geist.verschiebenUm(-4, 0);
if (this.testSchneiden(geist) == false) {
Richtung = "links";
geist.verschiebenUm(4, 0);
} else {
DrehenAuf(270);
geist.verschiebenUm(0, 3);
Richtung = "unten";
}
}
}
}
if (Richtung == "unten") {
DrehenAuf(270);
geist.verschiebenUm(0, 3);
if (testSchneiden(geist)) {
geist.verschiebenUm(0, -3);
geist.verschiebenUm(4, 0);
if (testSchneiden(geist) == false) {
Richtung = "rechts";
geist.verschiebenUm(-4, 0);
} else {
geist.verschiebenUm(-4, 0);
if (this.testSchneiden(geist) == false) {
Richtung = "links";
geist.verschiebenUm(4, 0);
} else {
DrehenAuf(90);
geist.verschiebenUm(0, -3);
Richtung = "unten";
}
}
}
}
if (Richtung == "rechts") {
DrehenAuf(270);
geist.verschiebenUm(3, 0);
if (testSchneiden(geist)) {
geist.verschiebenUm(-3, 0);
geist.verschiebenUm(0, 4);
if (testSchneiden(geist) == false) {
Richtung = "unten";
geist.verschiebenUm(0, -4);
} else {
geist.verschiebenUm(0, -4);
if (this.testSchneiden(geist) == false) {
Richtung = "oben";
geist.verschiebenUm(0, 4);
} else {
DrehenAuf(90);
geist.verschiebenUm(-3, 0);
Richtung = "links";
}
}
}
}
if (Richtung == "links") {
DrehenAuf(180);
geist.verschiebenUm(-3, 0);
if (testSchneiden(geist)) {
geist.verschiebenUm(3, 0);
geist.verschiebenUm(0, 4);
if (testSchneiden(geist) == false) {
Richtung = "unten";
geist.verschiebenUm(0, -4);
} else {
geist.verschiebenUm(0, -4);
if (this.testSchneiden(geist) == false) {
Richtung = "oben";
geist.verschiebenUm(0, 4);
} else {
DrehenAuf(90);
geist.verschiebenUm(3, 0);
Richtung = "rechts";
}
}
}
}
}
public boolean Schneidet(Raum raum) {
return this.geist.beruehrt(raum);
}
public boolean testSchneiden(BILD geist) {
//alle Rechtecke aus LEVEL werden geprüft
for (RECHTECK r : Levelprüfung.wandstück) {
//If Schleife: Geist-Schneidet Raum methode
if (Schneidet(r)) {
return true;
}
}
return false;
}
}
Tipp: halte dich an die Names Convention von Java . Das habe ich nicht angepasst.
A Computer Science portal for geeks. It contains well written, well thought and well explained computer science and programming articles, quizzes and practice/competitive programming/company interview Questions.
Der Code macht nur eins. Es wird durch Zufall eine Richtung bestimmt. Es wird geprüft ob das frei ist. Wenn nein wird je nachdem wekcgeruchtung es war eine Andere versucht ist die auch nicht frei dann die andrere geht das sich nicht dann zurück.
Da es nur aller 30 Ticks einen neuen Zufall gibt geht der Geist auch solang in die Richtung wenn keine Wand kommt.
Hallo ich steh kurz vorm Verzweifeln. Ich habe jetzt soo viele Möglichkeiten für die Random Moves gesucht: aber nix geht wirklich
auch nicht mit diesem Code: die bewegen sich ständig gleich alle 4.
könntest du mir vielleicht dabei helfen, oder mir ein beispiel zeigen? Weil dein beispiel zuvor hat ja nicht funktioniert.
@Jw456 Ich muss morgen mit dem projekt fertig sein, und es geht einfach nicht.
if(this.Richtung == "rechts"){ //hier eigentlich equels und nicht ==
this.geist.verschiebenUm(4,0);
if(this.testSchneiden(geist) == true){
this.geist.verschiebenUm(-8,0);
// ok die richtung ist belegt also schieben zurück wieso jetzt 8 Pixel. Sind doch nur 4.
this.Richtung = "links"; // du gibst einfach eine neue Richtung vor ohne vorher zu schieben und dann zu testen ob frei ist.
if(this.testSchneiden(geist) == true){
this.geist.verschiebenUm(4,-4);
this.Richtung = "oben";
if(this.testSchneiden(geist) == true){
this.geist.verschiebenUm(0,8);
this.Richtung = "unten";
if(this.testSchneiden(geist) == true){
this.geist.verschiebenUm(0,-4);
this.setRandomRichtung();
}
}
}
Schaue dir meinen Code an duch denke ihn.
Bei dem recht habe ich zuerst nach recht geschoben geprüft. War es Frei würde nichts mehr gemacht.
War es nicht frei also habe ich das schieben zurück genommen. Eine andrere Richtung geschoben zb nach oben und getestet war es frei fertig.
Auch nach oben belegt dann wider Schieben zurück und neue Richtung versuchen. Ist das auch belegt dann in die Richtung aus der du kamst.
Immer erst schieben testeten wenn nicht frei wier zurückschieben und neue Richtung testen.
Auch das Setzen des des tick Zähler auf 200 ist nicht gut.