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

BLU3 L30PARD

Treue Seele

  • »BLU3 L30PARD« ist der Autor dieses Themas

Beiträge: 336

Wohnort: Hoch oben im Norden Schleswig Holsteins

Beruf: Schüler

  • Private Nachricht senden

1

30.12.2010, 12:45

Schuss / Projekil Klasse - Brauche Hilfe!

Moin!

Ich habe bin gerade dabei, mir ein kleines Spiel zusammenzubasteln (was ganz simples).
Das Prinzip ist dasselbe, wie beim Aliens / Space Invaders Spiel. Gegner kommen von oben und
man selbst steht unten, kann sich nur nach links & rechts bewegen und soll die Feinde abschießen.
Da wären wir dann auch schon beim Problem: bei den Projektilen.
Ich arbeite mit SFML.NET 1.6 und programmiere dann das Spiel in C#.
Meine bisherige Shot Klasse sieht so aus:

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
using System;
using SFML.Graphics;

namespace sfml_ZombieInvasion
{
    public class Shot : Sprite
    {
        public float startPosX;
        public float startPosY;
        public int speed;
        Image image;

        public Shot()
        {
            image = new Image("Data/Textures/Bullet.png");
            this.Image = image;
            speed = -2;
            startPosX = this.Position.X;
            startPosY = this.Position.Y;
        }

        private void Move(float OffsetX, float OffsetY)
        {
            this.Position = new Vector2(this.Position.X + OffsetX, this.Position.Y + OffsetY);
        }

        public void update(RenderWindow targetWindow)
        {
            this.Move(0, speed);
            targetWindow.Draw(this);
        }
    }
}

Bei einem normalen Schuss sollte es ja so ablaufen:
Man drückt z.B. die linke Maustaste und eine Patrone kommt aus der Waffe
und fliegt weiter. Allerdings ist das nicht so einfach, wie ich dachte :(
In der Main Klasse steht bei mir folgendes:

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
using System;
using SFML.Window;
using SFML.Graphics;

namespace sfml_ZombieInvasion
{
    class Game
    {
        Game()
        {
            RenderWindow App = new RenderWindow(new VideoMode(800, 600, 32), "Zombie Invasion");
            App.Closed += new EventHandler(OnClose);

            Image img_background = new Image("Data/Textures/Background.png");
            Sprite background = new Sprite();
            background.Image = img_background;

            Player player = new Player();
            player.sprite.Position = new Vector2((App.Width / 2) - player.sprite.Width,
                                                App.Height - player.sprite.Height);

            bool GameIsRunning = true;
            while (App.IsOpened())
            {
                if (GameIsRunning)
                {
                    // Moving the Player
                    if (App.Input.IsKeyDown(KeyCode.A) || App.Input.IsKeyDown(KeyCode.Left))
                    {
                        player.Move(-200 * App.GetFrameTime(), 0);
                        player.sprite.Image = player.image02;
                    }
                    if (App.Input.IsKeyDown(KeyCode.D) || App.Input.IsKeyDown(KeyCode.Right))
                    {
                        player.Move(200 * App.GetFrameTime(), 0);
                        player.sprite.Image = player.image03;
                    }
                    if (App.Input.IsKeyDown(KeyCode.Up))
                    {
                        player.sprite.Image = player.image01;
                    }

                    // Is the Player out of the Window?
                    if (player.sprite.Position.X > App.Width + player.sprite.Width)
                    {
                        player.sprite.Position = new Vector2((App.Width - App.Width) - player.sprite.Width, player.sprite.Position.Y);
                    }
                    if (player.sprite.Position.X < (App.Width - App.Width) - player.sprite.Width)
                    {
                        player.sprite.Position = new Vector2(App.Width + player.sprite.Width, player.sprite.Position.Y);
                    }
                    App.DispatchEvents();
                    App.Clear();
                    App.Draw(background);
                    player.Draw(App);
                    App.Display();
                }
            }
        }
    }
}

Man muss sich jetzt vorstellen, dass shot die Position ((App.Width / 2) - player.sprite.Width, (App.Height / 2) - player.sprite.Height) hat.
(Die Klasse Player ist kein Sprite, sondern hat eins)

Naja, aber in diesem Fall habe ich das Problem, dass immer wenn ich die Space Taste drücke, ein neues Projektil erstellt wird,
das sich dann noch oben bewegt, aber eben nur solange ich die Taste drücke. So wird es garnicht erst angezeigt :(
Aber ich kann das ja nicht anders machen, da ich ja, wenn ich das so mache:

C#-Quelltext

1
2
Shot shot = new Shot();
[Main Loop]

nicht mehrer Projektile hintereinander erzeugen kann, sondern immer nur das gleiche neu geschossen wird.

Weiß jemand, man das machen könnte, dass das Projektil seinen Weg alleine Fortsetzt, sodass ich auch mehrere Schüsse
hintereinander abgeben kann?

Fred

Supermoderator

Beiträge: 2 121

Beruf: Softwareentwickler

  • Private Nachricht senden

2

30.12.2010, 12:58

du solltest alle Objekte, die auf der Map zu sehen sind aktualisieren(also eine update-Funktion oder so aufrufen). Dazu zählen dann natürlich auch Geschosse. Wenn du das machst, dann kannst du in der Update-Funktion die Bewegung des Geschosses realisieren und schon wird das Geschoss auch bewegt, wenn man nicht mehr die Taste drückt. Und so lassen sich dann natürlich auch mehrere Schüsse erstellen.

EDIT: Um das ganze noch etwas zu präzisieren. Du brauchst praktisch einen Objekt-Manager, der alle Objekte in der Spielwelt verwaltet(natürlich kannst du auch nur einen Geschoss-Manager implementieren, aber wenn du später andere Objekte haben willst, dann brauchst du das bei denen ja auch. Ganz simpel speichert der Objekt-Manager einfach alle Objekte in einer Liste und ruft dann für alle Objekte in dieser Liste, in jedem Frame einmal die "update"-Funktion auf. Dort wird dann das Objekt bewegt oder was auch immer. Natürlich muss der Objektmanager auch Funktionen mitbringen, um Objekte hinzuzufügen und zu löschen. Wenn du dann ein Geschoss erstellst, dann wird das dem Objektmanager übergeben, kommt in die Liste, wird bewegt und irgendwann eben wieder zerstört.

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Fred« (30.12.2010, 13:03)


NachoMan

Community-Fossil

Beiträge: 3 885

Wohnort: Berlin

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

  • Private Nachricht senden

3

30.12.2010, 13:02

schreib dir ne klasse für die schüsse, die ein array oder ne liste mit den schüssen enthält und diese updatet, löscht und rendert. ähnliches für den spieler, der sollte bei gutem code nur eine updatefunktion haben und seine bewegung selbst aktualisieren.(auch bei kleinen programmen)
ausserdem gehört das image NICHT in die schussklasse! da die schüsse alle das selbe image verwenden reicht es das image zentral zu laden.
"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?

BLU3 L30PARD

Treue Seele

  • »BLU3 L30PARD« ist der Autor dieses Themas

Beiträge: 336

Wohnort: Hoch oben im Norden Schleswig Holsteins

Beruf: Schüler

  • Private Nachricht senden

4

30.12.2010, 13:03

Also statt dem gegebenen

C#-Quelltext

1
Draw(sprite);

lieber eine eigene Update Funktion schreiben, in der alle Objekte sowohl
gezeichnet als auch bewegt werden oder wie?

Fred

Supermoderator

Beiträge: 2 121

Beruf: Softwareentwickler

  • Private Nachricht senden

5

30.12.2010, 13:04

Siehe mein Edit ;)

NachoMan

Community-Fossil

Beiträge: 3 885

Wohnort: Berlin

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

  • Private Nachricht senden

6

30.12.2010, 13:05

die klassen sollten eine draw UND eine updatemethode bekommen. es gibt situationen in denen man zwar updaten aber nicht zeichnen will(wenn die objekte unsichtbar sind) oder nicht updaten aber zeichnen will(in einer pause). deshalb sollte man das trennen.
"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?

BLU3 L30PARD

Treue Seele

  • »BLU3 L30PARD« ist der Autor dieses Themas

Beiträge: 336

Wohnort: Hoch oben im Norden Schleswig Holsteins

Beruf: Schüler

  • Private Nachricht senden

7

30.12.2010, 13:08

Ja aber ich sollte nicht in der Main Funktion Draw() afurufen sonder ObjectManager.update() oder sowas ;)

NachoMan

Community-Fossil

Beiträge: 3 885

Wohnort: Berlin

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

  • Private Nachricht senden

8

30.12.2010, 13:10

ObjectManager.update() und ObjectManager.draw(). die rufen dann die entsprechenden methoden von den einzelnen objekten in der liste auf.
"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?

Fred

Supermoderator

Beiträge: 2 121

Beruf: Softwareentwickler

  • Private Nachricht senden

9

30.12.2010, 13:13

Das wäre sinnvoll ;).
Also du musst dir ja vorstellen, wenn du mal 20 Objekte hast, wird das auch ziemlich unübersichtlich, wenn du in deiner Game-Funktion dann 20 Mal Draw aufrufst.
Bei mir sieht das in der Game-Klasse meist so aus:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void gs_game::update()
{
   level_->update();
}

void level::update()
{
   object_manager_->update();
   light_manager_->update();
   physics_world_->update();
   //...
}

void object_manager::update()
{
   for( int i = 0; i<objects_.size(); i++ )
   {
       objects_[i]->update();
   }
}


Stark vereinfacht zumindest.

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

10

30.12.2010, 14:25

Die Bewegung, bzw. Geschwindigkeit deiner Schüsse hängt von der Anzahl der Aufrufe (und damit Framerate) ab, das ist milde gesagt mies. Die Physik bietet genug Formeln für gleichförmig bewegte oder beschleunigte Objekte. Die hängen von der Zeit ab. Nimm das.
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]

Werbeanzeige