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

j0ck

Frischling

  • »j0ck« ist der Autor dieses Themas
  • Private Nachricht senden

1

17.09.2011, 11:18

[XNA] Bei Kollision nächster GameState, aber Spiel läuft im Hintergrund weiter!

Hallo,

Mein Jump'n'Run SpaceShooter nimmt langsam Form an.
Leider stehe ich vor dem nächsten Problem:

Ich habe 3 GameStates.
-Menu
-Spiel
-Ende

Starte ich mein Spiel, dann erscheint GameState Menu. Mit Taste "S" kommt man in GameState Spiel. Nun folgendes: Im GameState Menu läuft mein Spiel schon im Hintergrund, d.h. wenn ich ein bisschen warte mit der Taste "S" kann es passieren, dass im Hintergrund schon eine Kollision passiert ist und ich zum GameOver GameState springe... .
Kann mir jemand helfen, dass zuerst das GameState Menu startet ohne das das Spiel im Hintergrund läuft? :D
Das gleiche passiert übrigens auch im letzten GameState Ende. Nach der Kollision, kommt der GameState, aber das Spiel läuft einfach weiter! :(

Ich habe sämtlichen Code in die Game1.cs geschrieben, da es für mich als Anfänger einfacher ist.
Bitte nicht auslachen etc... ich programmiere noch nicht so lang! :D :P

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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace SpaceJump_N_Run
{
    /// <summary>
    /// Dies ist der Haupttyp für Ihr Spiel
    /// </summary>
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;

        // Player Sprite
        // Variable für das Player Sprite 
        Texture2D playerTexture;
        // Startposition des Player Sprite
        Vector2 playerPos;
        // Animation des PlayerSprite
        // Das Sprite Sheet besteht aus 3 Spalten und 1 Zeile
        Point playerSheetSize = new Point(3,1);
        // Die Größe jedes Sprite auf dem Sprite Sheet ist 200 (Höhe) und 80 (Breite)
        Point playerSize = new Point (200,80);
        // Die Animation wird mit dem ersten Sprite gestartet
        Point currentSprite = new Point(0, 0);
        // Kollisionspuffer
        int playerCollison = 15;
        // Bewegeungsgeschwindigkeit des Player Sprite
        const float playerSpeed = 6;

        
        bool playerTreffer = false;

        // Gegner Sprite
        // Variable für das Gegner Sprite
        Texture2D enemyTexture;
        // Startposition des Gegner Sprite
        List<Vector2> enemyPos = new List<Vector2>();
        float enemySpawnProbability = 0.02f;
        // Bewegungsgeschwindigkeit des Enemy Sprite
        const int enemySpeed = 5;

        // Random Variable für das Erscheinen der Gegner
        Random random = new Random();

        // Hintergrund Sprite
        Texture2D bgTexture;
        Vector2 bgPos = new Vector2(0, 0);

        // Anpassung der Animationsgeschwindigkeit
        int timeSinceLastFrame = 0;
        int millisecondsPerFrame = 80;

        // Sound
        bool play = false;
        // Hintergrundmusik
        Song hintergrundMusik;
        // Sound-Effekt
        SoundEffect treffer;

        // Gamestates
        // Gamestate Variable mit mit Enumeration
        enum GameState { Start, Spiel, Ende }
        // Erster GameState
        GameState aktuellerGameState = GameState.Start;
        // Gamestate Variablen für die Darstellung der Textur
        // Gamestate Start
        Texture2D gameStateStart;
        // Gamestate Ende
        Texture2D gameStateEnde;
                      

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

            graphics.PreferredBackBufferWidth = 1024;
            graphics.PreferredBackBufferHeight = 768;

            

        }

        /// <summary>
        /// Ermöglicht dem Spiel die Durchführung einer Initialisierung, die es benötigt, bevor es ausgeführt werden kann.
        /// Dort kann es erforderliche Dienste abfragen und nicht mit der Grafik
        /// verbundenen Content laden.  Bei Aufruf von base.Initialize werden alle Komponenten aufgezählt
        /// sowie initialisiert.
        /// </summary>
        protected override void Initialize()
        {
            // TODO: Fügen Sie Ihre Initialisierungslogik hier hinzu

            // Es wird eine Instanz der Position des Player Sprite erstellt.
            playerPos = new Vector2(GraphicsDevice.Viewport.X, GraphicsDevice.Viewport.Y + (GraphicsDevice.Viewport.Height / 2));
           
            base.Initialize();
        }

        /// <summary>
        /// LoadContent wird einmal pro Spiel aufgerufen und ist der Platz, wo
        /// Ihr gesamter Content geladen wird.
        /// </summary>
        protected override void LoadContent()
        {
            // Erstellen Sie einen neuen SpriteBatch, der zum Zeichnen von Texturen verwendet werden kann.
            spriteBatch = new SpriteBatch(GraphicsDevice);

            // TODO: Verwenden Sie this.Content, um Ihren Spiel-Content hier zu laden

            // GameStates werden geladen
            gameStateStart = Content.Load<Texture2D>("GameStateStart");
            gameStateEnde = Content.Load<Texture2D>("GameStateEnde");
            
            // Das Player Sprite wird geladen
            playerTexture = Content.Load<Texture2D>("player");

            // Das Gegner Sprite wird geladen
            enemyTexture = Content.Load<Texture2D>("enemy");

            // Der Hintergrund wird geladen
            bgTexture = Content.Load<Texture2D>("background");

            // Der Soundeffekt wird geladen
            treffer = Content.Load<SoundEffect>("explosion");

            // Die Hintergrundmusik wird geladen
            hintergrundMusik = Content.Load<Song>("megaman");
            MediaPlayer.Play(hintergrundMusik);
        }

        /// <summary>
        /// UnloadContent wird einmal pro Spiel aufgerufen und ist der Ort, wo
        /// Ihr gesamter Content entladen wird.
        /// </summary>
        protected override void UnloadContent()
        {
            // TODO: Entladen Sie jeglichen Nicht-ContentManager-Content hier
        }

        /// <summary>
        /// Ermöglicht dem Spiel die Ausführung der Logik, wie zum Beispiel Aktualisierung der Welt,
        /// Überprüfung auf Kollisionen, Erfassung von Eingaben und Abspielen von Ton.
        /// </summary>
        /// <param name="gameTime">Bietet einen Schnappschuss der Timing-Werte.</param>
        protected override void Update(GameTime gameTime)
        {
            // Ermöglicht ein Beenden des Spiels
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();

            // TODO: Fügen Sie Ihre Aktualisierungslogik hier hinzu

            // GameStates
            
            switch (aktuellerGameState)
            { 
                case GameState.Start:
                    if (GamePad.GetState(PlayerIndex.One).Buttons.Start == ButtonState.Pressed)
                    {
                        aktuellerGameState = GameState.Spiel;
                    }
                    break;
                case GameState.Spiel:
                    if (Keyboard.GetState().IsKeyDown(Keys.Escape))
                    {
                        this.Exit();
                    }                           
                    break;

                case GameState.Ende:
                    if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                    {
                        this.Exit();
                    }
                    break;
            }


            switch (aktuellerGameState)
            {
                case GameState.Start:
                    if (Keyboard.GetState().IsKeyDown(Keys.S))
                    {
                        aktuellerGameState = GameState.Spiel;
                    }
                    break;
                case GameState.Spiel:
                    if (Keyboard.GetState().IsKeyDown(Keys.Escape))
                    {
                        this.Exit();
                    }
                    break;

                case GameState.Ende:
                    if (Keyboard.GetState().IsKeyDown(Keys.Escape))
                    {
                        this.Exit();
                    }
                    break;
            }
 
 

            // Das Player Sprite mit der Tastatur bewegen
            KeyboardState keyboardState = Keyboard.GetState();
            if (keyboardState.IsKeyDown(Keys.Left))
                playerPos.X -= playerSpeed;
            if (keyboardState.IsKeyDown(Keys.Right))
                playerPos.X += playerSpeed;
            if (keyboardState.IsKeyDown(Keys.Up))
                playerPos.Y -= playerSpeed;
            if (keyboardState.IsKeyDown(Keys.Down))
                playerPos.Y += playerSpeed;

            // Mit dem Gamepad bewegen
            GamePadState gamepadState = GamePad.GetState(PlayerIndex.One);
            playerPos.X += playerSpeed * gamepadState.ThumbSticks.Left.X;
            playerPos.Y -= playerSpeed * gamepadState.ThumbSticks.Left.Y;



            // Die Animationsgeschwindigkeit wird angepasst.
            timeSinceLastFrame += gameTime.ElapsedGameTime.Milliseconds;
            if (timeSinceLastFrame > millisecondsPerFrame)
            {
                timeSinceLastFrame -= millisecondsPerFrame;

                // Das Player Sprite Sheet wird animiert.
                ++currentSprite.X;
                if (currentSprite.X >= playerSheetSize.X)
                {
                    currentSprite.X = 0;

                    ++currentSprite.Y;
                    if (currentSprite.Y >= playerSheetSize.Y)
                        currentSprite.Y = 0;
                }
            }

            // Gegner werden gespawned
            if (random.NextDouble() < enemySpawnProbability)
            {
                float x = (float)random.NextDouble() *
                    (Window.ClientBounds.Height - enemyTexture.Height);
                enemyPos.Add(new Vector2(Window.ClientBounds.Width, x));
            }


            // Bounding Box Player
            Rectangle playerBB =
                new Rectangle((int)playerPos.X + playerCollison, (int)playerPos.Y + playerCollison,
                playerSize.X - (playerCollison *2), playerSize.Y - (playerCollison * 2));

            playerTreffer = false;
            for (int i = 0; i < enemyPos.Count; i++)
            {
                // Gegner kommt von Rechts nach Links
                enemyPos[i] =
                    new Vector2(enemyPos[i].X - enemySpeed,
                                enemyPos[i].Y);

                // Bounding Box Gegner
                Rectangle enemyBB =
                    new Rectangle((int)enemyPos[i].X, (int)enemyPos[i].Y,
                    enemyTexture.Width, enemyTexture.Height);

                // Kollisionsabfrage
                if (playerBB.Intersects(enemyBB))
                    playerTreffer = true;

                // Gegner verschwinden wenn ausserhalb des Spielfensters
                if (enemyPos[i].X > Window.ClientBounds.Width)
                {
                    enemyPos.RemoveAt(i);
                                        
                    i--;
                }
            }


            if (playerTreffer)
            {
                if (!play)
                {
                    treffer.Play();
                    play = true;
                    
                    aktuellerGameState = GameState.Ende;   
                                                                                     
                }
                
            }
            else if (play)
            {
                play = false;
            }
          

            base.Update(gameTime);
        }

        /// <summary>
        /// Dies wird aufgerufen, wenn das Spiel selbst zeichnen soll.
        /// </summary>
        /// <param name="gameTime">Bietet einen Schnappschuss der Timing-Werte.</param>
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.Black);

            // TODO: Fügen Sie Ihren Zeichnungscode hier hinzu

            

            switch (aktuellerGameState)
            {
                case GameState.Start:

                    GraphicsDevice.Clear(Color.Black);
                    spriteBatch.Begin();
                    spriteBatch.Draw(gameStateStart, Vector2.Zero, Color.White);
                    spriteBatch.End();

                    break;

                case GameState.Spiel:

                    GraphicsDevice.Clear(Color.Black);
                    spriteBatch.Begin(SpriteSortMode.FrontToBack, BlendState.AlphaBlend);
                    // Die Sprites zeichnen
                    // Den Hintergrund zeichnen
                    spriteBatch.Draw(bgTexture, bgPos, null, Color.White, 0, Vector2.Zero, 1, SpriteEffects.None, 0);
                    // Das Player Sprite zeichnen
                    spriteBatch.Draw(playerTexture, playerPos, new Rectangle(currentSprite.X * playerSize.X, currentSprite.Y * playerSize.Y, playerSize.X, playerSize.Y),
                    Color.White, 0, Vector2.Zero, 1, SpriteEffects.None, 1);
                    // Das Gegner Sprite zeichnen
                    foreach (Vector2 enemyPositions in enemyPos)
                        spriteBatch.Draw(enemyTexture, enemyPositions, null, Color.White, 0, Vector2.Zero, 1, SpriteEffects.None, 1);
                    spriteBatch.End();

                    break;

                case GameState.Ende:

                    GraphicsDevice.Clear(Color.Black);
                    spriteBatch.Begin();
                    spriteBatch.Draw(gameStateEnde, Vector2.Zero, Color.White);
                    spriteBatch.End();

                    break;
            }
                              

            base.Draw(gameTime);
        }
    }
}

2

17.09.2011, 11:27

Naja, in deiner Updatemethode hast du zwar eine switch-case-Anweisung, aber deine Bewegungen, Kollisionen, Gegner spawnen, etc stehen außerhalb vom switch-Block, wodurch sie immer ausgeführt werden. Also auch wenn es ein ganz anderer Gamestate ist. Die einfachste Lösung wäre einfach eine If-Anweisung drum zu machen. Für ein nächstes Spiel wäre es besser das ganze mit einer Klasse GameState zu lösen.

j0ck

Frischling

  • »j0ck« ist der Autor dieses Themas
  • Private Nachricht senden

3

17.09.2011, 11:29

Naja, in deiner Updatemethode hast du zwar eine switch-case-Anweisung, aber deine Bewegungen, Kollisionen, Gegner spawnen, etc stehen außerhalb vom switch-Block, wodurch sie immer ausgeführt werden. Also auch wenn es ein ganz anderer Gamestate ist. Die einfachste Lösung wäre einfach eine If-Anweisung drum zu machen. Für ein nächstes Spiel wäre es besser das ganze mit einer Klasse GameState zu lösen.


Ah ok. Das mit der Switch Anweisung macht Sinn! Danke für den Hinweis...
Wie sollte die If-Anweisung ungefähr aussehen? ;( :)

4

17.09.2011, 12:02

Mach doch einfach ein bool gamerun = false; und wenn du den GameState Spiel aufrufst setzt du gamerun auf true.
Dann noch ne If anweisung: if(gamerun) dann spiel ausführen...

mfg
Tom


Architekt

Community-Fossil

Beiträge: 2 481

Wohnort: Hamburg

Beruf: Student

  • Private Nachricht senden

5

17.09.2011, 12:06

Hab nur fix rüber geschaut, aber müsste ein

C#-Quelltext

1
if (aktuellerGameState != GameState.Spiel) return;

Nach der zweiten switch Klausel nicht reichen?
Der einfachste Weg eine Kopie zu entfernen ist sie zu löschen.
- Stephan Schmidt -

j0ck

Frischling

  • »j0ck« ist der Autor dieses Themas
  • Private Nachricht senden

6

17.09.2011, 12:16

if (aktuellerGameState != GameState.Spiel) return;


Hallo,

erstmal vielen Dank für die schnellen Antworten.

@Architekt: Es hat tatsächlich gereicht! Es funktioniert nun ohne Probleme! Ich danke dir! Auch danke an den anderen!!!!!!!!!
Ist echt ein tolles Forum und ich freue mich, dass Anfängern so schnell geholfen wird!! :thumbup: :thumbsup:

Werbeanzeige