Heim  >  Artikel  >  Web-Frontend  >  Ausführliche Erklärung des horizontalen Schießspiels basierend auf HTML5

Ausführliche Erklärung des horizontalen Schießspiels basierend auf HTML5

黄舟
黄舟Original
2017-03-24 15:33:562896Durchsuche

Funktionsbeschreibung:

Basierend auf HTML5Horizontales Schießspiel, siehe Flash-Spiel „Double Agent“ Die linke und rechte Pfeiltaste steuert die Bewegung, die Pfeiltaste nach unten zum Hocken, die Pfeiltaste nach oben zum Springen und die Leertaste zum Schießen Schalten Sie die Eingabemethode aus, bevor Sie es erleben. 🎜>

Dieses Spiel basiert auf dem selbst entwickelten HTML5-Spielframework cnGameJS

Effektvorschau:

Ausführliche Erklärung des horizontalen Schießspiels basierend auf HTML5

<.>Implementierungsanalyse:

 

1. Über mehrschichtige Karten

 Im vorherigen HTML5-Spiel Die verwendete Karte „Tank Support Team“ bedeutet, dass es außer Steinen nur eine Ebene mit offenem Raum gibt. Diese einschichtige Karte weist jedoch relativ große Einschränkungen auf, wenn eine Szene implementiert werden muss -basierten Spielen (wie Super Mario und die oben genannten Spiele) reicht eine Karte mit nur einer Ebene oft nicht aus, da wir zusätzlich zu den Hindernissen, auf denen der Spielprotagonist steht, auch Spielhintergrund und andere Elemente (z. B B. die Wand dahinter usw.), daher müssen wir die Kartenobjekte schichten, um mehrere zu erreichen. Der Zweck der Ebenenanzeige:

Neues Ebenenobjekt:

Jedes Ebenenobjekt behält das Sprite des bei Ebene, ist für deren Aktualisierung und Zeichnung verantwortlich und kann die angegebenen Koordinaten auf der Matrix der Ebene abrufen. Der Quellcode des Ebenenobjekts lautet wie folgt:

Wir können dann problemlos Erstellen Sie verschiedene Ebenen und fügen Sie sie der Karte hinzu:
/**
        *层对象
        **/                               
        var layer = function(id,mapMatrix, options) {
    
            if (!(this instanceof arguments.callee)) {
                return new arguments.callee(id,mapMatrix, options);
            }
            this.init(id,mapMatrix, options);
        }
        layer.prototype={
            
            /**
            *初始化
            **/
            init: function(id,mapMatrix,options) {
                /**
                *默认对象
                **/    
                var defaultObj = {
                    cellSize: [32, 32],   //方格宽,高
                    x: 0,                      //layer起始x
                    y: 0                  //layer起始y
    
                };    
                options = options || {};
                options = cg.core.extend(defaultObj, options);
                this.id=options.id;
                this.mapMatrix = mapMatrix;
                this.cellSize = options.cellSize;
                this.x = options.x;
                this.y = options.y;
                this.row = mapMatrix.length; //有多少行
                this.width=this.cellSize[0]* mapMatrix[0].length;
                this.height=this.cellSize[1]* this.row;
                this.spriteList=new cg.SpriteList();//该层上的sprite列表
                this.imgsReference=options.imgsReference;//图片引用字典:{"1":{src:"xxx.png",x:0,y:0},"2":{src:"xxx.png",x:1,y:1}}
                this.zIindex=options.zIndex;
            },
            /**
            *添加sprite
            **/            
            addSprites:function(sprites){
                if (cg.core.isArray(sprites)) {
                    for (var i = 0, len = sprites.length; i < len; i++) {
                        arguments.callee.call(this, sprites[i]);
                    }
                }
                else{
                    this.spriteList.add(sprites);
                    sprites.layer=this;
                }                
                
            },
            /**
            *获取特定对象在layer中处于的方格的值
            **/
            getPosValue: function(x, y) {
                if (cg.core.isObject(x)) {
                    y = x.y;
                    x = x.x;
                }
                var isUndefined = cg.core.isUndefined;
                y = Math.floor(y / this.cellSize[1]);
                x = Math.floor(x / this.cellSize[0]);
                if (!isUndefined(this.mapMatrix[y]) && !isUndefined(this.mapMatrix[y][x])) {
                    return this.mapMatrix[y][x];
                }
                return undefined;
            },
            /**
            *获取特定对象在layer中处于的方格索引
            **/
            getCurrentIndex: function(x, y) {
                if (cg.core.isObject(x)) {
                    y = x.y;
                    x = x.x;
                }
                return [Math.floor(x / this.cellSize[0]), Math.floor(y / this.cellSize[1])];
            },
            /**
            *获取特定对象是否刚好与格子重合
            **/
            isMatchCell: function(x, y) {
                if (cg.core.isObject(x)) {
                    y = x.y;
                    x = x.x;
                }
                return (x % this.cellSize[0] == 0) && (y % this.cellSize[1] == 0);
            },
            /**
            *设置layer对应位置的值
            **/
            setPosValue: function(x, y, value) {
                this.mapMatrix[y][x] = value;
            },
            /**
            *更新层上的sprite列表
            **/            
            update:function(duration){
                this.spriteList.update(duration);
                
            },
            /**
            *根据layer的矩阵绘制layer和该layer上的所有sprite
            **/
            draw: function() {
                var mapMatrix = this.mapMatrix;
                var beginX = this.x;
                var beginY = this.y;
                var cellSize = this.cellSize;
                var currentRow;
                var currentCol
                var currentObj;
                var row = this.row;
                var img;
                var col;
                for (var i = beginY, ylen = beginY + row * cellSize[1]; i < ylen; i += cellSize[1]) {    //根据地图矩阵,绘制每个方格
                    currentRow = (i - beginY) / cellSize[1];
                    col=mapMatrix[currentRow].length;
                    for (var j = beginX, xlen = beginX + col * cellSize[0]; j < xlen; j += cellSize[0]) {
                        currentCol = (j - beginX) / cellSize[0];
                        currentObj = this.imgsReference[mapMatrix[currentRow][currentCol]];
                        if(currentObj){
                            currentObj.x = currentObj.x || 0;
                            currentObj.y = currentObj.y || 0;
                            img = cg.loader.loadedImgs[currentObj.src];
                            //绘制特定坐标的图像
                            cg.context.drawImage(img, currentObj.x, currentObj.y, cellSize[0], cellSize[1], j, i, cellSize[0], cellSize[1]); 
                        }
                    }
                }
                //更新该layer上所有sprite
                this.spriteList.draw();
    
            }
        }

/*    背景矩阵    */
var bgMatrix = [
                    [1,1,1],
                    [1,1,1],
                    [1,1,1]
                ];

this.map = new cnGame.Map({width:3000,height:3000});
var newLayer=new cnGame.Layer("bg",bgMatrix, { cellSize: [1000, 1000], width: this.map.width, height: this.map.height });
newLayer.imgsReference={ "1": { src: srcObj.bg }};
this.map.addLayer(newLayer);
2. Informationen zum Verschieben von Szenen

Im letzten HTML5 „Game Super Mario Game Demo“ haben wir Der Effekt der Spielerfixierung und Szenenbewegung wird durch die Umwandlung der Bewegung des Spielers in die Bewegung der Spielszene erreicht. Diese Implementierungsmethode weist jedoch ein großes Problem auf, da sie die Änderungen der xy-Werte von stört Dies verursacht große Unannehmlichkeiten.

Eine bessere Implementierungsmethode besteht darin, die XY-Werte des Players und der Karte beim Zeichnen unverändert zu lassen. Die neue Methode des Ansichtsobjekts: applyInView:

Die Funktion der applyInView-Methode

besteht darin, die Karte und den Player nicht zu ändern. Unter der Voraussetzung der tatsächlichen Koordinaten ist die Ansicht festgelegt Zeichnen und andere Spielelemente bewegen sich relativ zur Ansicht, um den Effekt einer Verschiebung des Hintergrunds zu erzielen. Beispielsweise müssen wir den Spieler relativ zum Mittelpunkt der Ansicht fixieren, und alle anderen Spielelemente auf der Karte sind relativ zum Mittelpunkt Um die Ansicht zu verschieben, müssen wir beim Zeichnen nur Folgendes tun:

Auf diese Weise werden alle Elemente in der Karte relativ zur Ansicht verschoben Das Implementierungsprinzip von applyInView ist ebenfalls sehr einfach. Es sorgt dafür, dass der Ursprung der Zeichnung und die Koordinaten der Ansicht immer gleich und entgegengesetzt sind:

Auf diese Weise wird unabhängig davon, wie sich die Koordinaten der Ansicht ändern, Die Ansicht ist immer visuell auf
   this.view=new cnGame.View({map:this.map,x:0,y:0,width:cnGame.width,height:cnGame.height});
        this.view.centerElem(this.player,true);
Leinwand

fixiert, die Koordinaten anderer Elemente sind immer visuell relativ zur Ansicht.

 this.view.applyInView(function(){
            map.draw();        
        });

Das obige ist der detaillierte Inhalt vonAusführliche Erklärung des horizontalen Schießspiels basierend auf HTML5. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn