1. Суммируйте ключевые моменты и проблемы, с которыми сталкиваются
1. Наследование в JavaScript, для родительского класса лучше всего предоставлять только обмен методами, а атрибуты записываются на их соответствующие подклассы, чтобы избежать путаницы конструкторов родительского класса и подкласса.
2. Прототип имитирует наследственный код и должен быть записан до всех определений методов.
Кода -копия выглядит следующим образом:
Hero.prototype = новый танк (0, 0, 0);
Hero.prototype.constructor = hero;
Hero.prototype.addlife = function () {
this.lifetimes ++;
document.queryselector ("#life"). innerhtml = hero.lifetimes;
}
3. Когда графика холста, за исключением прямоугольников, все остальное должно быть добавлено с помощью ctx.beginpath ();
4. Функция CONCAT может объединять массивы или вернуть элемент в новый массив
5. Изображение будет загружено после назначения атрибута SRC, но если изображение не загружено, оно вызовет сбой, поэтому используйте событие Onload для его обработки.
6. Разверните функцию массива и удалите указанный элемент
Кода -копия выглядит следующим образом:
// расширить, чтобы удалить указанный элемент
Array.prototype.deleteelement = function (obj) {
if (obj) {
for (var i = 0; i <this.length; i ++) {
if (this [i] === obj) {
this.splice (i, 1);
}
}
}
}
7. Настройки таймера, первым параметром метода SetInterval («развлечение», 1000) может быть строка, такой как «hero.say ()», аналогичный Eval, выполнит эту строку кода, поэтому он может дать Функция Верхний параметр, а также указывает работает контекст этой функции. Но если пропуск - это ручка для функции, он не может принять параметры, и контекст не может быть указан.
Кода -копия выглядит следующим образом:
// Таймер, упражнение самостоятельно
this.timer = setInterval ((function (context) {
return function () {
Bullet.prototype.move.call (контекст)
}
}) (это), 30);
Я сохранил текущую среду выполнения и вызвал метод вызова для выполнения вручную.
8. Функциональная конструкция метода, в дополнение к функциям, должна включать условное обнаружение этой функции, такую как ход, который должен включать в какими обстоятельствами перемещаться и куда бы вы не могли двигаться. Это обнаружение не должно быть размещено извне.
9. При написании кода вы не должны думать о проектировании или оптимизации. Будьте ясны в мышлении, не путайтесь и сосредоточьтесь на одном.
10. Javascript не имеет функции сна, вы можете создать переменную в качестве буфера для достижения цели выполнения интервала
2. Реализация кода
1. Эта программа разделена на Bomb.js, bullet.js, draw.js, tank.js, index.html, img, музыка,
2. Окончательный эффект
3. код
1. index.html
Кода -копия выглядит следующим образом:
<! Doctype html>
<html>
<голова>
<title> </title>
<meta charset = "utf-8">
<стиль типа = "text/css">
тело {
Шрифт: 14px "sans-serif"
}
#Map {
фоновый цвет: #000000;
}
.показывать {
Плавание: слева
}
#гид {
Плавание: осталось;
Ширина: 200px;
Высота: 390px;
Полевая левая: 5px;
Фон: #cccccc;
Заполнение: 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 () {
// Информация о холсте
width = document.getElementbyId ('map'). ширина;
высота = document.getElementbyId ('map'). Высота;
ctx = document.getElementbyId ('map'). getContext ('2d');
// начальная страница
var starimg = new Image ();
starimg.src = "img/star.jpg";
starimg.onload = function () {
ctx.drawimage (starimg, 0, 0, ширина, высота);
}
// Мониторинг клавиатуры и вернуться, чтобы начать игру
document.body.onkeydown = function () {
var keycode = event.keycode;
Switch (KeyCode) {
Случай 13:
// параметры инициализации
init ()
// обновить страницу
SetInterval (Draw, 30);
document.body.onkeydown = gamecontrol;
перерыв;
}
}
}
function init () {
// игроки и компьютеры
Hero = новый герой (100, 300, 0);
Enemys = [];
для (var i = 0; i <3; i ++) {
Enemys.push (новый враг (100 + i * 50, 0, 2));
}
// Merge Array
alltank = enemys.concat (герой);
//бомбить
Бомбы = [];
im = новое изображение ();
im2 = новое изображение ();
im3 = новое изображение ();
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) {
Случай 65:
hero.moveleft ();
перерыв; // слева
Случай 83:
hero.modyown ();
Break; // Далее
Случай 87:
hero.moveup ();
Break; // on
Случай 68:
Hero.moveright ();
Перерыв; // Правильно
Случай 74:
hero.shot ();
перерыв;
Случай 49:
Hero.addlife ()
перерыв;
}
}
// расширить, чтобы удалить указанный элемент
Array.prototype.deleteelement = function (obj) {
if (obj) {
for (var i = 0; i <this.length; i ++) {
if (this [i] === obj) {
this.splice (i, 1);
}
}
}
}
</script>
</head>
<тело>
<div>
<canvas id = "map">
</canvas>
<audio id = "music" autoplay = "autoplay">
<источник src = "music/111.wav">
</audio>
</div>
<div id = "Руководство">
<p> Нажмите Enter, чтобы начать игру </p>
<p> Нажмите 1 клавишу, чтобы увеличить срок службы, по умолчанию 1 </p>
<p> Оставшиеся срок службы: <label id = "life"> 1 </label> </p>
<div id = "data">
</div>
</div>
</body>
</html>
2.draw.js
Кода -копия выглядит следующим образом:
/**
* Создан Аланом 14-3-18.
*/
функция draw () {
// обнаружение жизни и смерти пуль и танков
checkDead ();
// очистить холст
ctx.clearrect (0,0,500,400);
// Нарисуйте игрока
if (! Hero.isdead) {
Drawtank (герой);
}еще{
Hero.cutlife ();
}
// нарисовать вражеские танки
for (var i = 0; i <enemys.length; i ++) {
Drawtank (Enemys [i]);
}
// нарисовать вражеские пули
for (var j = 0; j <enemys.length; j ++) {
var temp = Enemys [j] .bulletslist;
for (var i = 0; i <temp.length; i ++) {
Drawbullet (Temp [i]);
}
}
// нарисовать пулю игрока
var temp = hero.bulletslist;
for (var i = 0; i <temp.length; i ++) {
Drawbullet (Temp [i]);
}
// рисовать бомбу
for (var i = 0; i <bombs.length; i ++) {
Drawbown (Bombs [i]);
}
}
Функция Drawtank (танк) {
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 ();
}еще{
ctx.beginpath ();
ctx.moveto (x+10, y+24);
ctx.lineTo (x+10, y+32);
ctx.closepath ();
}
ctx.stroke ();
}еще{
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 ();
}еще{
ctx.beginpath ();
ctx.moveto (x+24, y+10);
ctx.lineTo (x+32, y+10);
ctx.closepath ();
}
ctx.stroke ();
}
}
функция DrawBullet (bullet) {
ctx.fillstyle = bullet.color;
ctx.beginpath ();
ctx.arc (bullet.x, bullet.y, 2360, true);
ctx.closepath ();
ctx.fill ();
}
функция 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);
}еще{
ctx.drawimage (im3, obj.x, obj.y, 50,50);
}
obj.lifedown ();
if (obj.life <= 0) {
Bombs.DeleteElement (OBJ);
}
}
function checkdead () {
// обнаружение жизни и смерти вражеской пули
for (var j = 0; j <enemys.length; j ++) {
var temp = Enemys [j] .bulletslist;
for (var i = 0; i <temp.length; i ++) {
var o = temp [i];
if (o.isdead) {
Temp.DeleteElement (O);
}
}
}
// Обнаружение игрока пулевой жизни и смерти
var temp = hero.bulletslist;
for (var i = 0; i <temp.length; i ++) {
var o = temp [i];
if (o.isdead) {
Temp.DeleteElement (O);
}
}
// обнаружение жизни и смерти вражеского танка
for (var i = 0; i <enemys.length; i ++) {
var O = Enemys [i];
if (o.isdead) {
Enemys.DeleteElement (O);
}
}
}
Bomb.js
Кода -копия выглядит следующим образом:
/**
* Создан Аланом 14-3-18.
*/
Функциональная бомба (x, y) {
this.Life = 12;
this.x = x;
this.y = y;
}
Bomb.prototype.lifedown = function () {
this.life--;
}
Tank.js
Кода -копия выглядит следующим образом:
/**
* Создан Аланом 14-3-7.
*/
/**
* Direct 0 на
* 1 ПРАВО
* 2
* 3 осталось
* @param x
* @param y
* @param Direct
* @constructor
*/
// ************************************************** ********************************************* ********************************************* ********************************************* ********************************************* ********************************************* ********************************************* ************************* ******************* **************************/
// Танк родительский класс
Функциональный танк (x, y, direct) {
this.speed = 2;
}
Tank.prototype.moveup = function () {
// обнаружение границы
if (this.y <0) {
// изменение направления
this.changedirect ();
возвращаться;
}
this.y -= this.speed;
this.direct = 0;
}
Tank.prototype.modalown = function () {
if (this.y> высота - 30) {
this.changedirect ();
возвращаться;
}
this.y += this.speed;
this.direct = 2;
}
Tank.prototype.moveleft = function () {
if (this.x <0) {
this.changedirect ();
возвращаться;
}
this.x -= this.speed;
this.direct = 3;
}
Tank.prototype.moveright = function () {
if (this.x> width - 30) {
this.changedirect ();
возвращаться;
}
this.x += this.speed;
this.direct = 1;
}
// изменение направления
Tank.prototype.changedirect = function () {
while (true) {
var temp = math.round (math.random () * 3);
if (this.direct! = temp) {
this.direct = temp;
перерыв;
}
}
//alert("x="+this.x+ "y ="+this.y+"direct ="+this.direct)
}
// выстрелы пули
Tank.prototype.shot = function () {
if (this.isdead) {
возвращаться;
}
if (this.bulletslist.length <this.maxbulletsize) {
// Создать новую пулю
var bullet = null;
Switch (this.direct) {
Случай 0:
bullet = new Bullet (this.x + 10, this.y - 2, 0, this.color);
перерыв;
Случай 1:
bullet = new Bullet (this.x + 32, this.y + 10, 1, this.color);
перерыв;
Случай 2:
bullet = new Bullet (this.x + 10, this.y + 32, 2, this.color);
перерыв;
Случай 3:
bullet = new Bullet (this.x - 2, this.y + 10, 3, this.color);
перерыв;
}
// Поместите в журнал
this.bulletslist.push (bullet);
}
}
// ************************************************** ********************************************* ********************************************* ********************************************* ********************************************* ********************************************* ********************************************* ************************* ******************* **************************/
// игрок
Функция героя (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 = новый танк (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 = null;
document.queryselector ("#life"). innerhtml = hero.lifetimes;
}
// ************************************************** ********************************************* ********************************************* ********************************************* ********************************************* ********************************************* ********************************************* ************************* ******************* **************************/
// вражеский танк
Функция Enemy (x, y, Direct) {
this.isdead = false;
this.color = 'blue';
this.x = x;
this.y = y;
this.direct = direct;
this.bulletslist = [];
this.maxbulletsize = 1;
// таймер, автоматическое движение
this.imer1 = setInterval ((function (context) {
return function () {
//двигаться
Egine.prototype.move.call (контекст);
}
}) (это), 30);
// таймер, стрельба
this.imer2 = setInterval ((function (context) {
return function () {
// стрельба
Tank.prototype.shot.call (контекст);
}
}) (это), 2000);
// таймер, изменить направление
this.imer3 = setInterval ((function (context) {
return function () {
// стрельба
Tank.prototype.changedirect.call (контекст);
}
}) (это), 3000);
}
Egure.prototype = новый танк (0, 0, 0);
Egure.prototype.constructor = erege;
Egure.prototype.move = function () {
Switch (this.direct) {
Случай 0:
this.moveup ();
перерыв;
Случай 1:
this.moveright ();
перерыв;
Случай 2:
this.modyown ();
перерыв;
Случай 3:
this.moveleft ();
перерыв;
}
}
Bullet.js
Кода -копия выглядит следующим образом:
/**
* Создан Аланом 14-3-11.
*/
Функциональная пуля (x, y, direct, color) {
this.isdead = false;
this.x = x;
this.y = y;
this.direct = direct;
this.speed = 4;
this.color = color;
// Таймер, упражнение самостоятельно
this.timer = setInterval ((function (context) {
return function () {
Bullet.prototype.move.call (контекст)
}
}) (это), 30);
}
Bullet.prototype.move = function () {
Switch (this.direct) {
Случай 0:
this.y -= this.speed;
перерыв;
Случай 1:
this.x += this.speed;
перерыв;
Случай 2:
this.y += this.speed;
перерыв;
Случай 3:
this.x -= this.speed;
перерыв;
}
// обнаружение границы
if (this.y <0 || this.x> width || this.y> height || this.x <0) {
clearInterval (this.timer);
this.isdead = true;
}
// обнаружение столкновений обнаруживает вражеские танки
for (var i = 0; i <alltank.length; i ++) {
var temp = alltank [i];
if (temp.isdead) {
продолжать;
}
Switch (temp.direct) {
Случай 0:
Случай 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) {
перерыв;
}
Bombs.push (новая бомба (Temp.x-10, Temp.y-10));
clearInterval (this.timer);
this.isdead = true;
temp.isdead = true;
}перерыв
Случай 1:
Случай 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) {
перерыв;
}
Bombs.push (новая бомба (Temp.x-10, Temp.y-10));
clearInterval (this.timer);
this.isdead = true;
temp.isdead = true;
}перерыв;
}
}
}
Скачать исходный код