Gegner automatisch bewegen lassen



  • Hallo community!

    Ich bin grad dabei ein kleines Konsolenspiel namens Space Invaders zu programmieren!
    Das Spielfeld, das Schiff und die Bewegungen des Schiffes sind kein Problem!
    Nur weiß ich nicht, wie ich automatische Bewegungen (Die Gegner und die Schüsse) realisieren soll! Dachte zuerst an einen Schleifenzähler (meine main besteht aus einer do-while) der bei jedem 100 Durchlauf die Gegner bewegt(so ungefähr)!
    Das ist aber ziemlich unsauber und das Problem beim Schießen besteht immer noch!
    Gibts für mein Problem eine Funktion oder weiß jemand einen anderen Rat?

    Danke im Vorraus! 🙂



  • Es gibt ziemlich sicher keine Funktion, welche deinen Gegnern eine tolle KI verpasst. Das musst du selbst schreiben. Allerdings ist deine Beschreibung ziemlich ungenau, da du das Problem deiner Methode nicht erläutert hast. Was ist zum Beispiel das "Problem beim schießen"?

    Du kannst natürlich einfach, statt in jedem 100. Durchlauf eine volle Bewegung durchzuführen, eine Bewegung jeden Durchlauf machen, allerdings dann nur um ein viel kleineres Stück(halt 1/100.)

    Meine Glaskugel ist kaputt, mehr Tipps konnte sie nicht mehr ausspucken.



  • Zagatho_zero87 schrieb:

    Hallo community!

    Ich bin grad dabei ein kleines Konsolenspiel namens Space Invaders zu programmieren!
    Das Spielfeld, das Schiff und die Bewegungen des Schiffes sind kein Problem!
    Nur weiß ich nicht, wie ich automatische Bewegungen (Die Gegner und die Schüsse) realisieren soll! Dachte zuerst an einen Schleifenzähler (meine main besteht aus einer do-while) der bei jedem 100 Durchlauf die Gegner bewegt(so ungefähr)!

    Zeitabhängige Bewegung.



  • Hallo otze!

    Das Problem beim Schießen ist, dass wenn ich die Schießtaste drücke, der Schuss innerhalb weniger millisekunden von meinem Schiff an den oberen Bildschirmrand geht!
    Das ist natürlich viel zu schnell, angemessen wäre eine halbe sekunde oder so!
    Des weiteren erhalte ich anstatt eines Schusses eine Linie unngefähr so:

    *
         *
         *
         *
         *
         *
    

    wollen tu ich aber einen Punkt, der wandert, und nicht eine volle Linie hinterher zieht!

    Hier zur Vervollständigung mein Code(Der Gegner steht, er kann sich nicht bewegen)

    #include <cstdlib>
    #include <iostream>
    #include <conio.h>
    
    //Funktionsprototypen
    //////////////////////////////////////////////////////////////////////
    void create_battlefield();
    void shoot();
    void ship();
    void enemy();
    void start_game();
    void move_ship();
    //////////////////////////////////////////////////////////////////////
    //globale Variablen
    //////////////////////////////////////////////////////////////////////
    char battlefield[21][31];
    int position_x=13, position_y=19;
    //////////////////////////////////////////////////////////////////////
    
    int main(int argc, char *argv[])
    {
    
    	do{
    		enemy();
    		ship();
    		create_battlefield();
    		move_ship();
    		shoot();
    		system("cls");
    	}while(1);
    
       system("PAUSE");
       return EXIT_SUCCESS;
    }
    
    void create_battlefield(){
    
    	//erzeuge Spielfeldrand
    	///////////////////////////////////////////////////////////////////
    	for(int k=0; k<21; k++){
    
    		battlefield[k][0]='|';
    		battlefield[k][30]='|';
    	}// end for
    
    	for(int l=0; l<31; l++){
    
    		battlefield[0][l]='-';
    		battlefield[20][l]='-';
    	}// end for	
    	///////////////////////////////////////////////////////////////////
    
    	//Spielfeld erzeugen
    	///////////////////////////////////////////////////////////////////
    	for(int i=0; i<21; i++){
    
    		for(int j=0; j<31; j++){
    
    			std::cout<<battlefield[i][j]<<' ';
    		}// end for
    		std::cout<<std::endl;
    	}// end for
    }// end create_battlefield()
    
    void ship(){
    
    	char texture_of_ship='#';
    	battlefield[position_y][position_x]=texture_of_ship; //Null-Referenzpunkt
    	battlefield[position_y][position_x-1]=texture_of_ship;
    	battlefield[position_y][position_x-2]=texture_of_ship;
    	battlefield[position_y-1][position_x-1]=texture_of_ship;
    
    }//end ship()
    
    void move_ship(){
    
    	char move;
    	move=getch();
    
    	if(move=='a' || move=='d'){
    		//Wenn sich Schiff bewegt, altes überdecken
    		////////////////////////////////////////////////////////////////
    
    		battlefield[position_y][position_x]=' ';
    		battlefield[position_y][position_x-1]=' ';
    		battlefield[position_y][position_x-2]=' ';
    		battlefield[position_y-1][position_x-1]=' ';
    		////////////////////////////////////////////////////////////////
    	}// end if
    
    	switch(move){
    
    		case 'a': if(position_x>3)
    						position_x--;
    						break;
    
    		case 'd': if(position_x<29)
    						position_x++;
    						break;
    	}// end switch	
    }// end move()
    
    void enemy(){
    
    	char enemy='v';
    
    	battlefield[1][15]=enemy;
    }// end enemy()
    
    void shoot(){
    
    	char shoot;
    	char shoot_ball='*';
    	shoot=getch();
    
    	if(shoot==' '){
    
    		for(int i=17; i>0; i--){
    
    			battlefield[position_y-i][position_x-1]=shoot_ball;
    		}// end for
    	}// end if
    }// end shoot()
    


  • Mit dem Code:

    for(int i=17; i>0; i--){
    
       battlefield[position_y-i][position_x-1]=shoot_ball;
    }
    

    weißt du dein Programm ja an, eine Linie zu zeichnen. Warum sollte es etwas anderes tun?

    Das Grundproblem ist, dass das so nicht funktioniert. Überlege dir einfach mal, was dein Programm macht, wenn du shoot() aufrufst:

    zuerst zeichnest du deine Linie(bzw vielleicht die bewegende Kugel, wenn du den Code etwas änderst) und erst dann verlässt das Programm die Funktion shoot(). Selbst wenn der Gegner sich bewegen könnte, würde die Funktion, die ihn bewt, würde nicht aufgerufen werden, bis der Schuss durch ist. Auch du als Spieler könntest dich nicht bewegen, bis shoot() in das Hauptprogramm zurück gekehrt ist.

    Was du machen musst, ist dein Programm in Zeitabschnitte zu unterteilen. In jedem Zeitabschnitt ruft deine Hauptroutine dann alle benötigten Funktionen auf, bewegt alle Schüsse und Gegner weiter, und lässt dich ein Stück bewegen. Das bedeutet, dass du dir in jedem Zeitpunkt die Position des Schusses, des Gegners und deiner eigenen Position merken musst.



  • Zagatho_zero87 schrieb:

    ...!
    ......!
    ..!
    ....!
    .!
    .........!

    Könntest Du es bitte mal unterlassen, jeden verdammten Satz mit einem Ausrufezeichen zu beenden?



  • lolalter schrieb:

    Könntest Du es bitte mal unterlassen, jeden verdammten Satz mit einem Ausrufezeichen zu beenden?

    Könntest du es unterlassen, unter einen ernst gemeinten Thread so ne Scheiße zu posten? 🙂

    @otze

    An so etwas habe ich noch nicht gedacht, aber das klingt recht logisch.
    Danke erstmal für die Antwort, ich werde mal meinen Code nochmal neu überdenken.
    👍



  • Int ShootRichtung = -1
    Int ShootX = ShootStartX
    Int ShootY = ShootStartY
    void shoot(){

    char shoot;
    char shoot_ball='*';
    shoot=getch();

    if(shoot==' '){
    zeichneShoot(ShootX, ShootY);
    ShootY += ShootRichtung;
    }// end if
    }// end shoot()

    [/cpp][/quote]



  • @ano

    also laut deinem Code würde sich bei jedem Aufruf der Funktion shoot(sofern die Taste ' ' gedrückt) die Kugel um eine Position weiter rücken.
    Aber wie vergewissere ich mich, dass die Kugel bis ganz nach oben bewegt?



  • das musst du wohl testen. Zum Beispiel mit einer if-abfrage...

    probiers einfach aus. Schreib dir die Logik auf ein Blatt papier und versuche das auszuprogrammieren.



  • Zagatho_zero87 schrieb:

    @ano

    also laut deinem Code würde sich bei jedem Aufruf der Funktion shoot(sofern die Taste ' ' gedrückt) die Kugel um eine Position weiter rücken.
    Aber wie vergewissere ich mich, dass die Kugel bis ganz nach oben bewegt?

    genau. und da Du ja in einer Schleife hängst, trifft der Schuss irgendwann oder verschwindet aus dem Sichtfeld.



  • Am ehesten geeignet wäre wohl sowas wie ein Event System, das Events in festen Intervallen abarbeitet. Das könnte etwa so aussehen:

    struct GameData
    {
       int PlayerMovement; // z.B. <0 für links, >0 für rechts, 0 keine Bewegung
       std::vector<Shots>  // Shots enthält Informationen über abgegeben Schüsse
       std::vector<Ships>  // Ships enthält Informationen über Positionen der gegnerischen Raumschiffe
    };
    
    // ggf. als eigenen Thread implementieren, um die Benutzereingabe und Spielablauf voneinander zu trennen
    void process_events()
    {
       while( !GameEnd ) 
       {
          // Cooldown ist die Spielgeschwindigkeit, je niedriger, desto schneller ist das Spiel
          Sleep( Cooldown ); 
    
          // Bewegung des Spielerraumschiffs, Schüsse und gegnerischen Raumschiffe
          // Überprüfung auf Kollision, Spielende, etc.
       }
    }
    

    Die Benutzereingabe für die Bewegung und das Abfeuern eines Schusses löst nicht sofort die Bearbeitung aus, sondern macht nur die entsprechenden Einträge in GameData . Beim nächsten Trigger werden die Daten dann ausgewertet.



  • Zagatho_zero87 schrieb:

    lolalter schrieb:

    Könntest Du es bitte mal unterlassen, jeden verdammten Satz mit einem Ausrufezeichen zu beenden?

    Könntest du es unterlassen, unter einen ernst gemeinten Thread so ne Scheiße zu posten? 🙂

    Ach so lange man es ernst meint ist die Form egal oder wie?
    Ne...


Anmelden zum Antworten