Laden...

XNA Spiel friert nach dem ersten durchlauf einer while-schleife ein

Erstellt von Qweide vor 8 Jahren Letzter Beitrag vor 8 Jahren 2.573 Views
Q
Qweide Themenstarter:in
8 Beiträge seit 2015
vor 8 Jahren
XNA Spiel friert nach dem ersten durchlauf einer while-schleife ein

hi,
ich habe etwas mit xna programmiert. nach aufruf einer funktion wird ein neues objekt einer klasse erzeugt. hierbei handelt es sich um eine kampfszene. ich habe die boolsche variable "IsFighting", um zu prüfen, ob der kampf noch abgewickelt wird oder nicht.
nachdem das objekt der klasse für den kampf erzeugt wurde, geht das programm in folgende schleife:

while(fight_.IsFighting)
            {
                fight_.Update();
                fight_.Draw(spriteBatch);
            }

zu testzwecken soll in der update() methode nur ein tastendruck abgefragt werden, der den kampf unterbricht. in der draw() methode wird nur die textur des gegners gezechnet.

public void Draw(SpriteBatch spriteBatch)
        {
            spriteBatch.Begin();
            spriteBatch.Draw(enemyTexture, new Rectangle((int)enemyLocation.X, (int)enemyLocation.Y, enemyTexture.Width, enemyTexture.Height), Color.White);
            spriteBatch.End();
        }

ich habe das programm an vielen punkten anhalten lassen und bin zu der erkenntnis gekommen, dass das programm nach dem ersten schleifendurchlauf einfriert. jedoch habe ich keine ahnung woran das liegen könnte.

5.658 Beiträge seit 2006
vor 8 Jahren

Hi Qweide,

so wird das nichts, du mußt die Game.Draw-Methode überschreiben.

Ehe du anfängst, dich intensiver mit einer seit Jahren veralteten Technologie zu beschäftigen, schau dir mal die anderen Optionen an: [FAQ] Wie finde ich den Einstieg in die 3D-Programmierung mit C#?

Christian

Weeks of programming can save you hours of planning

Q
Qweide Themenstarter:in
8 Beiträge seit 2015
vor 8 Jahren

hallo,

danke für deine antwort und deinen hinweis bezüglich der veralteten technologie. ich werde es mir zu herzen nehmen, aber trotzdem noch ein wenig mit xna herumspielen.

bedeutet das, dass ich nach einer abfrage von der game.draw methode aus die draw methode aus der kampfklasse ausführen könnte?
das erscheint mir jedoch nicht unbedingt sinnvoll, da ich das kampf-objekt in der klasse der umgebung, in der sich der spieler befindet, erzeuge. das alles anzupassen würde großen aufwand bedeuten. außerdem kann ich mir vorstellen, dass mein code danach nicht mehr so übersichtlich ist.

5.658 Beiträge seit 2006
vor 8 Jahren

Du brauchst dir doch bloß mal die einführenden Tutorials in der Doku anzuschauen, um herauszufinden, wie ein XNA-Game aufgebaut ist, wie man seine Assets organisiert und Frames rendert.

Ob das Refactorieren deines Codes viel Aufwand bedeutet, und ob der Code hinterher weniger übersichtlicher ist als vorher, liegt doch an deinen Programmierkenntnissen und -fähigkeiten. Daher kann ich den Einwand nicht ganz nachvollziehen.

Christian

Weeks of programming can save you hours of planning

Q
Qweide Themenstarter:in
8 Beiträge seit 2015
vor 8 Jahren

wenn du lust und zeit dafür hast, kann ich dir auch meinen code geben, damit du besser nachvollziehen kannst, was ich meine.

die game.draw methode ist doch aber protected override void. kann ich die überhaupt überschrieben? sorry, wenn ich jetz wie ein newb klinge, aber ich habe noch nie methoden überschrieben etc.

T
2.224 Beiträge seit 2008
vor 8 Jahren

Wenn du noch nie Methoden überschrieben hast, dann fehlen dir für XNA und auch zukünftige C# Projekte wichtige Grundlagen.
Das überschreiben von Methoden gehört zur Vererbung und ist somit Fundamental.
Du solltest dich vorher mehr mit C# befassen und erst einmal die Grundlagen festigen bevor du dich an Spiele ran machst.
Gerade mit C# und XNA wirst du solche Grundlagen schon für die Basis Architektur deines Spiels benötigen um keinen Code doppelt zu schreiben bzw. wie hier sogar gar nicht.

Mein Tipp:
Lern die Grundlagen und dann stell dein Game z.B. auf SFML um.
Die haben auch ein C# Binding und dein Game läuft dann auch mit Mono auf Linux und MACs 😄

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

Q
Qweide Themenstarter:in
8 Beiträge seit 2015
vor 8 Jahren

Wenn du noch nie Methoden überschrieben hast, dann fehlen dir für XNA und auch zukünftige C# Projekte wichtige Grundlagen.
Das überschreiben von Methoden gehört zur Vererbung und ist somit Fundamental.
Du solltest dich vorher mehr mit C# befassen und erst einmal die Grundlagen festigen bevor du dich an Spiele ran machst.
Gerade mit C# und XNA wirst du solche Grundlagen schon für die Basis Architektur deines Spiels benötigen um keinen Code doppelt zu schreiben bzw. wie hier sogar gar nicht.

Mein Tipp:
Lern die Grundlagen und dann stell dein Game z.B. auf SFML um.
Die haben auch ein C# Binding und dein Game läuft dann auch mit Mono auf Linux und MACs 😄

T-Virus

naja, die grundlagen kenne ich bereits. ich weiß auch, wie objektorientierte programmierung funktioniert. ich kannte nur eben diese eine sache nicht, weil ich mich damit noch nie beschäftigt habe. im prinzip kenne ich auch den grundgedanken von vererbung und so, aber hab das in der praxis halt noch nie gemacht


EDIT:

ich hab jetzt meine kampf klasse von der Microsoft.XNA.Framework.Game KLasse abegeleitet, so wie es die Game1-klasse auch ist. Danach habe ich mir ebenfalls wie in der Game1 Klasse Draw und Update mit "protected override void ..." überschrieben. In der Klasse, die ein Objekt derKampfklasse erzeugt, habe ich jetzt immernoch die while schleife, die diesmal jedoch die fight_.DoFightProgress Funktion aufruft, welche wiederum innerhalb der Klasse dann Update und Draw aufruft, bis IsFighting dann irgendwann auf false gesetzt wird. Jedoch friert das Programm an dieser Stelle nach wie vor ein.
Habe ich einen grundlegenden Fehler gemacht oder einfach nur etwas übersehen?

Hier noch ein paar zeilen Code:

private void fight(string enemy, int enemy_count, SpriteBatch spriteBatch, ContentManager Content, GameTime gameTime)
        {
            fight_ = new Fight(enemy, enemy_count, Content, spriteBatch);
            while(fight_.IsFighting)
            {
                fight_.DoFightProgress(gameTime);
            }
        }

diese methode erzeugt das objekt der fight-klasse und führt daraufhin die schleife aus.

public class Fight : Microsoft.Xna.Framework.Game
    {
        #region fields
        public bool IsFighting { get; set; }
        SpriteBatch spriteBatch;
        Texture2D enemyTexture;
        Vector2 enemyLocation;

        private string enemyName;
        private int enemyCount;
        #endregion

        #region constructor
        public Fight(string enemy, int enemycount, ContentManager Content, SpriteBatch spritebatch)
        {
            IsFighting = true;    //gibt an, ob der kampf läuft
            spriteBatch = spritebatch;  //übergibt spritebatch
            enemyName = enemy;
            enemyCount = enemycount;
            enemyLocation.X = 100;      //position der textur
            enemyLocation.Y = 100;
            Load(enemyName, enemyCount, Content);   //ruft load funktion auf
        }
        #endregion

        #region private methods
        private void Load(string enemName, int enemCount, ContentManager Content)   //lädt textur des übergebenen gegners
        {
            switch(enemName)
            {
                case "ork": enemyTexture = Content.Load<Texture2D>("ork"); break;
            }
        }
        #endregion

        #region public methods
        public void DoFightProgress(GameTime gameTime)             //methode, die von außen verwendet wird, um update und draw aufzurufen
        {
            Update(gameTime);
            Draw(gameTime);
        }

        protected override void Update(GameTime gameTime)
        {
            
            if (Keyboard.GetState().IsKeyDown(Keys.F1))             //prüft, ob F1gedrückt wurde
            {
                IsFighting = false;                                 //wenn ja, dann unterbreche kampf
            }
            base.Update(gameTime);
        }
        protected override void Draw(GameTime gameTime)
        {
            spriteBatch.Begin();                                    //spritebatch, der vorerst nur den gegner zeichnet
            spriteBatch.Draw(enemyTexture, new Rectangle((int)enemyLocation.X, (int)enemyLocation.Y, enemyTexture.Width, enemyTexture.Height), Color.White);
            spriteBatch.End();
            base.Draw(gameTime);
        }
        #endregion
    }

hier wäre dann noch die ganze fight klasse. hab ein paar sachen kommentiert, damit man sich schneller rein findet, aber ich denke, so schwer kommt man da nicht rein.

T
2.224 Beiträge seit 2008
vor 8 Jahren

Das Problem ist deine Schleife.
Diese muss raus.

Es sollte im Spiel nur die Spielschleife und ggf. Schleifen zur Kollissionsprüfung geben.
Weitere Schleifen, vor allem in der eigentlichen Spiellogik, sorgen nur für solche hänger.

Damit dein Spiel flüssig läuft, solltest du mehr Zeitbasiert denken und programmieren.
Bestimmte Aktionen müssen über die Spielzeit getimet werden.
So kann dein Spiel auch die Aktionen rendern.

Du solltest dich mit dem Thema Spieleprogrammierung noch etwas intensiver befassen.
Kauf dir am besten ein Buch zu XNA und eins generell zur Spieleprogrammierung.

Ich habe folgendes da heim:
Amazon - Spieleprogrammierung mit dem XNA Framework: Entwickeln für PC und Xbox

Kann es dir als Anfänger empfehlen, da dies enfach erklärt und auch gut veranschaulicht wird.

Nachtrag:
Deinen Code solltest du auch überarbeiten.
Deine "fight" Methode solltest du an die Namensgebung von C# anpassen und groß schreiben.
Deine abgeleitet Klasse sollte nicht Fight heißen, sondern FightGame da du diese von der Game Klasse ableitest.

Ebenfalls solltest du in der Load Methode keinen Switch auf deinen String verwenden.
Für einen Feind Arten wäre z.B. eine Enemy Enum besser.
Ebenfalls solltest du deine "fields" auch wirklich zu Feldern bzw. Properties machen.
Wenn die deinen Texten etc. sauber verpacken willst, dann schieb diese in eine eigene Klasse.
Sonst blähst du deinen Code enorm auf und machst ihn auf lange Sicht sehr unleserlich da Code deiner Figuren in der Game Klasse liegen.

Nur als kleine Tipps.

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

5.658 Beiträge seit 2006
vor 8 Jahren

Ein Buch zu einer veralteten Technologie zu kaufen, würde ich jetzt vielleicht nicht unbedingt empfehlen. Aber sich mal die einführenden Tutorials zu XNA anzuschauen, kann man eigentlich erwarten. Denn da wird ja erklärt, wie es funktioniert, und gezeigt, wie man es richtig umsetzt. Abgesehen davon, geht es hier wohl eher um die Grundlagen von C#. Daß ein while-Schleife den Programmablauf unterbricht, solange sie läuft, und die Game-Logik währenddessen nicht mehr aktualisiert werden kann, sollte eigentlich klar sein.

Christian

Weeks of programming can save you hours of planning