1.遭遇したキーポイントと問題を要約します
1.継承JavaScriptの継承、親クラスのみをメソッド共有を提供することが最適であり、親クラスのコンストラクターとサブクラスの混乱を避けるために、それぞれのサブクラスに属性が書き込まれます。
2。プロトタイプは継承されたコードをシミュレートし、それ以外の場合はすべてのメソッド定義の前に記述する必要があります。
コードコピーは次のとおりです。
hero.prototype = new Tank(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属性が割り当てられた後に画像がロードされますが、画像がロードされていない場合、障害を引き起こすため、オンロードイベントを使用して処理します。
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( "fun"、1000)メソッドの最初のパラメーターは、evalと同様に「hero.say()」などの文字列にすることができます。関数上部パラメーターと、この関数の実行中のコンテキストも指定します。しかし、パスが関数のハンドルである場合、パラメーターを使用することはできず、コンテキストを指定することはできません。
コードコピーは次のとおりです。
//タイマー、自分で運動します
this.timer = setInterval((function(context){
return function(){
bulet.prototype.move.call(コンテキスト)
}
})(this)、30);
現在の実行環境を保存し、手動で実行するためにコールメソッドを呼び出しました。
8.メソッドの機能設計は、関数に加えて、動きなどのこの関数の条件付き検出を含める必要があります。この検出は外部に配置しないでください。
9.コードを書くときは、設計や最適化について考えるべきではありません。思考を明確にし、混乱しないでください、そして一つのことに集中してください。
10.JavaScriptには睡眠機能がありません。間隔実行の目的を達成するためにバッファーとして変数を作成できます
2。コード実装
1.このプログラムは、bomb.js、bulet.js、draw.js、tank.js、index.html、img、音楽、
2。最終効果
3。コード
1.index.html
コードコピーは次のとおりです。
<!doctype html>
<html>
<head>
<title> </title>
<メタcharset = "utf-8">
<style type = "text/css">
体 {
フォント:14px "sans-serif"
}
#map {
バックグラウンドカラー:#000000;
}
。見せる {
フロート:左
}
#guide {
フロート:左;
幅: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"> </scrip>
<script type = "text/javascript" src = "draw.js"> </script>
<script type = "text/javascript">
window.onload = function(){
//キャンバス情報
width = document.getElementById( 'Map')。width;
height = 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、width、height);
}
//キーボードの監視とゲームを開始するために戻ります
document.body.onkeydown = function(){
var keycode = event.keycode;
switch(keycode){
ケース13:
//初期化パラメーター
init()
//ページを更新します
setinterval(draw、30);
document.body.onkeydown = gamecontrol;
壊す;
}
}
}
function init(){
//プレーヤーとコンピューター
HERO = New Hero(100、300、0);
enemys = [];
for(var i = 0; i <3; i ++){
enemys.push(新しい敵(100 + i * 50、0、2));
}
//配列をマージします
alltank = enemys.concat(hero);
//爆弾
bombs = [];
im = new Image();
IM2 = new Image();
im3 = new Image();
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.movedown();
ブレーク; //次へ
ケース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>
<body>
<div>
<canvas id = "map">
</canvas>
<audio id = "music" autoplay = "autoplay">
<source src = "music/111.wav">
</audio>
</div>
<div id = "guide">
<p> Enterを押してゲームを開始します</p>
<p> 1キーを押して寿命を延ばすために、デフォルトは1 </p>です
<p>残りの寿命カウント:<ラベルID = "life"> 1 </label> </p>
<div id = "data">
</div>
</div>
</body>
</html>
2.draw.js
コードコピーは次のとおりです。
/**
* 14-3-18にAlaneによって作成されました。
*/
関数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(bulet.x、bulet.Y、2,360、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);
}
}
関数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にAlaneによって作成されました。
*/
関数爆弾(x、y){
this.life = 12;
this.x = x;
this.y = y;
}
bomb.prototype.lifedown = function(){
this.life--;
}
tank.js
コードコピーは次のとおりです。
/**
* 14-3-7にAlaneによって作成されました。
*/
/**
*直接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.movedown = 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 = new Tank(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 = setimeout( "Hero.NewLife()"、2000);
}
}
hero.prototype.newlife = function(){
this.isdead = false;
ClearTimeout(Hero.NewLife);
hero.newlife = null;
document.queryselector( "#life")。innerhtml = hero.lifetimes;
}
// ****************************************** ******************************************** ******************************************** ******************************************** ******************************************** ******************************************** ******************************************** ***************************************************** ************************/
//敵のタンク
関数敵(x、y、direct){
this.isdead = false;
this.color = 'blue';
this.x = x;
this.y = y;
this.direct = direct;
this.bulletslist = [];
this.maxbulletsize = 1;
//タイマー、自動ムーブメント
this.timer1 = setInterval((function(context){
return function(){
//動く
emeny.prototype.move.call(context);
}
})(this)、30);
//タイマー、撮影
this.timer2 = setInterval((function(context){
return function(){
//射撃
tank.prototype.shot.call(context);
}
})(this)、2000);
//タイマー、方向を変更します
this.timer3 = setInterval((function(context){
return function(){
//射撃
tank.prototype.changedirect.call(context);
}
})(this)、3000);
}
emeny.prototype = new Tank(0、0、0);
emeny.prototype.constructor = emeny;
emeny.prototype.move = function(){
switch(this.direct){
ケース0:
this.moveup();
壊す;
ケース1:
this.moveright();
壊す;
ケース2:
this.movedown();
壊す;
ケース3:
this.moveleft();
壊す;
}
}
bullet.js
コードコピーは次のとおりです。
/**
* 14-3-11にAlaneによって作成されました。
*/
function Bullet(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(){
bulet.prototype.move.call(コンテキスト)
}
})(this)、30);
}
bulet.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> heigh || 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(new bomb(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(new bomb(temp.x-10、temp.y-10));
ClearInterval(this.timer);
this.isdead = true;
temp.isdead = true;
}壊す;
}
}
}
ソースコードのダウンロード