1. Résumé les points clés et les problèmes rencontrés
1. Héritage en JavaScript, il est préférable que la classe parent ne fournisse que le partage de méthodes et les attributs sont écrits à leurs sous-classes respectives pour éviter la confusion des constructeurs de la classe parent et de la sous-classe.
2. Le prototype simule le code hérité et doit être écrit avant toutes les définitions de méthode.
La copie de code est la suivante:
Hero.prototype = nouveau Tank (0, 0, 0);
Hero.prototype.Constructor = Hero;
Héros.prototype.addlife = function () {
this.lifeTimes ++;
Document.QuerySelector ("# Life"). InnerHtml = Hero.lifeTimes;
}
3. Lorsque des graphiques de dessin de la toile, à l'exception des rectangles, tout le reste doit être ajouté avec ctx.beginpath (); et ctx.closepath ();
4. La fonction Concat peut fusionner les tableaux ou renvoyer un élément dans un nouveau tableau
5. L'image sera chargée une fois l'attribut SRC attribué, mais si l'image n'est pas chargée, elle entraînera une défaillance, alors utilisez l'événement Onload pour le gérer.
6. Développez la fonction du tableau et supprimez l'élément spécifié
La copie de code est la suivante:
// étendre pour supprimer l'élément spécifié
Array.prototype.deleteelement = fonction (obj) {
if (obj) {
for (var i = 0; i <this.length; i ++) {
if (this [i] === obj) {
this.splice (i, 1);
}
}
}
}
7. Paramètres de minuterie, le premier paramètre de la méthode setInterval ("Fun", 1000) peut être une chaîne, telle que "Hero.Say ()", similaire à EVAT, exécutera cette chaîne de code, afin qu'il puisse donner au fonction du paramètre supérieur et spécifie également le contexte exécutif de cette fonction. Mais si le passage est une poignée d'une fonction, il ne peut pas prendre de paramètres et le contexte ne peut pas être spécifié.
La copie de code est la suivante:
// temporisateur, exercice par vous-même
this.timer = setInterval ((function (context) {
return function () {
Bullet.prototype.move.call (contexte)
}
}) (this), 30);
J'ai enregistré l'environnement d'exécution actuel et appelé la méthode d'appel pour s'exécuter manuellement.
8. La conception fonctionnelle de la méthode, en plus des fonctions, doit inclure la détection conditionnelle de cette fonction, telle que Move, qui devrait inclure dans quelles circonstances peuvent être déplacées et partout où vous ne pouvez pas vous déplacer. Cette détection ne doit pas être placée en externe.
9. Lors de l'écriture de code, vous ne devriez pas penser à la conception ou à l'optimisation. Soyez clair dans la réflexion, ne soyez pas confus et concentrez-vous sur une chose.
10. JavaScript n'a pas de fonction de sommeil, vous pouvez créer une variable en tant que tampon pour atteindre l'objectif de l'exécution d'intervalle
2. Implémentation du code
1. Ce programme est divisé en bombe.js, bullet.js, draw.js, tank.js, index.html, img, musique,
2. Effet final
3. Code
1.Index.html
La copie de code est la suivante:
<! Doctype html>
<html>
<adal>
<Title> </Title>
<meta charset = "utf-8">
<style type = "text / css">
corps {
Police: 14px "Sans-Serif"
}
#Carte {
Color d'arrière-plan: # 000000;
}
.montrer {
flotter: à gauche
}
#guide {
flottant: à gauche;
Largeur: 200px;
hauteur: 390px;
marge-gauche: 5px;
Contexte: #cccccc;
rembourrage: 5px;
}
</ style>
<script type = "text / javascript" src = "tank.js"> </ script>
<script type = "text / javascript" src = "bullet.js"> </ script>
<script type = "text / javascript" src = "bomb.js"> </ script>
<script type = "text / javascript" src = "draw.js"> </ script>
<script type = "text / javascript">
window.onload = function () {
// Informations sur toile
width = document.getElementById ('map'). largeur;
height = document.getElementById ('map'). hauteur;
ctx = document.getElementById ('map'). getContext ('2d');
// page initiale
var starImg = new image ();
starImg.src = "img / star.jpg";
starImg.onload = function () {
ctx.DrawImage (starImg, 0, 0, largeur, hauteur);
}
// Surveillance du clavier et retour pour démarrer le jeu
document.body.onkeydown = function () {
var keycode = event.KeyCode;
commutateur (keycode) {
Cas 13:
// Paramètres d'initialisation
init ()
// actualiser la page
setInterval (Draw, 30);
document.body.onkeydown = GameControl;
casser;
}
}
}
fonction init () {
// Players et ordinateurs
Hero = nouveau héros (100, 300, 0);
ennemis = [];
pour (var i = 0; i <3; i ++) {
enness.push (nouvel ennemi (100 + i * 50, 0, 2));
}
// Fusionner le tableau
alltank = enness.concat (héros);
//bombe
Bombes = [];
IM = new Image ();
IM2 = nouvelle image ();
IM3 = nouvelle image ();
im.src = "img / bomb_3.gif";
im2.src = "img / bomb_2.gif";
im3.src = "img / bomb_1.gif";
}
fonction gameControl () {
var keycode = event.KeyCode;
commutateur (keycode) {
Cas 65:
Hero.Moveleft ();
pause; // à gauche
Cas 83:
Hero.Movedown ();
pause; // suivant
Cas 87:
Hero.Moveup ();
pause; // sur
Cas 68:
Hero.Moveright ();
pause; // à droite
Cas 74:
Hero.shot ();
casser;
Cas 49:
Hero.AddLife ()
casser;
}
}
// étendre pour supprimer l'élément spécifié
Array.prototype.deleteelement = fonction (obj) {
if (obj) {
for (var i = 0; i <this.length; i ++) {
if (this [i] === obj) {
this.splice (i, 1);
}
}
}
}
</cript>
</ head>
<body>
<div>
<canvas id = "map">
</ canvas>
<audio id = "music" autoplay = "autoplay">
<source src = "music / 111.wav">
</ audio>
</div>
<div id = "guide">
<p> Appuyez sur Entrée pour démarrer le jeu </p>
<p> Appuyez sur la touche 1 pour augmenter la vie, la valeur par défaut est 1 </p>
<p> Compte de vie restant: <étiquette id = "life"> 1 </bable> </p>
<div id = "data">
</div>
</div>
</docy>
</html>
2.Draw.js
La copie de code est la suivante:
/ **
* Créé par Alane le 14-3-18.
* /
fonction Draw () {
// Détection de la vie et de la mort de balles et de chars
checkDead ();
// effacer la toile
CTX.ClearRect (0,0,500 400);
// dessine le joueur
if (! Hero.isdead) {
Drawtank (héros);
}autre{
Hero.cutLife ();
}
// dessiner des chars ennemis
pour (var i = 0; i <enevys.length; i ++) {
Drawtank (ennemis [i]);
}
// dessiner des balles ennemies
pour (var j = 0; j <ennemis.length; j ++) {
var temp = Enemys [J] .BulletsList;
pour (var i = 0; i <temp.length; i ++) {
drawbullet (temp [i]);
}
}
// dessine la balle du joueur
var temp = Hero.BulletsList;
pour (var i = 0; i <temp.length; i ++) {
drawbullet (temp [i]);
}
// dessiner une bombe
pour (var i = 0; i <bombs.length; i ++) {
Drawown (bombes [i]);
}
}
fonction DrawTank (réservoir) {
var x = tank.x;
var y = tank.y;
ctx.fillstyle = tank.color;
if (tank.direct == 0 || tank.direct == 2) {
ctx.fillrect (x, y, 5,30);
ctx.fillrect (x + 15, y, 5,30);
ctx.fillrect (x + 6, y + 8, 8,15);
ctx.strokestyle = tank.color;
ctx.linewidth = '1.5';
if (tank.direct == 0) {
ctx.beginPath ();
ctx.moveto (x + 10, y-2);
ctx.lineto (x + 10, y + 8);
ctx.closepath ();
}autre{
ctx.beginPath ();
ctx.moveto (x + 10, y + 24);
ctx.lineto (x + 10, y + 32);
ctx.closepath ();
}
ctx.stroke ();
}autre{
ctx.fillrect (x, y, 30,5);
ctx.fillrect (x, y + 15, 30,5);
ctx.fillrect (x + 8, y + 6, 15,8);
ctx.strokestyle = '# ff0000';
ctx.linewidth = '1.5';
if (tank.direct == 3) {
ctx.beginPath ();
ctx.moveto (x-2, y + 10);
ctx.lineto (x + 8, y + 10);
ctx.closepath ();
}autre{
ctx.beginPath ();
ctx.moveto (x + 24, y + 10);
ctx.lineto (x + 32, y + 10);
ctx.closepath ();
}
ctx.stroke ();
}
}
fonction drawbullet (bullet) {
CTX.FillStyle = Bullet.Color;
ctx.beginPath ();
CTX.ARC (Bullet.x, Bullet.Y, 2 360, True);
ctx.closepath ();
ctx.fill ();
}
Fonction DrawBown (obj) {
if (obj.life> 8) {
CTX.DrawImage (IM, Obj.x, Obj.Y, 50,50);
} else if (obj.life> 4) {
CTX.DrawImage (IM2, Obj.x, Obj.Y, 50,50);
}autre{
CTX.DrawImage (IM3, Obj.x, Obj.Y, 50,50);
}
obj.lifedown ();
if (obj.life <= 0) {
Bombes.deleteelement (obj);
}
}
fonction CheckDead () {
// Détection de la vie et de la mort de la balle ennemie
pour (var j = 0; j <ennemis.length; j ++) {
var temp = Enemys [J] .BulletsList;
pour (var i = 0; i <temp.length; i ++) {
var o = temp [i];
if (o.isdead) {
Temp.Deleteelement (o);
}
}
}
// Détection de la vie et de la mort des joueurs
var temp = Hero.BulletsList;
pour (var i = 0; i <temp.length; i ++) {
var o = temp [i];
if (o.isdead) {
Temp.Deleteelement (o);
}
}
// Détection de la vie et de la mort du réservoir ennemi
pour (var i = 0; i <enevys.length; i ++) {
var o = ennemis [i];
if (o.isdead) {
ennemis.deleteelement (o);
}
}
}
Bombe.js
La copie de code est la suivante:
/ **
* Créé par Alane le 14-3-18.
* /
bombe de fonction (x, y) {
this.life = 12;
this.x = x;
this.y = y;
}
Bomb.prototype.lifEdown = function () {
this.life--;
}
Tank.js
La copie de code est la suivante:
/ **
* Créé par Alane le 14-3-7.
* /
/ **
* Direct 0 sur
* 1 à droite
* 2
* 3 à gauche
* @param x
* @param y
* @param direct
* @constructor
* /
// ************************************************** **************************************************** **************************************************** **************************************************** **************************************************** **************************************************** **************************************************** *************************** *********************** ************************** /
// classe parent de chars
Tank de fonction (x, y, direct) {
this.speed = 2;
}
Tank.prototype.moveup = function () {
// Détection des frontières
if (this.y <0) {
// Changer la direction
this.changeDirect ();
retour;
}
this.y - = this.speed;
this.direct = 0;
}
Tank.prototype.mouvedown = function () {
if (this.y> hauteur - 30) {
this.changeDirect ();
retour;
}
this.y + = this.speed;
this.direct = 2;
}
Tank.prototype.moveleft = function () {
if (this.x <0) {
this.changeDirect ();
retour;
}
this.x - = this.speed;
this.direct = 3;
}
Tank.prototype.moveright = function () {
if (this.x> largeur - 30) {
this.changeDirect ();
retour;
}
this.x + = this.speed;
this.direct = 1;
}
// Changer la direction
Tank.prototype.changeDirect = fonction () {
while (true) {
var temp = math.round (math.random () * 3);
if (this.direct! = temp) {
this.direct = temp;
casser;
}
}
//alert("x="+ ce
}
// des balles tirées
Tank.prototype.shot = function () {
if (this.isdead) {
retour;
}
if (this.bulletslist.length <this.maxbulletsize) {
// Créer une nouvelle balle
var bullet = null;
commutateur (this.direct) {
Cas 0:
Bullet = nouvelle balle (this.x + 10, this.y - 2, 0, this.color);
casser;
Cas 1:
Bullet = nouvelle balle (this.x + 32, this.y + 10, 1, this.color);
casser;
Cas 2:
Bullet = nouvelle balle (this.x + 10, this.y + 32, 2, this.color);
casser;
Cas 3:
Bullet = nouvelle balle (this.x - 2, this.y + 10, 3, this.color);
casser;
}
// mis dans le magazine
this.bulletslist.push (balle);
}
}
// ************************************************** **************************************************** **************************************************** **************************************************** **************************************************** **************************************************** **************************************************** *************************** *********************** ************************** /
//Joueur
fonction héros (x, y, direct) {
this.lifETimes = 5;
this.isdead = false;
this.color = '# ff0000';
this.x = x;
this.y = y;
this.Direct = Direct;
this.bulletsList = [];
this.maxbulletSize = 10;
this.newLife = null;
}
Hero.prototype = nouveau Tank (0, 0, 0);
Hero.prototype.Constructor = Hero;
Héros.prototype.addlife = function () {
this.lifeTimes ++;
Document.QuerySelector ("# Life"). InnerHtml = Hero.lifeTimes;
}
Héros.prototype.cutlife = function () {
if (this.lifetimes> = 1 &&! this.newlife) {
ce.lifETimes--;
this.newLife = setTimeout ("Hero.NewLife ()", 2000);
}
}
Héros.prototype.newlife = function () {
this.isdead = false;
ClearTimeout (Hero.NewLife);
Hero.NewLife = null;
Document.QuerySelector ("# Life"). InnerHtml = Hero.lifeTimes;
}
// ************************************************** **************************************************** **************************************************** **************************************************** **************************************************** **************************************************** **************************************************** *************************** *********************** ************************** /
// Tank ennemi
fonction ennemi (x, y, direct) {
this.isdead = false;
this.color = 'bleu';
this.x = x;
this.y = y;
this.Direct = Direct;
this.bulletsList = [];
this.maxbulletSize = 1;
// minuterie, mouvement automatique
this.timer1 = setInterval ((function (context) {
return function () {
//se déplacer
Ennemi.prototype.move.call (contexte);
}
}) (this), 30);
// minuterie, tir
this.timer2 = setInterval ((function (context) {
return function () {
//tournage
Tank.prototype.shot.call (contexte);
}
}) (this), 2000);
// temporisateur, modifier la direction
this.timer3 = setInterval ((function (context) {
return function () {
//tournage
Tank.prototype.changeDirect.Call (contexte);
}
}) (this), 3000);
}
Ennemi.prototype = nouveau réservoir (0, 0, 0);
Ennemi.prototype.constructor = ennemi;
Ennemi.prototype.move = fonction () {
commutateur (this.direct) {
Cas 0:
this.moveup ();
casser;
Cas 1:
this.moveright ();
casser;
Cas 2:
this.Movedown ();
casser;
Cas 3:
this.moveleft ();
casser;
}
}
Bullet.js
La copie de code est la suivante:
/ **
* Créé par Alane le 14-3-11.
* /
Fonction Bullet (x, y, direct, couleur) {
this.isdead = false;
this.x = x;
this.y = y;
this.Direct = Direct;
this.speed = 4;
this.color = couleur;
// temporisateur, exercice par vous-même
this.timer = setInterval ((function (context) {
return function () {
Bullet.prototype.move.call (contexte)
}
}) (this), 30);
}
Bullet.prototype.move = function () {
commutateur (this.direct) {
Cas 0:
this.y - = this.speed;
casser;
Cas 1:
this.x + = this.speed;
casser;
Cas 2:
this.y + = this.speed;
casser;
Cas 3:
this.x - = this.speed;
casser;
}
// Détection des frontières
if (this.y <0 || this.x> largeur || this.y> hauteur || this.x <0) {
ClearInterval (this.timer);
this.isdead = true;
}
// La détection de collision détecte les réservoirs ennemis
pour (var i = 0; i <alltank.length; i ++) {
var temp = alltank [i];
if (temp.isdead) {
continuer;
}
commutateur (temp.Direct) {
Cas 0:
Cas 2: if (this.x> temp.x && this.x <temp.x + 20 && this.y> temp.y && this.y <temp.y + 30) {
if (this.color == temp.color) {
casser;
}
Bombs.push (nouvelle bombe (temp.x-10, temp.y-10));
ClearInterval (this.timer);
this.isdead = true;
temp.isdead = true;
}casser
Cas 1:
Cas 3: if (this.x> temp.x && this.x <temp.x + 30 && this.y> temp.y && this.y <temp.y + 20) {
if (this.color == temp.color) {
casser;
}
Bombs.push (nouvelle bombe (temp.x-10, temp.y-10));
ClearInterval (this.timer);
this.isdead = true;
temp.isdead = true;
}casser;
}
}
}
Téléchargement du code source