2016-08-07 8 views
0

私はゲーム作成用の楽しいAPIをまとめました。コードでは、Moverのプロトタイプを作成し、いくつかの特定のプロトタイプ(Gold、Monster、Hero)で拡張します。それぞれは特定のIDを持つimgタグに基づいています。私はコンストラクタで型固有情報を使用し、型ごとに単一のテンプレートメソッドを使用します。 Moverの機能コードのほとんどは、そのタイプ固有の詳細に依存しています。私は単純化のために一つの例を挙げました。Javascript:複数のインスタンスのイベントを処理できません

別のスクリプトでメソッド呼び出しを使用して、Moverの子タイプのインスタンスを作成および破棄します。一度に1つのインスタンスを作成して破棄すると、すべてが意図どおりに機能します。画像が更新され、サウンドが再生され、正しい遅延後に削除されます。しかし、2つ以上を作成すると、最後のものだけが期待どおりに機能します。だからもし私が金を作るなら、大部分は英雄です。主人公だけが正しく削除されます。他の2人はオーディオを再生しますが、アップデートしていないようです。

複数のインスタンスのonclickイベントに関数をアタッチしようとしたとき、同じ問題が発生しました。最後のものだけが働き、他は何もしなかった。明らかに、私はjavaがメソッドの代入を処理する方法について何か不足しています。あなたが提供できる説明があれば助けになります。 おかげで、 BSD

function Mover() 
{ 
} 

Mover.prototype.InitTag = function() 
{ 
    this.HTMLtag.src=this.imageURL; 
    this.HTMLtag.style.position="absolute"; 
    this.HTMLtag.style.width=characterSize; 
    this.HTMLtag.style.height=characterSize; 
    this.Position(Math.floor(Math.random()*(MaxW-characterSize)+(characterSize/2)),Math.floor(Math.random()*(MaxH-characterSize)+(characterSize/2))); 
} 

Mover.prototype.Destroy = function() 
{ 
    var disp = this.HTMLtag.display; 
    this.HTMLtag.src=this.destroyURL 
    this.HTMLtag.display = disp; 
    this.destroyAudio.play(); 

    this.RemoveTag(); 
} 

function Monster(id) 
{ 
    this.MonsterID = id; 
    this.HTMLtag = document.getElementById("monster"+id); 
    this.imageURL = "monster1.jpg"; 
    this.destroyURL = "monster2.jpg"; 
    this.destroyAudio = monsterAudio; 
} 

Monster.prototype = new Mover(); 

Monster.prototype.RemoveTag = function() 
{ 
    var mID = this.MonsterID; 
    setTimeout(function() {field.DeleteMonster(mID)}, 1000); 
} 

function Hero() 
{ 
    this.HTMLtag = document.getElementById("hero"); 
    this.imageURL = "hero1.jpg"; 
    this.destroyURL = "hero2.jpg"; 
    this.destroyAudio = heroAudio; 
} 

Hero.prototype = new Mover(); 

Hero.prototype.RemoveTag = function() 
{ 
    setTimeout(function() {field.DeleteHero()}, 5000); 
} 

function Gold(id) 
{ 
    this.GoldID = id; 
    this.HTMLtag = document.getElementById("gold"+id); 
    this.imageURL = "gold1.jpg"; 
    this.destroyURL = "gold2.jpg"; 
    this.destroyAudio = goldAudio; 
} 

Gold.prototype = new Mover(); 

Gold.prototype.RemoveTag = function() 
{ 
    var mID = this.GoldID; 
    setTimeout(function() {field.DeleteGold(mID)}, 1000); 
} 

--------- UPDATE更新UPDATE ----------- は、私は、少なくとも部分的に問題を修正しました。私はそれを働かせてくれましたが、なぜそれが意図したように機能しなかったのかまだ分かりません。私は、ブラウザの(Chrome)デベロッパーツールが、最近追加されたMoverを、破壊されたときに視覚的に特定できる一方で、他のムーバーではできないことに気付きました。

Tag of most recently added Mover can be identified in Chrome developer tools. これは、Mover.HTMLtagが実際にdocument.getElementById( 'mover1')と同じではないことを示しています。私はGoldField.DeleteMoverの変数を調べることでこれを確認できました。示された行では、mover.srcは変更されていませんが、movers [id] .HTMLtag.srcは正しく更新されています。最近追加されたケースでは、両者は同じでした。

GoldField.prototype.DeleteMover = function(id) 
{ 
    var isHero = false; 
    if(this.Hero!=null && id==this.Hero.myID) 
    { 
    this.Hero = null; 
    isHero = true; 

    } 
    else if(this.Tower!=null && id==this.Tower.myID) 
    { 
    this.Tower = null; 
    } 

    var mover = document.getElementById("mover"+id); 
    if(!isHero) 
    { 
    this.tag.removeChild(mover);//<<< HERE HERE HERE HERE 
    delete this.movers[id]; 
    } 
} 

私はMover.Destroyの1行を変更しました。 IDでタグを探し、srcを設定する。私は信頼できる行動をとることができました。 Mover.HTMLtagは、2番目のMoverが追加された後も同じ信頼性がありません。説明は?これは私が英雄のいくつかの基本的な動きを設定this.HTMLtagに他の更新に及ぶ可能性があることを容疑で

Mover.prototype.Destroy = function() 
{ 
    document.getElementById(this.HTMLtag.id).src=this.destroyURL; 
    this.HTMLtag.src=this.destroyURL;//old method 
    this.destroyAudio.play(); 

    this.RemoveTag(); 
} 

。それは素晴らしいですが、もしあなたがどんな種類のMoverを追加しても、それはもはや動きません。それは質問をかなり絞り込んでいます。第二のムーバーを構築すると、プロトタイプメンバーが変わるのはなぜですか?

+0

[mdn](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Introduction_to_Object-Oriented_JavaScript)をご覧ください。おそらく継承を行う方法が問題の原因です。 – mrdotb

+0

参考になりました。しかし、そのサイトを見ると、私は全く異なることをしていません。型コンストラクタを格納するための変数を作成し、親プロトタイプをリンクするためにObject.createを使用することは、何の違いもないようです。実際、私はその方法でそれを実装するコードを改訂し、その動作は同じです。私が参照に特定のものを見逃していない限り。私にお知らせください。 – BSD

+0

他にも役立つものがあります。各インスタンスのDestroyメソッドの実行をトレースすることができます。それぞれの場合にHTMLタグが適切に設定され、srcが更新されます。オーディオが再生されます。タグは削除されます。オーディオは聞こえますが、画像は更新されません。最近追加されたものだけが画像を更新します。再び、事前に感謝します。 – BSD

答えて

0

コードをもう一度チェックして、セレクタをリフレッシュせずに動作させます。この問題は、innerHTMLを使用してdom要素を作成することによって発生します。

まずその後の代わり

//Mover.prototype.Destroy 
this.tag.innerHTML+="<img id='mover"+this.moverCount+"'>"; 

私はIMGのDOMエルを作成

this.HTMLtag.src=this.destroyURL 

をリセットします。

var img = document.createElement("img"); 
img.setAttribute('id', 'mover' + this.moverCount); 
this.tag.appendChild(img); 

すべてのモンスターが画像とともに削除されました。
ヒーローはチェックしませんが、問題がまだ残っている場合はまずinnerHTMLを更新して返信してください。私はいくつかのプロトタイプに問題はないとは思わない。

+0

ビンゴ!私たちは勝者を持っています。私はそれらの方法を読んで、私が学生に正しい方法を示していることを確認します。どうもありがとう。それが問題でした。 – BSD

0

コードをデバッグして、問題の原因を見つけました。問題は、モンスターの新しいインスタンスを作成したときに、モンスターにそのモンスターのリファレンスを保存することでした。そしてあなたがそれを削除するとき、それへの参照を削除/更新しません。したがって、あなたのdelete関数myField.DeleteMover(id)は既に削除されたモンスターを削除しようとします。これを解決する方法。

// create an array to keep ref to our instances 
var monsters= []; 
// var monster = null; 
function addMonster() 
{ 
    // monster = goldField.AddMonster();⏎ 
    // push every monster in array 
    monsters.push(goldField.AddMonster()); 
} 

function killMonster() 
{ 
    // if array.length is true 
    if (monsters.length) { 
    // call the destroy function on the last ref 
    monsters[monsters.length - 1].Destroy(); 
    // remove the last ref from array using pop 
    monsters.pop(); 
    } 
//monster.Destroy(); 
} 

これは機能していますが、これはすべてオブジェクト自体で行う必要があると思います。そして、あなたはここでそれを気にするべきではありません。

もう1つアドバイスを使用してください。array methods配列インデックスの削除は避けてください。代わりにsplice(index、1)を使用してください。配列内のアイテムの追加には任意のインデックスの代わりにpushを使用します。

とにかく面白いゲーム!それを完了するために幸運。

編集すると、回答後、私はテストに戻ります。 これを動作させるために、私はこれを行います。

// First go inGoldField.prototype.DeleteMover and replace the ugly delete index by 
this.movers.splice(id, 1); 
// Then in the Mover.prototype.Destroy 
// This part is a a little blurred for me. 
// the current HTMLtag looks good but when I console.log like this 
console.log('before', this.HTMLtag); 
this.HTMLtag = document.querySelector("#mover" + this.myID); 
console.log('after', this.HTMLtag); 
// They are not equal look like the first is outdated 

すべての削除と追加をスプライスとプッシュの方法に変換する必要があります。
これは単なるクイックデバッグです。なぜセレクタが古くなったのか分かりません。

+0

さて、私はあなたがそれを好きでうれしいです。私はこの秋に学生と一緒に作業するためのAPIとしてこれを書いています。残念ながら、それは私が解決しようとしていた問題ではありませんでした。サンプルコードは、私のAPIの機能のための単なる骨のテスト用サンドボックスです。これらのテスト手順を試して問題を確認してください。モンスター1体を加える。それを殺します。それが爆発し、それが "私はあなたを殺す"と聞くのを見てください。これは正しい行動です。あなたがモンスターと他のアイテムを追加した場合、モンスターを殺すとあなたはそれをまだ聞いても消えますが、もはや爆発しません。なぜ画像が更新されていないのかわかりません。 – BSD

+0

編集メッセージを参照してください。 – mrdotb

+0

Mmmm。いいえ、コードをメソッドにコピーしましたが、目的の効果がありません。いずれにしても削除と追加を使用することには何も問題ありません。これは単に配列オブジェクトをハッシュとして使用し、それはJavascriptのすべてのオブジェクトの基底状態です。いずれにしても、問題はタグの削除に関連するものではなく、意図したとおりに発生します。これは、破壊プロセスを開始するときにイメージsrcを変更することと何とか関係しています。 – BSD

関連する問題