Detaillierte Erklärung zur Erstellung von Schießspielen mit CocosCreator

Detaillierte Erklärung zur Erstellung von Schießspielen mit CocosCreator

Szeneneinstellung

Spielressourcen

Turmdrehung

Der Mechanismus ist derselbe wie beim Auto in der vorherigen Handle-Instanz und verwendet Touchmove, um auf Berührungsereignisse zu warten.

  1. Berührungsposition abrufen
  2. Verwenden Sie die Methode signAngle, um die Winkeldifferenz zwischen der Position und der Position cc.v2(1,0) zu ermitteln (denken Sie daran, ein negatives Vorzeichen hinzuzufügen. Der Vergleich gegen den Uhrzeigersinn ist negativ und der Vergleichswert gegen den Uhrzeigersinn ist positiv).
  3. Der gesuchte Winkel ist der Endwinkel.

 beim Laden(){
        //Auf 90 Grad initialisieren this.node.angle=90;
        dies.node.on('touchstart',dieses.onTouchStart,dieses);
        dies.node.on('touchmove',dies.onTouchMove,dies);
        dies.node.on('touchend',dieses.onTouchEnd,dieses);
        dies.node.on('touchconcel',dies.onTouchConcel,dies);
    }
   
    beiBerührenStart(e:cc.Event.EventTouch){
        //Startposition abrufen this.starPos=this.node.parent.convertToNodeSpace(e.getLocation());
        //Den Anfangswinkel der Mündung abrufen this.starAngle=this.node.angle;

    }
    beiBerührenEnde(e:cc.Event.EventTouch){

    }
    beiBerührenBewegung(e:cc.Event.EventTouch){
        // Aktuelle Position des Berührungspunkts abrufen let pos:cc.Vec2=this.node.parent.convertToNodeSpace(e.getLocation());

        //Winkel ermitteln //Der Winkel ist im Uhrzeigersinn negativ und gegen den Uhrzeigersinn positiv let sweep_radian=pos.signAngle(this.starPos); //Der Winkel von pos relativ zu starPose p ist im Uhrzeigersinn relativ zu s positiv let sweep_angle=sweep_radian*180/Math.PI; //Winkel in Radiant umrechnen //Den Turm auf den endgültigen Winkel zeigen lassen let angle=this.starAngle-sweep_angle;
      
        //Begrenzen Sie den Winkel zwischen 45 und 135, wenn (Winkel < 45) Winkel = 45;
        wenn(Winkel>135)Winkel=135;

        cc.log("Mündungsschwung: "+sweep_angle+"Endgültige Winkelposition: "+angle);
        this.node.angle=Winkel;
    }

Dynamisch generierte Aufzählungszeichen

  1. Erzeugen Sie einen Knoten cc.Node und fügen Sie eine Komponente addComponent(cc.Sprite) hinzu.
  2. Weisen Sie den Eigenschaften der Komponente und dem SpriteFrame des Bildes Werte zu
  3. Mounten Sie die Komponente unter einem übergeordneten Knoten
  4. Position, Winkel usw. festlegen.
  5. Um die Bewegung zu steuern, können Sie das neu erstellte Skript importieren und es der Komponente des dynamisch generierten Knotens hinzufügen.
 beiBerührenEnde(e:cc.Event.EventTouch){
        dies.feuer();
    }
    beiBerührenConcel(e:cc.Event.EventTouch){

    }

    Feuer(){

        wenn(dieses.bulleteicon==null)zurückgeben;
        let bullet:cc.Node=neuer cc.Node();
        let sprite:cc.Sprite=bullet.addComponent(cc.Sprite);
        sprite.spriteFrame=dieses.bulleteicon;
        

        //Am Knoten des Aufnahmesystems anbringen bullet.parent=this.node.parent;

        //Die relative Position des übergeordneten Knotens festlegen let ration=this.node.angle*Math.PI/180;
        sei Richtung = cc.v2 (Math.cos (Ration), Math.sin (Ration));
        bullet.angle=dieser.Knoten.angle;
        sei r=100;
        bullet.setPosition(cc.v3(r*direction.x,r*direction.y,0));
       
        //Zusätzliche Skriptkomponente let script=bullet.addComponent(Buletet);
         script.explodeImg=dieses.explodeImg;
         script.direction=Richtung;

    }
 Start () {
         dies.Zeitplan(dies.onTimer,0.01);
    }

    einTimer(){
        wenn(this.node.y>300){
            dies.aufheben(dies.aufTimer);
            dies.explodieren();
           
            zurückkehren;
        }
        sei dx = diese.Richtung.x * 5;
        sei dy=diese.Richtung.y*5;
        dieser.Knoten.y+=dy;
        dieser.Knoten.x+=dx;
    }

    explodieren()

        lass sp:cc.Sprite=this.getComponent(cc.Sprite);
        sp.spriteFrame=dieses.explodeImg;
      
        //Aufzählungszeichen verkleinern this.node.scale=0.1;
        //Beschleunigungssystem für Explosionsanimationseffekte let self=this;
        cc.tween(dieser.Knoten)
            .bis(0,5,{Maßstab:1,Deckkraft:0})
            .call(Funktion(){
                selbst.nachExplode();
            })
            .Start();

            
    }

    nachExplode(){
        dies.node.destroy();
    }

Dieser Fehler:

  1. Der importierte Klassenname unterscheidet sich vom Dateinamen. Beachten Sie, dass durch das Umbenennen der Datei der Klassenname im Code nicht automatisch geändert wird. Sie müssen ihn daher zweimal ändern.
  2. Bei Verwendung der Methode setposition() werden die Parameter in den Konstruktor von cc.v3 geschrieben. Achten Sie unbedingt auf die Position der Parameter.

Kollisionsberechnung

Berechnen Sie die relative Position der Kugel und des Ziels. Wenn sie kleiner als die Reichweite ist, wird das Ziel als getroffen beurteilt und der Treffervorgang wird ausgeführt. Andernfalls wird das Ziel als nicht getroffen beurteilt und der Nichttreffervorgang wird ausgeführt.

Das Skript muss den Zielknoten übergeben und das Zielattribut hinzufügen

   @Eigenschaft(cc.SpriteFrame)
    explodierenBild: cc.SpriteFrame = null;
    
    Richtung: cc.Vec2 = null;

    Ziel: cc.Node = null;
    beim Laden() {

    }

    Start() {
        dies.schedule(dieses.onTimer, 0,01);
    }

    einTimer() {
        wenn (this.node.y > 350) {
            wenn (this.isHit()) {
                //Explosionseffekt abspielen this.explode();
                console.log("Triff das Ziel");
            }
            anders {
                console.log("vom Ziel abgekommen");
                dies.disMiss();
            }
            dies.aufheben(dies.aufTimer);
            zurückkehren;
        }
        sei dx = diese.Richtung.x * 5;
        sei dy = diese.Richtung.y * 5;
        dieser.Knoten.y += dy;
        dieser.Knoten.x += dx;
    }

    //Beurteilen, ob es trifft isHit(): boolean {
        lass targetPos: cc.Vec2 = this.geWorldLocation(this.target);
        lass selfPos: cc.Vec2 = this.geWorldLocation(this.node);
        sei Abstand = Math.abs(ZielPos.x - SelbstPos.x);
        console.log("Ziel x=" + ZielPos.x + " , Aufzählungszeichen x=" + SelbstPos.x);

        wenn (Entfernung < 50) {
            gibt true zurück;

        }
        anders {
            gibt false zurück;
        }

    }
    explodieren() {

        let sp: cc.Sprite = this.getComponent(cc.Sprite);
        sp.spriteFrame = dies.explodeImg;

        //Aufzählungszeichen verkleinern this.node.scale = 0.1;
        // Beschleunigungssystem für Explosionsanimationseffekte let self = this;
        cc.tween(dieser.Knoten)
            .to(0,5, { Maßstab: 1, Deckkraft: 0 })
            .call(Funktion () {
                selbst.disMiss();
            })
            .Start();


    }

    geWorldLocation(Knoten: cc.Node): cc.Vec2 {
        let pos = node.getPosition();
        //Beachten Sie, dass dies node.parent ist. Der Aufrufer der Methode sollte das Koordinatensystem des aktuellen Knotens sein. return node.parent.convertToWorldSpaceAR(pos);

    }

    zurückweisen() {
        dies.node.destroy();
    }

Dieser Fehler:

Beim Abrufen der Weltkoordinaten wird nicht das Koordinatensystem des übergeordneten Knotens aufgerufen, sondern das Koordinatensystem des aktuellen Knotens verwendet, sodass der zurückgegebene Wert immer noch der Wert des aktuellen Koordinatensystems selbst ist. Denken Sie daran, dass der Methodenaufrufer zum Konvertieren von Weltkoordinaten das Koordinatensystem des aktuellen Knotens ist, normalerweise dessen übergeordneter Knoten. return node.parent.convertToWorldSpaceAR(pos); (mit dem Ankerpunkt als Ursprung)

Erhöhen Sie die Wirkung

Fügen Sie unter dem Zielknoten ein Skript hinzu, um die Bewegung zu steuern, sich nach links und rechts zu bewegen und einen Textaufforderungseffekt hinzuzufügen, wenn die Kugel trifft.

Texttipps:

 jubeln() {
        //Einen Knoten erstellen und let node mounten: cc.Node = new cc.Node();
        node.parent = this.node.parent; //Beide sind auf derselben Ebene, mit demselben übergeordneten Objekt let label: cc.Label = node.addComponent(cc.Label);
        label.string = "+10 Punkte";

        //Position, Transparenz usw. festlegen node.setPosition(cc.v3(0, 250, 0));
        Knoten. Opazität = 200;
        node.color = neue cc.Color(255, 0, 0);

        //Animation cc.tween(Knoten)
            .bis(0,5, { Maßstab: 1,5 })
            .to(0.2, { Deckkraft: 0 })
            .call(Funktion () {
                node.zerstören();
            })
            .Start();

    }

Zielbewegung

 update (dt) {
         sei Geschwindigkeit=3;
         wenn(dies.istLinks){
             Geschwindigkeit=-Geschwindigkeit;
         }
         this.node.x+=Geschwindigkeit;
         wenn(dies.istLinks&&dieser.knoten.x<-350){
             dies.isLeft=false;
         }
         wenn(!this.isLeft&&this.node.x>350){
            dies.isLeft=true;
        }
    }

Anzeige des Munitionsdepots hinzugefügt

  1. Munitionsdepot-Knoten zum Stapelgenerieren von Geschossbildern hinzugefügt (Position kann mithilfe der Widget-Komponente festgelegt werden)
  2. Fügen Sie eine Methode zum Reduzieren von Aufzählungszeichen hinzu und reduzieren Sie Aufzählungszeichen, indem Sie die aktive Eigenschaft des Aufzählungszeichenbildes festlegen.
  3. Rufen Sie die Methode auf, um die Anzahl der Kugeln im Geschützturm zu reduzieren

Es gibt zwei Aufrufmethoden. Eine besteht darin, den Munitionsdepotknoten im Turmskript abzurufen und ihn dann aufzurufen. Die andere besteht darin, eine öffentliche Klasse (statische Variable) festzulegen, den Knoten in der Methode onLoad() zu initialisieren und ihn dann direkt aufzurufen. Verwenden Sie Letzteres.

 @Eigenschaft(cc.SpriteFrame)
    Aufzählungszeichen: cc.SpriteFrame = null;
    Kapazität: Zahl = 10;
    Lagernummer: Zahl = 10;


    beim Laden() {

        lass Platz: Zahl = diese.Knotenbreite / diese.Kapazität;
        für (lass i = 0; i < diese.Kapazität; i++) {
            //Bild generieren let bulleteNode: cc.Node = new cc.Node();
            let bulleteSprite: cc.Sprite = bulleteNode.addComponent(cc.Sprite);
            bulleteSprite.spriteFrame = dieses.bulleteIcon;
            dies.node.addChild(bulleteNode);

            //Position festlegen bulleteNode.x += space * i + 10;
            bulleteNode.y = 0;

        }

    }

    Start() {

    }

    verbrauchen(num: Zahl) {
        diese.stockNumber -= Zahl;
        wenn (diese.Bestandsnummer < 0) {
            diese.Bestandsnummer = 0;
        }
        dies.anzeige();
    }

    Anzeige() {
        lass Knoten: cc.Node[] = this.node.children;
        Konsole.log(Knoten.Länge);
        für (lass i = 0; i < Knoten. Länge; i++) {
            wenn(i>=diese.Bestandsnummer){
                Knoten[i].aktiv=false;
            }
           
        }
    }

Gemeinsame öffentliche Klasse

  //Statische Klasse, globale Variable, definiere alle allgemeinen Variablen und Klassen in der allgemeinen Klasse static ammo:Ammo=null;

    beim Laden() {
        Common.ammo=cc.find('Leinwand/Munition').getComponent('Munition');
        Konsole.log(Common.ammo);
    }

Hier ist der Fehler:

Denken Sie daran, in der Methode cc.find() den Schrägstrich für die Division zu verwenden.

Punktzahl für die Aufzählungserschöpfung

  1. Erstellen Sie eine Maskenebene, importieren Sie die Skriptklasse in die Common-Klasse und setzen Sie die aktive Eigenschaft auf „false“
  2. Fügen Sie dem ResultDialog-Skript die Show-Methode hinzu, setzen Sie ihre Active-Eigenschaft auf True und zeigen Sie den Punktestand auf dem Bildschirm an.
  3. Bestimmen Sie in Bullete (dem Skript, das die Bewegung der Aufzählungszeichen steuert), ob die Anzahl der Aufzählungszeichen <= 0 ist, und rufen Sie die Show-Methode in Common auf, um das Eingabeaufforderungsfeld für die Punkte anzuzeigen.

ResultDialog-Skript (steuert das Punkte-Eingabefeld)

 beim Laden () {
         let replay:cc.Node=cc.find('Canvas/Eingabeaufforderungsfeld beenden/ein anderes Spiel spielen');
         Konsole.log(Wiedergabe);
         Wiederholung.auf('touchstart',dies.verwerfen,dies);

         dies.node.on('touchstart',dieses.onTouchdisable,dieses);
         dies.node.on('touchmove', dies.onTouchdisable, dies);
         dies.node.on('touchend', dies.onTouchdisable, dies);
   
     }

     //Eingabeaufforderungsfeld anzeigen show(){
        dieser.Knoten.aktiv=wahr;  
        lass scoreNode: cc.Node = cc.find('Ergebnisbox/Ergebnis', dieser.Knoten);
        Lassen Sie scoreLabel: cc.Label = scoreNode.getComponent(cc.Label);   
        scoreLabel.string = Common.score + 'Punkte';   
       
        
     }

     //Das Eingabeaufforderungsfeld ausblenden exclude(){
         dieser.Knoten.aktiv=falsch;
     }

     //Shield onTouchdisable wenn Maske angezeigt wird (e: cc.Event.EventTouch) {
         e.stopPropagation();
     }
    Start () {

    }

Allgemeine Skripte

 //Statische Klasse, globale Variable, definiere alle allgemeinen Variablen und Klassen in der allgemeinen Klasse static ammo:Ammo=null;
    statische Punktzahl: Zahl = 0;
    statischer Ergebnisdialog: Ergebnisdialog = null;
  

    beim Laden() {
        Common.resultdialog=cc.find('Leinwand/Eingabeaufforderungsfeld beenden').getComponent('ResultDialog');
        Common.ammo=cc.find('Leinwand/Munition').getComponent('Munition');
    }

Erhöhen Sie die Punktzahl in der Bullete-Methode

  wenn (this.isHit()) {
                //Explosionseffekt abspielen this.explode();
                //+10 Punkte anzeigen this.cheer();
                //Gesamtpunktzahl +10
                Gemeinsamer Score + = 10;
                console.log("Triff das Ziel");
            }

Spielneustart

Dieses Spiel ist relativ einfach. Um es neu zu starten, müssen Sie nur den Munitionsdepotknoten zurücksetzen. Daher wird die Reset-Methode im Ammo-Skript platziert. Erstellen Sie ein Ammo-Objekt in der öffentlichen Klasse, legen Sie eine statische Methode fest, setzen Sie den Punktestand zurück und rufen Sie die Reset-Methode von Ammo auf.

Ammo (Munitionsdepot) Skript hinzugefügt

 zurücksetzen(){
        diese.Bestandsnummer=diese.Kapazität;
        dies.anzeige();
    }

Ändern des allgemeinen Skripts

 //Statische Klasse, globale Variable, definiere alle allgemeinen Variablen und Klassen in der allgemeinen Klasse static ammo:Ammo=null;
    statische Punktzahl: Zahl = 0;
    statischer Ergebnisdialog: ResultDialog = null;
  

    beim Laden() {
        Common.resultdialog=cc.find('Leinwand/Eingabeaufforderungsfeld beenden').getComponent('ResultDialog');
        Common.ammo=cc.find('Leinwand/Munition').getComponent('Munition');
        Konsole.log(Common.ammo);
    }
    statisches ResetGame() {
        Gemeinsam.score=0;
        Common.ammo.reset();
    }

Fügen Sie einige Details hinzu

Spielgeräusche und Änderungen an der Geschützturmaktivierung hinzugefügt

1. Eigenschaften zum Turmskript hinzugefügt

 //Soundeffekt @property(cc.AudioClip)
    audioFire: cc.AudioClip = null;
    @Eigenschaft(cc.AudioClip)
    audioExplode: cc.AudioClip = null;

    //Turmbild @property(cc.SpriteFrame)
    SymbolNormal: cc.SpriteFrame = null;
    @Eigenschaft(cc.SpriteFrame)
    Symbol Aktiv: cc.SpriteFrame = null;

Bildschalter

 onTouchStart(e: cc.Event.EventTouch) {am Ende der Methode hinzufügen //Turmbild aktivieren this.node.getComponent(cc.Sprite).spriteFrame = this.iconActive;
 onTouchEnd(e: cc.Event.EventTouch) {Methode schließlich hinzugefügt //Bildwiederherstellung this.node.getComponent(cc.Sprite).spriteFrame = this.iconNormal;
      }

Soundeffekt-Wiedergabe

fire(){ Nach der Methode hinzufügen //Senden Sie den Ton der Bullet-Explosion an das Bullet-Skript script.audioExplode = this.audioExplode;
 wenn (this.audioFire != null) {
            cc.audioEngine.play(this.audioFire, false, 1);
        }
    }

Methode zum Abspielen von Audio: ==cc.audioEngine.play(this.audioFire, false, 1); ==Der zweite Parameter gibt an, ob in einer Schleife abgespielt werden soll, und der dritte Parameter ist die Lautstärke

Bullet-Skript

//Attribut hinzufügen @property(cc.SpriteFrame)
explodierenBild: cc.SpriteFrame = null;
Fügen Sie if(this.audioExplode!=null){ hinzu
	cc.audioEngine.play(dieses.audioExplode,false,1);
}

Oben finden Sie eine ausführliche Erklärung, wie Sie mit CocosCreator Schießspiele erstellen. Weitere Informationen zu CocosCreator-Schießspielen finden Sie in den anderen verwandten Artikeln auf 123WORDPRESS.COM!

Das könnte Sie auch interessieren:
  • Unity nutzt Physik-Engine zur Simulation des Flugs von Multirotor-Drohnen
  • Einfaches Beispiel für die Verwendung von Box2d, einer 2D-Physik-Engine für Android
  • Interpretation des CocosCreator-Quellcodes: Engine-Start und Hauptschleife
  • CocosCreator allgemeines Framework-Design Ressourcenmanagement
  • So erstellen Sie eine Liste in CocosCreator
  • Analyse des neuen Ressourcenmanagementsystems von CocosCreator
  • CocosCreator Skelettanimation Drachenknochen
  • So zeichnen Sie in CocosCreator ein cooles Radardiagramm
  • Detaillierte Erklärung der CocosCreator MVC-Architektur
  • So verwenden Sie Verbindungen der Physik-Engine in CocosCreator

<<:  Detaillierte Erklärung zur Verwendung des Grep-Befehls in Linux

>>:  MySQL-Hochverfügbarkeitslösung MMM (MySQL Multi-Master-Replikationsmanager)

Artikel empfehlen

So installieren Sie Docker unter Windows Server 2016

Kürzlich hat Microsoft Windows Server 2016 veröff...

Erfahrungsaustausch über die Priorität des Ladens von CSS-Stilen

Während der Projektentwicklung bin ich gestern auf...

So erstellen Sie ein standardisiertes VMware-Image für Kubernetes unter Rancher

Wenn wir Kubernetes lernen, müssen wir in der Kub...

CocosCreator klassisches Einstiegsprojekt flappybird

Inhaltsverzeichnis Entwicklungsumgebung Game-Engi...

CSS-Rand halb oder teilweise sichtbarer Implementierungscode

1. Verwenden Sie Pseudoklassen, um die Hälfte des...

Vue implementiert dreidimensionales Säulendiagramm basierend auf E-Charts

Das dreidimensionale Säulendiagramm besteht aus d...

IIS und APACHE implementieren die HTTP-Umleitung auf HTTPS

IIS7 Laden Sie das HTTP Rewrite-Modul von der off...

Schritte zum Verpacken und Freigeben des Vue-Projekts

Inhaltsverzeichnis 1. Übergang von der Entwicklun...

Node.js verwendet die Express-Fileupload-Middleware zum Hochladen von Dateien

Inhaltsverzeichnis Initialisieren des Projekts Sc...

Was Sie über MySQL-Sperren wissen müssen

1. Einleitung MySQL-Sperren können je nach Umfang...