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

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

31

01.05.2013, 21:51

Ich rede dabei eigentlich nicht von einem Menü, sondern von Instanzen generell. Ist ja nicht das erste Mal, dass Du irgendwo eine bestimmte Variable brauchst und Dir einfach eine neue Instanz erstellt, was natürlich dann nicht das tun kann, was es soll. Schnapp Dir Dein Buch und lies das Kapitel nochmal.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

TigerClaw25

unregistriert

32

01.05.2013, 22:26

Da hast du Recht. Aber was z.B. die Energie des Spielers angeht, habe ich das meiner Meinung nach so gemacht, wie im Buch oft beschrieben. Eine Variable für Energie und zwei FUnktionen zum Setzen und Übergeben der Variable, da ich direkt nicht zugreifen kann (private!).


EDIT: Habe jetzt mal die Zeit genutzt und statt einem Menü, das ich ala StateMachine nicht hinbekomme, meine Gegner programmiert.

Also Übung habe ich meinem Gegner eine Rechteckige Flugbahn gegönnt ...

C-/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
// Update
//
// Aufgabe: Spieler updaten
//
void CEnemy::Update ()
{   
    // Rechteckige Bewegung des Gegners
    MoveEnemyRectangle ();

    // Prüfen, ob geschossen wurde
    ProcessShooting ();

    // Rechteckige Bewegung des Gegners
    RectEnemyRectangle ();

    // Gegnerschuss
    EnemyShot();
    
} // Update

// ProcessShooting
//
// Aufgabe: Waffe abfeuern
//
void CEnemy::MoveEnemyRectangle ()
{
    // Nach links?
    if (m_right)
    {
        m_fXPos += 300.0f * g_pTimer->GetElapsed ();
        m_fAnimPhase += 20.0f * g_pTimer->GetElapsed ();
    }
    // Nach rechts?
    else if (m_left)
    {   
        m_fXPos -= 300.0f * g_pTimer->GetElapsed ();
        m_fAnimPhase -= 20.0f * g_pTimer->GetElapsed ();
    }

    // Nach oben?
    else if (m_up)
    {
        m_fYPos -= 150.0f * g_pTimer->GetElapsed ();
        m_fAnimPhase -= 20.0f * g_pTimer->GetElapsed ();
    }
    // Nach unten?
    else if (m_down)
    {   
        m_fYPos += 150.0f * g_pTimer->GetElapsed ();
        m_fAnimPhase += 20.0f * g_pTimer->GetElapsed ();
    }
    
    else
    {
        // Animation zurück zum Ausgangspunkt (Mitte entspricht 5 Bild!)
        if (m_fAnimPhase > 5.0f)
            m_fAnimPhase -= 20.0f * g_pTimer->GetElapsed ();
        if (m_fAnimPhase < 5.0f)
            m_fAnimPhase += 20.0f * g_pTimer->GetElapsed ();
    }

        m_Rect.x = static_cast<int>(m_fXPos);
        m_Rect.y = static_cast<int>(m_fYPos);
} // ProcessShooting

// ProcessShooting
//
// Aufgabe: Waffe abfeuern
//
void CEnemy::RectEnemyRectangle ()
{
    // Bildschirmrand als Grenze
    if (m_fXPos > 600.0f)
        {
            m_fXPos = 600.0f;
            m_right = false;
            m_up = true;
        }

    else if (m_fXPos < 100.0f)
    {
            m_fXPos = 100.0f;
            m_left = false;
            m_down = true;
    }

    else if (m_fYPos > 300.0f)
        {
            m_fYPos = 300.0f;
            m_down = false;
            m_right = true;
        }

    else if (m_fYPos < 0.0f)
    {
            m_fYPos = 0.0f;
            m_up = false;
            m_left = true;
    }

    // Animationsphase prüfen
    if (m_fAnimPhase < 0.0f)
        m_fAnimPhase = 0.0f;
    else if (m_fAnimPhase > 10.0f)
        m_fAnimPhase = 10.0f;
} // ProcessShooting


Könnte man auch mit einem Switch Block lösen. Jetzt stellt sich die Frage, wie ich am besten mehrere Gegner, die alle unterschiedliche Bahnen fliegen und in unterschiedlichen Abständen kommen, am besten manage.

Derzeit habe ich einen Allgemeine Spieletimer und setze jeden neuen Gegner nach einer bestimmten Zeit ins Spiel.

Gesamttimer = 0;

if Gesamttimer >=20 Sekunden, dann Asteroiden nicht mehr spawn.

if (Gesamttimer >=20) ->SpawnEnemy

So habe ich es momentan gelöst. Bei einer Vielzahl an Gegner hätte ich aber jede Menge ifelse Bedingungen .. :(

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »TigerClaw25« (02.05.2013, 11:30)


Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

33

02.05.2013, 19:06

Ich mache dir einen Vorschlag. Nimm dein Buch und schlag Kapitel1 auf. Jetzt machst du alle Übungsaufgaben. Du machst sie selber und versuchst sie erst mal ohne Hilfe zu lösen. Und du machst sie wirklich und überlegst dir nicht nur was man theoretisch machen sollte. Wirklich lösen. Wenn du eine Aufgabe nicht lösen kannst liess dir das Kapitel dazu noch mal durch. Das machst du mit jedem Kapitel. Dann sollten die Grundlagen eigentlich gefestigt sein. Bei dir merkt man ganz stark, dass du das Buch zu schnell durchgegangen bist. Viele Sachen sind nicht verinnerlicht und das muss jetzt passieren. Dann sollten sich die Probleme die du zur Zeit hier schilderst nicht mehr vorhanden sein.
„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.“

TigerClaw25

unregistriert

34

03.05.2013, 14:02

Das mache ich so oder so. Es wurde aber auch erwähnt, dass es nicht immer auf den Programmierstil ankommt. Und ich mache Dinge auch selbst.

Beispielsweise wollte ich mehrere Waffensysteme und bin dann nach kurzer Überlegung zu dieser einfachen Lösung gekommen:

C-/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
void CPlayer::ProcessShooting ()
{
    if (g_pFramework->KeyDown (SDLK_s))
    {
        Weapon = 1;
    }
    else if (g_pFramework->KeyDown (SDLK_d))
    {
        Weapon = 2;
    }

    switch (Weapon)
    {
    case 1:
        {
            // Wurde Space gedrückt und darf geschossen werden?
            if (g_pFramework->KeyDown (SDLK_SPACE) && m_bShotLock == false)
            {
                // Neuen Schuss erzeugen und initialisieren
                CShot Shot;

                Shot.Init (m_pSpriteShot, m_fXPos, m_fYPos);

                // Schuss in Liste einfügen
                m_ShotList.push_back (Shot);

                // Schießen erst wieder erlaubt, wenn Space losgelassen
                m_bShotLock = true;

            }
        } break;

    case 2:
        {   
            // Wurde Space gedrückt und darf geschossen werden?
            if (g_pFramework->KeyDown (SDLK_SPACE) && m_bShotLock == false)
            {
                // Neuen Schuss erzeugen und initialisieren
                CShot Shot;

                Shot.Init (m_pSpriteShot2, m_fXPos, m_fYPos);

                // Schuss in Liste einfügen
                m_ShotList.push_back (Shot);

                // Schießen erst wieder erlaubt, wenn Space losgelassen
                m_bShotLock = true;
            }
        } break;
}

    // Ist die Leertaste nicht mehr gedrückt, schießen wieder erlaubt (Autofire aktivieren/deaktivieren)
    if (g_pFramework->KeyDown (SDLK_SPACE) == false)
        m_bShotLock = false;

} // ProcessShooting


Sicherlich nicht die beste Lösung, aber der SPieler sieht den Code dahinter nicht und später werde ich sicherlich bei größeren Projekten an die Grenzen stoßen.

Aber für den Anfang reicht es doch aus ...

patrick246

Treue Seele

Beiträge: 328

Wohnort: nahe Heilbronn/BW

Beruf: TG Profil Informatik-Schüler

  • Private Nachricht senden

35

03.05.2013, 14:10

Da gebe ich dir einen Tipp: switch-Anweisungen können oft durch std::map ersetzt werden

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

36

03.05.2013, 15:06

Eigene Lösungen sind super. Aber warst nicht du es, der von "Profis" lernen wollte damit er sieht wie es richtig geht. Von wegen man muss sich nicht selbst die Sehnenscheidenentzündung holen sondern soll erst gucken wie es geht? Möglicherweise verwechsel ich das auch grad. Aber viel mehr haben wir ja nicht gemacht. Und mein letzter Vorschlag war einfach deshalb, da man bei dir krasse Lücken sieht. Wir können dir nur Vorschläge machen. Was du daraus machst ist deine 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.“

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

37

03.05.2013, 15:08

Auch so lässt sich der Code da oben massiv kürzen und vor allem würde ich ihn umschreiben... init ist für die Tonne!

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void CPlayer::ProcessShooting ()
{
    if ( !g_pFramework->KeyDown (SDLK_SPACE) )
    {
        m_bShotLock = false;
        return;
    }

    if ( m_bShotLock )
        return;

    if (g_pFramework->KeyDown (SDLK_s))
        m_ShotList.push_back ( Shot( pSpriteShot, m_fXPos, m_fYPos));
    else if (g_pFramework->KeyDown (SDLK_d))
        m_ShotList.push_back ( Shot( pSpriteShot2, m_fXPos, m_fYPos));
    else
        return;

    m_bShotLock = true;
} // ProcessShooting

Schon gleich viel übersichtlicher. Mit vorgeschlagener Map und einer Iteration wäre es noch etwas kürzer.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von »BlueCobold« (03.05.2013, 15:22)


TigerClaw25

unregistriert

38

03.05.2013, 16:22

Ich habe schon gemerkt, dass die Loesungen im Buch nicht immer optimal sind. Die Init funktion finde ich auch überflüssig, da das Ganze auch kin den Konstruktor gepackt werden kann. Kurze Anmerkung noch zum Code. Hast du da nicht die Instanz vergessen? Bin gerade unterwegs, aber wenn di Shot in eine Liste schiebst, wo wird dann vorher die Instanz Shot erzeugt? ;-)

Ansonsten ist die Loesung wesentlichkerr. Ich glaube, dass es fuer mich als anfaenger erst problematisch wird, wenn je nach Waffen und Gegner unterschiedlich starke gegner und unterschiedich starke Waffen zum einsatz komm. Da wird sich dann zege, dass ohne nachdenken alles scel durcheinander kommen wird.


was ich bei deiner Loesung nur nicht verstehe, muss dann nicht immer die Taste s gedrueckt sein?

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »TigerClaw25« (03.05.2013, 16:35)


BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

39

03.05.2013, 16:25

Die Instanz wird direkt als Parameter erzeugt. Steht doch auch da. Das funktioniert natürlich nur mit einem passenden Konstruktor. Dass Dir das nicht klar ist, ist nicht ungewöhnlich, wenn man Dein doch sehr lückenhaftes Wissen um Variablen und Instanzen bedenkt...
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

TigerClaw25

unregistriert

40

03.05.2013, 16:36

Stimmt, war ein extra kapitelchen im Buch ;-) ist aber uebersichtlicher.

Werbeanzeige