質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

2回答

2804閲覧

イベントリスナが削除できない

navca

総合スコア44

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2016/11/16 11:11

プログラミング初心者です。Javascriptの練習のため、初心者向きのゲームエンジンでコードの練習しています。
自分でとにかくコードを書いてみようと思い、とりあえずキャラクターをジャンプさせようとしたのですが、イベントリスナの性質のためか、一度↑ボタンを押すと、2,3回ジャンプしてしまいます。そこで調べてイベントリスナは登録されるもので削除しなきゃならないことを知って以下のコード以外にも様々かいてみたのですが、removeを加えると動かなくなってしまいます。

if(game.input.up){ bear.addEventListener(Event.ENTER_FRAME, function(){ bear.tl.moveBy(0, -120, 8, enchant.Easing.CUBIC_EASEOUT); bear.tl.moveBy(0, 120, 8, enchant.Easing.CUBIC_EASEIN); bear.jumping = true; }); if(bear.jumping === true){ removeEventListner(Event.ENTER_FRAME, function(){ bear.jumping = false; }); } }

一応
※参考書にはイベントリスナの第三引数がないので書いてません。
※bear.tl~というやつは物理法則でジャンプができるメソッドです。

着地したらジャンプフラグをtrueにしてから、同時にifでイベントリスナを削除というつもりで書きました。
とんちんかんなことをやってるかもしれませが、ご教示ください。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

addEventListener, removeEventListner は同じ参照を持つ関数オブジェクトを指定しなければなりません。
無名関数式を使わず、関数オブジェクトを変数に代入して下さい。

javascript

1bear.addEventListener(Event.ENTER_FRAME, listener, false); 2bear.removeEventListner(Event.ENTER_FRAME, listener, false);

Re: navca さん

投稿2016/11/16 11:21

think49

総合スコア18162

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

navca

2016/11/16 11:32

早速回答ありがとうございます! ↓こうやってみたら若干進歩しました!まだ↑を押すと二回ジャンプしてしまうんですが、さらにコード変えてやってみます! function jump(){ if(game.input.up){ bear.tl.moveBy(0, -120, 8, enchant.Easing.CUBIC_EASEOUT); bear.tl.moveBy(0, 120, 8, enchant.Easing.CUBIC_EASEIN); bear.jumping = true; } if(bear.jump === true){ removeEventListner(Event.ENTER_FRAME,jump); bear.jump = false; } } bear.addEventListener(Event.ENTER_FRAME, jump);
think49

2016/11/16 13:02

このアプローチをとるなら addEventListener で jump ハンドラが呼び出された直後に必ず removeEventListener して下さい。 対象が着地した時点で再度、addEventListener すればいいと思います。 enchant.jsは使用した事がないのですが、地面からの距離を得る方法があるなら addEventListener で jump ハンドラが呼び出された時に地面からの距離が0だった場合のみにジャンプするようにすれば removeEventListener は不要になります。 bear.jumping でフラグを立てるなら bear.jumping === true の場合にジャンプ処理を行わないようにif文で分岐すれば removeEventListener は不要になります。 最も、着地時の処理が別途必要になりますが。
navca

2016/11/16 13:56

回答いただきありがとうございます。先ほどコメントとして投稿したすぐ上のを手直しして再度やってみましたが駄目でした。地面からの距離は測れるんですが、ブロックに乗った時にもジャンプしたいのでフラグでやっています。 しかしフラグだと、僕の考えでは先ほど挙げたコメントのコードはメソッド→メソッド→フラグが順番に実行されると思ってたんですが、、if(game.input.up)がtrueになった時点でメソッドと同時にbear.jumpingにもtrueがだいにゅうされるからなのか、そのすぐ下のif(bear.jump === true)の処理まで同時に実行されてるような挙動でした。(つまり↑を押しても動きませんでした。) またいろいろやってみます。アドバイス頂きありがとうございました。
think49

2016/11/16 14:11

上のコメントのコードを使うと game.input.up が truthy なら bear.tl.moveBy が必ず実行されます(bear.jump が true/false のどちらでも)。 修正するならこうなると思います。 function jump () { if (game.input.up) { bear.tl.moveBy(0, -120, 8, enchant.Easing.CUBIC_EASEOUT); bear.tl.moveBy(0, 120, 8, enchant.Easing.CUBIC_EASEIN); removeEventListner(Event.ENTER_FRAME, jump, false); } } 繰り返しますが、着地処理が必要です。この方法を採用するなら着地した時に再度、jump処理が働くようにしなければなりません。 最も、どの方法でも着地した事が判定する必要があるのですが…。 > 地面からの距離は測れるんですが、ブロックに乗った時にもジャンプしたいのでフラグでやっています。 その場合はブロックからの距離を測ればいいでしょう。 ジャンプした対象のY軸で下方向に向けて着地する物体があるまで探す処理を入れる等、何らかの手段があると思います。
navca

2016/11/17 14:00

think49さん回答ありがとうございますm(__)m 何度かやってるうちに関数の配下にイベントリスナを置くとイベントリスナが動かなくなることが分かったので、ジャンプそのものの処理とイベントリスナを分けてやってみました。↓ function jump(){ if(game.input.up){ bear.tl.moveBy(0, -120, 8, enchant.Easing.CUBIC_EASEOUT); bear.tl.moveBy(0, 120, 8, enchant.Easing.CUBIC_EASEIN); bear.jumping = true; } } function land(){ if(bear.jumping === true){ bear.jumping = false; } } bear.addEventListener(Event.ENTER_FRAME, jump, false); bear.removeEventListner(Event.ENTER_FRAME,land, false); 結果、やっぱり一度↑ボタンを押すと2~4回ジャンプします。 >その場合はブロックからの距離を測ればいいでしょう。 本当は段々になったブロックにジャンプしたキャラクターの頭が当たるとそこでとまって戻ってくるという処理を書いていたんですが、それもできなかったのでじゃあ一番基礎的なところからということでブロックとかは一切考慮してません。 正直、一番最初に若干進歩したといったやつも早とちりだったみたいで駄目でした^^; イベントリスナの性質によるものなんでしょうか?いまいちどイベントリスナを勉強しなおしてみます。m(__)m
guest

0

イベントリスナは動かしっぱなしにして、その中身を↑を押してから着地するまで動作するようにしてみてはいかがでしょうか?

投稿2016/11/16 11:28

Diawel

総合スコア190

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

navca

2016/11/16 11:33

ありがとうございます!やってみます!
navca

2016/11/16 11:50

すいません もうちょいヒント頂けないでしょうか?的外れかもしれませんが、高階関数を使うということでしょうか?動かしっぱなしとはどういう状況でしょうか?^^;
Diawel

2016/11/16 12:04 編集

僕がやるとしたらこんな感じですかね。 ですがbear.tl.moveByの使用を完全に理解してるわけではないので、間違っているかもしれないですが。 document.addEventListener("keydown" , function(e){ if(e.keyCode==38){ bear.tl.moveBy(0, -120, 8, enchant.Easing.CUBIC_EASEOUT); bear.tl.moveBy(0, 120, 8, enchant.Easing.CUBIC_EASEIN); } });
navca

2016/11/16 12:11

ありがとうございます!やってみます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問