Maison  >  Article  >  interface Web  >  Partagez vous-même l'exemple de code pour créer vous-même html5 Star Trek

Partagez vous-même l'exemple de code pour créer vous-même html5 Star Trek

黄舟
黄舟original
2017-04-01 11:26:101753parcourir

Le troisième jour d'apprentissage html5 canevas , je trouve que c'est quand même bien Ce n'est pas amusant et j'oublie ça en un clin d'œil, alors je vais faire un petit jeu pour jouer quand j'ai le temps Le jeu doit faire attention aux performances, et il y en a ! logiques qui doivent être prises en compte. Je pense que cela nécessite également une modifiabilité par l'utilisateur, c'est-à-dire une configuration utilisateur. Commençons notre voyage simple mais intéressant -

Si vous voulez d'abord voir l'effet, sautez et essayez-le

Première étape, bien sûr, vous avez besoin d'un canevas

1 <canvas id="canvas" width="300" height="400">你的浏览器不支持Canvas</canvas>

La structure globale de JavaScript est la suivante suit :

var定义一些变量
planeMoveTimer飞机移动监听/计时器
attackEnemyTimer发射炮弹计时器
onkeydown监听
onkeyup监听
drawPlane画飞机
drawEnemy画敌人

Prédéfinissez d'abord quelques variables

var _keyA = _keyD = _keyW = _keyS = 0,  // 存储按键状态

    step = 8,                          // 飞机移动速率
    w = 34, h = 44,                  // 飞机实际大小
    planeX = 133, planeY = 356,      // 飞机目前位置
    planeSrc = "feiji.png",          // 飞机素材位置
    imgW = 177, imgH = 220,          // 飞机源图尺寸

    cw = 300, ch = 400,  // 画布大小
    canvas = document.getElementById("canvas"),
    ctx = canvas.getContext("2d");

Ce jeu n'utilise qu'une seule ressource externe, qui est la image Pour obtenir l'adresse, veuillez visiter. le lien de localisation GitHub du projet donné au bas de cet article. Jump

Regardons d'abord les deux méthodes de dessin

function drawPlane(x, y) {
    var img = new Image();
    img.src = planeSrc;  // 飞机源图地址
    img.onload = function() {
        ctx.drawImage(img, 0, 0, imgW, imgH, planeX, planeY, w, h);
    }
}
function drawEnemy(){
    for(var a=0;a<cw;a+=10) {
        for(var b=0;b<ch-300;b+=10) {
            ctx.beginPath();
            ctx.fillStyle = "orange";
            ctx.strokeStyle = "black";
            ctx.strokeRect(a, b, 10 ,10);
            ctx.fillRect(a, b, 10, 10);
            ctx.closePath();
        }
    }
}

L'image de l'avion doit être dessinée dans le chargement. (). L'ennemi actuel est toujours un tas de briques orange immobiles. Dessinez-les en parcourant le haut de la toile

Ensuite, regardez les deux événements du clavier  :

Quant à savoir pourquoi les variables _keyA, _keyD, _keyW et _keyS sont définies dans les deux événements, et l'événement de dessin n'est pas déclenché directement. La raison est que lorsque deux touches sont enfoncées longuement en même temps. , l'événement ne peut pas être déclenché en même temps. Celui qui appuie en premier ne peut déclencher l'événement qu'une seule fois. Seul celui qui appuie sur le dernier bouton peut déclencher l'événement tout le temps. Pour faire simple, si je veux passer à. le coin supérieur gauche et appuyez sur A et W en même temps, en supposant que A est un peu plus lent que W, même s'il est très petit, alors la trajectoire de mouvement de l'avion consiste à monter d'abord d'un pas, puis à se déplacer complètement à gauche. Ce n'est évidemment pas ce que je veux. Oui, j'utilise 4 variables pour stocker l'état des touches. Lorsque la touche est enfoncée, définissez son état sur 1. Lorsque la touche est enfoncée, définissez son état sur 0. . Ensuite, nous utilisons une minuterie pour lire en continu l'état de ces clés et
window.document.onkeydown = function(evt){
    evt = (evt) ? evt : window.event;
    switch(evt.keyCode) {
        case 65:  // A
            _keyA = 1;
            break;
        case 68:  // D
            _keyD = 1;
            break;
        case 87:  // W
            _keyW = 1;
            break;
        case 83:  // S
            _keyS = 1;
            break;
    }
}
window.document.onkeyup = function(evt){
    evt = (evt) ? evt : window.event;
    switch(evt.keyCode) {
        case 65:  // A
            _keyA = 0;
            break;
        case 68:  // D
            _keyD = 0;
            break;
        case 87:  // W
            _keyW = 0;
            break;
        case 83:  // S
            _keyS = 0;
            break;
    }
}
mettre à jour

l'état de l'avion comme suit :

ctx.clearRect() est utilisé pour. effacez l'avion à sa position d'origine pour le dessin. Préparez-vous pour l'état suivant de l'avion, mais il y a un gros problème. Si le jeu a un arrière-plan et des chevauchements, cela ne signifie pas que tout le bloc est effacé. les choses qui ne sont pas l'avion sont également effacées ? Pardonnez-moi ? Stupide, ne considérez pas ce problème pour l'instant

En jugeant l'état du bouton, la distance de pas de chaque mouvement est le pas prédéfini et la limite. est bien géré :
var planeMoveTimer = window.setInterval(function(){
    if(_keyA||_keyD||_keyW||_keyS){
        ctx.clearRect(planeX, planeY, w, h);
        _keyA && (planeX-=step);
        _keyD && (planeX+=step);
        _keyW && (planeY-=step);
        _keyS && (planeY+=step);
        planeX>=0 || (planeX=0);
        planeX<=(cw-w) || (planeX=cw-w);
        planeY>=0 || (planeY=0);
        planeY<=(ch-h) || (planeY=ch-h);
        drawPlane(planeX, planeY);
    }
}, 10);

Ensuite, la minuterie d'attaque :

Un boulet de canon est tiré toutes les 0,5 secondes, et chaque boulet de canon est configuré avec une minuterie séparée pour un contrôle facile. J'utilise également le. méthode d'essuyage d'abord puis de peinture pour le mouvement du boulet de canon. Étant donné que le mouvement du boulet de canon a également une distance de pas, ce qu'on appelle l'effet de pénétration de l'obus consiste simplement à tracer une ligne droite avec la même couleur que la couleur de fond. Essayez de modifier la foulée du boulet de canon pour ajuster la vitesse du boulet de canon, ainsi que la taille du boulet de canon.

C'est la dernière étape. Il n'y a plus rien à faire. Nous devons dessiner les ennemis et les avions dès le début !
var attackEnemyTimer = window.setInterval(function(){
    var cannonX = planeX+Math.floor(w/2);  // 炮口X轴位置
    var cannonY = planeY;  // 炮口Y轴位置
    var tmpTimer = window.setInterval(function(){  // 每颗炮弹的移动计时器
        ctx.clearRect(cannonX-1, cannonY-3, 2, 3);
        cannonY -= 3;  // 炮弹步距
        if(cannonY<0){
            // 炮弹的贯透效果
            ctx.beginPath();
            ctx.moveTo(cannonX, 100);  // 100为enemy的最低位置
            ctx.strokeStyle = "white";
            ctx.lineWidth = "4";  // 模拟不规则毁坏,暂时尚未没实现
            ctx.lineTo(cannonX, 0);
            ctx.stroke();
            ctx.closePath();
            window.clearInterval(tmpTimer);  // 清除该炮弹的计时器
        }
        ctx.clearRect(cannonX-1, cannonY-3, 2, 3);
        ctx.beginPath();
        ctx.fillStyle="red";
        ctx.fillRect(cannonX-1, cannonY-3, 2, 3);  // 炮弹大小:2X3
        ctx.closePath();
    }, 0);
}, 500);

Fait ! Je veux toujours continuer à optimiser et augmenter la jouabilité, mais je n’ai vraiment pas le temps de le faire. Il y a beaucoup d’autres choses à apprendre, donc ce jeu sera comme ça pour l’instant ! N'est-ce pas très simple ! Haha, c'est gênant, le titre est trop tentant, je n'y peux rien !

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