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

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

ただいまの
回答率

89.10%

画面全体の入力処理について

解決済

回答 4

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 1,148

kamecha

score 41

現状

現在、ゲームを自作しようとしているのですが、入力処理で困ってしまいました。
ネットで調べたところ、キャラクターにタッチして入力する方法は理解したのですが、
自分が作成しているのは、早押しゲームですので表示された画面ならどこをタッチしても反応するような入力処理をしたいのです。

コード

作成途中のコードの為(自分が初心者の為)、無駄に長く読みにくいコードですが、よろしくお願いします。

enchant();

var start;      //スタートシーン
var STFunc;

var Pscene;     //待期シーン
var PFunc;


//ゲームの状態
var START = 0;
var PLAY = 1;

var gameState = 0;

var time = 0;       //全体の時間

//タッチ用変数
var touchFlag = false;

window.onload = function(){


    var game = new Core(320, 320);
    game.preload('img/chara1.png','img/sirokuma.png','img/start.png');
    game.fps = 15;

    game.onload = function(){

        //startシーンの作成
        start = new Scene();
        var startflag = new Sprite(236, 48);
        startflag.image = game.assets['img/start.png'];
        startflag.x = 10;
        startflag.y = 20;
        startflag.frame = 0;
        start.addChild(startflag);

        STFunc = function(){
            game.pushScene(start);
        }

        //Psceneの作成
        Pscene = new Scene();

        var bear = new Sprite(32, 32);
        bear.image = game.assets['img/chara1.png'];
        bear.x = 30;
        bear.y = 80;
        bear.frame = 0;
        Pscene.addChild(bear);

        var enemy = new Sprite(32, 32);
        enemy.image = game.assets['img/sirokuma.png'];
        enemy.x = 200;
        enemy.y = 80;
        enemy.scaleX = -1;
        enemy.frame = 2;
        Pscene.addChild(enemy);

        PFunc = function(){
            game.pushScene(Pscene);
        }



        //タッチイベントの追加!
        document.addEventListener(Event.TOUCH_START, clickfunc);


         //メインループの開始


             switch (gameState){

                 case START:
                    startFunc();
                    break;

                 case PLAY:
                    playFunc();
                    break;

                 default:
                    break;

             }



         function startFunc(){
             STFunc();

             if (touchFlag == true) {
                 gameState = PLAY;
                 touchFlag = false;
                 time = 0;
                 game.popScene(start);
             }
         }

         function playFunc(){
             PFunc();
         }


         function clickfunc(){
             touchFlag = true;
         }

    }
    game.debug();
};

疑問点

現在のコードで実行すると、START画面が表示されたままで画面をクリックしても全く変わりません、エラーを見てみても何も表示されていません。
そのため、
・現在の入力処理であるgame.rootScene.addEventListener()が正しく使用できているか

・画面全体のタッチを認識する入力処理の方法

・その他文法的に間違えているところ

を、ご指摘いただきたいです。

追記

現在、学生の身ですので、返信に時間がかかることがあります。
現在の環境
下のHTMLファイルをGoogle Chromeで開いています。

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta http-equiv="x-ua-compatible" content="IE=Edge">
    <meta name="viewport" content="width=device-width, user-scalable=no">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <script type="text/javascript" src="js/lib/enchant.js"></script>
    <script type="text/javascript" src="js/main.js"></script>
    <style type="text/css">
        body {
            margin: 0;
            padding: 0;
            background-color: #ffffff;
        }
    </style>
</head>
<body>
</body>
</html>
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 4

checkベストアンサー

+3

画面の遷移が行われない原因が分かりました。
今回使用しているenchant.jsの環境下で、setInterval関数を使うと画面のイベントが発行されないようです。
なので、setInterval関数を消してください。

タイマーの用途で使用していると思いますが、タイマーは以下のコードで実現可能です。

var time_label = new Label();
time_label.x = time_label.y = 2;
time_label.addEventListener(enchant.Event.ENTER_FRAME, function(){
            var progress = parseInt(game.frame/game.fps);
            time = LIMIT_TIME - parseInt(game.frame/game.fps)+"";
            this.text = "リミット : " + time;
            // タイムが0以下になったらゲームオーバーシーンに移行する
            if (time <= 0) { changeToGameOverScene(); }
});
Pscene.addChild(time_label);

私の環境では、画面遷移の問題以外にも、前のシーンの画像が残るなど別の問題も有りましたが、
今回の問題からは外れますので、修正していません。
フラグ管理などいろいろと大変だと思いますが、頑張ってください。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/07/12 23:06

    どうしてだろう・・・
    やはり、反応しないなぁ
    何か他にも原因があるのかもしれません。
    僕の環境下では、駄目な理由が他にあると思います。

    しかし、頑張ってみます。

    キャンセル

  • 2017/07/13 01:41

    お困りのようですのでいくつかアドバイスを。
    まず、
    document.addEventListener(Event.TOUCH_START, clickfunc);
    がよくありません。
    enchant.jsでは、シーンという考え方をするようです。
    一番上のシーンのみイベントをキャッチできます。
    なので、documentはイベントをキャッチできません。
    初期状態では、一番上のイベントはgame.rootSceneです。

    次に、switch文についてです。
    今回は一般的なフロー駆動型ではなくイベント駆動型です。
    switch文は毎回実行したい部分だと思いますが、今回は一度しか実行されません。
    イベント駆動について理解を深めると、switch文の記述がおかしいことに気付くと思います。

    上記を参考に頑張ってください。

    キャンセル

  • 2017/07/16 20:58

    有り難うございます。
    基本をしっかりと学び直してからもう一度作成してみます。

    キャンセル

+1

全体は見ていませんが、下記部分は関数が渡せていません。

    //タッチイベントの追加!
//    game.rootScene.addEventListener('click', clickfunc());
//     ↓
    game.rootScene.addEventListener('click', clickfunc );

    //メインループの開始
//    setInterval(loop(), 100);
//     ↓
    setInterval(loop, 100);

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/07/09 17:01

    変更しました。
    けれども、現状は変化しませんでした。
    論理的に間違っているのでしょうか?

    キャンセル

  • 2017/07/09 18:44

    > 論理的に間違っているのでしょうか?
    「論理的に間違っている」は「ロジックが間違っている」「組み方が間違っている」ということでしょうか。
    「こう動くだろう」と思って動かないのであれば、ほとんどの場合コードの書き方が問題です。

    まず、どこまで動きますか?動くところまでコードを削ってください。そうやって問題を切り分けていくことで「動くコード」が作れるようになると思います。

    【enchant.js ゲーム制作 Tips – マウスクリックやタッチでプレイヤーを移動させてみよう!! | TM Life】
    http://tmlife.net/programming/javascript/enchant-js-game-create-tips-mouse-touch.html

    【Let’s start enchant.js | enchant.js - A simple JavaScript framework for creating games and apps.】
    http://enchantjs.com/ja/tutorial/lets-start-enchant-js/

    キャンセル

  • 2017/07/10 21:59

    減らしてみました。
    やはり、STARTシーンからPLAYシーンへの移行が出来ません。
    何が問題なのでしょうか・・・

    すいません、自分の現在の知識では分かりませんでした。

    キャンセル

+1

全体を見ていませんので、適切かどうかわかりませんが、ソースを載せます。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>Hello</title>
    <script>
        var context = null;
        var context = null;
        var x         = 300;
        var y         = 350;
        var dx         = 5;

        function initial(){
            canvas     = document.querySelector('#canvas');
            context = canvas.getContext('2d');

            context.fillStyle     = "#EEFFEE";
            context.fillRect(0, 0, 800, 400);
            context.fillStyle     = "black";
            context.font = "128pt 'san serif'";
            context.fillText('Hello', 150, 150);

            canvas.addEventListener('click', onClicked, true);
        }
        function onClicked(){
            setInterval(draw, 50);
        }
        function draw(){
            //背景を描画
            context.fillStyle     = "#EEFFEE";
            context.fillRect(0, 0, 800, 400);

            //赤い四角を描画
            context.fillStyle     = "red";
            context.fillRect(x, y, 50, 50);

            x += dx;
            if(x < 0){dx *= -1;}
            if(x > 750){dx *= -1;}
        }
    </script>
</head>
<body onload="initial();">
    <canvas id="canvas" width="800" height="400" />

</body>
</html>

上記のソースを拡張子「html」で保存してブラウザで実行して下さい。
タイトル画面が表示されて、クリックで赤色の四角が動くようになると思います。

上記でもご指摘頂いている通り、まず動くソースコードを作ってから、そのソースを拡張していくといいかと思います。
また、長いソースコードを記載しますと、読むほうも大変ですので、本当に重要な部分のみ、記載頂くといいと思います。
不必要と思われる変数定義や関数などは、出来るだけ排除した状態で、質問頂ければと思います。

内容を深く理解していませんので、的外れな回答をしているかもしれません。
ご参考程度に見て頂ければと思います。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/07/10 22:02

    コード有り難うございました。
    現在Canvasの知識が無いため難しく感じましたが、
    自分の言うgame.rootSceneがCanvasといった感じでよろしいのでしょうか。

    また、コード削減しました。(読みやすくなっていると幸いです。)

    キャンセル

  • 2017/07/11 02:16

    コードの修正ありがとうございます。
    おっしゃる通り、canvasがgame.rootSceneと同じようなものだと思います。
    ただ、私もenchant.jsに詳しくないので、正確には分かりません。
    少し調べたのだけなのですが、以下に修正して見てはどうでしょうか。
    before) game.rootScene.addEventListener('click', clickfunc);
    after) game.rootScene.addEventListener(Event.TOUCH_START, clickfunc);

    キャンセル

  • 2017/07/11 23:27

    有り難うございます。
    コードを変更してみたのですが、上手く作動しませんでした。
    5秒後には、画面変更するので、やはり入力処理が難しいですね..

    キャンセル

+1

まずdocument自体にイベントを追加しておけばどこでも反応します。

document.addEventListener('click',function(e){
  console.log(e.target.nodeName);
});


あとは、ターゲットを限定していけば要素ごとの処理が可能です。
またquerySelectorやquerySelectorAllで絞り込むのも有効です

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/07/11 23:33

    変更したつもりですが、反応しませんでした。
    ということは、関数が間違っているのでしょうか?

    キャンセル

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

  • ただいまの回答率 89.10%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる