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

Raidenkk

Treue Seele

  • »Raidenkk« ist der Autor dieses Themas

Beiträge: 151

Wohnort: Bergkamen/Oberaden

Beruf: Multimedia Informatik

  • Private Nachricht senden

1

24.05.2011, 10:09

[C++/SFML] Schuss Realisierung

Hey,
ich wollte aus langeweile mal eine Schusswaffe Pixeln und sie zum Leben bringen.
Das Pixeln der Waffe ist mir gelungen doch jetzt scheitere ich an der Realisierung der Schüsse :/.

Fehler:
Jedesmal wenn ich die Leertaste drücke wird ein Schuss gezeichnet doch sobald ich nochmal die Leertaste drücke, verschwindet der alte Schuss und ein neuer wird Gezeichnet.
Der alte Schuss soll aber Trotzdem auch gezeichnet bleiben.
Ich weis der Speicher wird nicht Freigegeben sobald der Schuss aus dem Bildschierm geht, doch das wird Später noch mit eingebaut.

Code:

Quellcode

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
// #####################################
// Project: Schusswaffe
// Info: Zeichnet eine Schießbare Waffe
// #####################################

#include <SFML\Graphics.hpp>
#include <iostream>

sf::RenderWindow App(sf::VideoMode (800, 600, 32), "Project: Schusswaffe");

// Klasse
class CSchuss
{
    private:

        // MemberVariabeln
        int m_Schaden;
        float m_X;
        float m_Y;
        float m_Geschwindigkeit;

    public:

        // MemberMethoden
        CSchuss (); // Initialisieren (Konstruktor)
        void Gravity (); // Stellt die Gravity ein
        void Zeichnen (); // Zeichnet die Schüsse
};

// Initialisieren
// Aufgabe: Initialisiert die Schüsse
CSchuss::CSchuss ()
{
    m_Schaden = 1;
    m_X = 330;
    m_Y = 213;
    m_Geschwindigkeit = 500;
}

// Zeichnen
// Aufgabe: Zeichnet die Schüsse
void CSchuss::Zeichnen ()
{
    App.Draw(sf::Shape::Rectangle(m_X, m_Y, m_X+5, m_Y+1, sf::Color::Yellow));
}

// Gravity
// Aufgabe: Gravity der Schüsse
void CSchuss::Gravity ()
{
    m_X += m_Geschwindigkeit *App.GetFrameTime ();
}

int main ()
{
    // Daten Laden
    sf::Image Image_Waffe;
    Image_Waffe.LoadFromFile ("gfx/Waffe.png");
    Image_Waffe.CreateMaskFromColor (sf::Color (255, 0, 255));
    sf::Sprite Sprite_Waffe;
    Sprite_Waffe.SetImage (Image_Waffe);

    // Variablen
    CSchuss *pProjectil = NULL;
    int SchussAnzahl = 0;

    // Game Loop
    while (App.IsOpened ())
    {
        App.UseVerticalSync (true);

        sf::Event Event_Pistole;
        while (App.GetEvent(Event_Pistole))
        {
            // Pistole abdrücken
            if ((Event_Pistole.Key.Code == sf::Key::Space) && (App.GetInput().IsKeyDown(sf::Key::Space)))
            {
                SchussAnzahl ++;
                std::cout << SchussAnzahl << std::endl;

                // Speicher Resavieren
                pProjectil = new CSchuss[SchussAnzahl];
            }
        }

        // Pistole Zeichnen
        Sprite_Waffe.SetPosition (300,200);
        App.Draw (Sprite_Waffe);


        for (int i=0; i<SchussAnzahl; i++)
        {
            // Schuss Zeichnen
            pProjectil[i].Zeichnen ();
            // SchussGravity
            pProjectil[i].Gravity ();
        }

        App.Display ();
        App.Clear ();
    }

    return EXIT_SUCCESS;
}


MFG:
Raidenkk/Kevin

Fred

Supermoderator

Beiträge: 2 121

Beruf: Softwareentwickler

  • Private Nachricht senden

2

24.05.2011, 10:28

Du musst alle Schüsse in einen Container oder in ein Array stecken und nicht das Array bei jedem Schuss neu erstellen.
Denn nichts anderes macht:

C-/C++-Quelltext

1
pProjectil = new CSchuss[SchussAnzahl];

Raidenkk

Treue Seele

  • »Raidenkk« ist der Autor dieses Themas

Beiträge: 151

Wohnort: Bergkamen/Oberaden

Beruf: Multimedia Informatik

  • Private Nachricht senden

3

24.05.2011, 10:50

Hmm ich weis leider nicht was ein Container ist im Buch habe ich jetzt auch nix gefunden darüber :/

Fred

Supermoderator

Beiträge: 2 121

Beruf: Softwareentwickler

  • Private Nachricht senden

4

24.05.2011, 11:15

Naja entweder du nimmst ein Array - da ist alerdings die größe fest vorgeben oder du greifst auf einen STL-Container, wie std::vector, std::list, std::map oder so zurück.

Architekt

Community-Fossil

Beiträge: 2 481

Wohnort: Hamburg

Beruf: Student

  • Private Nachricht senden

5

24.05.2011, 11:15

Der einfachste Weg eine Kopie zu entfernen ist sie zu löschen.
- Stephan Schmidt -

NachoMan

Community-Fossil

Beiträge: 3 885

Wohnort: Berlin

Beruf: (Nachhilfe)Lehrer (Mathematik, C++, Java, C#)

  • Private Nachricht senden

6

24.05.2011, 11:24

Ein Container ist ein genormtes Objekt, in das man alles mögliche packen kann. :D
Kapitel 9(Die STL) in C++ für Spieleprogrammierer. Google würde auch helfen. "C++ container"
Ich sagte dir schon ein paar mal, sei nicht so ungeduldig^^

Du könntest auch ein dynamisches Array nehmen. Das ist aber nicht gerade einfach...
Hier eine erklärung wie es ungefähr abläuft:
Anfangst hast du einen Zeiger auf CSchuss und die Größe.
Wenn ein neuer Schuss erstellt wird inkrementierst du die größe, erstellst einen temporären Zeiger auf CSchuss und erzeugst ein Array mit der neuen größe. Nun kopierst du das alte Array in das neue und erzeugst noch den letzten Schuss neu(setzt ihn an die Position des neuen Schusses usw.), gibst das Alte frei und speicherst den neuen Zeiger im alten. Dann musst du das Array noch jedes Frame mindestens einmal durchlaufen um alle Elemente zu Zeichnen und Aktualisieren. Wird dabei ein Schuss zerstört, weil es getroffen hat oder so, musst du das gleiche nochmal machen. Größe des dekrementieren, neues Array anfordern, kopieren(wobei du diesmal das eine, das du löschen willst auslässt), altes freigeben, Zeiger kopieren und fertig.
Am Ende des Spiels musst du das Array auch noch freigeben.(Das solltest du aber unbedingt mit delete[] machen)

Das ist viel zu viel Arbeit und es gibt unter Umständen noch weitere Dinge zu beachten.. Am besten du liest einfach im Buch weiter und benutzt die STL. Das ist dann viel einfacher, sicherer und schneller(weil die std::vector Speicher vorreserviert und nicht so oft neu reservieren und kopieren muss)^^
"Der erste Trunk aus dem Becher der Erkenntnis macht einem zum Atheist, doch auf dem Grund des Bechers wartet Gott." - Werner Heisenberg
Biete Privatunterricht in Berlin und Online.
Kommt jemand mit Nach oMan?

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »NachoMan« (24.05.2011, 11:43)


Raidenkk

Treue Seele

  • »Raidenkk« ist der Autor dieses Themas

Beiträge: 151

Wohnort: Bergkamen/Oberaden

Beruf: Multimedia Informatik

  • Private Nachricht senden

7

24.05.2011, 11:38

Okay :) naja ich war wohl wirklich mal wider ungeduldig... danke Nacho ;)

8

26.05.2011, 19:18

Also soweit ich sein Problem gelesen habe, wäre eine list viel effektiver und schneller als ein vector. Vector ist nur dann gut, wenn man von einer X beliebigen Stelle im Array das Item abfragen möchte. Eine List wiederum ist gut, wenn man oft einfügen (an verschiedenen Stellen) einfügen muss. Also für deinen Fall würde ich eine List absolut bevorzugen.

9

26.05.2011, 21:08

std::deque wär auch noch ne Möglichkeit, denn einfügen musst du ja eher weniger bei Schüssen. Nur am Ende weitere Elemente hinzufügen und welche löschen.

NachoMan

Community-Fossil

Beiträge: 3 885

Wohnort: Berlin

Beruf: (Nachhilfe)Lehrer (Mathematik, C++, Java, C#)

  • Private Nachricht senden

10

26.05.2011, 21:20

Man löscht aber oft Elemente in der Mitte der Liste ;) Das ist hier das eigentliche problem. Einfügen am ende eines std::vectors ist noch recht schnell weil Speicher vorreserviert wird.
"Der erste Trunk aus dem Becher der Erkenntnis macht einem zum Atheist, doch auf dem Grund des Bechers wartet Gott." - Werner Heisenberg
Biete Privatunterricht in Berlin und Online.
Kommt jemand mit Nach oMan?

Werbeanzeige