1. Resumir puntos clave y problemas encontrados
1. Herencia en JavaScript, es mejor que la clase principal solo proporcione compartir métodos y los atributos se escriben a sus respectivas subclases para evitar la confusión de los constructores de la clase principal y la subclase.
2. El prototipo simula el código heredado y debe escribirse antes de todas las definiciones de método.
La copia del código es la siguiente:
Hero.prototype = nuevo tanque (0, 0, 0);
Hero.prototype.constructor = hero;
Hero.prototype.addlife = function () {
this.lifetimes ++;
document.queryselector ("#life"). innerhtml = hero.lifetimes;
}
3. Cuando los gráficos de dibujo de lienzo, excepto los rectángulos, todo lo demás debe agregarse con CTX.BeginPath ();
4. La función concat puede fusionar matrices o devolver un elemento a una nueva matriz
5. La imagen se cargará después de asignar el atributo SRC, pero si la imagen no se carga, causará falla, así que use el evento de entrada para manejarlo.
6. Expanda la función de matriz y elimine el elemento especificado
La copia del código es la siguiente:
// extender para eliminar el elemento especificado
Array.prototype.deleteElement = function (obj) {
if (obj) {
para (var i = 0; i <this.length; i ++) {
if (this [i] === obj) {
this.splice (i, 1);
}
}
}
}
7. Configuración del temporizador, el primer parámetro del método SetInterval ("Fun", 1000) puede ser una cadena, como "Hero.say ()", similar a EVAL. Funciona el parámetro superior y también especifica el contexto de ejecución de esta función. Pero si el paso es un mango de una función, no puede tomar parámetros y el contexto no se puede especificar.
La copia del código es la siguiente:
// temporizador, ejercita solo
this.timer = setInterval ((function (context) {
Función de retorno () {
Bullet.prototype.move.call (contexto)
}
}) (esto), 30);
Guardé el entorno de ejecución actual y llamé al método de llamada para ejecutar manualmente.
8. El diseño funcional del método, además de las funciones, debe incluir la detección condicional de esta función, como Mover, que debe incluir en qué circunstancias se pueden mover y donde no pueda moverse. Esta detección no debe colocarse externamente.
9. Al escribir código, no debe pensar en el diseño u optimización. Sea claro al pensar, no se confunda y concéntrese en una cosa.
10. JavaScript no tiene función de sueño, puede crear una variable como un amortiguador para lograr el propósito de la ejecución del intervalo
2. Implementación del código
1. Este programa se divide en Bomb.js, Bullet.js, sorth.js, Tank.js, index.html, img, música,
2. Efecto final
3. Código
1.Index.html
La copia del código es la siguiente:
<! Doctype html>
<html>
<Evista>
<title> </title>
<meta charset = "utf-8">
<style type = "text/css">
cuerpo {
fuente: 14px "sans-serif"
}
#Map {
Color de fondo: #000000;
}
.espectáculo {
flotante: izquierda
}
#guía {
flotante: izquierda;
Ancho: 200px;
Altura: 390px;
margen-izquierda: 5px;
Antecedentes: #CCCCCC;
relleno: 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 () {
// Información de lienzo
width = document.getElementById ('map'). width;
altura = document.getElementById ('map'). Height;
ctx = document.getElementById ('map'). getContext ('2d');
// página inicial
var starimg = nueva imagen ();
starimg.src = "img/star.jpg";
starimg.onload = function () {
ctx.DrawImage (Starimg, 0, 0, ancho, altura);
}
// Monitoreo del teclado y regresa para comenzar el juego
document.body.onkeydown = function () {
var keycode = event.keycode;
Switch (KeyCode) {
Caso 13:
// Parámetros de inicialización
init ()
// Actualiza la página
setInterval (dibujo, 30);
document.body.onkeydown = gameControl;
romper;
}
}
}
función init () {
// jugadores y computadoras
héroe = nuevo héroe (100, 300, 0);
enemys = [];
para (var i = 0; i <3; i ++) {
enemys.push (nuevo enemigo (100 + i * 50, 0, 2));
}
// Matriz de fusiones
allTank = enemys.concat (héroe);
//bomba
Bombas = [];
im = nueva imagen ();
im2 = nueva imagen ();
im3 = nueva imagen ();
im.src = "img/bomb_3.gif";
im2.src = "img/bomb_2.gif";
im3.src = "img/bomb_1.gif";
}
function gameControl () {
var keycode = event.keycode;
Switch (KeyCode) {
Caso 65:
hero.moveleft ();
ruptura; // izquierda
Caso 83:
Hero.MoVoDown ();
romper;/Siguiente
Caso 87:
hero.moveUp ();
romper;/
Caso 68:
hero.moveright ();
romper; // correcto
Caso 74:
hero.shot ();
romper;
Caso 49:
hero.addlife ()
romper;
}
}
// extender para eliminar el elemento especificado
Array.prototype.deleteElement = function (obj) {
if (obj) {
para (var i = 0; i <this.length; i ++) {
if (this [i] === obj) {
this.splice (i, 1);
}
}
}
}
</script>
</ablo>
<Body>
<div>
<Canvas id = "map">
</able>
<audio id = "music" autoplay = "autoplay">
<fuente src = "music/111.wav">
</audio>
</div>
<div id = "guía">
<p> Presione Entrar para iniciar el juego </p>
<p> Presione 1 tecla para aumentar la vida, el valor predeterminado es 1 </p>
<p> Recuento de vida restante: <Label id = "Life"> 1 </selabel> </p>
<div id = "datos">
</div>
</div>
</body>
</html>
2.draw.js
La copia del código es la siguiente:
/**
* Creado por Alane el 14-3-18.
*/
function draw () {
// Detección de vida y muerte de balas y tanques
checkdead ();
// borrar el lienzo
CTX.ClearRect (0,0,500,400);
// Dibuja al jugador
if (! hero.isdead) {
DrawTank (héroe);
}demás{
hero.cutlife ();
}
// dibujar tanques enemigos
para (var i = 0; i <enemys.length; i ++) {
DrawTank (enemigos [i]);
}
// dibujar balas enemigas
para (var j = 0; j <enemys.length; j ++) {
var temp = enemys [j] .bulletsList;
para (var i = 0; i <temp.length; i ++) {
DrawBullet (temp [i]);
}
}
// Dibuja la bala del jugador
var temp = hero.bulletsList;
para (var i = 0; i <temp.length; i ++) {
DrawBullet (temp [i]);
}
// dibujar bomba
para (var i = 0; i <bombs.length; i ++) {
Drawbown (bombas [i]);
}
}
function drawTank (tanque) {
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 ();
}demás{
ctx.beginpath ();
ctx.moveto (x+10, y+24);
ctx.lineto (x+10, y+32);
ctx.ClosePath ();
}
ctx.stroke ();
}demás{
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 ();
}demás{
ctx.beginpath ();
ctx.moveto (x+24, y+10);
ctx.lineto (x+32, y+10);
ctx.ClosePath ();
}
ctx.stroke ();
}
}
función DrawBullet (Bullet) {
ctx.fillstyle = Bullet.color;
ctx.beginpath ();
ctx.arc (bullet.x, bullet.y, 2,360, verdadero);
ctx.ClosePath ();
ctx.fill ();
}
function 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);
}demás{
CTX.DrawImage (IM3, obj.x, obj.y, 50,50);
}
obj.lifedown ();
if (obj.life <= 0) {
Bombas.deleteelement (obj);
}
}
función checkdead () {
// Detección de la vida y la muerte de la bala enemiga
para (var j = 0; j <enemys.length; j ++) {
var temp = enemys [j] .bulletsList;
para (var i = 0; i <temp.length; i ++) {
var o = temp [i];
if (o.isdead) {
temp.deleteElement (O);
}
}
}
// Detección de la vida de la bala del jugador y la muerte
var temp = hero.bulletsList;
para (var i = 0; i <temp.length; i ++) {
var o = temp [i];
if (o.isdead) {
temp.deleteElement (O);
}
}
// Detección de la vida y muerte del tanque enemigo
para (var i = 0; i <enemys.length; i ++) {
var o = enemigos [i];
if (o.isdead) {
enemys.deleteelement (o);
}
}
}
Bomba.js
La copia del código es la siguiente:
/**
* Creado por Alane el 14-3-18.
*/
Función Bomb (x, y) {
this.life = 12;
this.x = x;
this.y = y;
}
Bomb.prototype.lifedown = function () {
this.life--;
}
Tanque.js
La copia del código es la siguiente:
/**
* Creado por Alane el 14-3-7.
*/
/**
* Dirigir 0 en
* 1 derecho
* 2
* 3 izquierda
* @param x
* @param y
* @param directo
* @constructor
*/
// ****************************************************** ************************************************************ ************************************************************ ************************************************************ ************************************************************ ************************************************************ ************************************************************ ***************************** ******************************** ****************************/
// Clase padre del tanque
Tank de funciones (x, y, directo) {
this.speed = 2;
}
Tank.prototype.moveUp = function () {
// detección de fronteras
if (this.y <0) {
// cambiar de dirección
this.changedirect ();
devolver;
}
this.y -= this.speed;
this.Direct = 0;
}
Tank.prototype.MoveDown = function () {
if (this.y> altura - 30) {
this.changedirect ();
devolver;
}
this.y += this.speed;
this.Direct = 2;
}
Tank.prototype.moveleft = function () {
if (this.x <0) {
this.changedirect ();
devolver;
}
this.x -= this.speed;
this.Direct = 3;
}
Tank.prototype.moveright = function () {
if (this.x> ancho - 30) {
this.changedirect ();
devolver;
}
this.x += this.speed;
this.Direct = 1;
}
// cambiar de dirección
Tank.prototype.changedirect = function () {
while (verdadero) {
var temp = Math.round (Math.random () * 3);
if (this.direct! = temp) {
this.direct = temp;
romper;
}
}
//alert("x="+This.x+ "y ="+this.y+"direct ="+this.Direct)
}
// disparó balas
Tank.prototype.shot = function () {
if (this.isdead) {
devolver;
}
if (this.bulletsList.length <this.maxbulletsize) {
// crear una nueva bala
var bala = nulo;
Switch (this.Direct) {
Caso 0:
bala = nueva bala (this.x + 10, this.y - 2, 0, this.color);
romper;
Caso 1:
bala = nueva bala (this.x + 32, this.y + 10, 1, this.color);
romper;
Caso 2:
bala = nueva bala (this.x + 10, this.y + 32, 2, this.color);
romper;
Caso 3:
bala = nueva bala (this.x - 2, this.y + 10, 3, this.color);
romper;
}
// Poner en la revista
this.bulletsList.push (bala);
}
}
// ****************************************************** ************************************************************ ************************************************************ ************************************************************ ************************************************************ ************************************************************ ************************************************************ ***************************** ******************************** ****************************/
//Jugador
function hero (x, y, directo) {
this.lifetimes = 5;
this.isdead = false;
this.color = '#ff0000';
this.x = x;
this.y = y;
this.direct = directo;
this.bulletsList = [];
this.maxbulletsize = 10;
this.newlife = null;
}
Hero.prototype = nuevo tanque (0, 0, 0);
Hero.prototype.constructor = hero;
Hero.prototype.addlife = function () {
this.lifetimes ++;
document.queryselector ("#life"). innerhtml = hero.lifetimes;
}
Hero.prototype.cutlife = function () {
if (this.lifetimes> = 1 &&! this.newlife) {
this.lifetimes--;
this.newlife = setTimeout ("hero.newlife ()", 2000);
}
}
Hero.prototype.newlife = function () {
this.isdead = false;
Cleartimeout (hero.newlife);
hero.newlife = nulo;
document.queryselector ("#life"). innerhtml = hero.lifetimes;
}
// ****************************************************** ************************************************************ ************************************************************ ************************************************************ ************************************************************ ************************************************************ ************************************************************ ***************************** ******************************** ****************************/
// tanque enemigo
function enemy (x, y, directo) {
this.isdead = false;
this.color = 'Blue';
this.x = x;
this.y = y;
this.direct = directo;
this.bulletsList = [];
this.maxbulletsize = 1;
// temporizador, movimiento automático
this.timer1 = setInterval ((function (context) {
Función de retorno () {
//mover
Enemy.prototype.move.call (contexto);
}
}) (esto), 30);
// temporizador, disparo
this.timer2 = setInterval ((function (context) {
Función de retorno () {
//tiroteo
Tank.prototype.shot.call (contexto);
}
}) (esto), 2000);
// temporizador, cambiar de dirección
this.timer3 = setInterval ((function (context) {
Función de retorno () {
//tiroteo
Tank.prototype.changedirect.call (contexto);
}
}) (esto), 3000);
}
Enemy.prototype = nuevo tanque (0, 0, 0);
Enemy.prototype.constructor = enemy;
Enemy.prototype.move = function () {
Switch (this.Direct) {
Caso 0:
this.MoveUp ();
romper;
Caso 1:
this.moveright ();
romper;
Caso 2:
this.moveDown ();
romper;
Caso 3:
this.moveleft ();
romper;
}
}
Bullet.js
La copia del código es la siguiente:
/**
* Creado por Alane el 14-3-11.
*/
Function Bullet (x, y, directo, color) {
this.isdead = false;
this.x = x;
this.y = y;
this.direct = directo;
this.speed = 4;
this.color = color;
// temporizador, ejercita solo
this.timer = setInterval ((function (context) {
Función de retorno () {
Bullet.prototype.move.call (contexto)
}
}) (esto), 30);
}
Bullet.prototype.move = function () {
Switch (this.Direct) {
Caso 0:
this.y -= this.speed;
romper;
Caso 1:
this.x += this.speed;
romper;
Caso 2:
this.y += this.speed;
romper;
Caso 3:
this.x -= this.speed;
romper;
}
// detección de fronteras
if (this.y <0 || this.x> ancho || this.y> altura || this.x <0) {
ClearInterval (this.timer);
this.isdead = true;
}
// La detección de colisiones detecta tanques enemigos
para (var i = 0; i <allTank.length; i ++) {
var temp = AllTank [i];
if (temp.isdead) {
continuar;
}
Switch (temp.direct) {
Caso 0:
Caso 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) {
romper;
}
Bombs.push (nueva bomba (temp.x-10, temp.y-10));
ClearInterval (this.timer);
this.isdead = true;
temp.isdead = true;
}romper
Caso 1:
Caso 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) {
romper;
}
Bombs.push (nueva bomba (temp.x-10, temp.y-10));
ClearInterval (this.timer);
this.isdead = true;
temp.isdead = true;
}romper;
}
}
}
Descarga del código fuente