Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

41

18.12.2012, 17:37

Ich habe es versucht, jedoch funktioniert es nicht :(
Wenn ich die Taste N drücke passiert nichts. Wenn ich einen Breakpoint in die Zeile setze stehen currentGameState, currentState, lastGameState und lastState auf dem QuitgameState. Eigentlich müssten aber beide auf MaingameState stehen, da der MaingameState ja der Zustand vor dem QuitgameState ist.
Update Methode aus Quit-Klasse:

C#-Quelltext

1
2
3
4
5
6
7
public void Update(GameTime gametime)         { 
            KeyboardState kbState = Keyboard.GetState(); 
            if (kbState.IsKeyDown(Keys.Y)) 
                game1.ChangeGameState(Game1.GameStates.MenuState); 
            if (kbState.IsKeyDown(Keys.N)) 
                game1.ChangeCurrentToLastGameState(); 
        } 


Die neue Methode in Game1:

C#-Quelltext

1
2
3
4
public void ChangeCurrentToLastGameState()         { 
            currentGameState = lastGameState; 
            currentState = lastState; 
        } 

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

42

18.12.2012, 23:03

Wo setzt du den Breakpoint? Auch nach der Funktion?
„Es ist doch so. Zwei und zwei macht irgendwas, und vier und vier macht irgendwas. Leider nicht dasselbe, dann wär's leicht.
Das ist aber auch schon höhere Mathematik.“

43

18.12.2012, 23:16

Ich habe den Breakpoint in folgende Zeile gesetzt:

C#-Quelltext

1
game1.ChangeCurrentToLastGameState();

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

44

19.12.2012, 03:53

Dann kann auch noch nichts passiert sein. Bei einem Breakpoint hält er an, bevor er die Zeile ausführt. Du kannst die Anwendung Schritt für Schritt ausführen. Wenn du das tust, kannst du gucken was nach der Methode passiert. Funktioniert es denn nicht?
„Es ist doch so. Zwei und zwei macht irgendwas, und vier und vier macht irgendwas. Leider nicht dasselbe, dann wär's leicht.
Das ist aber auch schon höhere Mathematik.“

45

19.12.2012, 09:51

C#-Quelltext

1
position.Y += 3 * delta;

Wenn ich in dieser Zeile der Maingame-Klasse einen Breakpoint setze, haben CurrentSate/currentGameState(MaingameState) einen anderen Zustand als LastState/lastGameState(MenuState). So ist es ja richtig.


Danach habe ich folgenden Breakpoint gesetzt.

C#-Quelltext

1
KeyboardState kbState = Keyboard.GetState();

Wenn ich in dieser Zeile der Quit-Klasse einen Breakpoint setze, haben CurrentSate/currentGameState(QuitgameState) den gleichen Zustand als LastState/lastGameState(QuitgameState). Eigentlich dürften die Zustände ja nicht bei beiden gleich sein.

Ich habe aber keine Ahnung wo der Fehler liegt ?(
Komplettes Projekt zum Download: http://www.file-upload.net/download-6945…terung.rar.html

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

46

19.12.2012, 13:27

Dir fehlt teilweise noch das gewisse Denken. Du schaffst dir selbst Probleme, welche du dann wieder lösen musst. Beim Aufruf von "ChangeCurrentToLastGameState" sind der aktuelle und der letzte Zustand auf den Quit Zustand gesetzt. Noch bevor der Code dieser Methode ausgeführt wird. Da musst du also mal genauer nachhaken. Solltest aber auch darüber nachdenken erst mal wieder zu deiner Switch oder If Variante zurück zu wechseln. Es bringt dir nichts wild zu mischen. Die Probleme die vorhanden sind zeigen einfach, dass du dafür noch ein wenig mehr programmieren musst.
Hier hast du noch mal ein ganz gutes Tutorial. Es erklärt erst eine C# Grundlagen und geht hinterher auf viele Dinge die XNA betreffen ein. Da gehts wirklich um einige interessante Dinge. Selbst ein paar weiterführende Themen werden angesprochen. Ich würde mir das an deiner Stelle mal genau angucken und dann einfach mal drauf los programmieren. Für den Anfang machst du vielleicht mal Pong für zwei Spieler an einem Rechner. Wenn du ein paar Ideen hast, machst du noch eine KI sodass man gegen den Computer spielen kann. Danach mal Breakout versuchen. Dann vielleicht mal ein Puzzlespiel. Sokoban ist auch super interessant, vor allem weil es dabei mehrere Knackpunkte gibt die man beachten muss.
Wenn du dich ein wenig wohl fühlst mit der Sprache, dann kannst du bei Google mal nach Entwurfsmustern (Design Pattern) suchen. Dazu gehört auch das Zustandsmuster welches ich dir hier gezeigt hatte. Für deinen Pausemodus in der Spielklasse würde sich zum Beispiel das Strategiemuster anbieten, wobei du dir das Problem mit dem Pause handling selbst geschaffen hast. ;)
Das was ich hier schreibe sind natürlich nur Vorschläge. Du kannst sicherlich auch eigene Ideen umsetzen, wobei man sich da schnell vertut wie komplex so eine Idee ist.

Ein weiterer Tipp von mir. Wenn es dir eher um das bauen von Spielen und um das Ergebnis geht, als um das eigentliche programmieren und das was dazu gehört, dann solltest du dir mal Unity angucken. Damit arbeite ich auch seit einiger Zeit. Ist wirklich eine feine Sache.
„Es ist doch so. Zwei und zwei macht irgendwas, und vier und vier macht irgendwas. Leider nicht dasselbe, dann wär's leicht.
Das ist aber auch schon höhere Mathematik.“

47

22.12.2012, 14:42

Ich habe jetzt einen GameoverState eingebaut. Er funktioniert auch, jedoch nur unter einer Bedingung.
Wenn ich Enter während des Gameoverscreens drücke, komme ich nur in den MenuState, wenn ich in folgender Zeile der Menu-Klasse nicht Enter als Taste angebe.
Mit einer anderen Taste(zum Beispiel Q) funktioniert es:

C#-Quelltext

1
if (kbState.IsKeyDown(Keys.Q))    game1.ChangeGameState(Game1.GameStates.MaingameState);

Mit Enter funktioniert es nicht. Dann komme ich nicht ins Menü, sondern ins Maingame.

C#-Quelltext

1
if (kbState.IsKeyDown(Keys.Enter))    game1.ChangeGameState(Game1.GameStates.MaingameState);

Meine Vermutung:
Wenn ich während des Gameoversreens Enter drücke, wechselt das Spiel zuerst auf den MenuState, und danach sofort auf den MaingameState, weil ich in der Menü-Klasse durch Enter drücken ins Maingame wechsele. Deshalb müssen sich die Tasten unterscheiden damit nicht automatisch ein State übersprungen wird.
Jetzt meine Frage:
Wie kann ich das Problem umgehen? Sagen wir mal ich möchte alles mit Enter machen. Also das switchen vom GameoverState auf den MenuState und das switchen vom MenuState auf den MaingameState.
Wie geht man am besten vor wenn man möchte dass pro Tasten-Druck nur eine if-Abfrage ausgeführt wird? Und nicht noch eine andere if-Abfrage in einer anderen Klasse.

Der komplette Code(im Code ist die erwähnte Zeile(mit Taste Q) in der Menü-Klasse bereits geändert)

C#-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
public class Game1 : Microsoft.Xna.Framework.Game { 
    GraphicsDeviceManager graphics; 
    SpriteBatch spriteBatch; 
    IState lastState, currentState; 

    public enum GameStates 
    { 
        IntroState = 0, 
        MenuState = 1, 
        MaingameState = 2, 
        IngamemenuState = 3, 
        GameoverState = 4 
    } 

    public void ChangeGameState(GameStates newState) 
    { 
        if (newState == currentGameState) 
            return; 
        lastGameState = currentGameState; 
        lastState = currentState; 
        switch (newState) 
        { 
            case GameStates.IntroState: 
                currentState = new Intro(this); 
                currentGameState = GameStates.IntroState; 
                break; 
            case GameStates.MenuState: 
                currentState = new Menu(this); 
                currentGameState = GameStates.MenuState; 
                break; 
            case GameStates.MaingameState: 
                  currentState = new Maingame(this); 
                  currentGameState = GameStates.MaingameState; 
                break; 
            case GameStates.IngamemenuState: 
                currentState = new Ingamemenu(this); 
                currentGameState = GameStates.IngamemenuState; 
                break; 
            case GameStates.GameoverState: 
                currentState = new Gameover(this);              
                currentGameState = GameStates.GameoverState; 
                break; 
        } 
        currentState.Load(Content); 
    } 

    public void ChangeCurrentToLastGameState() 
    { 
        currentGameState = lastGameState; 
        currentState = lastState; 
    } 

    public GameStates CurrentState 
    { 
        get { return currentGameState; } 
        set { currentGameState = value; } 
    } 

    public GameStates LastState 
    { 
        get { return lastGameState; } 
        set { lastGameState = value; } 
    } 

    private GameStates currentGameState = GameStates.IntroState; 
    private GameStates lastGameState; 

    public Game1() 
    { 
        graphics = new GraphicsDeviceManager(this); 
        Content.RootDirectory = "Content"; 
    } 

    protected override void Initialize() 
    { 
        currentState = new Intro(this); 
        currentGameState = GameStates.IntroState; 
        base.Initialize(); 
    } 

    protected override void LoadContent() 
    {        
        spriteBatch = new SpriteBatch(GraphicsDevice); 
        currentState.Load(Content); 
    } 

    protected override void Update(GameTime gameTime) 
    { 
        currentState.Update(gameTime); 
        if ((lastGameState == GameStates.MaingameState) && (currentGameState == GameStates.IngamemenuState)) 
        { 
            lastState.Update(gameTime); 
        } 
        base.Update(gameTime); 
    } 

    protected override void Draw(GameTime gameTime) 
    { 
        GraphicsDevice.Clear(Color.CornflowerBlue); 
        spriteBatch.Begin(); 
        if ((lastGameState == GameStates.MaingameState) && (currentGameState == GameStates.IngamemenuState)) 
        { 
          lastState.Render(spriteBatch); 
        } 
        currentState.Render(spriteBatch); 
        spriteBatch.End(); 

        base.Draw(gameTime); 
    } 
}

C#-Quelltext

1
2
3
4
5
public interface IState { 
    void Load(ContentManager content); 
    void Update(GameTime gametime); 
    void Render(SpriteBatch batch); 
}


C#-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public class Intro : IState { 
Texture2D Titelbildschirm; 
private Game1 game1;        

public Intro(Game1 game) 
{ 
    game1 = game; 
} 

public void Load(ContentManager content) 
{ 
   Titelbildschirm = content.Load<Texture2D>("gruft"); 
} 

public void Update(GameTime gametime) 
{ 
    KeyboardState kbState = Keyboard.GetState(); 
    if (kbState.IsKeyDown(Keys.Space)) 
        game1.ChangeGameState(Game1.GameStates.MenuState); 
} 

public void Render(SpriteBatch batch) 
{ 
    batch.Draw(Titelbildschirm, new Rectangle(0, 0, 1280, 720), Color.White); 
} 
}


C#-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public class Menu:IState { 
Texture2D Choosescreen; 
private Game1 game1; 

public Menu(Game1 game) 
{ 
    game1 = game; 
} 

public void Load(ContentManager content) 
{ 
Choosescreen = content.Load<Texture2D>("menubild"); 
} 

public void Update(GameTime gametime) 
{ 
KeyboardState kbState = Keyboard.GetState(); 
if (kbState.IsKeyDown(Keys.Q)) 
    game1.ChangeGameState(Game1.GameStates.MaingameState); 
if (kbState.IsKeyDown(Keys.Escape)) 
    game1.Exit(); 
} 

public void Render(SpriteBatch batch) 
{ 
batch.Draw(Choosescreen, new Rectangle(0, 0, 1280, 720), Color.White); 
} 
}


C#-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
public class Maingame : IState { 
Texture2D Spielbildschirm, axe; 
Vector2 position = new Vector2(100,100); 

private Game1 game1; 

public Maingame(Game1 game) 
{ 
    game1 = game; 
} 

public void Load(ContentManager content) 
{ 
    Spielbildschirm = content.Load<Texture2D>("hauszombie"); 
    axe = content.Load<Texture2D>("axxx"); 
} 

public void Update(GameTime gametime) 
{ 
      KeyboardState keyboardState = Keyboard.GetState(); 
      float delta = (float)gametime.ElapsedGameTime.TotalSeconds; 
      position.X += 5 * delta; 
      position.Y += 3 * delta; 

      if (keyboardState.IsKeyDown(Keys.Escape)) 
        game1.ChangeGameState(Game1.GameStates.IngamemenuState);  
      if (keyboardState.IsKeyDown(Keys.A)) 
        game1.ChangeGameState(Game1.GameStates.GameoverState);  
} 

public void Render(SpriteBatch batch) 
{ 
    batch.Draw(Spielbildschirm, new Rectangle(0, 0, 1280, 720), Color.White); 
    batch.Draw(axe, position, Color.White); 
} 
} 


C#-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public class Ingamemenu : IState { 
Texture2D Quitscreen; 
private Game1 game1; 

public Ingamemenu(Game1 game) 
{ 
    game1 = game; 
} 

public void Load(ContentManager content) 
{ 
    Quitscreen = content.Load<Texture2D>("quit"); 
} 

public void Update(GameTime gametime) 
{ 
    KeyboardState kbState = Keyboard.GetState(); 
    if (kbState.IsKeyDown(Keys.Y)) 
       game1.ChangeGameState(Game1.GameStates.MenuState); 
    if (kbState.IsKeyDown(Keys.N)) 
      game1.ChangeCurrentToLastGameState(); 
} 

public void Render(SpriteBatch batch) 
{ 
    batch.Draw(Quitscreen, new Rectangle(200, 200, 200, 200), Color.White); 
} 
}


C#-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class Gameover : IState { 
    Texture2D Gameoverscreen; 

    private Game1 game1; 

    public Gameover(Game1 game) 
    { 
        game1 = game; 
    } 

    public void Load(ContentManager content) 
    { 
        Gameoverscreen = content.Load<Texture2D>("gameover"); 
    } 

    public void Update(GameTime gametime) 
    { 
        KeyboardState kbState = Keyboard.GetState(); 
        if (kbState.IsKeyDown(Keys.Enter)) 
            game1.ChangeGameState(Game1.GameStates.MenuState); 
    } 

    public void Render(SpriteBatch batch) 
    { 
        batch.Draw(Gameoverscreen, new Rectangle(0, 0, 1280, 720), Color.White); 
    } 
}

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

48

22.12.2012, 14:59

Das ist im Prinzip ne neue Sache und beim nächsten mal solltest du dafür nen neuen Thread aufmachen. Ich bin auch glaube ich der einzige der sich diesen Thread hier noch anguckt,)
Das Tastenproblem ist ein allgemeines. Du willst nur im ersten Frame in welchem die Taste gedrückt wird ein true haben. Danach nicht mehr. Also wirklich nur beim drücken der Taste und nicht beim halten. Dafür speicherst du den Tastaturzustand (Keyboard.GetState()) vom letzten Frame und vom aktuellen. Wenn eine Taste im letzten Zustand nicht gedrückt wurde, aber im aktuellen, dann liegt ein Tastendruck vor. Wenn nicht, wurde die Taste gar nicht oder nicht erst jetzt gedrückt.
„Es ist doch so. Zwei und zwei macht irgendwas, und vier und vier macht irgendwas. Leider nicht dasselbe, dann wär's leicht.
Das ist aber auch schon höhere Mathematik.“

49

22.12.2012, 21:24

Wegen dem Tastendruck werde ich ein neues Thema eröffnen. Ich habe versucht das Problem zu lösen, jedoch funktioniert es noch nicht.
Ich habe aber noch eine Frage zu den Gamestates. Das HUD sollte ja kein State sein, oder? Ich wollte einfach eine neue Klasse namens HUD dafür machen, und diese dann dauernd in Game1 updaten und zeichnen. Ist das gut so?

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

50

22.12.2012, 22:03

Es gibt ja kein falsch oder richtig bei sowas. Kannst du natürlich so machen. Am besten ist es wenn du einfach selbst rumspielst und guckst wie du am besten klar kommst. Du hast jetzt hier ja einen Ansatz gesehen. Da gibts viele andere. Einfach machen.
„Es ist doch so. Zwei und zwei macht irgendwas, und vier und vier macht irgendwas. Leider nicht dasselbe, dann wär's leicht.
Das ist aber auch schon höhere Mathematik.“

Werbeanzeige