Spiel Architektur verbessern



  • Hallo,

    ich nutze die olcPixelGameEngine und stoße auf folgendes Problem:

    Ich möchte ungern alles in einer Klasse behandeln, sondern eigene Klassen für Input und Screen haben. Diese sind aber jedoch an die Hauptklasse gebunden.

    Die Hauptklasse sieht so aus:

    #pragma once
    #include "Food.h"
    #include "OlcPixelGameEngine.h"
    #include "Snake.h"
    
    class GameLogic : olc::PixelGameEngine
    {
    private:
    	static int GameWidth, GameHeight;
    	static Snake* GameSnake;
    	static Food* GameFood;
    
    	bool OnUserCreate() override;
    	bool OnUserUpdate(float) override;
    
    	void RegisterInput();
    	bool EatFood();
    	void MoveSnake();
    	bool Collision();
    public:
    	GameLogic(int width, int height);
    	//GetterSetter
    	static int GetHeight() { return GameHeight; }
    	static int GetWidth() { return GameWidth; }
    	static Snake GetSnake() { return *GameSnake; }
    	static Food GetFood() { return *GameFood; }
    };
    

    In dieser kann ich die Privaten Funktionen der olc::PixelGameEngine nutzen. Aber ich möchte gern, dass ich im Update Loop eine Funktion einer anderen Klasse aufrufen kann und diese z.B. den Screen bemalt.

    So sähe es ca in der Hauptklasse aus:

    bool OnUserUpdate(float fElapsed){
    FillCircle(...);
    return true;
    }
    

    Nun soll das aber so sein:

    bool OnUserUpdate(float fElapsed){
    Screen.PaintScreen();
    return true;
    }
    

    Und dann in der Screen.h würde dann halt FillCircle() ausgeführt werden. Problem nun ist dabei, wenn ich einen Pointer zur Klasse GameLogic mache und Screen ein Member der Klasse, dann scheint es recursive Mäßig alles zu Includen.
    Also meine Screen.h sah so aus:

    #pragma once
    #include "GameLogic.h"
    class Screen{
    GameLogic* Screen;
    public:
    Screen(GameLogic*);
    void PaintScreen();
    };
    

    Dies Funktionierte leider nicht. Wie kann ich das in eine andere Klasse "outsourcen"?



  • Das war jetzt relativ viel Text, aber wenn ich dich richtig verstanden habe, ist dein Problem soweit nur das Gegenseitige Inkludieren.

    Das ist vom konkreten Problem unabhängig und das löst man mit Vorwärtsdeklarationen.

    In deiner letzten Klasse brauchst du GameLogic.h nicht zu inkludieren, es reicht ein forward include:

    class GameLogic;



  • @Mechanics Ah danke! Wusste bisher nicht dass sowas geht 😃 Dachte man redeklariert das plötzlich xD



  • @Gamestarplayer41 sagte in Spiel Architektur verbessern:

    In dieser kann ich die Privaten Funktionen der olc::PixelGameEngine nutzen.

    Hat zwar wohl mit deinem Problem nichts zu tun, aber private Funktionen kannst du in der Ableitung nicht nutzen.



  • Was hältst du von der Idee, das als Publisher/Subscriber zu lösen? Damit entkoppelst du GameLogic und Screen.



  • Meine Frage wäre eher: Warum muss der Screen was von der Game-Logik wissen? Ich denke das sollte sich vermeiden lassen.



  • Und wenn wir schon dabei sind Fragen zu stellen:
    Warum ist das alles static?



  • @hustbaer da die Funktionen zum zeichnen in GameLogic gebunden sind. Screen soll halt die Logik aus der Klasse rausnehmen und in screen.cpp verlagern. Geht leider nicht wirklich anders



  • Naja, es würde schon anders gehen - siehe z.B. Vorschlag von DocShoe.
    Ist auch etwas irritierend, dass die GameLogic Variable wieder Screen heißt.



  • @Mechanics MHH naja ich baue das ganze jetzt in SFML, da ist das wenigstens nicht son Drama 🙄



  • @Gamestarplayer41
    Verstehe ich das richtig dass die Funktionen zum Zeichnen des Screens in der Klasse GameLogic sind, und die Funktionen für die Game-Logik in der Klasse Screen? Falls ja würde ich mal behaupten dass deine Namensgebung echt suboptimal ist.



  • @hustbaer Also GameLogic erbt von PixelGameEngine, wo die Zeichen funktionen drin sind. Namensgebung ist wirklich doof


  • Mod

    @Gamestarplayer41 sagte in Spiel Architektur verbessern:

    @hustbaer Also GameLogic erbt von PixelGameEngine, wo die Zeichen funktionen drin sind. Namensgebung ist wirklich doof

    Sofern du jetzt nicht noch erzählst, dass EatFood, MoveSnake etc. bei dir auch Namen für Zeichenfunktionen sind, dann ist die Modellierung trotzdem falsch. Vererbung heißt eine "ist ein"-Beziehung. D.h. deine GameLogic ist eine PixelGameEngine. Klingt nicht sinnvoll.

    Geschichte zur Vererbung: https://www.c-plusplus.net/forum/topic/75672/kennt-ihr-schon-die-geschichte-des-mannes-der-regel-35-von-ecp-nicht-beachtet-hat

    Aber auch Komposition ist hier nicht so ganz das Wahre. DocShoe hat bereits wertvolle Stichworte genannte, wie man Systeme entkoppelt.

    Aber allgemein: Bring deine Namensgebung in Ordnung! Du verwirrst nicht nur dich selbst und potentielle Helfer. Wenn du gründlich über Namen von Klassen und Objekten nachdenkst, dann denkst du auch über ihre Aufgabe nach und findest dabei Modellierungsfehler, wenn dir auffällt, dass es für ein Ding keinen klaren, eindeutigen Namen gibt.



  • @SeppJ Stimmt, GameLogic müsste engine heißen oder so ähnlich zumindest. War mir garnicht klar.

    Hast du zufällig einen Link der Gut subscriber und Publisher erklärt?


Log in to reply