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

De_Struktor

unregistriert

1

06.05.2013, 12:35

Foreach-Schleife wird nicht erreicht

Hallo,

Ich hatte das Bomberman-spiel anti objekt orientiert programmiert.

jetzt wollte ich es nochmal schön mit OOP neu schreiben, was auch gut geklappt hat, bis jetzt.

Alle Blöcke und die Spielfigur wurden gezeichnet wie sie es sollten und auch aus der Playerklasse heraus funktioniert die Update funktion, so das sich die Figur auch bewegt.

Aber in der gleichen Update funktion, wo wirklich sonst alles passiert wie es soll, will er die Kollisionen nicht erkennen und ich habe die Kollisionsprüfung vom alten übernommen, also mit der rectangle.intersects methode hat alles wunderbar funktioniert.

nur er kollidiiert nur wenn ich ihm sage:

C#-Quelltext

1
2
3
4
if (player_rect.X <= winWidth - 70)
                    {
                        player_rect.X += 30;
                    }


aber die Foreach schleife wird einfach nicht durchgelaufen habe ich das gefühl, wieso?


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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;

namespace FrostBomber
{
   public class Player : FrostBomber
    {
        private Texture2D player_Text;
        private Rectangle player_rect;
        private bool[] active = new bool[4];
        
        /// Here begins the Constructor which initialize the right values 
        /// for our object
        /// </summary>
        
        public Player(Texture2D text, Rectangle rect) 
        {
            player_Text = text;
            player_rect = rect;
        }
        /// <summary>
        /// Here ends the initialization
        /// </summary>
        public void UpdatePlayer(GameTime gameTime)
        {
            if (Keyboard.GetState().IsKeyUp(Keys.W))
            {
                active[0] = false;
            }
            if (Keyboard.GetState().IsKeyUp(Keys.A))
            {
                active[1] = false;
            }
            if (Keyboard.GetState().IsKeyUp(Keys.S))
            {
                active[2] = false;
            }
            if (Keyboard.GetState().IsKeyUp(Keys.D))
            {
                active[3] = false;
            }

            if (Keyboard.GetState().IsKeyDown(Keys.W))
            {
                if (!active[0])
                {
                    active[0] = true;
                    if (player_rect.Y >= 30)
                    {
                        player_rect.Y -= 30;
                    }
                }
            }
            else if (Keyboard.GetState().IsKeyDown(Keys.A))
            {
                if (!active[1])
                {
                    active[1] = true;
                    player_rect.X -= 30;
                }
            }
            else if (Keyboard.GetState().IsKeyDown(Keys.S))
            {
                if (!active[2])
                {
                    active[2] = true;
                    player_rect.Y += 30;
                }
            }
            else if (Keyboard.GetState().IsKeyDown(Keys.D))
            {
                if (!active[3])
                {
                    active[3] = true;

                    if (player_rect.X <= winWidth - 70)
                    {
                        player_rect.X += 30;
                    }
                     // Der entscheidende Codepfad ist hier, alles was bei den Tasten W-A-S-D passiert, passiert auch wie gewollt, nur das eben nicht
                    foreach (Rectangle rect in Red_Block)
                    {
                        if (player_Rect.Intersects(rect))
                        {
                            player_Rect.X = 30;
                        }   
                    }
                }
            }
        }
        public void Draw(SpriteBatch spritebatch)
        {
            spritebatch.Draw(player_Text, player_rect, 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
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
public class FrostBomber : Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        /// <summary>
        /// Datas for the Player
        /// </summary>
        protected Rectangle player_Rect;
        Player player;
        /// <summary>
        /// Datas for the map
        /// </summary>
        Map Block_map;
       protected Rectangle[] Red_Block = new Rectangle[216];
       protected Rectangle[] Tree_rect = new Rectangle[225];

       protected const int winWidth = 810;
       protected const int winHeight = 630;
        
        public FrostBomber()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
        }

        /// <summary>
        /// Allows the game to perform any initialization it needs to before starting to run.
        /// This is where it can query for any required services and load any non-graphic
        /// related content. Calling base.Initialize will enumerate through any components
        /// and initialize them as well.
        /// </summary>
        protected override void Initialize()
        {
            graphics.PreferredBackBufferWidth = winWidth;
            graphics.PreferredBackBufferHeight = winHeight;
            IsMouseVisible = true;
            graphics.ApplyChanges();
            player = new Player(Content.Load<Texture2D>("playerpic"), player_Rect = new Rectangle(30, 30, 30, 30));
            Block_map = new Map(Content.Load<Texture2D>("Tree_Block"), Content.Load<Texture2D>("red_Block"), Red_Block, Tree_rect);
            base.Initialize();
        }
  
        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);
            Block_map.LoadConstblocks();
            Block_map.LoadBombableBlocks();
        }
        protected override void UnloadContent()
        {
            base.UnloadContent();
        }

        protected override void Update(GameTime gameTime)
        {
            player.UpdatePlayer(gameTime);
            base.Update(gameTime);
        }
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.LightGreen);
            spriteBatch.Begin();
            ///////////////////
            Block_map.Draw(spriteBatch);
            player.Draw(spriteBatch);
            ///////////////////
            spriteBatch.End();
            base.Draw(gameTime);
        }


Ich weiss, es ist etwas nervig den code zu lesen, nur ich habe wirklich überlegt und ausrobiert, nur es ist mir ein rätsel.
»De_Struktor« hat folgendes Bild angehängt:
  • Debug_Photo.PNG

TGGC

1x Rätselkönig

Beiträge: 1 799

Beruf: Software Entwickler

  • Private Nachricht senden

2

06.05.2013, 12:50

Muss der Operator in einem Enum nicht ein bestimmtes Interface haben in der Art IEnumerable? Ansonsten hilft dir sicher der Debugger.

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

3

06.05.2013, 12:51

Guck mal in welchem Codeblock sich die Schleife befindet. Das ganze wird nur ausgeführt, wenn die Taste D gedrückt wird. Wenn das gewollt ist, kannst du gucken ob die Datenstruktur Red_Block überhaupt Elemente enthält. Einfach einen Breakpoint setzen und nachgucken. Wenn Elemente drin sind, dann Step mal weiter und guck ob er die Schleife wirklich überspringt.

edit: Wenn man über eine eigene Klasse iterieren möchte, dann muss diese IEnumerable implementieren. Aber hier in diesem Fall handelt es sich ja um ein Array. Daran liegt es also 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.“

De_Struktor

unregistriert

4

06.05.2013, 12:58

ichbin mir ganz sicher das da elemente drinne sind, denn sonst würden sie nicht gezeichnet werden.

De_Struktor

unregistriert

5

06.05.2013, 12:59

aber ich werden mal den debugger anschmeißen.^^

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

6

06.05.2013, 13:17

Mir fällt da grad noch was anderes auf. Du arbeitest ja mit einem bool Array um zu gucken ob die Tasten nur runtergedrückt werden, dabei aber nicht gedrückt gehalten werden. Doof zu beschreiben aber ich denke du weißt was ich meine. Das kannst du dir noch ein wenig einfacher machen. Ein bisschen Code sagt mehr als 1000 Worte:

C#-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
private KeyboardState currentState;
private KeyboardState lastState;

// Das hier kommt in die Update Methode ganz an den Anfang:
lastState = currentState;
currentState = Keyboard.GetState();

// Hier wird jetzt ein Tastendruck abgefragt:

if( currentState.IsKeyDown(Keys.D) && lastState.IsKeyUp(Keys.D))
{
    // Die Taste D wird in diesem Frame gedrückt, im letzten wurde sie es jedoch noch nicht.
}


Ist meiner Meinung nach viel viel weniger Schreibarbeit. Die Abfrage kannst du dir sogar in eine Methode kapseln:

C#-Quelltext

1
2
3
4
public bool KeyHit(Keys key)
{
    return currentState.IsKeyDown(key) && lastState.IsKeyUp(key);
}


Noch schöner wäre natürlich das alles in eine Klasse zu kapseln. So mache ich das normalerweise, aber wie man das sinnvoll machen kann überlasse ich dir selbst:) Wenn du das so überhaupt benutzen willst. Ist natürlich alles nur ein Vorschlag.



edit:
Ich hab grad auch noch mal genauer auf deinen Code geguckt. Du leitest Frostbomber von Game ab und davon leitest du Player ab. Ein Spieler ist kein Spiel, also sollte man den Spieler nicht davon ableiten. Das ist schon grundlegend völlig falsch, da sind also ganz andere Probleme als nur deine Schleife;)
„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.“

De_Struktor

unregistriert

7

06.05.2013, 14:14

die überlegung hatte ich auch, das die vererbung falsch ist, weiss ich^^ aber ich musste an die Blöcke von frostbomber kommen, damit ich diese schleife bauen kann, aber das mit den anderen Ideen für die Tastendrücke, ist erstmal irrelavant.

nur trotzdem sehe ich keinen logischen fehler da drin ?(

De_Struktor

unregistriert

8

06.05.2013, 14:19

denn das hat beim alten Projekt ja so funktioniert, daher frage ich mich, wenn ich das in die klasse schreibe wo es ja anscheinend alles funktiiniert hat schreibe, dann müsste ja auch die Kollisionsabfrage stattfinden, da tut er aber auf einmal so, als würder da nix mehr stehen???

weshalb, ich rufe seperat alles auf

De_Struktor

unregistriert

9

06.05.2013, 15:16

Jo hat alles geklappt :)

danke trtotzdem schorsch und Tggc

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

10

07.05.2013, 11:27

Wenn du noch schrieben würdest woran es lag;) Und das mit der Vererbung solltest du schon versuchen richtig zu lösen. Du machst das ganze doch weil du OOP lernen willst. Da bringt es dir ja nichts wenn du das ganze direkt falsch lernst. Wenn du in einer Funktion ein Array benötigen würdest, welches außerhalb ist, was würdest du dann in diesem Fall machen? Keine Funktionen benutzen und den Code jedes mal direkt hinschreiben? Oder wie würdest du dafür sorgen, dass die Funktion das jeweilige Array kennen würde?
„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