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

Vermeiden Sie den Missbrauch zum Lesen von Daten in Vue

Inhaltsverzeichnis Vorwort 1. Der Prozess der Ver...

Implementierung der Nummernschild-Eingabefunktion im WeChat-Applet

Inhaltsverzeichnis Vorwort Hintergrund Große Verm...

CSS-Tutorial: CSS-Attribut-Medientyp

Eines der wichtigsten Merkmale eines Stylesheets ...

JavaScript zum Erzielen eines Fensteranzeigeeffekts

In diesem Artikel wird der spezifische JavaScript...

Ist es notwendig, dem Img-Bild-Tag ein Alt-Attribut zuzuweisen?

Fügen Sie dem img-Bild-Tag ein Alt-Attribut hinzu?...

Gründe und Lösungen für das Nicht-Wirksamwerden der MySQL-SQL-Modus-Änderung

Inhaltsverzeichnis Vorwort Szenariosimulation Zus...

Vue implementiert QR-Code-Scanfunktion (mit Stil)

brauchen: Verwenden Sie Vue, um das Scannen von Q...

Lösungen für das Problem der Erstellung von XHTML- und CSS-Webseiten

Die Lösungen für die Probleme, die bei der Erstell...

Eine Untersuchung des JS-Operators im Problem

Die Sache ist: Jeder kennt „Speicherlecks“. Es gi...

So visualisieren Sie skizzierte Diagramme in Vue.js mit RoughViz

einführen Ein Diagramm ist eine grafische Darstel...

Zusammenfassung der DTD-Verwendung in HTML

DTD ist ein Satz grammatikalischer Regeln zur Ausz...

Zwei gängige Lösungen für den HTML-Textüberlauf zeigen Auslassungszeichen an

Methode 1: Verwenden Sie zur Lösung die CSS-Überl...

Vue+Element - benutzerdefinierte Abfragekomponente

In diesem Artikel wird hauptsächlich das Vue-Proj...

Das Prinzip und die grundlegende Verwendung von Vue.use() in Vue

Inhaltsverzeichnis Vorwort 1. Verstehen mit Beisp...