Maison > interface Web > Tutoriel H5 > Utiliser HTML5 Canvas pour réaliser un jeu de masturbation

Utiliser HTML5 Canvas pour réaliser un jeu de masturbation

不言
Libérer: 2018-06-22 15:33:37
original
3688 Les gens l'ont consulté

Cet article présente principalement l'utilisation de HTML5 Canvas pour créer un jeu de masturbation simple. L'auteur fournit également du code Javascript pertinent. Les amis qui en ont besoin peuvent s'y référer

Plus tôt dans la DÉMO de Dang Knight, j'ai vu une masturbation. jeu et a retiré ses images et son audio. . . . Je l'ai réécrit juste pour m'amuser. Juste pour le divertissement. . . . . . Je n'utilise pas de framework, j'écris moi-même tous les js. . . . . . Il s'agit donc d'un didacticiel simple. Il peut être utile à ceux qui débutent sur Canvas. L'auteur ne joue pas à Canvas depuis longtemps et ses compétences ne sont pas très bonnes.

Sans plus tarder, commençons par la DÉMO : Airplane Game. L'affiche originale a écrit ceci juste pour le plaisir, et n'avait pas l'intention de l'écrire dans un jeu sérieux.

Entrons dans le vif du sujet : Le fichier du jeu de masturbation comprend le fichier d'entrée index.html, le fichier de traitement logique des sprites allSprite.js, le fichier de traitement de chargement chargement.js et data.js (certaines données initialisées).

Tout d'abord, les jeux normaux nécessitent essentiellement un chargement. La page de chargement est utilisée pour précharger les données, y compris les images des feuilles de sprite, l'audio, etc. Comme il s'agit d'un petit jeu, les seules choses qui doivent être chargées. sont quelques audio et image. Le code de chargement à l'intérieur est principalement le suivant. Les autres servent à créer des animations de chargement. Celui-ci est relativement simple, donc je ne le publierai pas. Si vous êtes intéressé, regardez simplement la console dans la DÉMO :

loadImg:function(datas){   
            var _this = this;   
            var dataIndex = 0;   
            li();   
            function li(){   
                if(datas[dataIndex].indexOf("mp3")>=0){   
                    var audio = document.createElement("audio");   
                    document.body.appendChild(audio);   
                    audio.preload = "auto";   
                    audio.src = datas[dataIndex];   
                    audio.oncanplaythrough = function(){   
                        this.oncanplaythrough = null;   
                        dataIndex++;   
                        if(dataIndex===datas.length){   
                            _this.percent = 100;   
                        }else {   
                            _this.percent = parseInt(dataIndex/datas.length*100);   
                            li.call(_this);   
                        }   
                    }   
                }else {   
                    preLoadImg(datas[dataIndex] , function(){   
                        dataIndex++;   
                        if(dataIndex===datas.length){   
                            _this.percent = 100;   
                        } else {   
                            _this.percent = parseInt(dataIndex/datas.length*100);   
                            li.call(_this);   
                        }   
                    })   
                }   
            }   
        },   
//再贴出preLoadImg的方法   
function preLoadImg(src , callback){   
    var img = new Image();   
    img.src = src;   
    if(img.complete){   
        callback.call(img);   
    }else {   
        img.onload = function(){   
            callback.call(img);   
        }   
    }   
}
Copier après la connexion
J'utilise d'abord un tableau pour enregistrer les liens vers les fichiers dans data.js, puis je détermine si ces liens sont des images ou des audios. S'il s'agit d'images, utilisez preLoadImg pour les charger. le code pour précharger les images est très simple, c'est un nouvel objet image. Ensuite, attribuez-lui le lien et rappelez-le après le chargement. L'audio est chargé en générant un objet dom audio HTML5 et en lui attribuant le lien. L'audio a un événement "canplaythrough". Lorsque le navigateur s'attend à pouvoir continuer la lecture de l'audio/vidéo spécifié sans s'arrêter pour la mise en mémoire tampon, l'événement canplaythrough se produit. , ce qui signifie que lorsque canplaythrough est appelé, l'audio est presque chargé et l'audio suivant peut être chargé. Juste comme ça, lorsque tout est chargé, le rappel est effectué et le jeu démarre.


Le jeu a commencé. Un jeu nécessitera beaucoup d'objets, je l'ai donc unifié en un objet sprite. Le mouvement de chaque image entre différents objets peut être écrit séparément en utilisant le comportement .

W.Sprite = function(name , painter , behaviors , args){   
    if(name !== undefined) this.name = name;   
    if(painter !== undefined) this.painter = painter;   
    this.top = 0;   
    this.left = 0;   
    this.width = 0;   
    this.height = 0;   
    this.velocityX = 3;   
    this.velocityY = 2;   
    this.visible = true;   
    this.animating = false;   
    this.behaviors = behaviors;   
    this.rotateAngle = 0;   
    this.blood = 50;   
    this.fullBlood = 50;   
    if(name==="plan"){   
        this.rotateSpeed = 0.05;   
        this.rotateLeft = false;   
        this.rotateRight = false;   
        this.fire = false;   
        this.firePerFrame = 10;   
        this.fireLevel = 1;   
    }else if(name==="star"){   
        this.width = Math.random()*2;   
        this.speed = 1*this.width/2;   
        this.lightLength = 5;   
        this.cacheCanvas = document.createElement("canvas");   
        thisthis.cacheCtx = this.cacheCanvas.getContext('2d');   
        thisthis.cacheCanvas.width = this.width+this.lightLength*2;   
        thisthis.cacheCanvas.height = this.width+this.lightLength*2;   
        this.painter.cache(this);   
    }else if(name==="badPlan"){   
        this.badKind = 1;   
        this.speed = 2;   
        this.rotateAngle = Math.PI;   
    }else if(name==="missle"){   
        this.width = missleWidth;   
    }else if(name==="boom"){   
        this.width = boomWidth;   
    }else if(name==="food"){   
        this.width = 40;   
        this.speed = 3;   
        this.kind = "LevelUP"
    }   
    this.toLeft = false;   
    this.toTop = false;   
    this.toRight = false;   
    this.toBottom = false;   
    this.outArcRadius = Math.sqrt((this.width/2*this.width/2)*2);   
    if(args){   
        for(var arg in args){   
            this[arg] = args[arg];   
        }   
    }   
}   
Sprite.prototype = {   
    constructor:Sprite,   
    paint:function(){   
        if(this.name==="badPlan"){this.update();}   
        if(this.painter !== undefined && this.visible){   
            if(this.name!=="badPlan") {   
                this.update();   
            }   
            if(this.name==="plan"||this.name==="missle"||this.name==="badPlan"){   
                ctx.save();   
                ctx.translate(this.left , this.top);   
                ctx.rotate(this.rotateAngle);   
                this.painter.paint(this);   
                ctx.restore();   
            }else {   
                this.painter.paint(this);   
            }   
        }   
    },   
    update:function(time){   
        if(this.behaviors){   
            for(var i=0;i<this.behaviors.length;i++){   
                this.behaviors[i].execute(this,time);   
            }   
        }   
    }   
}
Copier après la connexion
Après avoir écrit la classe elfe, vous pouvez générer différents objets en écrivant chaque peintre et chaque comportement. L'étape suivante consiste à écrire des peintres. Les peintres sont divisés en deux types, l'un est un peintre ordinaire et l'autre est un peintre de feuilles de sprites, car les animations d'explosion et les animations de prise de vue d'avion ne peuvent pas être réalisées avec une seule image, vous devez donc utiliser It's time. pour la feuille de sprite :


2015511181456172.png (168×24)

2015511181533636.png (896×64)

Pour les dessiner, vous devez personnaliser un peintre de feuille de sprite pour eux. Ce qui suit est le sprite le plus simple. . Peintre de tableaux, selon la complexité du jeu, vous pouvez modifier la méthode d'écriture du tableau des sprites jusqu'à ce qu'elle soit adaptée, mais les principes sont similaires, juste des modifications mineures :

var SpriteSheetPainter = function(cells){   
            this.cells = cells || [];   
            this.cellIndex = 0;   
        }   
        SpriteSheetPainter.prototype = {   
            advance:function(){   
                if(this.cellIndex === this.cells.length-1){   
                    this.cellIndex = 0;   
                }   
                else this.cellIndex++;   
            },   
            paint:function(sprite){   
                var cell = this.cells[this.cellIndex];   
                context.drawImage(spritesheet , cell.x , cell.y , cell.w , cell.h , sprite.left , sprite.top , cell.w , cell.h);   
            }   
        }
Copier après la connexion
Et dessin ordinaire L'outil est encore plus simple. Écrivez simplement un peintre et écrivez-y tout ce que vous voulez peindre.


Avec la classe sprite et le moteur de rendu de feuille de sprite, nous pouvons écrire des étoiles, des avions, des balles et des objets d'explosion : Voici l'intégralité du code allSprite.js :

(function(W){   
    "use strict"
    var planWidth = 24,   
        planHeight = 24,   
        missleWidth = 70,   
        missleHeight = 70,   
        boomWidth = 60;   
    //精灵类 
    W.Sprite = function(name , painter , behaviors , args){   
        if(name !== undefined) this.name = name;   
        if(painter !== undefined) this.painter = painter;   
        this.top = 0;   
        this.left = 0;   
        this.width = 0;   
        this.height = 0;   
        this.velocityX = 3;   
        this.velocityY = 2;   
        this.visible = true;   
        this.animating = false;   
        this.behaviors = behaviors;   
        this.rotateAngle = 0;   
        this.blood = 50;   
        this.fullBlood = 50;   
        if(name==="plan"){   
            this.rotateSpeed = 0.05;   
            this.rotateLeft = false;   
            this.rotateRight = false;   
            this.fire = false;   
            this.firePerFrame = 10;   
            this.fireLevel = 1;   
        }else if(name==="star"){   
            this.width = Math.random()*2;   
            this.speed = 1*this.width/2;   
            this.lightLength = 5;   
            this.cacheCanvas = document.createElement("canvas");   
            this.cacheCtx = this.cacheCanvas.getContext(&#39;2d&#39;);   
            this.cacheCanvas.width = this.width+this.lightLength*2;   
            this.cacheCanvas.height = this.width+this.lightLength*2;   
            this.painter.cache(this);   
        }else if(name==="badPlan"){   
            this.badKind = 1;   
            this.speed = 2;   
            this.rotateAngle = Math.PI;   
        }else if(name==="missle"){   
            this.width = missleWidth;   
        }else if(name==="boom"){   
            this.width = boomWidth;   
        }else if(name==="food"){   
            this.width = 40;   
            this.speed = 3;   
            this.kind = "LevelUP"
        }   
        this.toLeft = false;   
        this.toTop = false;   
        this.toRight = false;   
        this.toBottom = false;   
        this.outArcRadius = Math.sqrt((this.width/2*this.width/2)*2);   
        if(args){   
            for(var arg in args){   
                this[arg] = args[arg];   
            }   
        }   
    }   
    Sprite.prototype = {   
        constructor:Sprite,   
        paint:function(){   
            if(this.name==="badPlan"){this.update();}   
            if(this.painter !== undefined && this.visible){   
                if(this.name!=="badPlan") {   
                    this.update();   
                }   
                if(this.name==="plan"||this.name==="missle"||this.name==="badPlan"){   
                    ctx.save();   
                    ctx.translate(this.left , this.top);   
                    ctx.rotate(this.rotateAngle);   
                    this.painter.paint(this);   
                    ctx.restore();   
                }else {   
                    this.painter.paint(this);   
                }   
            }   
        },   
        update:function(time){   
            if(this.behaviors){   
                for(var i=0;i<this.behaviors.length;i++){   
                    this.behaviors[i].execute(this,time);   
                }   
            }   
        }   
    }   
    // 精灵表绘制器 
    W.SpriteSheetPainter = function(cells , isloop , endCallback , spritesheet){   
        this.cells = cells || [];   
        this.cellIndex = 0;   
        this.dateCount = null;   
        this.isloop = isloop;   
        this.endCallback = endCallback;   
        this.spritesheet = spritesheet;   
    }   
    SpriteSheetPainter.prototype = {   
        advance:function(){   
            this.cellIndex = this.isloop?(this.cellIndex===this.cells.length-1?0:this.cellIndex+1):(this.cellIndex+1);   
        },   
        paint:function(sprite){   
            if(this.dateCount===null){   
                this.dateCount = new Date();   
            }else {   
                var newd = new Date();   
                var tc = newd-this.dateCount;   
                if(tc>40){   
                    this.advance();   
                    this.dateCount = newd;   
                }   
            }   
            if(this.cellIndex<this.cells.length || this.isloop){   
                var cell = this.cells[this.cellIndex];   
                ctx.drawImage(this.spritesheet , cell.x , cell.y , cell.w , cell.h , sprite.left-sprite.width/2 , sprite.top-sprite.width/2 , cell.w , cell.h);   
            } else if(this.endCallback){   
                this.endCallback.call(sprite);   
                this.cellIndex = 0;   
            }   
        }   
    }   
    //特制飞机精灵表绘制器 
    W.controllSpriteSheetPainter = function(cells , spritesheet){   
        this.cells = cells || [];   
        this.cellIndex = 0;   
        this.dateCount = null;   
        this.isActive = false;   
        this.derection = true;   
        this.spritesheet = spritesheet;   
    }   
    controllSpriteSheetPainter.prototype = {   
        advance:function(){   
            if(this.isActive){   
                this.cellIndex++;   
                if(this.cellIndex === this.cells.length){   
                    this.cellIndex = 0;   
                    this.isActive = false;   
                }   
            }   
        },   
        paint:function(sprite){   
            if(this.dateCount===null){   
                this.dateCount = new Date();   
            }else {   
                var newd = new Date();   
                var tc = newd-this.dateCount;   
                if(tc>sprite.firePerFrame){   
                    this.advance();   
                    this.dateCount = newd;   
                }   
            }   
            var cell = this.cells[this.cellIndex];   
            ctx.drawImage(this.spritesheet , cell.x , cell.y , cell.w , cell.h , -planWidth/2 , -planHeight/2 , cell.w , cell.h);   
        }   
    }   
    W.planBehavior = [   
        {execute:function(sprite,time){   
            if(sprite.toTop){   
                sprite.top = sprite.top<planHeight/2? sprite.top : sprite.top-sprite.velocityY;   
            }   
            if(sprite.toLeft){   
                sprite.left = sprite.left<planWidth/2? sprite.left : sprite.left-sprite.velocityX;   
            }   
            if(sprite.toRight){   
                sprite.left = sprite.left>canvas.width-planWidth/2? sprite.left : sprite.left+sprite.velocityX;   
            }   
            if(sprite.toBottom){   
                sprite.top = sprite.top>canvas.height-planHeight/2? sprite.top : sprite.top+sprite.velocityY;   
            }   
            if(sprite.rotateLeft){   
                sprite.rotateAngle -= sprite.rotateSpeed;   
            }   
            if(sprite.rotateRight){   
                sprite.rotateAngle += sprite.rotateSpeed;   
            }   
            if(sprite.fire&&!sprite.painter.isActive){   
                sprite.painter.isActive = true;   
                this.shot(sprite);   
            }   
        },   
        shot:function(sprite){   
            this.addMissle(sprite , sprite.rotateAngle);   
            var missleAngle = 0.1   
            for(var i=1;i<sprite.fireLevel;i++){   
                this.addMissle(sprite , sprite.rotateAngle-i*missleAngle);   
                this.addMissle(sprite , sprite.rotateAngle+i*missleAngle);   
            }   
            var audio = document.getElementsByTagName("audio");   
            for(var i=0;i<audio.length;i++){   
                console.log(audio[i].paused)   
                if(audio[i].src.indexOf("shot")>=0&&audio[i].paused){   
                    audio[i].play();   
                    break;   
                }   
            }   
        },   
        addMissle:function(sprite , angle){   
                for(var j=0;j<missles.length;j++){   
                    if(!missles[j].visible){   
                        missles[j].left = sprite.left;   
                        missles[j].top = sprite.top;   
                        missles[j].rotateAngle = angle;   
                        var missleSpeed = 20;   
                        missles[j].velocityX = missleSpeed*Math.sin(-missles[j].rotateAngle);   
                        missles[j].velocityY = missleSpeed*Math.cos(-missles[j].rotateAngle);   
                        missles[j].visible = true;   
                        break;   
                    }   
                }   
            }   
        }   
    ]   
    W.starBehavior = [   
        {execute:function(sprite,time){   
            if(sprite.top > canvas.height){   
                sprite.left = Math.random()*canvas.width;   
                sprite.top = Math.random()*canvas.height - canvas.height;   
            }   
            sprite.top += sprite.speed;   
        }}   
    ]   
    W.starPainter = {   
        paint:function(sprite){   
            ctx.drawImage(sprite.cacheCanvas , sprite.left-sprite.width/2-sprite.lightLength , sprite.top-sprite.width/2-sprite.lightLength)   
        },   
        cache:function(sprite){   
            sprite.cacheCtx.save();   
            var opacity = 0.5,addopa = 1/sprite.lightLength;   
            sprite.cacheCtx.fillStyle = "rgba(255,255,255,0.8)";   
            sprite.cacheCtx.beginPath();   
            sprite.cacheCtx.arc(sprite.width/2+sprite.lightLength , sprite.width/2+sprite.lightLength , sprite.width/2 , 0 , 2*Math.PI);   
            sprite.cacheCtx.fill();   
            for(var i=1;i<=sprite.lightLength;i+=2){   
                opacity-=addopa;   
                sprite.cacheCtx.fillStyle = "rgba(255,255,255,"+opacity+")";   
                sprite.cacheCtx.beginPath();   
                sprite.cacheCtx.arc(sprite.width/2+sprite.lightLength , sprite.width/2+sprite.lightLength , sprite.width/2+i , 0 , 2*Math.PI);   
                sprite.cacheCtx.fill();   
            }   
        }   
    }   
    W.foodBehavior = [   
        {execute:function(sprite,time){   
            sprite.top += sprite.speed;   
            if(sprite.top > canvas.height+sprite.width){   
                sprite.visible = false;   
            }   
        }}   
    ]   
    W.foodPainter = {   
        paint:function(sprite){   
            ctx.fillStyle = "rgba("+parseInt(Math.random()*255)+","+parseInt(Math.random()*255)+","+parseInt(Math.random()*255)+",1)"
            ctx.font="15px 微软雅黑"
            ctx.textAlign = "center";   
            ctx.textBaseline = "middle";   
            ctx.fillText(sprite.kind , sprite.left , sprite.top);   
        }   
    }   
    W.missleBehavior = [{   
        execute:function(sprite,time){   
            sprite.left -= sprite.velocityX;   
            sprite.top -= sprite.velocityY;   
            if(sprite.left<-missleWidth/2||sprite.top<-missleHeight/2||sprite.left>canvas.width+missleWidth/2||sprite.top<-missleHeight/2){   
                sprite.visible = false;   
            }   
        }   
    }];   
    W.misslePainter = {   
        paint:function(sprite){   
            var img = new Image();   
            img.src="../planGame/image/plasma.png"
            ctx.drawImage(img , -missleWidth/2+1 , -missleHeight/2+1 , missleWidth , missleHeight);   
        }   
    }   
    W.badPlanBehavior = [{   
        execute:function(sprite,time){   
            if(sprite.top > canvas.height || !sprite.visible){   
                var random = Math.random();   
                if(point>=200&&point<400){   
                    sprite.fullBlood = 150;   
                    if(random<0.1){   
                        sprite.badKind = 2;   
                        sprite.fullBlood = 250;   
                    }   
                }else if(point>=400&&point<600){   
                    sprite.fullBlood = 250;   
                    if(random<0.2){   
                        sprite.badKind = 2;   
                        sprite.fullBlood = 400;   
                    }   
                    if(random<0.1){   
                        sprite.badKind = 3;   
                        sprite.fullBlood = 600;   
                    }   
                }else if(point>=600){   
                    sprite.fullBlood = 500;   
                    if(random<0.4){   
                        sprite.badKind = 2;   
                        sprite.fullBlood = 700;   
                    }   
                    if(random<0.2){   
                        sprite.badKind = 3;   
                        sprite.fullBlood = 1000;   
                    }   
                }   
                sprite.visible = true;   
                sprite.blood = sprite.fullBlood;   
                sprite.left = Math.random()*(canvas.width-2*planWidth)+planWidth;   
                sprite.top = Math.random()*canvas.height - canvas.height;   
            }   
            sprite.top += sprite.speed;   
        },   
        shot:function(sprite){   
            this.addMissle(sprite , sprite.rotateAngle);   
            var missleAngle = 0.1   
            for(var i=1;i<sprite.fireLevel;i++){   
                this.addMissle(sprite , sprite.rotateAngle-i*missleAngle);   
                this.addMissle(sprite , sprite.rotateAngle+i*missleAngle);   
            }   
        },   
        addMissle:function(sprite , angle){   
            for(var j=0;j<missles.length;j++){   
                if(!missles[j].visible){   
                    missles[j].left = sprite.left;   
                    missles[j].top = sprite.top;   
                    missles[j].rotateAngle = angle;   
                    var missleSpeed = 20;   
                    missles[j].velocityX = missleSpeed*Math.sin(-missles[j].rotateAngle);   
                    missles[j].velocityY = missleSpeed*Math.cos(-missles[j].rotateAngle);   
                    missles[j].visible = true;   
                    break;   
                }   
            }   
        }   
    }];   
    W.badPlanPainter = {   
        paint:function(sprite){   
            var img = new Image();   
            img.src="../planGame/image/ship.png"
            switch(sprite.badKind){   
                case 1:ctx.drawImage(img , 96 , 0 , planWidth , planWidth , -planWidth/2 , -planHeight/2 , planWidth , planWidth);   
                break;   
                case 2:ctx.drawImage(img , 120 , 0 , planWidth , planWidth , -planWidth/2 , -planHeight/2 , planWidth , planWidth);   
                break;   
                case 3:ctx.drawImage(img , 144 , 0 , planWidth , planWidth , -planWidth/2 , -planHeight/2 , planWidth , planWidth);   
                break;   
            }   
            ctx.strokeStyle = "#FFF";   
            ctx.fillStyle = "#F00";   
            var bloodHeight = 1;   
            ctx.strokeRect(-planWidth/2-1 , planHeight+bloodHeight+3 , planWidth+2 , bloodHeight+2);   
            ctx.fillRect(planWidth/2-planWidth*sprite.blood/sprite.fullBlood , planHeight+bloodHeight+3 , planWidth*sprite.blood/sprite.fullBlood , bloodHeight);   
        }   
    }   
    W.planSize = function(){   
        return {   
            w:planWidth,   
            h:planHeight   
        }       
    }   
})(window);
Copier après la connexion
Ces méthodes de dessin sont relativement simples.


Parlez principalement du mouvement de l'avion et du contrôle du nombre d'objets. Comment se déplace l'avion ? Il ne fait aucun doute qu'en contrôlant son mouvement via le clavier, de nombreuses personnes peuvent penser à faire continuer l'avion à se déplacer en jugeant le keyCode lors de l'appui sur la méthode keydown. Mais il y a un problème. L'événement keydown ne prend pas en charge les pressions multiples sur une touche, c'est-à-dire que lorsque vous appuyez sur la touche X, le keyCode est 88. En même temps, lorsque vous appuyez sur la touche de direction, le keyCode deviendra instantanément. 37, c'est-à-dire que si vous voulez simplement contrôler le mouvement de l'avion avec la touche enfoncée, l'avion ne peut faire qu'une seule chose, soit il ne peut se déplacer que dans une certaine direction, soit il ne peut que tirer.

Par conséquent, nous devons réaliser le mouvement de l'avion via keydown et keyup. Le principe est facile à comprendre : lorsque nous appuyons sur la touche de direction gauche, nous donnons à l'avion un état gauche, ce qui signifie que l'avion. L'attribut toLeft est vrai, et dans la boucle d'animation, l'état de l'avion est jugé. Si toLeft est vrai, la valeur x de l'avion continuera à diminuer et l'avion continuera à se déplacer vers la gauche, puis le. keyup sera déclenché lorsque nous lèverons notre doigt, nous libérerons l'état gauche de l'avion dans l'événement keyup. L'avion a arrêté de se déplacer vers la gauche. Le même principe s'applique aux autres états. Si vous l'écrivez ainsi, vous pouvez faire en sorte que l'avion ait plusieurs états tout au long de sa vie. Vous pouvez tirer et courir en même temps.

Le code implémenté est le suivant :

//keydown/keyup事件的绑定     
  window.onkeydown = function(event){   
            switch(event.keyCode){   
                case 88:myplan.fire = true;   
                break;   
                case 90:myplan.rotateLeft=true;   
                break;   
                case 67:myplan.rotateRight=true;   
                break;   
                case 37:myplan.toLeft = true;   
                break;   
                case 38:myplan.toTop = true;   
                break;   
                case 39:myplan.toRight = true;   
                break;   
                case 40:myplan.toBottom = true;   
                break;   
            }   
        }   
        window.onkeyup = function(event){   
            switch(event.keyCode){   
                case 88:myplan.fire = false;   
                break;   
                case 90:myplan.rotateLeft=false;   
                break;   
                case 67:myplan.rotateRight=false;   
                break;   
                case 37:myplan.toLeft = false;   
                break;   
                case 38:myplan.toTop = false;   
                break;   
                case 39:myplan.toRight = false;   
                break;   
                case 40:myplan.toBottom = false;   
                break;   
            }   
        }       
//飞机每一帧的状态更新处理代码   
execute:function(sprite,time){   
            if(sprite.toTop){   
                spritesprite.top = sprite.top<planHeight/2? sprite.top : sprite.top-sprite.velocityY;   
            }   
            if(sprite.toLeft){   
                spritesprite.left = sprite.left<planWidth/2? sprite.left : sprite.left-sprite.velocityX;   
            }   
            if(sprite.toRight){   
                spritesprite.left = sprite.left>canvas.width-planWidth/2? sprite.left : sprite.left+sprite.velocityX;   
            }   
            if(sprite.toBottom){   
                spritesprite.top = sprite.top>canvas.height-planHeight/2? sprite.top : sprite.top+sprite.velocityY;   
            }   
            if(sprite.rotateLeft){   
                sprite.rotateAngle -= sprite.rotateSpeed;   
            }   
            if(sprite.rotateRight){   
                sprite.rotateAngle += sprite.rotateSpeed;   
            }   
            if(sprite.fire&&!sprite.painter.isActive){   
                sprite.painter.isActive = true;   
                this.shot(sprite);   
            }
Copier après la connexion
C'est aussi simple que cela.


  然后说下对象控制,打飞机游戏,会发射大量子弹,产生大量对象,包括爆炸啊,飞机啊,子弹等,如果不停地进行对象的生成和销毁,会让浏览器的负荷变得很大,运行了一段时间后就会卡出翔了。所以,我们要用可以循环利用的对象来解决这个问题,不进行对象的销毁,对所有对象进行保存,循环利用。

  我的做法就是,在游戏初始化的时候,直接生成一定数量的对象,存放在数组里面。当我们需要一个对象的时候,就从里面取,当用完后,再放回数组里面。数组里的所有对象都有一个属性,visible,代表对象当前是否可用。

  举个例子,当我的飞机发射一发炮弹,我需要一发炮弹,所以我就到炮弹数组里遍历,如果遍历到的炮弹visible为true,也就说明该对象正在使用着,不能拿来用,所以继续遍历,直到遍历到visible为false的炮弹对象,说明这个对象暂时没人用。然后就可以拿过来重新设置属性,投入使用了。当炮弹击中敌人或者打出画布外的时候,把炮弹的visible设成false,又成了一个没人用的炮弹在数组里存放起来等待下一次调用。

  所以,我们要预算算好页面大概要用到多少个对象,然后就预先准备好对象,这样,在游戏进行中,不会有对象进行生成和销毁,对游戏性能方面就有了提升了。

    最后再说下音频,游戏里面要用到多个同样的audio才能保证音效的不间断性:

var audio = document.getElementsByTagName("audio");   
                                            for(var i=0;i<audio.length;i++){   
                                                console.log(audio[i].paused)   
                                                if(audio[i].src.indexOf("boom")>=0&&audio[i].paused){   
                                                    audio[i].play();   
                                                    break;   
                                                }   
                                            }
Copier après la connexion

好吧,基本上就这样了。技术或许还不够好,纯碎做个记录,如果代码有不当正处,欢迎指出,共同学习。

以上就是本文的全部内容,希望对大家的学习有所帮助,更多相关内容请关注PHP中文网!

相关推荐:

html5和css3 动态气泡按钮的实现

如何使用jQuery和HTML5实现手机摇一摇的换衣特效

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!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
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
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal