Maison  >  Article  >  interface Web  >  Explication détaillée du jeu de tir horizontal basé sur HTML5

Explication détaillée du jeu de tir horizontal basé sur HTML5

黄舟
黄舟original
2017-03-24 15:33:562907parcourir

Description de la fonction :

Basé sur HTML5Un jeu de tir à défilement latéral basé sur le jeu flash "Double Agent". Les touches fléchées gauche et droite contrôlent le mouvement, la touche fléchée vers le bas contrôle le mouvement et la touche fléchée vers le haut saute. avant d'en faire l'expérience.

Ce jeu est basé sur le framework de jeu HTML5 auto-développé cnGameJS

Aperçu de l'effet :

Explication détaillée du jeu de tir horizontal basé sur HTML5

<.>Analyse de la mise en œuvre :

 

1. À propos des cartes multicouches  

Dans le jeu HTML5 précédent "Tank Support Team ", la carte utilisée était seule. Une simple carte à une seule couche signifie qu'il n'y a qu'une seule couche d'espace ouvert à l'exception des pierres. Cependant, cette carte à une seule couche a des limitations relativement importantes. Si vous devez implémenter des jeux basés sur des scènes ( comme Super Mario et les jeux ci-dessus), une carte avec une seule couche n'est souvent pas suffisante, car en plus des obstacles sur lesquels se trouve le protagoniste du jeu, nous avons également l'arrière-plan du jeu et d'autres éléments (comme le mur derrière). , etc.), nous devons donc superposer les objets de la carte pour obtenir plusieurs objets de couche.

Nouvel objet de couche :

Chaque objet de couche maintient le sprite de la couche, est responsable. pour les mettre à jour et les dessiner, et peut obtenir les coordonnées spécifiées sur la matrice du calque. La valeur Le code source de l'objet calque est le suivant :

/**
        *层对象
        **/                               
        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();
    
            }
        }
On peut alors facilement créer différents calques et. ajoutez-les à la carte :

/*    背景矩阵    */
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. À propos du déplacement de la scène

Dans le dernier HTML5 "Game Super Mario Game Demo", nous avons obtenu l'effet de. fixation du joueur et mouvement de la scène en convertissant le mouvement du joueur en mouvement de la scène de jeu, mais cette méthode de mise en œuvre a un gros problème, car elle interfère avec les changements dans les valeurs xy de la carte et du joueur, cela causera donc beaucoup d'inconvénients.

Une meilleure méthode d'implémentation consiste à conserver les valeurs xy du joueur et de la carte inchangées. Changez les coordonnées de l'origine lors de leur dessin. l'objet de vue : applyInView : La fonction de applyIn

View méthode

est de ne pas modifier la carte et le joueur. Sous le principe des coordonnées réelles, la vue est fixe lors du dessin, et autres. les éléments du jeu se déplacent par rapport à la vue pour obtenir l'effet de déplacer l'arrière-plan. Par exemple, nous devons fixer le joueur par rapport au milieu de la vue, et tous les autres éléments du jeu sur la carte sont relatifs à la vue. la vue, il suffit de :

lors du dessin :

   this.view=new cnGame.View({map:this.map,x:0,y:0,width:cnGame.width,height:cnGame.height});
        this.view.centerElem(this.player,true);
De cette façon, tous les éléments de la carte se déplaceront par rapport à la vue. Le principe de mise en œuvre de applyInView. est également très simple. Il suffit de rendre l'origine du dessin et les coordonnées de la vue égales et opposées :

 this.view.applyInView(function(){
            map.draw();        
        });
De cette façon, peu importe la façon dont les coordonnées de la vue changent, la vue est toujours visuellement fixées à

canvas

, les coordonnées des autres éléments sont toujours visuellement relatives à la vue.

/**
            *使坐标相对于view
            **/
            applyInView:function(func){    
                cg.context.save();
                cg.context.translate(-this.x, -this.y);
                func();
                cg.context.restore();
            },

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn