speed=15 touchmove

激重の極みeasy? 改をさらに改良して、touchmoveを習ったので、バーをtouchmoveで動かせるようにし、球の速さも一定(プログラムの中で15に設定)にしたものです。

ゲームクリアすると、ボタンが出て、オートマチック画面になります。

バーをドラッグで動かす部分

 // 画面をドラッグしてバーを動かす
 scene.addEventListener(Event.TOUCH_START, function(e){
     console.log("タッチ");
     console.log(e.x);
     X = bar.x - e.x; // サイコロとタッチした場所の座標の差分
 });
 scene.addEventListener(Event.TOUCH_MOVE,function(e){
     bar.x = e.x + X; 
 });
完成したソースコード
speed=15 touchmove

豚さんスナイパー(解説)

Box2dを使ったゲームの授業で発表したものです。

豚がトンネルの上から矢を放ちます。今までは、矢の動きは直線的に同じ速度にしか動きませんでしたが、Box2dを使えば、下に重力を加えて、矢はリアルな放物線を描くことができます。

先生のサンプルコードの中に、前回説明したパワーメーターがあったのですが、これが出る前に、息子は角度メーターを作りたいと作り始めていたので、そちらを付けることにしました。

角度は、クリックしたところの角度を取ることができるので、どちらかと言うとこちらのほうが簡単です。何週間か前に角度メータと矢の角度を連動させるものを考えたので、どうやって作ったのかもう忘れてしまいましたが、今見返すと思ったほど全然計算してなかったです^^;

サンプルに加えてオリジナルで付け加えた工夫は、

・目標物(だるま)までの距離を長くして、透明の石を動かして画面をスクロールさせて見せる機能をつける

・角度メーターをつけてクリックした角度で矢を飛ばす

・modeのパラメータをつけて、スクロールしている間は撃てないように制御する

・最後だるまが落ちるときに、だるまにスクロールレンジを設定して、落ちるだるまが見えるようにする

などです。

画面のスクロール

画面より外のドカンに目標物があるので、まず、それを見せます。そのために、透明の箱を作って飛ばしてから戻すという方法でやってみました。(息子のアイデア)

透明な箱には、setScrollRangeというプログラムを設定します。これは、設定したパディングを常に保ってくれるというもので、スプライトを移動させても画面から出てしまうことがなく、画面のほうがスクロールしてくれるというものです。これは今井先生がプログラムを作ってくださいました。

箱にこれをつけて移動させれば、画面がスクロールするというわけです。

箱の色はテスト用にredにしておき、あとで消します。

そのままではずっと向こうに移動し続けてしまうので、壁にぶつかって止まるように、壁も配置します。

    //スクロールさせる用オブジェクト
    var scro = new PhyBoxSprite(32, 32, enchant.box2d.DYNAMIC_SPRITE,
       1.0,
       0,
       0.3
    );
    //scro.backgroundColor = "red"; // テスト用・透明にする
    scro.x = 160;
    scro.y = 55;
    scene.addChild(scro);
    //
    var wall = new PhyBoxSprite(45, 480, enchant.box2d.STATIC_SPRITE);
    //wall.backgroundColor = "red";// テスト用・透明にする
    wall.x = daruma.x+ 140;
    wall.y = 0;
    scene.addChild(wall);

これで、scroはだるまより向こうに飛んで行って、壁にぶつかって落ちます。

さらに、スクロールしている間は矢が発射できないように、幕を作って、それをタッチできないようにします。ここではbackiというスプライトを画面一杯に大きさで上にかぶせています。

 // scroが移動している間はタッチ無効化すべし
 scro.tl.then(function(){
     backi.touchEnabled = false;
     scro.addImpulse(10, -2);
 });

適度なタイミングで豚の方に戻します。帰ってくるときにだるまにぶつからないように調節します。(addImpulse(-9, -2))

戻ってから、scroと壁は消します。

    // だるまにぶつからないように修正
    scro.tl.delay(25);
    scro.tl.then(function(){
        scro.setAwake(false);
        scro.addImpulse(-9, -2);
    });
    scro.tl.delay(45);
    scro.tl.then(function(){
        scro.remove();
        wall.remove();
        backi.touchEnabled = true;// 帰ってきたらタッチ可能
    });   
    scene.setScrollRange(scro, 55);

角度メーターをつくる

上下に振れるメーターをつくります。幅1、長さ32ピクセルのスプライトを作り、ワイパーのように動かしたいので、基準をx=0、y=32とします(下のbar.originX = 0;     bar.originY = 32;)。

これを、90度まで動かしてから、0度まで戻すという動きをloopさせれば、ワイパーのようなメーターができます。yの値が複雑なのは、豚の矢の位置に合わせるために微調整したからです。

ただ、ここで、あとでrotationと対応させるときに、ExSprite(1、32)とするより、(32、1)としたほうがやりやすかったかもしれません。途中で気づきましたが、90度ずらすだけなのでそのままやってしまいました。

    // メーター
    var bar = new ExSprite(1, 32);
    bar.backgroundColor = "red";
    bar.x = 52;
    bar.y = 480 - 64 - 32 - 13 - 170;// 豚の位置に合わせる
    scene.addChild(bar);
    bar.originX = 0; // 回転の基準
    bar.originY = 32; //   〃
    bar.tl.rotateBy(90, 32);
    bar.tl.rotateTo(0, 32);
    bar.tl.loop();

矢を飛ばす

タッチして矢を飛ばします

    // 矢を飛ばす
    backi.addEventListener(Event.TOUCH_START, function(e) {    
        // やを飛ばせるのはmode=0のときのみ
        if(mode == 0){
            var arrow = new PhyBoxSprite(
                22,     // 
                9,     // 高さ
                enchant.box2d.DYNAMIC_SPRITE,    // 動作モード
                1    // 密度
                //2      // 実験
            );
            arrow.image = core.assets["images/bal_arrow.png"];
            arrow.x = pig.x + pig.width + 1;
            arrow.y = pig.y + 18;
            scene.addChild(arrow);
            arrow.tag = "";
            scene.setScrollRange(arrow, 50);
            var sounds2 = core.assets["sounds/cf307/muti.mp3"].clone();
            sounds2.play();

角度メーターと矢の角度を連動させる

ここが角度メーターの肝ですが、簡単です。なぜなら、bar.rotationというプロパティが、タッチしたときのbarの角度を取ってくれるからです。

そして、この2.5・・ってなんでしょう・・自分でやったのに忘れました・・多分、bar.rotationというのは、動いているbarをタッチしたときの角度になるので、0〜90の値そのままでは、addImpulseに入れる値としては大き過ぎるので、それで、一旦100で割って、すると今度は小さくなりすぎるので、調節して2.5倍くらいにすると、矢の飛ぶ距離としてはちょうどよくなったのだと思います。

つまり、メーターのスプライトは(1、32)なので、垂直に立った状態から倒す方向で動かしています。ですから、x方向は、bar.rotationの値に比例させればいいので、その比例定数は的との距離で適当に調整して、2.5/100となりました。

逆にy方向は、傾きが大きくなるほど、y方向への力は小さくなるので、(傾きの最大値90度のとき0となる)(90-bar.rotation)に比例させればよく、これも調整して、2.5/90となり、上方向にとばすので-(マイナス)となります。

そのあとまた微調整して、arrow.addImpulse(ax * 1.2, ay * 1.2)でいい具合に飛ばすことができました。

     // バーの角度と矢の飛ぶ方向を対応させる
        var ax;
        ax = 2.5 *  bar.rotation / 100;
        var ay;
        ay = - 2.5 * (90 - bar.rotation) / 90;
        console.log(ax);
        console.log(ay);
        arrow.addImpulse(ax * 1.2, ay * 1.2);

矢の出し方

上で、矢を飛ばす力については決めました。しかし画面上の画像としては、そのままでは矢が真横に出て、真横のまま放物線を描くことになるので不自然です。(Box2dはそこまではやってくれない)

そこで矢を出す時の角度もメーターの角度と同じになるようにして、飛ばしたあとも角度に合わせてゆるやかに回転させるようにしました。

また、矢と同時に一旦消したスクロール用の透明の箱を、矢をフォローして一緒に動くようにします。これで、矢が遠くに飛んでも画面がスクロールして見ることができます。

        // 矢の角度
        arrow.angle = -(90 - bar.rotation);// 矢の角度はメーターの角度と同じ
        arrow.addTorque(0.007);// 飛ばしているときに回転させる               
        arrow.originX = 0;
        arrow.originY = 9;// 回転するときにちょうどよくなるように
        backi.tl.then(function(){
            backi.touchEnabled = false;
            scene.addChild(scro);
            scro.x = pig.x + 32;
            scro.y = pig.y - 32;
            scro.follow(arrow);// scroが矢についていくことで画面スクロール
        });

矢が外れたら画面を豚に戻す

矢に衝突判定をつけ、地面に落ちたら矢をフォローしていたscroは消して、別のscro2という箱を出し、それを豚のところまで戻すことで画面をスクロールさせます。

矢が地面に落ちた時点で箱を出します。ただし、だるまが地面に落ちたとき(ゲームクリアのとき)にだるまだけでなく矢も落ちてしまったときには出したくないので、だるまが落ちていないときだけ出るようにif(daruma.y <= 219)という条件分岐をつけます。

矢がだるまを超えたときは、戻るときに高さが足りなくてだるまや土管にぶつかって戻ってこれなかったので、scro2の高さを高くしました。(scro2.y = daruma.y – 32;)

外れた矢がそのままだと、次に外れた矢がその上に乗ってしまったとき、地面との衝突判定が効かなくなるので、外れた矢は消します。( arrow.remove();

        // 矢が地面に落ちたら青いscro2を出して画面をスクロールしてぶたに戻す
        arrow.addCollision(ground);
        daruma.addCollision(arrow);
        arrow.addEventListener(Event.COLLISION, function(e){
            if (e.collision.target.tag == "地面"){
                if(daruma.y <= 219){// だるまが落ちていないとき
                    console.log("矢を打ってから戻る");
                    scro.remove();
                    arrow.tl.delay(8).then(function(){
                        if(mode == 1){
                            mode = 2;
                            var scro2 = new PhyBoxSprite(32, 32,
                                enchant.box2d.DYNAMIC_SPRITE,
                                1.0,
                                0.1,//摩擦
                                0.3
                            );
                            //scro2.backgroundColor = "blue";
                            // 矢ががだるまを超えちゃった場合
                            if(scro.x > daruma.x){
                                scro2.x = scro.x;
                                scro2.y = daruma.y - 32;   
                            }else{
                                scro2.x = scro.x;
                                scro2.y = scro.y;
                            }
                            scene.addChild(scro2);
                            console.log(daruma.y);
                            console.log("scro2でます");         
                            scro2.addImpulse(-8, -5);
                            console.log("戻ります");
                            scene.setScrollRange(scro2, 55);
                            // scro2がトンネルまで戻ってぶつかったら消える、モードを戻す
                    scro2.addCollision(tunnel1);
                            scro2.addEventListener(Event.COLLISION, function(){
                                scro2.remove();
                                mode = 0;
                                // 矢も消す
                                arrow.remove();
                            });
                        }                   
                    });
                }
            }         
        });

modeを使った制御

画面をスクロールさせている間に、矢が撃ててしまうと、スクロールがおかしくなってしまうので、その間は撃てないように、modeのパラメーターを使って制御します。

だるまについても、地面に落ちたときにゲームクリアにすると、だるまが跳ね返って地面に衝突する度に何度もゲームクリアが発動してしまうので、地面に衝突した最初の一度目だけゲームクリアとなるようにします。

    // modeで制御(scro2を一個だけにするのと、連射できないようにするため、
    // だるまの衝突判定のため)) 
    /* 矢を飛ばす前 0 :mode = 0; modec = 0;
       飛ばしたら 1 :mode = 1;
       scro2が発射できるのは1のときのみにして2個以上出ないようにする
       scro2が発射されたらすぐ 2: mode = 2;
       scro2が帰ってきたら 0に戻す mode = 0;
       矢を飛ばせるのは 0の時のみにする if(mode == 0){}
       だるまが地面におちたら modec = 1;
    */

だるまにスクロールレンジをセットする

だるまに矢が当たって、土管から落ちる時(ゲームクリアのとき)、だるまが見えなくなってしまうとつまらないので、だるまにsetScrollRangeをつけます。

だるまのy座標を見ると、218.79968127001965なので、(box2dだと重力によって、ほんの少し下がるようです)落ち始めたらセットとなるようにします。

ただし、だるまが地面に落ちてからもスクロールし続けると、ゲームクリアの文字やお殿様の画像がずれてしまうので、地面に落ちたら外します。(cancelScrollRangeも今井先生が作ってくださいました)

    console.log(daruma.y);
    // だるまが消えないようにだるまが落ち始めたらスクロールレンジ設定
    scene.addEventListener(Event.ENTER_FRAME, function(){
        if(daruma.y > 220){ // 218.7
            scene.setScrollRange(daruma, 55);
        }
        if(daruma.y > 300){ //
            scene.cancelScrollRange(daruma);
        }
    });

感想

角度メーターと矢の飛び方を連動させる調整のところ以外は、アイデアも含めて息子が頑張りました。先生もおっしゃっていたけれど、一人で全部できるものなんてないのだから、(そもそも基のゲームのつくりかただって全部先生から教えてもらったものなのだし)、手伝ってもらったことを負い目に感じる必要はないと思うのですが、息子は手伝ってもらったにしても自分でコードを打ったという実感がないと嫌みたいなので、その辺さりげなく手伝うようにしています。息子も頼ってくれるので、それも嫌でないうちは、協力したいと思います。

だいたい以上の流れで作りましたが、一つ機能を増やすと、その影響でそれまでのところに不具合がでて調整するために何かを付け足さないといけない、また一つ増やすとまた調整、この繰り返しです。おそろしく何度もプレイしなければなりません。

今までもそうでしたが、今この記事を書いていて、改めてそれを実感しました。

ゲーム作りって大変ですね。でもパズルを解いていくみたいで本当に面白いです。私にとってはゲーム作り自体が、今までで一番面白いパズルゲームです。 

完成したソースコード

以上を組み合わせて完成です

var assets = [
    // 背景
    "images/do_background.png",
    "images/do_ground.png",
    // 
    "images/do_box.png",
    // ダルマ
    "images/do_daruma.png",
    "images/gameclear.png",
    // ブタ
    "images/bal_pig.png",
    // 土管
    "images/ft_tunnel.png",
    // 
    "images/bal_arrow.png",
    // その他
    "images/title.png",// タイトル
    "images/bk_body.png",
    "images/bk_mage.png",
    "sounds/cf307/hyoushigi2.mp3",
    "sounds/cf307/muti.mp3",
    "sounds/cf307/hit04.mp3",
    "sounds/cf307/drum-japanese1.mp3",
];

function gameStart(){// ゲーム画面
    scene = new Scene();
    core.replaceScene(scene); core.resume();

    //==========
    // ここから
    //==========

    // モードと背景色
    var modec = 0;
    scene.backgroundColor = "#76d4fe";
    var mode = 1;

    // 背景
    var back = new Sprite(320 * 100, 480);
    back.image = core.assets["images/do_background.png"];
    scene.addChild(back);
    back.y = -32;

    // 重力のある世界
    var world = new PhysicsWorld( 0, 6 );
    scene.addEventListener(Event.ENTER_FRAME, function() {
        world.step(core.fps);
    });

    // 土管1
    var tunnel1 = new PhyBoxSprite(45, 200, enchant.box2d.STATIC_SPRITE);
    tunnel1.image = core.assets["images/ft_tunnel.png"];
    tunnel1.x = 10;
    tunnel1.y = 250;
    //tunnel1.y = 100;
    scene.addChild(tunnel1);

    // 土管2
    var tunnel2 = new PhyBoxSprite(45, 480, enchant.box2d.STATIC_SPRITE);
    tunnel2.image = core.assets["images/ft_tunnel.png"];
    tunnel2.x = 220+320;
    tunnel2.y = 250;
    scene.addChild(tunnel2);

    // 地面
    var ground = new PhyBoxSprite(320 * 100, 64, enchant.box2d.STATIC_SPRITE);
    ground.image = core.assets["images/do_ground.png"];
    ground.x = 0;
    ground.y = 480-64;
    scene.addChild(ground);
    ground.tag = "地面";

    // ダルマ落とし   第四引数:density(密度)・・・省略時:1.0
    //              第五引数:friction(摩擦)・・・省略時:0.5←難易度を決めるのはこれ
    //              第六引数:restitution(反発)・・・省略時:0.3

    // だるま
    var daruma = new PhyBoxSprite(
        31,
        31,
        enchant.box2d.DYNAMIC_SPRITE,
        0.35,// 初めの設定は0.5
        0.5,
        0.3,
    );
    daruma.image = core.assets["images/do_daruma.png"];
    daruma.x = tunnel2.x + tunnel2.width / 2 - daruma.width / 2;
    daruma.y = tunnel2.y - daruma.height;
    scene.addChild(daruma);
    daruma.tag = "だるま";
    // 衝突判定
    daruma.addCollision(ground);
    daruma.addEventListener(Event.COLLISION, function(e){
        // 矢が当たったら
        if(e.collision.target.tag == ""){
            console.log("当たった");
            var hit = core.assets["sounds/cf307/hit04.mp3"].clone();
            hit.play();
        }
        // 地面に落ちたら
        if(modec != 1 && e.collision.target.tag == "地面"){
            scro.remove();
            var sounds = core.assets["sounds/cf307/drum-japanese1.mp3"].clone();
            sounds.play();
            // だるまが消えてしまうので
            //scene.setScrollRange(daruma, 55);
            // だるまが地面に落ちたらゲームクリア!
            var gameclear = new ExSprite(230, 32);
            gameclear.image = core.assets["images/gameclear.png"];
            gameclear.x = daruma.x - 230;
            gameclear.y = daruma.y - 200 + 13;
            scene.addChild(gameclear);
            console.log("クリア");
            modec = 1;
            scene.setScrollRange(gameclear, 45);
            gameclear.tl.delay(32).then(function(){
                scene.setScrollRange(gameclear, 45);
                var tono = new ExSprite(190, 140);
                tono.image = core.assets["images/bk_body.png"];
                tono.x = gameclear.x + gameclear.width / 2 - tono.width / 2;
                tono.y = gameclear.y - 140;
                scene.addChild(tono);
                // あっぱれ
                var label = new Label("  あっ      ぱれ");
                label.color = 'white';
                label.font = "30px 'PixelMplus10'";// 28
                label.x = tono.x - 32;
                label.y = tono.y + tono.height / 2;
                scene.addChild(label); 
                // まげ
                var mage = new ExSprite(45, 60);
                mage.image = core.assets["images/bk_mage.png"];
                mage.x = tono.x + tono.width / 2 - mage.width / 2;
                mage.y = tono.y - 60;
                scene.addChild(mage);
                var sounds = core.assets["sounds/cf307/hyoushigi2.mp3"];
                sounds.play();
            });           
        }
    });    

    // 豚さん 
    var pig = new PhyBoxSprite(32, 32, enchant.box2d.DYNAMIC_SPRITE);
    pig.image = core.assets["images/bal_pig.png"];
    pig.x = tunnel1.x + tunnel1.width - pig.width;
    pig.y = tunnel1.y - pig.height;
    pig.frame = [0,0,1,1,2,2,3,3];
    scene.addChild(pig);

    // 撃てなくするための背景
    var backi = new Sprite(320 * 100, 480);
    //backi.image = core.assets["images/do_background.png"];
    scene.addChild(backi);
    backi.y = -32;

    // メーター
    var bar = new ExSprite(1, 32);
    bar.backgroundColor = "red";
    bar.x = 52;
    bar.y = 480 - 64 - 32 - 13 - 170;
    scene.addChild(bar);
    bar.originX = 0;
    bar.originY = 32;
    bar.tl.rotateBy(90, 32);
    bar.tl.rotateTo(0, 32);
    bar.tl.loop();

    // modeで制御(scro2を一個だけにするのと、連射できないようにするため) 
    /* 矢を飛ばす前 0
       飛ばしたら 1
       scro2が発射できるのは1のときのみにして2個以上出ないようにする
       scro2が発射されたらすぐ 2
       scro2が帰ってきたら 0に戻す
       矢を飛ばせるのは 0の時のみにする
       だるまが地面におちたらmodec = 1;
    */

    mode = 0; // モードの初期値

    // 矢を飛ばす
    backi.addEventListener(Event.TOUCH_START, function(e) {    
        // やを飛ばせるのはmode=0のときのみ
        if(mode == 0){
            var arrow = new PhyBoxSprite(
                22,     // 
                9,     // 高さ
                enchant.box2d.DYNAMIC_SPRITE,    // 動作モード
                1    // 密度
                //2      // 実験
            );
            arrow.image = core.assets["images/bal_arrow.png"];
            arrow.x = pig.x + pig.width + 1;
            arrow.y = pig.y + 18;
            scene.addChild(arrow);
            arrow.tag = "";
            scene.setScrollRange(arrow, 50);
            var sounds2 = core.assets["sounds/cf307/muti.mp3"].clone();
            sounds2.play();
            // バーの角度と矢の飛ぶ方向を対応させる
            var ax;
            ax = 2.5 *  bar.rotation / 100;
            var ay;
            ay = - 2.5 * (90 - bar.rotation) / 90;
            console.log(ax);
            console.log(ay);
            arrow.addImpulse(ax * 1.2, ay * 1.2);
            // 矢の角度
            arrow.angle = -(90 - bar.rotation);
            arrow.addTorque(0.007);               
            arrow.originX = 0;
            arrow.originY = 9;
            backi.tl.then(function(){
                backi.touchEnabled = false;
                scene.addChild(scro);
                scro.x = pig.x + 32;
                scro.y = pig.y - 32;
                scro.follow(arrow);// followの解除の仕方がわからない
            });  
            // 矢を飛ばしたらモード1に
            mode = 1;
            // 矢が地面に落ちたら青いscroを出して画面をスクロールしてぶたに戻す
            arrow.addCollision(ground);
            daruma.addCollision(arrow);
            arrow.addEventListener(Event.COLLISION, function(e){
                if (e.collision.target.tag == "地面"){
                    if(daruma.y <= 219){ // だるまのyが218と少しなので
                    console.log("矢を打ってから戻る");
                    scro.remove();
                    arrow.tl.delay(8).then(function(){
                        if(mode == 1){
                            mode = 2;
                            var scro2 = new PhyBoxSprite(32, 32,
                            enchant.box2d.DYNAMIC_SPRITE,
                            1.0,
                            0.1,//摩擦
                            0.3
                            );
                            //scro2.backgroundColor = "blue";
                            // スクロがだるまを超えちゃった場合
                            if(scro.x > daruma.x){
                                //scro2.x = daruma.x;
                                scro2.x = scro.x;
                                scro2.y = daruma.y - 32;   
                            }else{
                            scro2.x = scro.x;
                            scro2.y = scro.y;
                            }                       
                                scene.addChild(scro2);
                                console.log(daruma.y);
                                console.log("scro2でます");         
                                scro2.addImpulse(-8, -5);
                                console.log("戻ります");
                                scene.setScrollRange(scro2, 55);
                                // scro2がトンネルまで戻ってぶつかったら消える、モードを戻す
                        scro2.addCollision(tunnel1);
                                scro2.addEventListener(Event.COLLISION, function(){
                                    scro2.remove();
                                    mode = 0;
                                    // 矢も消す
                                    arrow.remove();
                                });                         
                        }
                    });
                }
            }         
        });
        // 戻ってから撃てるように
        backi.tl.then(function(){
            backi.touchEnabled = true;
        }); 
        console.log(daruma.y); 
        }     
    });

    //スクロールさせる用オブジェクト
    var scro = new PhyBoxSprite(32, 32, enchant.box2d.DYNAMIC_SPRITE,
       1.0,
       0,
       0.3
    );
    //scro.backgroundColor = "red";
    scro.x = 160;
    scro.y = 55;
    scene.addChild(scro);
    // scroが移動している間はタッチ無効化すべし
    scro.tl.then(function(){
       backi.touchEnabled = false;
       scro.addImpulse(10, -2);
    });
    // だるまにぶつからないように修正
    scro.tl.delay(25);
    scro.tl.then(function(){
       scro.setAwake(false);
       scro.addImpulse(-9, -2);
    });
    scro.tl.delay(45);
    scro.tl.then(function(){
         scro.remove();
         wall.remove();
         backi.touchEnabled = true;
    });   
    scene.setScrollRange(scro, 55);

    //
    var wall = new PhyBoxSprite(45, 480, enchant.box2d.STATIC_SPRITE);
    //wall.backgroundColor = "red";
    wall.x = daruma.x+ 140;
    wall.y = 0;
    scene.addChild(wall);  
    console.log(daruma.y);

    // だるまが消えないようにだるまが落ち始めたらスクロールレンジ設定
    scene.addEventListener(Event.ENTER_FRAME, function(){
        if(daruma.y > 220){ // 218.7
            scene.setScrollRange(daruma, 55);
            //scro.remove(); // ここで消すとはやすぎるのでラベルのところで消す
        }
        if(daruma.y > 300){ //
            scene.cancelScrollRange(daruma);
        }
    });

    //==========
    // ここまで
    //==========

}

function titleStart(){// タイトル画面
    var scene = gameManager.createTitleScene();
    core.replaceScene(scene); core.pause();
    scene.on(enchant.Event.TOUCH_START, function(){gameStart();});
}

//==========

// EnchantJS
enchant();
var gameManager;
var core;
var scene;
window.onload = function(){
    gameManager = new common.GameManager();
    core = gameManager.createCore(320, 480);
    core.preload(assets);
    core.onload = function(){titleStart();};
    core.start();
}
/*
enchant.Scene.prototype.setScrollRange = function(child, padding) {

    if (!child) return;
    var _paddingLeft = padding || 0;
    var _paddingRight = padding || 0;
    var _paddingTop = padding || 0;
    var _paddingBottom = padding || 0;
    // EnterFrameを解除
    if (this._scrollRangeArg) {
        this.removeEventListener(Event.ENTER_FRAME, this._scrollRangeArg);
        this._scrollRangeArg = null;
    }
    // 対象が画面の表示領域からはみ出ようとした時にスクロールさせる
    this.addEventListener(Event.ENTER_FRAME, function(){
        this._scrollRangeArg = arguments.callee;
        // Left
        if (child.x < _paddingLeft - this.x) {
            this.x += (_paddingLeft - this.x) - child.x;
        }
        // Right
        if (child.x > this.width - _paddingRight - this.x) {
            this.x -= child.x - (this.width - _paddingRight - this.x);
        }
        // Top
        if (child.y < _paddingTop - this.y) {
            this.y += (_paddingTop - this.y) - child.y;
        }
        // Bottom
        if (child.y > this.height - _paddingBottom - this.y) {
            this.y -= child.y - (this.height - _paddingBottom - this.y);
        }
    });
};
*/

ニャイコロ

すごろくをつくろうと思って、まずつくったサイコロです。

デザインは、娘が厚紙で作ったサイコロをそのまま再現しました。

猫がサイコロを転がすのかと思いきや、いっしょにぐるぐる転がっているだけというところがポイントです。

苦労したところは、音です。ドラムロールの音を長く鳴らして、振ったところで止めるということをしたかったのですが、どうやってもうまく制御できないので、断念しました。音についてはいろいろ難しいところがあるようです。

// Main

console.log("Hello EnchantJS!!");

var assets = [    
    "images/title.png",// タイトル
    "images/cf307/nekosai128abc.png",
    "sounds/cf307/drum-roll1.mp3",
    "sounds/cf307/roll-finish1.mp3",
    "sounds/cf307/cat-cry1.mp3",
];

function gameStart(){// ゲーム画面
    scene = gameManager.createGameScene();
    core.replaceScene(scene); core.resume();

    //==========
    // ここから
    //==========

    scene.backgroundColor = "#FADCE9";

    // サイコロ
    var sai = new ExSprite(128, 128);
    sai.image = core.assets["images/cf307/nekosai128abc.png"];
    sai.x = 320 / 2 - 128 / 2;
    sai.y = 480 / 2 - 128 / 2;
    sai.originY = 0;
    scene.addChild(sai);

    // サイコロ
    // タッチするとサイコロを振る
    scene.addEventListener(Event.TOUCH_START,function(){
        var sound1 = core.assets["sounds/cf307/drum-roll1.mp3"].clone();
        sound1.play();
        scene.tl.delay(32).then(function(){
            sound1.stop();
        });
     //sound1.src.loop = true;
        // サイコロが下にあるとき(回ってないとき)   
        if(sai.y == 480 / 2 - 128 / 2){
            console.log("回ってないとき");
            sai.tl.moveBy(0, -150, 3, enchant.Easing.QUART_EASEIN);
            sai.tl.moveTo(320 / 2 - 128 / 2, 480 / 2 - 128 / 2 - 100, 2);
            sai.frame = [0, 1, 2, 3, 4, 5];
            sai.scale(0.8, 0.8);             
        }
        // 上にあるとき(回っているとき)
        if(sai.y == 480 / 2 - 128 / 2 - 100){           
            console.log("回っているとき");
            sai.tl.moveTo(320 / 2 - 128 / 2, 480 / 2 - 128 / 2, 5, enchant.Easing.BOUNCE_EASEOUT);//and().scaleTo(1.2, 1.2, 0);
            sai.tl.scaleTo(1, 1, 0);
            sound1.stop();
            var sound = core.assets["sounds/cf307/roll-finish1.mp3"].clone();
            sound.play();
            sai.tl.delay(5).then(function(){
                var sound2 = core.assets["sounds/cf307/cat-cry1.mp3"].clone();
                sound2.play();
            });
            // さいころの目
            var s0 = getRandom(1, 6);
            if(s0 == 1){
                console.log("1");
                sai.frame = [0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 6, 6, 6, 6, 6, 6, 6, 0, null];
            }   
            if(s0 == 2){
                //sai.frame = [7];
                console.log("2");
                sai.frame = [12, 12, 12, 12, 12, 12, 12, 12, 7, 7, 7, 7, 7, 7, 7, 7, 7, 12, null];     
            }
            if(s0 == 3){
                //sai.frame = [8]; 
                console.log("3"); 
                sai.frame = [13, 13, 13, 13, 13, 13, 13, 13, 8, 8, 8, 8, 8, 8, 8, 8, 8, 13, null];     
            }
            if(s0 == 4){
                //sai.frame = [9];
                console.log("4");
                sai.frame = [3, 3, 3, 3, 3, 3, 3, 3, 9, 9, 9, 9, 9, 9, 9, 9, 9, 3, null];      
            }
            if(s0 == 5){
                //sai.frame = [10];
                console.log("5");
                sai.frame = [14, 14, 14, 14, 14, 14, 14, 14, 10, 10, 10, 10, 10, 10, 10, 10, 10, 14, null];                  
            }
            if(s0 == 6){
                //sai.frame = [11];
                console.log("6"); 
                sai.frame = [15, 15, 15, 15, 15, 15, 15, 15, 11, 11, 11, 11, 11, 11, 11, 11, 11, 15, null];              
            }      
        }
    });
    
    //==========
    // ここまで
    //==========

}

function getRandom(start, end) {
    return start + Math.floor( Math.random() * (end - start + 1));
}

function titleStart(){// タイトル画面
    var scene = gameManager.createTitleScene();
    core.replaceScene(scene); core.pause();
    scene.on(enchant.Event.TOUCH_START, function(){gameStart();});
}

//==========
// EnchantJS
enchant();
var gameManager;
var core;
var scene;
window.onload = function(){
    gameManager = new common.GameManager();
    core = gameManager.createCore(320, 480);
    core.preload(assets);
    core.onload = function(){titleStart();};
    core.start();
}

激重の極みeasy? 改

前回と変えたのは、球を大きくしたので、一度に消えるブロックが増えたところです。さらに負荷が高まりましたが難易度としてはeasyになりました。

得点によって球の大きさを変えようとしたのですが、これも場合によってすり抜けてしまうので、やめました。

それから、このシリーズ全部に共通していますが、クリアの判定がややこしいことになっています。2000個目のブロックに当たった瞬間にクリアにするようにしたために、「スコアが1999でブロックに当たる」と「当たってスコアが2000になる」の二つの場合をつけなければなりませんでした。衝突のタイミングが判定のタイミングになるからです。

だから、スコアラベルのところENTER_FRAMEなので、ここでやればよかったんじゃないかと思うのですが、そのときはENTER_FRAMEの意味がよくわからなかったのかもしれません。

この頃、windowsからmacに変えたのですが、windowsで綺麗に字下げをして揃えて書いたつもりなのに、macで開くとぐちゃぐちゃになっていることがよくありました。

先生にきいたら教えてくださったのですが、Windowsでは全角と半角が混ざっていても気づかないので、ところどころ全角の半角が混ざっていたために、ずれてしまっていたのでした。それからは、全部半角スペースでやるようにしました。

あと、ここにソースコードを貼るときに、改行がどうしてもずれてしまいます。貼った後に修正するのですが、行が多いので面倒です。何かいい方法はないものかといろいろ試していますがまだ見つかりません。

// Main
console.log("Hello EnchantJS!!");
var assets = [
    "images/back_space.png",    
    "images/kati_tanuki.png",
    "images/title.png",// タイトル
    "sounds/coin.mp3",
    "sounds/jump.mp3",
    "images/cf307/baayoko64.png",
    "images/xe_bullet_r.png",
    "images/gameover.png", 
    "images/cf307/blueground.png",
    "sounds/cf307/decision1.mp3",
    "sounds/cf307/decision3.mp3",
    "sounds/cf307/rabohyuuu.mp3",
    "images/gameclear.png",
    "sounds/cf307/trumpet-dub1.mp3",
    "sounds/cf307/boyoyon1.mp3",
    "sounds/cf307/trumpet1.mp3",
    "sounds/cf307/dondonpafupafu1.mp3",
    "images/block_d.png", 
    "images/cf307/block8p.png", 
    "sounds/cf307/ME014-090610-loss02-wav.mp3",
    "sounds/cf307/hit04.mp3",  
    "images/cf307/10_480.png", 
    "images/bomb.png",
    "images/b_blue.png",  
];
function gameStart(){// ゲーム画面
    scene = gameManager.createGameScene();
    core.replaceScene(scene); core.resume();
    //==========
    // ここから
    //==========
    scene.backgroundColor = "darkgray";
    
    // 背景
    var sky = new ExSprite(320, 480);
    sky.image = core.assets["images/back_space.png"];
    scene.addChild(sky);

    // 地面
    var ground = new ExSprite(320, 55);
    ground.image = core.assets["images/cf307/blueground.png"];
    ground.x = 0;
    ground.y = 480; 
    scene.addChild(ground);

   // 壁左
    var kabe = new ExSprite(10, 480);
    kabe.image = core.assets["images/cf307/10_480.png"]; 
    kabe.x = -10;
    kabe.y = 0;
    scene.addChild(kabe); 
    kabe.tag = "kabe";

   // 壁右
    var kabem = new ExSprite(10, 480);
    kabem.image = core.assets["images/cf307/10_480.png"]; 
    kabem.x = 320;
    kabem.y = 0;
    scene.addChild(kabem); 
    kabem.tag = "kabem";

    // バー
    var bar = new ExSprite(64, 6);
    bar.image = core.assets["images/cf307/baayoko64.png"];
    scene.addChild(bar);
    bar.x = 320 / 2 - 32;
    bar.y = 480 - 32;
    bar.tag = "bar";
    //bar.scale(10, 1);// テスト用

    // 玉グループ
   var tamaGroup = new Group();
    scene.addChild(tamaGroup); 
        
    // 玉
    var tama = new ExSprite(9, 9);
    tama.image = core.assets["images/xe_bullet_r.png"];
    //scene.addChild(tama);
    tama.x = bar.x + bar.width / 2 - tama.width / 2;
    tama.y = bar.y - tama.height;
    tamaGroup.addChild(tama);
    tama.originX = 0;
    tama.originY = 0;
    tama.scale(2, 2);  

    // 最初の音
    var sound0 = core.assets["sounds/cf307/decision3.mp3"].clone();
    sound0.play();   

    // 玉の動き
    var x1 = getRandom(0, 320 - 5);
    //var x1 = getRandom(-320, 0);// テスト用
    tama.tl.moveTo(x1, -9, 32, enchant.Easing.SINE_EASEOUT); 

    // 最初に跳ね返る音
    tama.tl.then(function(){
        var sound1 = core.assets["sounds/cf307/decision1.mp3"].clone();
        sound1.play();    
    });
    var x2 = getRandom(0, 320 - 5);
    tama.tl.moveTo(x2, 480, 32, enchant.Easing.SINE_EASEOUT); 

    // ブロックグループ
    var blockGroup = new Group();
    scene.addChild(blockGroup);

    // スコア表示
    var score = 0;
    scoreLabel = new Label('SCORE : 0');
    scene.addChild(scoreLabel);
    scoreLabel.x = 10;
    scoreLabel.y = 10;
    scoreLabel.color = 'white';
    scoreLabel.font = "24px 'PixelMplus10'";
    scoreLabel.addEventListener(Event.ENTER_FRAME, function() {
        scoreLabel.text = 'SCORE : ' + score;
    });
    
    // ブロック(繰り返し処理)
    var blocks = new Array();
    for(var i=0; i< 2000; i++){ 
        // ブロック
        var block = new ExSprite(8, 8);
        block.image = core.assets["images/cf307/block8p.png"];        
        block.x = 0  + ((i % 40) * 8);
        block.y = 0 + (Math.floor(i / 40) * 8);
        blockGroup.addChild(block);
        block.tag = "b";// タグをつけます 
        blocks.push(block);   //見よう見真似 
    } 
    // 当たり判定をつけます
    for(var i=0; i<blocks.length; i++){
       tama.addCollision(blocks[i]);
    }
    // 当たり判定
    tama.addCollision(bar); 
    //tama.addCollision(kabe); 
    tama.addCollision(kabem); 
    tama.addEventListener(Event.COLLISION, function(e) {
            // クリア
            if(2000 <= score){
                tama.remove();
                var label6 = new Label("?! アンビリーバボー!!!!");
                label6.x = 60;
                label6.y = 480 / 2 - 32 / 2 + 48;
                label6.color = "white";
                label6.font = "24px 'PixelMplus10'";
                scene.addChild(label6);
                var sound100 = core.assets["sounds/cf307/rabohyuuu.mp3"].clone();
                sound100.play();
                var clear = new ExSprite(230, 32);
                clear.image = core.assets["images/gameclear.png"];
                scene.addChild(clear);
                clear.x = 320 / 2 - clear.width / 2;
                clear.y = 480 / 2  - clear.height;
                clear.scale(0.5, 0.5);
                clear.tl.scaleTo(1.4, 1.4, 4);
                clear.tl.scaleTo(1.2, 1.2, 4);   
                // 秘密のボタン
                clear.tl.then(function(){
                var retry = new ExSprite(62, 55);
                retry.image = core.assets["images/b_blue.png"];
                scene.addChild(retry);
                retry.x = 320 / 2 - retry.width / 2;
                retry.y = 300 ;
                retry.tl.moveBy(0, 50, 20);
                // ボタンをタッチ
               retry.addEventListener(Event.TOUCH_START, function(){
                    retry.frame = 1; 
                    console.log("タッチしました");
               });  
               retry.addEventListener(Event.TOUCH_END, function(){
                   retry.frame = 0;
                   gameStart1();
               });
              var label = new Label("!?");
              label.color = 'red';
               label.font = "25px 'PixelMplus10'";
               //label.textAlign = "center";
               label.x = 135;             
               label.y = 360 + 55;
               scene.addChild(label);    
            }); 
        }                          
        // ブロックに当たったら
        if(e.collision.target.tag == "b"){
        // クリア
            if(1999 <= score){
                tama.remove();
                var label6 = new Label("?! アンビリーバボー!!!!");
                label6.x = 60;
                label6.y = 480 / 2 - 32 / 2 + 48;
                label6.color = "white";
                label6.font = "24px 'PixelMplus10'";
                scene.addChild(label6);
                var sound100 = core.assets["sounds/cf307/rabohyuuu.mp3"].clone();
                sound100.play();
                var clear = new ExSprite(230, 32);
                clear.image = core.assets["images/gameclear.png"];
                scene.addChild(clear);
                clear.x = 320 / 2 - clear.width / 2;
                clear.y = 480 / 2  - clear.height;
                clear.scale(0.5, 0.5);
                clear.tl.scaleTo(1.4, 1.4, 4);
                clear.tl.scaleTo(1.2, 1.2, 4);   
                // 秘密のボタン
           clear.tl.then(function(){
                var retry = new ExSprite(62, 55);
                retry.image = core.assets["images/b_blue.png"];
                scene.addChild(retry);
                retry.x = 320 / 2 - retry.width / 2;
                retry.y = 300 ;
                retry.tl.moveBy(0, 50, 20);
                // ボタンをタッチ
               retry.addEventListener(Event.TOUCH_START, function(){
                    retry.frame = 1; 
                    console.log("タッチしました");
                });
                retry.addEventListener(Event.TOUCH_END, function(){
                    retry.frame = 0;
                    gameStart1();
                });
                var label = new Label("!?");
                label.color = 'red';
                label.font = "25px 'PixelMplus10'";
                //label.textAlign = "center";
                label.x = 135;             
                label.y = 360 + 55;
                scene.addChild(label);  
            }); 
        }
            e.collision.target.tl.then(function() {
                e.collision.target.remove();// 消します 
           var bomb = new ExSprite(32, 32);
                bomb.image = core.assets["images/bomb.png"];
                bomb.x = e.collision.target.x;
                bomb.y = e.collision.target.y;
                scene.addChild(bomb); 
                bomb.scale(0.5, 0.5);
                bomb.frame = [0, 1, 2, 3, 4, null];
                //score += 2;// テスト用
                score += 1; 
                var sound = core.assets["sounds/cf307/hit04.mp3"].clone();
                sound.play();        
            }); 
        }
        // バーに当たったら
        if(e.collision.target.tag == "bar"){
            tama.tl.clear();                             
            // 玉の動きのパターン
        var p1 = getRandom(1, 3);
         // (1)最初に正面に当たる
            if(p1 == 1){
                var x1 = getRandom(0, 320 - 9); 
                tama.tl.moveTo(x1, -9, 32, enchant.Easing.SINE_EASEOUT);
                tama.tl.then(function(){
                    var sound = core.assets["sounds/cf307/decision1.mp3"].clone();
                    sound.play();
                });
                // 正面に当たった後
                var p2 = getRandom(1, 3);
         // (1)-1そのまま戻る
                if(p2 == 1){
                    var x2 = getRandom(0, 320 - 5); 
                    tama.tl.moveTo(x2, 480 - 5, 32, enchant.Easing.SINE_EASEOUT);
                } 
         // (1)-2左の壁に当たってから戻る
         if(p2 == 2){
                    var y1 = getRandom(0, 200);
                    tama.tl.moveTo(0, y1, 16, enchant.Easing.SINE_EASEOUT);
                    tama.tl.then(function(){
                        var sound = core.assets["sounds/cf307/decision1.mp3"].clone();
                        sound.play();
                    });
                    var x2 = getRandom(0, 320 - 5); 
                    tama.tl.moveTo(x2, 480 - 5, 32, enchant.Easing.SINE_EASEOUT);
                }
                // (1)-3右の壁に当たってから戻る
                if(p2 == 3){
                    var y1 = getRandom(0, 200);
                    tama.tl.moveTo(320 - 5, y1, 16, enchant.Easing.SINE_EASEOUT);
                    tama.tl.then(function(){
                        var sound = core.assets["sounds/cf307/decision1.mp3"].clone();
                        sound.play();
                    });
                    var x2 = getRandom(0, 320 - 5); 
                    tama.tl.moveTo(x2, 480 - 5, 32, enchant.Easing.SINE_EASEOUT);
                }
            } 
            // (2)最初に左の壁に当たる
            if(p1 == 2){
                var y1 = getRandom(200, 400);
                tama.tl.moveTo(0, y1, 16, enchant.Easing.SINE_EASEOUT); 
                tama.tl.then(function(){
                    var sound = core.assets["sounds/cf307/decision1.mp3"].clone();
                    sound.play();
                });
                var x1 = getRandom(0, 320 - 9); 
                tama.tl.moveTo(x1, -9, 20, enchant.Easing.SINE_EASEOUT);
                tama.tl.then(function(){
                    var sound = core.assets["sounds/cf307/decision1.mp3"].clone();
                    sound.play();
                });
                // 正面に当たった後
                var p2 = getRandom(1, 3);
          // (2)-1そのまま戻る
                if(p2 == 1){
                    var x2 = getRandom(0, 320 - 5); 
                    tama.tl.moveTo(x2, 480 - 5, 32, enchant.Easing.SINE_EASEOUT);
                } 
         // (2)-2左の壁に当たってから戻る
          if(p2 == 2){
                    var y1 = getRandom(0, 200);
                    tama.tl.moveTo(0, y1, 16, enchant.Easing.SINE_EASEOUT);
                    tama.tl.then(function(){
                        var sound = core.assets["sounds/cf307/decision1.mp3"].clone();
                        sound.play();
                    });                    
                    var x2 = getRandom(0, 320 - 5); 
                    tama.tl.moveTo(x2, 480 - 5, 32, enchant.Easing.SINE_EASEOUT);
                }
                // (2)-3右の壁に当たってから戻る
                if(p2 == 3){
                    var y1 = getRandom(0, 200);
                    tama.tl.moveTo(320 - 5, y1, 16, enchant.Easing.SINE_EASEOUT);
                    tama.tl.then(function(){
                        var sound = core.assets["sounds/cf307/decision1.mp3"].clone();
                        sound.play();
                    });
                    var x2 = getRandom(0, 320 - 5); 
                    tama.tl.moveTo(x2, 480 - 5, 32, enchant.Easing.SINE_EASEOUT);
                }
            }
            // (3)最初に右の壁に当たる
            if(p1 == 3){
                var y1 = getRandom(200, 400);
                tama.tl.moveTo(320 - 5, y1, 16, enchant.Easing.SINE_EASEOUT);
                tama.tl.then(function(){
                    var sound = core.assets["sounds/cf307/decision1.mp3"].clone();
                    sound.play();
                });
                var x1 = getRandom(0, 320 - 5); 
                tama.tl.moveTo(x1, -9, 16, enchant.Easing.SINE_EASEOUT);
          tama.tl.then(function(){
                    var sound = core.assets["sounds/cf307/decision1.mp3"].clone();
                    sound.play();
                });
                // 正面に当たった後
                var p2 = getRandom(1, 3);
          // (3)-1そのまま戻る
                if(p2 == 1){
                    var x2 = getRandom(0, 320 - 5); 
                    tama.tl.moveTo(x2, 480 - 5, 32, enchant.Easing.SINE_EASEOUT);
                } 
         // (3)-2左の壁に当たってから戻る
          if(p2 == 2){
                    var y1 = getRandom(0, 200);
                    tama.tl.moveTo(0, y1, 16, enchant.Easing.SINE_EASEOUT);
                    tama.tl.then(function(){
                        var sound = core.assets["sounds/cf307/decision1.mp3"].clone();
                        sound.play();
                    });                    
                    var x2 = getRandom(0, 320 - 5); 
                    tama.tl.moveTo(x2, 480 - 5, 32, enchant.Easing.SINE_EASEOUT);
                }
                // (3)-3右の壁に当たってから戻る
                if(p2 == 3){
                    var y1 = getRandom(0, 200);
                    tama.tl.moveTo(320 - 5, y1, 16, enchant.Easing.SINE_EASEOUT);
                    tama.tl.then(function(){
                        var sound = core.assets["sounds/cf307/decision1.mp3"].clone();
                        sound.play();
                    });
                    var x2 = getRandom(0, 320 - 5); 
                    tama.tl.moveTo(x2, 480 - 5, 32, enchant.Easing.SINE_EASEOUT);
                }
            }
            // 音
            var sound2 = core.assets["sounds/cf307/decision3.mp3"].clone();
            sound2.play();       
            //tama.tl.moveTo(160, 471, 16); //テスト用
            //score += 2000; //テスト用
        } 
    });   
   
    // 画面をタップしてバーを動かす
    scene.addEventListener(Event.TOUCH_START, function(e){
        console.log("タッチ");
        console.log(e.x);
        bar.tl.moveTo(e.x - 32, 480 - 32, 3, enchant.Easing.QUART_EASEINOUT);
    });
    // ゲームオーバー
    ground.addCollision(tama);    
    ground.addEventListener(Event.COLLISION, function(e) {
        tama.remove();
        var over = new ExSprite(230, 32);
        over.image = core.assets["images/gameover.png"];
        scene.addChild(over);
        over.x = 320 / 2 - over.width / 2;
        over.y = 480 / 2  - over.height + 16;
        over.scale(0.5, 0.5);
        over.tl.scaleTo(1, 1, 8);
        var sound = core.assets["sounds/cf307/ME014-090610-loss02-wav.mp3"].clone();
        sound.play();
        over.tl.then(function() {
            var label = new Label("  TAP TO RETRY");
           label.color = 'red';
            label.font = "28px 'PixelMplus10'";
            label.textAlign = "center";
            label.y = 220 + 100;
            scene.addChild(label); 
            scene.addEventListener(Event.TOUCH_START, function() {
                gameStart();
            });                                                      
        });        
    });  
                                                                                        
    //==========
    // ここまで
    //==========
}
function gameStart1(){// サービスゲーム画面
    scene = gameManager.createGameScene();
    core.replaceScene(scene); core.resume();
    //==========
    // ここから
    //==========
    scene.backgroundColor = "darkgray";
    
    // 背景
    var sky = new ExSprite(320, 480);
    sky.image = core.assets["images/back_space.png"];
    scene.addChild(sky);
    // 地面
    var ground = new ExSprite(320, 55);
    ground.image = core.assets["images/cf307/blueground.png"];
    ground.x = 0;
    ground.y = 480; 
    scene.addChild(ground);
     // 壁左
    var kabe = new ExSprite(10, 480);
    kabe.image = core.assets["images/cf307/10_480.png"]; 
    kabe.x = -10;
    kabe.y = 0;
    scene.addChild(kabe); 
    kabe.tag = "kabe";
     // 壁右
    var kabem = new ExSprite(10, 480);
    kabem.image = core.assets["images/cf307/10_480.png"]; 
    kabem.x = 320;
    kabem.y = 0;
    scene.addChild(kabem); 
    kabem.tag = "kabem";
    // バー
    var bar = new ExSprite(64, 6);
    bar.image = core.assets["images/cf307/baayoko64.png"];
    scene.addChild(bar);
    bar.x = 320 / 2 - 32;
    bar.y = 480 - 32;
    bar.tag = "bar";
    bar.scale(10, 1);// テスト用
    // 玉グループ
     var tamaGroup = new Group();
    scene.addChild(tamaGroup);         
    // 玉
    var tama = new ExSprite(9, 9);
    tama.image = core.assets["images/xe_bullet_r.png"];
    //scene.addChild(tama);
    tama.x = bar.x + bar.width / 2 - tama.width / 2;
    tama.y = bar.y - tama.height;
    tamaGroup.addChild(tama);
    tama.originX = 0;
    tama.originY = 0;
    tama.scale(2, 2);  
    // 最初の音
  var sound0 = core.assets["sounds/cf307/decision3.mp3"].clone();
    sound0.play();   
    // 玉の動き
    var x1 = getRandom(0, 320 - 5);
    //var x1 = getRandom(-320, 0);// テスト用
    tama.tl.moveTo(x1, -9, 32, enchant.Easing.SINE_EASEOUT); 
    // 最初に跳ね返る音
    tama.tl.then(function(){
        var sound1 = core.assets["sounds/cf307/decision1.mp3"].clone();
        sound1.play();    
    });
    var x2 = getRandom(0, 320 - 5);
    tama.tl.moveTo(x2, 480, 32, enchant.Easing.SINE_EASEOUT); 
    // ブロックグループ
    var blockGroup = new Group();
    scene.addChild(blockGroup);
    // スコア表示
    var score = 0;
    scoreLabel = new Label('SCORE : 0');
    scene.addChild(scoreLabel);
    scoreLabel.x = 10;
    scoreLabel.y = 10;
    scoreLabel.color = 'white';
    scoreLabel.font = "24px 'PixelMplus10'";
    scoreLabel.addEventListener(Event.ENTER_FRAME, function() {
        scoreLabel.text = 'SCORE : ' + score;
    });
    
    // ブロック(繰り返し処理)
    var blocks = new Array();
    for(var i=0; i< 2000; i++){ 
        // ブロック
        var block = new ExSprite(8, 8);
        block.image = core.assets["images/cf307/block8p.png"];        
        block.x = 0  + ((i % 40) * 8);
        block.y = 0 + (Math.floor(i / 40) * 8);
        blockGroup.addChild(block);
        block.tag = "b";// タグをつけます 
        blocks.push(block);   //見よう見真似 
    } 
    // 当たり判定をつけます
    for(var i=0; i<blocks.length; i++){
       tama.addCollision(blocks[i]);
    }
    // 当たり判定
    tama.addCollision(bar); 
    //tama.addCollision(kabe); 
    tama.addCollision(kabem); 
    tama.addEventListener(Event.COLLISION, function(e) {
            // クリア
            if(2000 <= score){
                tama.remove();
                var label6 = new Label("?! アンビリーバボー!!!!");
                label6.x = 60;
                label6.y = 480 / 2 - 32 / 2 + 48;
                label6.color = "white";
                label6.font = "24px 'PixelMplus10'";
                scene.addChild(label6);
                var sound100 = core.assets["sounds/cf307/rabohyuuu.mp3"].clone();
                sound100.play();
                var clear = new ExSprite(230, 32);
                clear.image = core.assets["images/gameclear.png"];
                scene.addChild(clear);
                clear.x = 320 / 2 - clear.width / 2;
                clear.y = 480 / 2  - clear.height;
                clear.scale(0.5, 0.5);
                clear.tl.scaleTo(1.4, 1.4, 4);
                clear.tl.scaleTo(1.2, 1.2, 4);  
        var label = new Label("  TAP TO RETRY");
           label.color = 'red';
            label.font = "28px 'PixelMplus10'";
            label.textAlign = "center";
            label.y = 400;
            scene.addChild(label); 
            scene.addEventListener(Event.TOUCH_START, function() {
                gameStart();    
            });
            }                          
        // ブロックに当たったら
        if(e.collision.target.tag == "b"){
            e.collision.target.tl.then(function() {
                e.collision.target.remove();// 消します 
         var bomb = new ExSprite(32, 32);
                bomb.image = core.assets["images/bomb.png"];
                bomb.x = e.collision.target.x;
                bomb.y = e.collision.target.y;
                scene.addChild(bomb); 
                bomb.scale(0.5, 0.5);
                bomb.frame = [0, 1, 2, 3, 4, null];
                //score += 2;// テスト用
                score += 1; 
                var sound = core.assets["sounds/cf307/hit04.mp3"].clone();
                sound.play();        
            }); 
            // クリア
            if(1999 <= score){
                tama.remove();
                var label6 = new Label("?! アンビリーバボー!!!!");
                label6.x = 60;
                label6.y = 480 / 2 - 32 / 2 + 48;
                label6.color = "white";
                label6.font = "24px 'PixelMplus10'";
                scene.addChild(label6);
                var sound100 = core.assets["sounds/cf307/rabohyuuu.mp3"].clone();
                sound100.play();
                var clear = new ExSprite(230, 32);
                clear.image = core.assets["images/gameclear.png"];
                scene.addChild(clear);
                clear.x = 320 / 2 - clear.width / 2;
                clear.y = 480 / 2  - clear.height;
                clear.scale(0.5, 0.5);
                clear.tl.scaleTo(1.4, 1.4, 4);
                clear.tl.scaleTo(1.2, 1.2, 4);  
        var label = new Label("  TAP TO RETRY");
           label.color = 'red';
            label.font = "28px 'PixelMplus10'";
            label.textAlign = "center";
            label.y = 400;
            scene.addChild(label); 
            scene.addEventListener(Event.TOUCH_START, function() {
                gameStart();    
            });
            }                       
        }
        // バーに当たったら
        if(e.collision.target.tag == "bar"){
            tama.tl.clear();
                               
            // 玉の動きのパターン
       var p1 = getRandom(1, 3);
        // (1)最初に正面に当たる
            if(p1 == 1){
                var x1 = getRandom(0, 320 - 9); 
                tama.tl.moveTo(x1, -9, 32, enchant.Easing.SINE_EASEOUT);
                tama.tl.then(function(){
                    var sound = core.assets["sounds/cf307/decision1.mp3"].clone();
                    sound.play();
                });
                // 正面に当たった後
                var p2 = getRandom(1, 3);
         // (1)-1そのまま戻る
                if(p2 == 1){
                    var x2 = getRandom(0, 320 - 5); 
                    tama.tl.moveTo(x2, 480 - 5, 32, enchant.Easing.SINE_EASEOUT);
                } 
         // (1)-2左の壁に当たってから戻る
         if(p2 == 2){
                    var y1 = getRandom(0, 200);
                    tama.tl.moveTo(0, y1, 16, enchant.Easing.SINE_EASEOUT);
                    tama.tl.then(function(){
                        var sound = core.assets["sounds/cf307/decision1.mp3"].clone();
                        sound.play();
                    });
                    var x2 = getRandom(0, 320 - 5); 
                    tama.tl.moveTo(x2, 480 - 5, 32, enchant.Easing.SINE_EASEOUT);
                }
                // (1)-3右の壁に当たってから戻る
                if(p2 == 3){
                    var y1 = getRandom(0, 200);
                    tama.tl.moveTo(320 - 5, y1, 16, enchant.Easing.SINE_EASEOUT);
                    tama.tl.then(function(){
                        var sound = core.assets["sounds/cf307/decision1.mp3"].clone();
                        sound.play();
                    });
                    var x2 = getRandom(0, 320 - 5); 
                    tama.tl.moveTo(x2, 480 - 5, 32, enchant.Easing.SINE_EASEOUT);
                }
            } 
            // (2)最初に左の壁に当たる
            if(p1 == 2){
                var y1 = getRandom(200, 400);
                tama.tl.moveTo(0, y1, 16, enchant.Easing.SINE_EASEOUT); 
                tama.tl.then(function(){
                    var sound = core.assets["sounds/cf307/decision1.mp3"].clone();
                    sound.play();
                });
                var x1 = getRandom(0, 320 - 9); 
                tama.tl.moveTo(x1, -9, 20, enchant.Easing.SINE_EASEOUT);
                tama.tl.then(function(){
                    var sound = core.assets["sounds/cf307/decision1.mp3"].clone();
                    sound.play();
                });
                // 正面に当たった後
                var p2 = getRandom(1, 3);
          // (2)-1そのまま戻る
                if(p2 == 1){
                    var x2 = getRandom(0, 320 - 5); 
                    tama.tl.moveTo(x2, 480 - 5, 32, enchant.Easing.SINE_EASEOUT);
                } 
         // (2)-2左の壁に当たってから戻る
          if(p2 == 2){
                    var y1 = getRandom(0, 200);
                    tama.tl.moveTo(0, y1, 16, enchant.Easing.SINE_EASEOUT);
                    tama.tl.then(function(){
                        var sound = core.assets["sounds/cf307/decision1.mp3"].clone();
                        sound.play();
                    });                    
                    var x2 = getRandom(0, 320 - 5); 
                    tama.tl.moveTo(x2, 480 - 5, 32, enchant.Easing.SINE_EASEOUT);
                }
                // (2)-3右の壁に当たってから戻る
                if(p2 == 3){
                    var y1 = getRandom(0, 200);
                    tama.tl.moveTo(320 - 5, y1, 16, enchant.Easing.SINE_EASEOUT);
                    tama.tl.then(function(){
                        var sound = core.assets["sounds/cf307/decision1.mp3"].clone();
                        sound.play();
                    });
                    var x2 = getRandom(0, 320 - 5); 
                    tama.tl.moveTo(x2, 480 - 5, 32, enchant.Easing.SINE_EASEOUT);
                }
            }
            // (3)最初に右の壁に当たる
            if(p1 == 3){
                var y1 = getRandom(200, 400);
                tama.tl.moveTo(320 - 5, y1, 16, enchant.Easing.SINE_EASEOUT);
                tama.tl.then(function(){
                    var sound = core.assets["sounds/cf307/decision1.mp3"].clone();
                    sound.play();
                });
                var x1 = getRandom(0, 320 - 5); 
                tama.tl.moveTo(x1, -9, 16, enchant.Easing.SINE_EASEOUT);
          tama.tl.then(function(){
                    var sound = core.assets["sounds/cf307/decision1.mp3"].clone();
                    sound.play();
                });
                // 正面に当たった後
                var p2 = getRandom(1, 3);
          // (3)-1そのまま戻る
                if(p2 == 1){
                    var x2 = getRandom(0, 320 - 5); 
                    tama.tl.moveTo(x2, 480 - 5, 32, enchant.Easing.SINE_EASEOUT);
                } 
         // (3)-2左の壁に当たってから戻る
          if(p2 == 2){
                    var y1 = getRandom(0, 200);
                    tama.tl.moveTo(0, y1, 16, enchant.Easing.SINE_EASEOUT);
                    tama.tl.then(function(){
                        var sound = core.assets["sounds/cf307/decision1.mp3"].clone();
                        sound.play();
                    });                    
                    var x2 = getRandom(0, 320 - 5); 
                    tama.tl.moveTo(x2, 480 - 5, 32, enchant.Easing.SINE_EASEOUT);
                }
                // (3)-3右の壁に当たってから戻る
                if(p2 == 3){
                    var y1 = getRandom(0, 200);
                    tama.tl.moveTo(320 - 5, y1, 16, enchant.Easing.SINE_EASEOUT);
                    tama.tl.then(function(){
                        var sound = core.assets["sounds/cf307/decision1.mp3"].clone();
                        sound.play();
                    });
                    var x2 = getRandom(0, 320 - 5); 
                    tama.tl.moveTo(x2, 480 - 5, 32, enchant.Easing.SINE_EASEOUT);
                }
            }
            // 音
            var sound2 = core.assets["sounds/cf307/decision3.mp3"].clone();
            sound2.play();       
            //tama.tl.moveTo(160, 471, 16); //テスト用
            //score += 500; //テスト用
        } 
    });   
   
    // 画面をタップしてバーを動かす
    scene.addEventListener(Event.TOUCH_START, function(e){
        console.log("タッチ");
        console.log(e.x);
        bar.tl.moveTo(e.x - 32, 480 - 32, 3, enchant.Easing.QUART_EASEINOUT);
    });
    // ゲームオーバー
    ground.addCollision(tama);    
    ground.addEventListener(Event.COLLISION, function(e) {
        tama.remove();
        var over = new ExSprite(230, 32);
        over.image = core.assets["images/gameover.png"];
        scene.addChild(over);
        over.x = 320 / 2 - over.width / 2;
        over.y = 480 / 2  - over.height + 16;
        over.scale(0.5, 0.5);
        over.tl.scaleTo(1, 1, 8);
        var sound = core.assets["sounds/cf307/ME014-090610-loss02-wav.mp3"].clone();
        sound.play();
        over.tl.then(function() {
            var label = new Label("  TAP TO RETRY");
           label.color = 'red';
            label.font = "28px 'PixelMplus10'";
            label.textAlign = "center";
            label.y = 220 + 100;
            scene.addChild(label); 
            scene.addEventListener(Event.TOUCH_START, function() {
                gameStart();
            });                                                      
        });        
    });                                                                                          
    //==========
    // ここまで
    //==========
}
function getRandom(start, end) {
    return start + Math.floor( Math.random() * (end - start + 1));
}
function titleStart(){// タイトル画面
    var scene = gameManager.createTitleScene();
    core.replaceScene(scene); core.pause();
    scene.on(enchant.Event.TOUCH_START, function(){gameStart();});
}
//==========
// EnchantJS
enchant();
var gameManager;
var core;
var scene;
window.onload = function(){
    gameManager = new common.GameManager();
    core = gameManager.createCore(320, 480);
    core.preload(assets);
    core.onload = function(){titleStart();};
    core.start();
}

激重の極み(空想芸~

前回1200個だったものを、画面の限界まで増やして、2000個にしたので、”極み”です。

macでは軽くて問題ありませんでしたが古いWindowsでは怪しい動きになりました。

全部消すと、?! アンビリーバボー!!!!と表示されます。

// Main
console.log("Hello EnchantJS!!");
var assets = [
    "images/back_space.png",    
    "images/kati_tanuki.png",
    "images/title.png",// タイトル
    "sounds/coin.mp3",
    "sounds/jump.mp3",
    "images/cf307/baayoko64.png",
    "images/xe_bullet_r.png",
    "images/gameover.png", 
    "images/cf307/blueground.png",
    "sounds/cf307/decision1.mp3",
    "sounds/cf307/decision3.mp3",
    "sounds/cf307/rabohyuuu.mp3",
    "images/gameclear.png",
    "sounds/cf307/trumpet-dub1.mp3",
    "sounds/cf307/boyoyon1.mp3",
    "sounds/cf307/trumpet1.mp3",
    "sounds/cf307/dondonpafupafu1.mp3",
    "images/block_d.png", 
    "images/cf307/block8p.png", 
    "sounds/cf307/ME014-090610-loss02-wav.mp3",
    "sounds/cf307/hit04.mp3",  
    "images/cf307/10_480.png", 
    "images/bomb.png",  
];
function gameStart(){// ゲーム画面
    scene = gameManager.createGameScene();
    core.replaceScene(scene); core.resume();

    //==========
    // ここから
    //==========

    scene.backgroundColor = "darkgray";
    
    // 背景
    var sky = new ExSprite(320, 480);
    sky.image = core.assets["images/back_space.png"];
    scene.addChild(sky);

    // 地面
    var ground = new ExSprite(320, 55);
    ground.image = core.assets["images/cf307/blueground.png"];
    ground.x = 0;
    ground.y = 480; 
    scene.addChild(ground);

   // 壁左
    var kabe = new ExSprite(10, 480);
    kabe.image = core.assets["images/cf307/10_480.png"]; 
    kabe.x = -10;
    kabe.y = 0;
    scene.addChild(kabe); 
    kabe.tag = "kabe";

   // 壁右
    var kabem = new ExSprite(10, 480);
    kabem.image = core.assets["images/cf307/10_480.png"]; 
    kabem.x = 320;
    kabem.y = 0;
    scene.addChild(kabem); 
    kabem.tag = "kabem";

    // バー
    var bar = new ExSprite(64, 6);
    bar.image = core.assets["images/cf307/baayoko64.png"];
    scene.addChild(bar);
    bar.x = 320 / 2 - 32;
    bar.y = 480 - 32;
    bar.tag = "bar";
    //bar.scale(10, 1);//テスト

    // 玉グループ
   var tamaGroup = new Group();
    scene.addChild(tamaGroup);    
     
    // 玉
    var tama = new ExSprite(9, 9);
    tama.image = core.assets["images/xe_bullet_r.png"];
    //scene.addChild(tama);
    tama.x = bar.x + bar.width / 2 - tama.width / 2;
    tama.y = bar.y - tama.height;
    tamaGroup.addChild(tama);
    tama.originX = 0;
    tama.originY = 0;
    tama.scale(0.6, 0.6);
  
    // 最初の音
    var sound0 = core.assets["sounds/cf307/decision3.mp3"].clone();
    sound0.play(); 
  
    // 玉の動き
    var x1 = getRandom(0, 320 - 5);
    //var x1 = getRandom(-320, 0);// テスト用
    tama.tl.moveTo(x1, -9, 32, enchant.Easing.SINE_EASEOUT); 
    // 最初に跳ね返る音
    tama.tl.then(function(){
        var sound1 = core.assets["sounds/cf307/decision1.mp3"].clone();
        sound1.play();    
    });
    var x2 = getRandom(0, 320 - 5);
    tama.tl.moveTo(x2, 480, 32, enchant.Easing.SINE_EASEOUT); 

    // ブロックグループ
    var blockGroup = new Group();
    scene.addChild(blockGroup);

    // スコア表示
    var score = 0;
    scoreLabel = new Label('SCORE : 0');
    scene.addChild(scoreLabel);
    scoreLabel.x = 10;
    scoreLabel.y = 10;
    scoreLabel.color = 'white';
    scoreLabel.font = "24px 'PixelMplus10'";
    scoreLabel.addEventListener(Event.ENTER_FRAME, function() {
        scoreLabel.text = 'SCORE : ' + score;
    });
    
    // ブロック(繰り返し処理)
    var blocks = new Array();
    for(var i=0; i< 2000; i++){ 
        // ブロック
        var block = new ExSprite(8, 8);
        block.image = core.assets["images/cf307/block8p.png"];        
        block.x = 0  + ((i % 40) * 8);
        block.y = 0 + (Math.floor(i / 40) * 8);
        blockGroup.addChild(block);
        block.tag = "b";// タグをつけます 
        blocks.push(block);   
    } 
    // 当たり判定をつけます
    for(var i=0; i<blocks.length; i++){
       tama.addCollision(blocks[i]);
    }
    // 当たり判定
    tama.addCollision(bar); 
    //tama.addCollision(kabe); 
    tama.addCollision(kabem); 
    tama.addEventListener(Event.COLLISION, function(e) {
        // クリア
        if(2000 <= score){
            tama.remove();
            var label6 = new Label("?! アンビリーバボー!!!!");
            label6.x = 60;
            label6.y = 480 / 2 - 16 / 2 + 48;
            label6.color = "white";
            label6.font = "24px 'PixelMplus10'";
            scene.addChild(label6);
            var sound100 = core.assets["sounds/cf307/rabohyuuu.mp3"].clone();
            sound100.play();
            var clear = new ExSprite(230, 32);
            clear.image = core.assets["images/gameclear.png"];
            scene.addChild(clear);
            clear.x = 320 / 2 - clear.width / 2;
            clear.y = 480 / 2  - clear.height;
            clear.scale(0.5, 0.5);
            clear.tl.scaleTo(1.4, 1.4, 4);
            clear.tl.scaleTo(1.2, 1.2, 4);      
         }    
        // ブロックに当たったら
        if(e.collision.target.tag == "b"){
            e.collision.target.tl.then(function() {
                e.collision.target.remove();// 消します 
         var bomb = new ExSprite(32, 32);
                bomb.image = core.assets["images/bomb.png"];
                bomb.x = e.collision.target.x;
                bomb.y = e.collision.target.y;
                scene.addChild(bomb); 
                bomb.scale(0.5, 0.5);
                bomb.frame = [0, 1, 2, 3, 4, null]
                score += 1; 
                var sound = core.assets["sounds/cf307/hit04.mp3"].clone();
                sound.play();        
            });
        // クリア
        if(1999 <= score){
            tama.remove();
            var label6 = new Label("?! アンビリーバボー!!!!");
            label6.x = 60;
            label6.y = 480 / 2 - 16 / 2 + 48;
            label6.color = "white";
            label6.font = "24px 'PixelMplus10'";
            scene.addChild(label6);
            var sound100 = core.assets["sounds/cf307/rabohyuuu.mp3"].clone();
            sound100.play();
            var clear = new ExSprite(230, 32);
            clear.image = core.assets["images/gameclear.png"];
            scene.addChild(clear);
            clear.x = 320 / 2 - clear.width / 2;
            clear.y = 480 / 2  - clear.height;
            clear.scale(0.5, 0.5);
            clear.tl.scaleTo(1.4, 1.4, 4);
            clear.tl.scaleTo(1.2, 1.2, 4);      
         }    
        }
        // バーに当たったら
        if(e.collision.target.tag == "bar"){
            tama.tl.clear();
            // 玉の動きのパターン
       var p1 = getRandom(1, 3);
        // (1)最初に正面に当たる
            if(p1 == 1){
                var x1 = getRandom(0, 320 - 9); 
                tama.tl.moveTo(x1, -9, 32, enchant.Easing.SINE_EASEOUT);
                tama.tl.then(function(){
                    var sound = core.assets["sounds/cf307/decision1.mp3"].clone();
                    sound.play();
                });
                // 正面に当たった後
                var p2 = getRandom(1, 3);
         // (1)-1そのまま戻る
                if(p2 == 1){
                    var x2 = getRandom(0, 320 - 5); 
                    tama.tl.moveTo(x2, 480 - 5, 32, enchant.Easing.SINE_EASEOUT);
                } 
         // (1)-2左の壁に当たってから戻る
         if(p2 == 2){
                    var y1 = getRandom(0, 200);
                    tama.tl.moveTo(0, y1, 16, enchant.Easing.SINE_EASEOUT);
                    tama.tl.then(function(){
                        var sound = core.assets["sounds/cf307/decision1.mp3"].clone();
                        sound.play();
                    });
                    var x2 = getRandom(0, 320 - 5); 
                    tama.tl.moveTo(x2, 480 - 5, 30, enchant.Easing.SINE_EASEOUT);
                }
                // (1)-3右の壁に当たってから戻る
                if(p2 == 3){
                    var y1 = getRandom(0, 200);
                    tama.tl.moveTo(320 - 5, y1, 16, enchant.Easing.SINE_EASEOUT);
                    tama.tl.then(function(){
                        var sound = core.assets["sounds/cf307/decision1.mp3"].clone();
                        sound.play();
                    });
                    var x2 = getRandom(0, 320 - 5); 
                    tama.tl.moveTo(x2, 480 - 5, 30, enchant.Easing.SINE_EASEOUT);
                }
            } 
            // (2)最初に左の壁に当たる
            if(p1 == 2){
                var y1 = getRandom(200, 400);
                tama.tl.moveTo(0, y1, 16, enchant.Easing.SINE_EASEOUT); 
                tama.tl.then(function(){
                    var sound = core.assets["sounds/cf307/decision1.mp3"].clone();
                    sound.play();
                });
                var x1 = getRandom(0, 320 - 9); 
                tama.tl.moveTo(x1, -9, 20, enchant.Easing.SINE_EASEOUT);
                tama.tl.then(function(){
                    var sound = core.assets["sounds/cf307/decision1.mp3"].clone();
                    sound.play();
                });
                // 正面に当たった後
                var p2 = getRandom(1, 3);
          // (2)-1そのまま戻る
                if(p2 == 1){
                    var x2 = getRandom(0, 320 - 5); 
                    tama.tl.moveTo(x2, 480 - 5, 32, enchant.Easing.SINE_EASEOUT);
                } 
         // (2)-2左の壁に当たってから戻る
          if(p2 == 2){
                    var y1 = getRandom(0, 200);
                    tama.tl.moveTo(0, y1, 16, enchant.Easing.SINE_EASEOUT);
                    tama.tl.then(function(){
                        var sound = core.assets["sounds/cf307/decision1.mp3"].clone();
                        sound.play();
                    });                    
                    var x2 = getRandom(0, 320 - 5); 
                    tama.tl.moveTo(x2, 480 - 5, 30, enchant.Easing.SINE_EASEOUT);
                }
                // (2)-3右の壁に当たってから戻る
                if(p2 == 3){
                    var y1 = getRandom(0, 200);
                    tama.tl.moveTo(320 - 5, y1, 16, enchant.Easing.SINE_EASEOUT);
                    tama.tl.then(function(){
                        var sound = core.assets["sounds/cf307/decision1.mp3"].clone();
                        sound.play();
                    });
                    var x2 = getRandom(0, 320 - 5); 
                    tama.tl.moveTo(x2, 480 - 5, 30, enchant.Easing.SINE_EASEOUT);
                }
            }
            // (3)最初に右の壁に当たる
            if(p1 == 3){
                var y1 = getRandom(200, 400);
                tama.tl.moveTo(320 - 5, y1, 16, enchant.Easing.SINE_EASEOUT);
                tama.tl.then(function(){
                    var sound = core.assets["sounds/cf307/decision1.mp3"].clone();
                    sound.play();
                });
                var x1 = getRandom(0, 320 - 5); 
                tama.tl.moveTo(x1, -9, 16, enchant.Easing.SINE_EASEOUT);
          tama.tl.then(function(){
                    var sound = core.assets["sounds/cf307/decision1.mp3"].clone();
                    sound.play();
                });
                // 正面に当たった後
                var p2 = getRandom(1, 3);
          // (3)-1そのまま戻る
                if(p2 == 1){
                    var x2 = getRandom(0, 320 - 5); 
                    tama.tl.moveTo(x2, 480 - 5, 32, enchant.Easing.SINE_EASEOUT);
                } 
         // (3)-2左の壁に当たってから戻る
          if(p2 == 2){
                    var y1 = getRandom(0, 200);
                    tama.tl.moveTo(0, y1, 16, enchant.Easing.SINE_EASEOUT);
                    tama.tl.then(function(){
                        var sound = core.assets["sounds/cf307/decision1.mp3"].clone();
                        sound.play();
                    });                    
                    var x2 = getRandom(0, 320 - 5); 
                    tama.tl.moveTo(x2, 480 - 5, 30, enchant.Easing.SINE_EASEOUT);
                }
                // (3)-3右の壁に当たってから戻る
                if(p2 == 3){
                    var y1 = getRandom(0, 200);
                    tama.tl.moveTo(320 - 5, y1, 16, enchant.Easing.SINE_EASEOUT);
                    tama.tl.then(function(){
                        var sound = core.assets["sounds/cf307/decision1.mp3"].clone();
                        sound.play();
                    });
                    var x2 = getRandom(0, 320 - 5); 
                    tama.tl.moveTo(x2, 480 - 5, 30, enchant.Easing.SINE_EASEOUT);
                }
            }
            // 音
            var sound2 = core.assets["sounds/cf307/decision3.mp3"].clone();
            sound2.play();       
            //tama.tl.moveTo(160, 471, 16); //テスト用
            //score += 500; //テスト用
        } 
    });   
   
    // 画面をタップしてバーを動かす
    scene.addEventListener(Event.TOUCH_START, function(e){
        console.log("タッチ");
        console.log(e.x);
        bar.tl.moveTo(e.x - 32, 480 - 32, 3, enchant.Easing.QUART_EASEINOUT);
    });
    // ゲームオーバー
    ground.addCollision(tama);    
    ground.addEventListener(Event.COLLISION, function(e) {
        tama.remove();
        var over = new ExSprite(230, 32);
        over.image = core.assets["images/gameover.png"];
        scene.addChild(over);
        over.x = 320 / 2 - over.width / 2;
        over.y = 480 / 2  - over.height + 16;
        over.scale(0.5, 0.5);
        over.tl.scaleTo(1, 1, 8);
        var sound = core.assets["sounds/cf307/ME014-090610-loss02-wav.mp3"].clone();
        sound.play();
        over.tl.then(function() {
            var label = new Label("  TAP TO RETRY");
           label.color = 'red';
            label.font = "28px 'PixelMplus10'";
            label.textAlign = "center";
            label.y = 220 + 100;
            scene.addChild(label); 
            scene.addEventListener(Event.TOUCH_START, function() {
                gameStart();
            });                                                      
        });                
    }); 
                                                                                         
    //==========
    // ここまで
    //==========
}
function getRandom(start, end) {
    return start + Math.floor( Math.random() * (end - start + 1));
}
function titleStart(){// タイトル画面
    var scene = gameManager.createTitleScene();
    core.replaceScene(scene); core.pause();
    scene.on(enchant.Event.TOUCH_START, function(){gameStart();});
}

//==========
// EnchantJS
enchant();
var gameManager;
var core;
var scene;
window.onload = function(){
    gameManager = new common.GameManager();
    core = gameManager.createCore(320, 480);
    core.preload(assets);
    core.onload = function(){titleStart();};
    core.start();
}

ブロック崩し激重(空想芸~(解説)

前回、先生のサンプルコードから、配列を使った当たり判定を知ったので、それをつかってブロックくずしのようなものを作ってみました。

ブロックは1200個です。通常のブロック崩しのように跳ね返らず、貫通するので、多くしてみました。どれくらい多くできるのかなとやってみたら、Windowsでは重くなってしましました。

スコアによってだんだん弾のスピードを上げていこうとしましたが、速くすると、タイミングによってはバーをすりぬけてしまうので、断念しました。動くものどうしの衝突判定は色々難しいようです。

クリアすると、「?! 全部消したの?!      想定外です‥」と表示されます。

// Main
console.log("Hello EnchantJS!!");

var assets = [
 "images/back_space.png", 
 "images/kati_tanuki.png",
 "images/title.png",// タイトル
 "sounds/coin.mp3",
 "sounds/jump.mp3",
 "images/cf307/baayoko64.png",
 "images/xe_bullet_r.png",
 "images/gameover.png", 
 "images/cf307/blueground.png",
 "sounds/cf307/decision1.mp3",
 "sounds/cf307/decision3.mp3",
 "sounds/cf307/rabohyuuu.mp3",
 "images/gameclear.png",
 "sounds/cf307/trumpet-dub1.mp3",
 "sounds/cf307/boyoyon1.mp3",
 "sounds/cf307/trumpet1.mp3",
 "sounds/cf307/dondonpafupafu1.mp3",
 "images/block_d.png", 
 "images/cf307/block8p.png", 
 "sounds/cf307/ME014-090610-loss02-wav.mp3",
 "sounds/cf307/hit04.mp3",  
 "images/cf307/10_480.png",   
];

function gameStart(){// ゲーム画面
 scene = gameManager.createGameScene();
 core.replaceScene(scene); core.resume();

//==========
// ここから
//==========

scene.backgroundColor = "darkgray";
 
 // 背景
 var sky = new ExSprite(320, 480);
 sky.image = core.assets["images/back_space.png"];
 scene.addChild(sky);

 // 地面
 var ground = new ExSprite(320, 55);
 ground.image = core.assets["images/cf307/blueground.png"];
 ground.x = 0;
 ground.y = 480; 
 scene.addChild(ground);

 // 壁左
 var kabe = new ExSprite(30, 480);
 kabe.image = core.assets["images/cf307/10_480.png"]; 
 kabe.x = -30;
 kabe.y = 0;
 scene.addChild(kabe); 
 kabe.tag = "kabe";

 // 壁右
 var kabem = new ExSprite(30, 480);
 kabem.image = core.assets["images/cf307/10_480.png"]; 
 kabem.x = 320;
 kabem.y = 0;
 scene.addChild(kabem); 
 kabem.tag = "kabem";

 // バー
 var bar = new ExSprite(64, 6);
 bar.image = core.assets["images/cf307/baayoko64.png"];
 scene.addChild(bar);
 bar.x = 320 / 2 - 32;
 bar.y = 480 - 32;
 bar.tag = "bar";
 //bar.scale(10, 0);//テスト用

 // 玉グループ
 var tamaGroup = new Group();
 scene.addChild(tamaGroup);     

 // 玉
 var tama = new ExSprite(9, 9);
 tama.image = core.assets["images/xe_bullet_r.png"];
 //scene.addChild(tama);
 tama.x = bar.x + bar.width / 2 - tama.width / 2;
 tama.y = bar.y - tama.height;
 tamaGroup.addChild(tama);
 tama.originX = 0;
 tama.originY = 0;
 tama.scale(0.6, 0.6);  
 //tama.scale(4, 4);// テスト用

 // 最初の音
 var sound0 = core.assets["sounds/cf307/decision3.mp3"].clone();
 sound0.play(); 
  
 // 玉の動き
 var x1 = getRandom(-320, 640 - tama.width);
 //var x1 = getRandom(-320, 0);// テスト用
 tama.tl.moveTo(x1, -9, 35, enchant.Easing.SINE_EASEOUT); 
 // 最初に跳ね返る音
 tama.tl.then(function(){
     var sound1 = core.assets["sounds/cf307/decision1.mp3"].clone();
     sound1.play(); 
 });
 var x2 = getRandom(0, 320 - tama.width);
 tama.tl.moveTo(x2, 480, 35, enchant.Easing.SINE_EASEOUT);

 // ブロックグループ
 var blockGroup = new Group();
 scene.addChild(blockGroup);

 // スコア表示
 var score = 0;
 scoreLabel = new Label('SCORE : 0');
 scene.addChild(scoreLabel);
 scoreLabel.x = 10;
 scoreLabel.y = 10;
 scoreLabel.color = 'white';
 scoreLabel.font = "24px 'PixelMplus10'";
 scoreLabel.addEventListener(Event.ENTER_FRAME, function() {
     scoreLabel.text = 'SCORE : ' + score;
 });
    
 // ブロック(繰り返し処理)
 var blocks = new Array();
 for(var i=0; i<1200; i++){ 
     // ブロック
     var block = new ExSprite(8, 8);
     block.image = core.assets["images/cf307/block8p.png"]; 
     block.x = 0 + ((i % 40) * 8);
     block.y = 0 + (Math.floor(i / 40) * 8);
     blockGroup.addChild(block);
     block.tag = "b";// タグをつけます 
     blocks.push(block); 
 }

 // 2, 当たり判定をつけます
 for(var i=0; i<blocks.length; i++){
     tama.addCollision(blocks[i]);
 }

 // 当たり判定
 tama.addCollision(bar); 
 tama.addCollision(kabe); 
 tama.addCollision(kabem); 
 tama.addEventListener(Event.COLLISION, function(e) {
     // クリア
     if(1200 <= score){
         tama.remove();
         var label6 = new Label("?! 全部消したの?!      想定外です‥");
         label6.x = 60;
         label6.y = 480 / 2 - 16 / 2 + 48;
         label6.color = "white";
         label6.font = "24px 'PixelMplus10'";
         scene.addChild(label6);
         var sound100 = core.assets["sounds/cf307/rabohyuuu.mp3"].clone();
         sound100.play();
         var clear = new ExSprite(230, 32);
         clear.image = core.assets["images/gameclear.png"];
         scene.addChild(clear);
         clear.x = 320 / 2 - clear.width / 2;
         clear.y = 480 / 2 - clear.height;
         clear.scale(0.5, 0.5);
         clear.tl.scaleTo(1.4, 1.4, 4);
         clear.tl.scaleTo(1.2, 1.2, 4);      
     } 
     // 壁にあたったら
     // 壁左
     if(e.collision.target.tag == "kabe"){
         tama.tl.clear();
         var x1 = getRandom(100, 320 - tama.width);
         tama.tl.moveTo(x1, -9, 17, enchant.Easing.SINE_EASEOUT);
         tama.tl.then(function(){
             var sound1 = core.assets["sounds/cf307/decision1.mp3"].clone();
             sound1.play(); 
         });
         var x2 = getRandom(0, 320 - tama.width);
         tama.tl.moveTo(x2, 480, 35, enchant.Easing.SINE_EASEOUT); 
     } 
     // 壁右
     if(e.collision.target.tag == "kabem"){
         console.log("kabem");
         tama.tl.clear();
         var x1 = getRandom(0, 220);
         tama.tl.moveTo(x1, -9, 17, enchant.Easing.SINE_EASEOUT);
         tama.tl.then(function(){
             var sound1 = core.assets["sounds/cf307/decision1.mp3"].clone();
             sound1.play(); 
         });
         var x2 = getRandom(0, 320 - tama.width);
         tama.tl.moveTo(x2, 480, 35, enchant.Easing.SINE_EASEOUT); 
     } 
     // ブロックに当たったら
     if(e.collision.target.tag == "b"){
         e.collision.target.tl.then(function() {
             e.collision.target.remove();// 消します 
             score += 1;
             //score += 100; // テスト 
             var sound = core.assets["sounds/cf307/hit04.mp3"].clone();
             sound.play(); 
         });
         if(1199 <= score){
             tama.remove();
             var label6 = new Label("?! 全部消したの?!      想定外です‥");
             label6.x = 60;
             label6.y = 480 / 2 - 16 / 2 + 48;
             label6.color = "white";
             label6.font = "24px 'PixelMplus10'";
             scene.addChild(label6);
             var sound100 = core.assets["sounds/cf307/rabohyuuu.mp3"].clone();
             sound100.play();
             var clear = new ExSprite(230, 32);
             clear.image = core.assets["images/gameclear.png"];
             scene.addChild(clear);
             clear.x = 320 / 2 - clear.width / 2;
             clear.y = 480 / 2 - clear.height;
             clear.scale(0.5, 0.5);
             clear.tl.scaleTo(1.4, 1.4, 4);
             clear.tl.scaleTo(1.2, 1.2, 4);      
         } 
     }
     // バーに当たったら
     if(e.collision.target.tag == "bar"){
         tama.tl.clear();
         var x1 = getRandom(-320, 640 - tama.width);
         tama.tl.moveTo(x1, -9, 35, enchant.Easing.SINE_EASEOUT);
         tama.tl.then(function(){
             var sound = core.assets["sounds/cf307/decision1.mp3"].clone();
             sound.play(); 
         }); 
         var x2 = getRandom(0, 320 - tama.width);
         tama.tl.moveTo(x2, 480, 35, enchant.Easing.SINE_EASEOUT);
         // 音
         var sound2 = core.assets["sounds/cf307/decision3.mp3"].clone();
         sound2.play();       
         //tama.tl.moveTo(160, 471, 16); //テスト用
         //score += 500; //テスト用
         /* // 球が速くなる
         if(300<= score && score < 600){
             tama.tl.clear();
             var x1 = getRandom(0, 320 - tama.width);
             tama.tl.moveTo(x1, -9, 30, enchant.Easing.SINE_EASEOUT); 
             tama.tl.then(function(){
                 var sound = core.assets["sounds/cf307/decision1.mp3"].clone();
                 sound.play(); 
             }); 
             var x2 = getRandom(0, 320 - tama.width);
             tama.tl.moveTo(x2, 480, 30, enchant.Easing.SINE_EASEOUT);
         }
         if(600 <= score && score < 1200){
             tama.tl.clear();
             var x1 = getRandom(0, 320 - tama.width);
             tama.tl.moveTo(x1, -9, 27, enchant.Easing.SINE_EASEOUT); 
             tama.tl.then(function(){
                 var sound = core.assets["sounds/cf307/decision1.mp3"].clone();
                 sound.play(); 
             }); 
             var x2 = getRandom(0, 320 - tama.width);
             tama.tl.moveTo(x2, 480, 27, enchant.Easing.SINE_EASEOUT);
         }
         if(900 <= score ){
             tama.tl.clear();
             var x1 = getRandom(0, 320 - tama.width);
             tama.tl.moveTo(x1, -9, 24, enchant.Easing.SINE_EASEOUT); 
             tama.tl.then(function(){
                 var sound = core.assets["sounds/cf307/decision1.mp3"].clone();
                 sound.play(); 
             }); 
             var x2 = getRandom(0, 320 - tama.width);
             tama.tl.moveTo(x2, 480, 24, enchant.Easing.SINE_EASEOUT);
         } 
*/ 
     } 
 }); 
 
 // 画面をタップしてバーを動かす
 scene.addEventListener(Event.TOUCH_START, function(e){
     console.log("タッチ");
     console.log(e.x);
     bar.tl.moveTo(e.x - 32, 480 - 32, 3, enchant.Easing.QUART_EASEINOUT);
 });

 // ゲームオーバー
 ground.addCollision(tama); 
 ground.addEventListener(Event.COLLISION, function(e) {
     tama.remove();
     var over = new ExSprite(230, 32);
     over.image = core.assets["images/gameover.png"];
     scene.addChild(over);
     over.x = 320 / 2 - over.width / 2;
     over.y = 480 / 2 - over.height + 16;
     over.scale(0.5, 0.5);
     over.tl.scaleTo(1, 1, 8);
     var sound = core.assets["sounds/cf307/ME014-090610-loss02-wav.mp3"].clone();
     sound.play();
     over.tl.then(function() {
         var label = new Label(" TAP TO RETRY");
         label.color = 'red';
         label.font = "28px 'PixelMplus10'";
         label.textAlign = "center";
         label.y = 220 + 100;
         scene.addChild(label); 
         scene.addEventListener(Event.TOUCH_START, function() {
             gameStart();
         }); 
     });
 });               

//==========
// ここまで
//==========
}

function getRandom(start, end) {
 return start + Math.floor( Math.random() * (end - start + 1));
}

function titleStart(){// タイトル画面
 var scene = gameManager.createTitleScene();
 core.replaceScene(scene); core.pause();
 scene.on(enchant.Event.TOUCH_START, function(){gameStart();});
}

//==========
// EnchantJS
enchant();
var gameManager;
var core;
var scene;
window.onload = function(){
 gameManager = new common.GameManager();
 core = gameManager.createCore(320, 480);
 core.preload(assets);
 core.onload = function(){titleStart();};
 core.start();
}

蘇ったcoinエアギタぬきv(解説・自由研究)

たぬきが障害物を飛び越えながらコインをとっていくというゲームです。

最初、背景と一緒にアイテムもスクロールにしてループで動かしたため、一度消えたものは2回目のループのときには消えてしまっていて出てこない(消したものをループさせていた)ということがわからず、苦労しました。

先生がサンプルコードをくださったので、それで色々動かしてみて、わかりました。

それで、コインが蘇ったので、このような題名になりました。

このサンプルコードには、配列を使った複数のアイテムの作り方と、それに対する衝突判定のやり方も書いてあったので、その後色々作るのに非常に参考になりました。

その部分の抜粋

    // 1, アイテムを10個作ります
    var items = new Array();
    for(var i=0; i<10; i++){
        var item = new ExSprite(16, 20);
        item.image = core.assets["images/coin.png"];
        item.x = 100 + i * 50;
        item.y = 390;
        item.tag = "c";// タグをつけます   
        stageGroup.addChild(item);
        items.push(item);
    }

まず、itemsという配列を作っています。var items = new Array();

そして、forループで10個のitemをつくり、それを配列itemsの中に入れています。items.push(item);

これで、itemの一つひとつは、items[i]という名前が振られることになります。(iは0から9まで)

  // 2, 当たり判定をつけます
    for(var i=0; i<items.length; i++){
       tanuki.addCollision(items[i]);
    }

それに当たり判定をつけるには、items[0]からitems[9]までの当たり判定をforループでつければよいということになります。

 

サンプルコード

// Main
console.log("Hello EnchantJS!!");
var assets = [
    // 背景
    "images/back_mountain.png",
    "images/kati_land.png",
    // コイン
    "images/coin.png",
    // 虫
    "images/bug.png",
    // たぬき
    "images/tanu.png",
    // CodeFriendsタイトル
    "images/title_gameclear.png",
    "images/title_gameover.png",
    "images/title.png"
];

function gameStart(){// ゲーム画面
    scene = gameManager.createGameScene();
    core.replaceScene(scene); core.resume();

    //==========
    // ここから
    //==========

    //グループ
    var stageGroup = new Group();
    scene.addChild(stageGroup); 
    stageGroup.tl.moveBy(-320, 0, 50);
    stageGroup.tl.moveTo(0,0,0);
    stageGroup.tl.loop();
    
    // 背景
    var background = new ExSprite(640, 480);
    background.image = core.assets["images/back_mountain.png"];
    background.x = 0;
    background.y = 0;
    stageGroup.addChild(background);
    var land = new ExSprite(640, 60);
    land.image = core.assets["images/kati_land.png"];
    land.x = 0;
    land.y = 420;
    stageGroup.addChild(land);

    // スコア
    var score = 0;
    var scoreLabel = new Label();
    scoreLabel.text = 'SCORE : 0';
    scoreLabel.color = 'white';
    scoreLabel.font = "24px 'PixelMplus10'";
    scene.addChild(scoreLabel);

    //むし1
    var bug1 = new ExSprite(32, 32);
    bug1.image = core.assets["images/bug.png"];
    bug1.x = 200;
    bug1.y = 390;
    stageGroup.addChild(bug1);

    //むし2
    var bug2 = new ExSprite(32, 32);
    bug2.image = core.assets["images/bug.png"];
    bug2.x = 520;
    bug2.y = 390;
    stageGroup.addChild(bug2);

    // 1, アイテムを10個作ります
    var items = new Array();
    for(var i=0; i<10; i++){
        var item = new ExSprite(16, 20);
        item.image = core.assets["images/coin.png"];
        item.x = 100 + i * 50;
        item.y = 390;
        item.tag = "c";// タグをつけます   
        stageGroup.addChild(item);
        items.push(item);
    }

    //たぬき
    var tanuki = new ExSprite(32, 32);
    tanuki.image = core.assets["images/tanu.png"];
    tanuki.x = 80;
    tanuki.y = 390;
    tanuki.frame = [0, 1, 2];
    scene.addChild(tanuki);
    scene.addEventListener(Event.TOUCH_START, function(){
        tanuki.frame = [3];
        tanuki.tl.moveBy(0, -100, 10, enchant.Easing.QUAD_EASEOUT);
        tanuki.tl.moveBy(0, 100, 10, enchant.Easing.QUAD_EASEIN);
        tanuki.tl.then(function() {
            tanuki.frame = [0, 1, 2];
        });
    });
    tanuki.addCollision(bug1);
    tanuki.addCollision(bug2);

    // 2, 当たり判定をつけます
    for(var i=0; i<items.length; i++){
       tanuki.addCollision(items[i]);
    }

    tanuki.addEventListener(Event.COLLISION, function(e){
        //虫と衝突したとき
        if (false) {
            core.stop();
        }
        //アイテムと衝突したとき
        if (e.collision.target.tag == "c") {
            score++;
            scoreLabel.text = 'SCORE : ' + score;
            //e.collision.target.tl.moveBy(0, -64, 10);
            // 同じタグの場合は消します
            e.collision.target.tl.then(function() {
                e.collision.target.remove();// 消します          
            });
        }
    });

    //==========
    // ここまで
    //==========
}

function getRandom(start, end) {
    return start + Math.floor( Math.random() * (end - start + 1));
}
function titleStart(){// タイトル画面
    var scene = gameManager.createTitleScene();
    core.replaceScene(scene); core.pause();
    scene.on(enchant.Event.TOUCH_START, function(){gameStart();});
}

//==========
// EnchantJS
enchant();
var gameManager;
var core;
var scene;
window.onload = function(){
    gameManager = new common.GameManager();
    core = gameManager.createCore(320, 480);
    core.preload(assets);
    core.onload = function(){titleStart();};
    core.start();
}

 

自由研究の内容はこちら

蘇ったcoinエアギタぬきv(自由研究)

恐怖ももちゃんサバイバル(解説)

いがぐりをたくさん出してみたら、あまりに気持ち悪く、そのままでは耐えられなかったので白くしてみたらウイルスっぽかったので、思いつきました。

ういるすは画面上いっぱいの範囲でランダムに出ますが、いきなりももちゃんに重なってしまうとそこですぐ終わってしまいます。

そこで、重ならないように出す工夫をしました。

まず、ウイルスを画面内のランダムの位置に出します。

 var igaguri = new ExSprite(32, 32);
 igaguri.image = core.assets["images/cf307/igagurikurugray.png"];
 igaguriGroup.addChild(igaguri);
 igaguri.tag = "いがぐり"; 
 igaguri.frame = [0, 1, 2, 3];
 var x1 = getRandom(0, 320 - 32);
 igaguri.x = x1;
 var y1 = getRandom(0, 480 - 32);
 igaguri.y = y1; 

ここで、ウイルスの出現する座標は、ランダムに指定される(x1, y1)です。

ももちゃんにいきなり重ならないように、ここでランダムの位置が重なる値ならば、重ならない値に変更するようにします。

if(momo.x - 32 <= x1 && x1 <= momo.x + 32){
    igaguri.x = x1 - 64;
}
if(momo.y - 32 <= y1 && y1 <= momo.y + 32){
    igaguri.y = y1 + 64;
} 

もしもウイルスがももちゃんの座標の周囲32ピクセル以内に入りそうなら、64ピクセル離れた座標にする、ということをしています。こうすれば、重なることがありません。

そして、ウイルスをももちゃんに向かってじわじわ接近させ、消します。

igaguri.tl.moveTo(momo.x, momo.y, 100); 
igaguri.tl.then(function(){      
    igaguri.remove();     
});       

以上を3カウント毎に繰り返す(3カウントに一個ずつのタイミングで、ウイルスを画面のどこかに出現させる)ので、合わせて以下のようになります。

// ももちゃんに被らないようにいがぐりを出す
var d = 3;
scene.tl.delay(d). then(function(){
    var igaguri = new ExSprite(32, 32);
    igaguri.image = core.assets["images/cf307/igagurikurugray.png"];
    igaguriGroup.addChild(igaguri);
    igaguri.tag = "いがぐり";
    igaguri.frame = [0, 1, 2, 3];
    var x1 = getRandom(0, 320 - 32);
    console.log(x1);        
    igaguri.x = x1;
    console.log(igaguri.x);
    var y1 = getRandom(0, 480 - 32);
    console.log(y1); 
    igaguri.y = y1;
    console.log(igaguri.y);
    if(momo.x - 32 <= x1 && x1 <= momo.x + 32){
        igaguri.x = x1 - 64;
        console.log("igaguri.x");
    }
    if(momo.y - 32 <= y1 && y1 <= momo.y + 32){
        igaguri.y = y1 + 64;
    }    
    igaguri.tl.moveTo(momo.x, momo.y, 100);
    igaguri.tl.then(function(){
        igaguri.remove();
    });           
});
scene.tl.loop();

お薬も同じようにして、ももちゃんに重ならないように出します。

完成したソースコード

// Main
console.log("Hello EnchantJS!!");

var assets = [
    "images/e_tanuki.png",
    "images/title.png",// タイトル
    "sounds/hit.mp3",
    "sounds/jump.mp3",
    "images/cf307/momo.png", 
    "images/cf307/igagurikurugray.png",
    "sounds/cf307/jump12.mp3",
    "sounds/cf307/pyu15.mp3",
    "images/cf307/momochanzannen.png",
    "images/cf307/igaguri.png",
    "sounds/cf307/se_maoudamashii_onepoint31.mp3",
    "images/title_gameover.png",
    "images/cf307/okusuri.png",
    "sounds/cf307/correct2.mp3",
    "images/cf307/retrybotan.png",
    "images/cf307/sikibutonn.png",
    "images/cf307/kakebutonn.png",
    "images/cf307/hyounoua.png",
    "images/title_gameclear.png",
    "images/cf307/tarunohuroue.png",
    "images/cf307/tarunohurosita.png",
    "images/cf307/yuge.png",
    "images/cf307/sizuku0.png",
    "sounds/cf307/water-dopon1.mp3",
    "sounds/cf307/jump03.mp3",
    "sounds/fall.mp3",
    "sounds/cf307/clear04.mp3",
    "images/cf307/tenugui.png",
    "images/cf307/momobotann.png",
    "images/joe_gass.png",
    "sounds/gass.mp3",
    "sounds/cf307/water-bukubuku3.mp3",
    "sounds/cf307/bath-thapon1.mp3",
    "sounds/cf307/matchstick-put-fire1.mp3",
    "sounds/cf307/boyon1.mp3",
    "sounds/cf307/jump02.mp3",
];

function gameStart(){// ゲーム画面
    scene = gameManager.createGameScene();
    core.replaceScene(scene); core.resume();

    //==========
    // ここから
    //==========

    scene.backgroundColor = "orange";
    // ももちゅあんグループ 
    var momoGroup = new Group();
    scene.addChild(momoGroup);

    // ウイルスグループ
    var igaguriGroup = new Group();
    scene.addChild(igaguriGroup);
    
    // 薬グループ
    var kusuriGroup = new Group();
    scene.addChild(kusuriGroup);

    // ももちゃん
    var momo = new ExSprite(32, 32);
    momo.image = core.assets["images/cf307/momo.png"];
    momo.x = 320 /2 - 16;
    momo.y = 128 + 32 * 3 + 16;
    scene.addChild(momo);
    momo.frame = [0, 0, 1, 1, 2, 2]; 
  
    // 薬グループ1
    var kusuriGroup1 = new Group();
    scene.addChild(kusuriGroup1);

    // ももちゃん移動
    scene.addEventListener(Event.TOUCH_START, function(e){
        momo.moveTo(e.x - 16, e.y - 16, 0);
        console.log(e.y);
        var sound = core.assets["sounds/cf307/jump12.mp3"].clone();
        sound.play();
    });

    // ももちゃんに被らないようにいがぐりを出す
    var d = 3;
    scene.tl.delay(d). then(function(){
        var igaguri = new ExSprite(32, 32);
        igaguri.image = core.assets["images/cf307/igagurikurugray.png"];
        igaguriGroup.addChild(igaguri);
        igaguri.tag = "いがぐり";
        igaguri.frame = [0, 1, 2, 3];
        var x1 = getRandom(0, 320 - 32);
        console.log(x1);        
        igaguri.x = x1;
        console.log(igaguri.x);
        var y1 = getRandom(0, 480 - 32);
        console.log(y1); 
        igaguri.y = y1;
        console.log(igaguri.y);
        if(momo.x - 32 <= x1 && x1 <= momo.x + 32){
            igaguri.x = x1 - 64;
            console.log("igaguri.x");
        }
        if(momo.y - 32 <= y1 && y1 <= momo.y + 32){
            igaguri.y = y1 + 64;
        }    
        igaguri.tl.moveTo(momo.x, momo.y, 100);
        igaguri.tl.then(function(){
           igaguri.remove();
        });           
    });
    scene.tl.loop();

    // ももちゃんに被らないように薬を出す
    momo.tl.delay(32).then(function(){
        var kusuri = new ExSprite(32, 32);
        kusuri.image = core.assets["images/cf307/okusuri.png"];
        var x2 = getRandom(0, 320 - 32);
        kusuri.x = x2;
        var y2 = getRandom(0, 480 - 32);
        kusuri.y = y2;
        kusuriGroup.addChild(kusuri);
       kusuri.tag = "くすり";  
        if(momo.x - 32 <= x2 && x2 <= momo.x + 32){
            kusuri.x = x2 - 64;
        }
        if(momo.y - 32 <= y2 && y2 <= momo.y + 32){
            kusuri.y = y2 + 64;
        }    
        kusuri.tl.delay(16).then(function(){
            kusuri.remove();
        }); 
    }); 
    momo.tl.loop();
    
    // ウイルスか薬か
    momo.addCollision(igaguriGroup);
    momo.addCollision(kusuriGroup);
    momo.addEventListener(Event.COLLISION, function(e) {
        scene.tl.clear();
        console.log(e.collision.target.tag);
        // ウイルス
        if (e.collision.target.tag == "いがぐり") {
        kusuriGroup.remove();      
        igaguriGroup.remove();
        momo.remove();
        var momoz = new ExSprite(32, 32);
        momoz.image = core.assets['images/cf307/momochanzannen.png'];
        momoz.x = momo.x;
        momoz.y = momo.y;
        momoGroup.addChild(momoz);
        // グサッ
        var sound = core.assets["sounds/cf307/pyu15.mp3"].clone();
        sound.play(); 
        // ウイルスの動き
        var asteroid = new ExSprite(32, 32);
        asteroid.image = core.assets["images/cf307/igagurikurugray.png"];
        asteroid.x = momo.x + 25;
        asteroid.y = momo.y + 18;
        scene.addChild(asteroid);
        asteroid.tl.moveBy(-5, -10, 2);
     // ももちゃん落ちていく
        asteroid.tl.delay(8).then(function(){             
            momoz.tl.moveBy(0, -25, 3);                 
            momoz.tl.delay(3).then(function(){
                var sound = core.assets["sounds/fall.mp3"].clone();
            sound.play();                
            });   
            momoz.tl.rotateBy(720, 20).and().moveBy(0, 480, 20, enchant.Easing.QUAD_EASEIN);           
            momoz.tl.then(function() {
                gameOver();
            });
         });
    }
       // 薬ゲット 
       if (e.collision.target.tag == "くすり") {
            igaguriGroup.remove();
            kusuriGroup.remove();
            // ピンポン
            var sound = core.assets["sounds/cf307/correct2.mp3"].clone();
            sound.play();
            var kusuri = new ExSprite(32, 32);
            kusuri.image = core.assets["images/cf307/okusuri.png"]; 
            kusuriGroup1.addChild(kusuri);
            kusuri.x = momo.x ;
            kusuri.y = momo.y + 5;
            kusuri.tl.rotateBy(270, 6).and().scaleTo(0.1, 0.1, 6);
            // ももちゃんジャンプ 
            kusuri.tl.then(function(){
                kusuri.remove();
                momo.tl.moveBy(0, 15, 6, enchant.Easing.QUAD_EASEOUT);
                momo.tl.then(function(){
                    var sound = core.assets["sounds/cf307/jump03.mp3"].clone();
                    sound.play();
                });
                momo.tl.moveBy(0, -480, 20, enchant.Easing.QUAD_EASEIN);                
                momo.tl.then(function(){
                    gameClear();
                });
            });   
        }      
    });

    //==========
    // ここまで
    //==========
}

function gameOver(){// ゲームオーバー画面
    scene = gameManager.createGameScene();
    core.replaceScene(scene); core.resume();

    //==========
    // ここから
    //==========

    scene.backgroundColor = "orange";

    // 敷ふとん
    var siki = new ExSprite(64, 64);
    siki.image = core.assets['images/cf307/sikibutonn.png'];
    siki.x = 0;
    siki.y = 480;
    scene.addChild(siki);
    siki.tl.moveTo(320 / 2 - 32, 200 - 10, 14).and().scaleTo(2, 2, 14).and().rotateBy(360, 14);
    
    // ざんねんももちゃん
    var momoz = new ExSprite(32, 32);
    momoz.image = core.assets['images/cf307/momochanzannen.png'];
    momoz.x = 320 / 2 - 16;
    momoz.y = 0;
    scene.addChild(momoz);
    momoz.tl.moveTo(320 / 2 - 16, 400 / 2 - 16, 16, enchant.Easing.QUAD_EASEOUT).and().scaleTo(2, 2, 16).and().rotateBy(360, 16);
    
    // 掛けぶとん     
    var kake = new ExSprite(64, 64);
    kake.image = core.assets['images/cf307/kakebutonn.png'];
    kake.x = 320;
    kake.y = 0;
    scene.addChild(kake);
    kake.tl.moveTo(320 / 2 - 32, 200 - 6, 18).and().scaleTo(2, 2, 18).and().rotateBy(-360, 18);
    
    // ふとん掛けたら音
    kake.tl.then(function(){
        var sound = core.assets["sounds/cf307/se_maoudamashii_onepoint31.mp3"].clone();
        sound.play();
    }); 

    // 氷嚢
    scene.tl.delay(24).then(function(){
        var hyou = new ExSprite(60, 50);
        hyou.image = core.assets['images/cf307/hyounoua.png'];
        hyou.x = 320 / 2 - 30;
        hyou.y = 0;
        scene.addChild(hyou);
        hyou.scale(0.5, 0.5);
        hyou.tl.moveTo(320 / 2 - 30, 400 / 2 - 53, 5,enchant.Easing.BOUNCE_EASEOUT);
        hyou.tl.then(function(){
            var sound = core.assets["sounds/cf307/boyon1.mp3"].clone();
        sound.play();
        });
    });
   
    // お大事に
    var label1 = new Label("  お大事に‥");
    label1.color = 'black';
    label1.font = "30px 'PixelMplus10'";
    label1.textAlign = "center";
    label1.y = 330; 
    scene.addChild(label1); 
  
    // ゲームオーバーを表示
    var gameover = new ExSprite(147, 48);
    gameover.image = core.assets['images/title_gameover.png'];
    gameover.x = 320 / 2 - gameover.width/2;
    gameover.y = 50;
    scene.addChild(gameover);
    // 大きく
    gameover.scale(0.5, 0.5);
    gameover.tl.scaleTo(1.5, 1.5, 20); 
        
    // リトライボタン
    var retry = new ExSprite(62, 55);
    retry.image = core.assets["images/cf307/retrybotan.png"];
    scene.addChild(retry);
    retry.x = 320 / 2 - retry.width / 2;
    retry.y = 350 ;
    retry.tl.moveBy(0, 50, 20);
    // ボタンをタッチ
   retry.addEventListener(Event.TOUCH_START, function(){
        retry.frame = 1;
        console.log("タッチしました");
    });
    retry.addEventListener(Event.TOUCH_END, function(){
        retry.frame = 0;
        gameStart();
    });

    //==========
    // ここまで
    //==========
}

function gameClear(){// ゲームクリア画面
    scene = gameManager.createGameScene();
    core.replaceScene(scene); core.resume();

    //==========
    // ここから
    //==========

    scene.backgroundColor = "orange";

    // 
    var sound = core.assets["sounds/cf307/clear04.mp3"].clone();
    sound.play();

    // 湯気
    var yuge = new ExSprite(64, 18);
    yuge.image = core.assets['images/cf307/yuge.png'];
    yuge.x = 320 / 2 - 32;
    yuge.y = 200 - 10 - 50;
    scene.addChild(yuge);
    yuge.tl.scaleTo(2, 2, 10);
    yuge.frame = [0, 0, 1, 1, 2, 2, 3, 3];

    // お風呂の上
    var huroue = new ExSprite(64, 19);
    huroue.image = core.assets['images/cf307/tarunohuroue.png'];
    huroue.x = 320 / 2 - 32;
    huroue.y = 200 - 10;
    scene.addChild(huroue);
    huroue.tl.scaleTo(2, 2, 10);

    // しずくグループ
    var sizukuGroup = new Group();
    scene.addChild(sizukuGroup);

    // ももちゃん
    var momo = new ExSprite(32, 32);
    momo.image = core.assets["images/cf307/momo.png"];
    momo.x = 320 / 2 - 16;
    momo.y = 0;
    scene.addChild(momo);
    momo.frame = [0, 0, 1, 1, 2, 2]; 
    momo.tl.moveTo(320 / 2 - 16, 400 / 2 - 8, 16, enchant.Easing.QUAD_EASEOUT).and().scaleTo(2, 2, 16);
    momo.tl.then(function(){
        momo.tl.moveBy(0, -5, 3);
        // しぶき
        var sizuku = new ExSprite(32, 32);
        sizuku.image = core.assets["images/cf307/sizuku0.png"];
        sizuku.x = momo.x;
        sizuku.y = momo.y;
        scene.addChild(sizuku);
        sizuku.scale(3, 3);             
        sizuku.frame = [0, 1, 2, 3, 4, null];
        var sound = core.assets["sounds/cf307/water-dopon1.mp3"].clone();
        sound.play();
        momo.tl.delay(3).then(function(){
            momo.tl.moveBy(0, 3, 6, enchant.Easing.QUAD_EASEOUT);
            momo.tl.moveBy(0, -3, 6, enchant.Easing.QUAD_EASEOUT);   
            momo.tl.loop();      
        });
        sizuku.tl.delay(24).then(function(){
            var sizuku = new ExSprite(32, 32);
            sizuku.image = core.assets["images/cf307/sizuku0.png"];
            sizuku.x = momo.x;
            sizuku.y = momo.y;
            sizukuGroup.addChild(sizuku);
            sizuku.scale(3, 3);             
            sizuku.frame = [0, 1, 2, 3, 4, null];
            var sound = core.assets["sounds/cf307/bath-thapon1.mp3"].clone();
            sound.play();
        });
        sizuku.tl.loop();
    }); 

    // てぬぐい
    scene.tl.delay(25).then(function(){
        var tenugui = new ExSprite(32, 16);
        tenugui.image = core.assets['images/cf307/tenugui.png'];
        tenugui.x = 320 / 2 - 16;
        tenugui.y = 0;
        scene.addChild(tenugui);
        tenugui.scale(1.3, 1.3);
        tenugui.tl.moveTo(320 / 2 - 16, 400 / 2 - 8 - 13, 6,enchant.Easing.QUAD_EASEOUT);
        tenugui.tl.then(function(){
            var sound = core.assets["sounds/cf307/jump02.mp3"].clone();
        sound.play();
        });   
        tenugui.tl.delay(3).then(function(){
            tenugui.tl.moveBy(0, 3, 6, enchant.Easing.QUAD_EASEOUT);
            tenugui.tl.moveBy(0, -3, 6, enchant.Easing.QUAD_EASEOUT);   
            tenugui.tl.loop();      
        });
    });  
 
    // お風呂の下
    var hurosita = new ExSprite(64, 64);
    hurosita.image = core.assets['images/cf307/tarunohurosita.png'];
    hurosita.x = 320 / 2 - 32;
    hurosita.y = 200  - 10 + 19;
    scene.addChild(hurosita);
    hurosita.tl.scaleTo(2, 2, 10);

    // Thank You
    var label1 = new Label("  THANK YOU!");
    label1.color = 'black';
    label1.font = "30px 'PixelMplus10'";
    label1.textAlign = "center";
    label1.y = 330; 
    scene.addChild(label1);

    // ゲームクリアを表示
    var gameclear = new ExSprite(147, 48);
    gameclear.image = core.assets['images/title_gameclear.png'];
    gameclear.x = 320 / 2 - gameclear.width/2;
    gameclear.y = 50;
    scene.addChild(gameclear);
    // 大きく
    gameclear.scale(0.5, 0.5);
    gameclear.tl.scaleTo(1.5, 1.5, 20); 
        
    // リトライボタン
    var retry = new ExSprite(62, 55);
    retry.image = core.assets["images/cf307/retrybotan.png"];
    scene.addChild(retry);
    retry.x = 320 / 2 - retry.width / 2;
    retry.y = 350 ;
    retry.tl.moveBy(0, 50, 20);  
    // ボタンをタッチ
   retry.addEventListener(Event.TOUCH_START, function(){
        retry.frame = 1;
        console.log("タッチしました");
    });
    retry.addEventListener(Event.TOUCH_END, function(){
        retry.frame = 0;
        gameStart();
    });

    // おまけボタン       
    var botan = new ExSprite(64, 64);
    botan.image = core.assets["images/cf307/momobotann.png"];
    scene.addChild(botan);
    botan.x = 320 - 64;
    botan.y = 480 - 64;
    botan.originX = 64;
    botan.originY = 64;
    botan.scale(0.1, 0.1);
    botan.tl.scaleTo(0.5, 0.5, 20);

   // もう一回の文字
    var label3 = new Label("おまけ");
    label3.color = 'black';
    label3.font = "10px 'PixelMplus10'";
    scene.addChild(label3);
    label3.x = 320 - 58;
    label3.y = 480 - 20;                 
    label3.scale(0.1, 0.1);
    label3.tl.scaleTo(0.8, 0.8, 20);
    // ボタンをタッチ
   botan.addEventListener(Event.TOUCH_START, function(){
        botan.frame = 1;
        label3.tl.moveBy(0, 6, 0);
        console.log("タッチしました");     
    });
    botan.addEventListener(Event.TOUCH_END, function(){
        botan.frame = 0;
        label3.tl.moveBy(0, -6, 0);
        // ももちゃんブッ 
        var sound = core.assets["sounds/gass.mp3"].clone();
        sound.play();
        label3.tl.delay(5).then(function(){
            var bomb = new ExSprite(32, 32);
            bomb.image = core.assets["images/joe_gass.png"];
            bomb.x = momo.x + 32;
            bomb.y = momo.y - 32;
            scene.addChild(bomb);
        bomb.scale(2, 2);       
            bomb.frame = [0, 1, 2, 3, 4, null]; 
            var sound = core.assets["sounds/cf307/water-bukubuku3.mp3"].clone();
            sound.play();              
        });                 
   });

    // ラべるをタッチ
    label3.addEventListener(Event.TOUCH_START, function(){
        botan.frame = 1;
        label3.tl.moveBy(0, 6, 0);
        console.log("タッチしました");
    });
    label3.addEventListener(Event.TOUCH_END, function(){
        botan.frame = 0;
        label3.tl.moveBy(0, -6, 0);
        // ももちゃんブッ 
        var sound = core.assets["sounds/gass.mp3"].clone();
        sound.play();
        label3.tl.then(function(){          
            var sound = core.assets["sounds/cf307/water-bukubuku3.mp3"].clone();
            sound.play();
        });
        label3.tl.delay(10).then(function(){
            var bomb = new ExSprite(32, 32);
            bomb.image = core.assets["images/joe_gass.png"];
            bomb.x = momo.x + 32;
            bomb.y = momo.y - 32;
            scene.addChild(bomb);
        bomb.scale(2, 2);       
            bomb.frame = [0, 1, 2, 3, 4, null];                           
        });   
    });

    //==========
    // ここまで
    //==========
}

function getRandom(start, end) {
    return start + Math.floor( Math.random() * (end - start + 1));
}

function titleStart(){// タイトル画面
    var scene = gameManager.createTitleScene();
    core.replaceScene(scene); core.pause();
    scene.on(enchant.Event.TOUCH_START, function(){gameStart();});
}

//==========
// EnchantJS
enchant();
var gameManager;
var core;
var scene;
window.onload = function(){
    gameManager = new common.GameManager();
    core = gameManager.createCore(320, 480);
    core.preload(assets);
    core.onload = function(){titleStart();};
    core.start();
}

ド・レ・か当ててミ・ソ~♪(解説)

🎹ピアノdeぽ~ん!🎹をさらに発展させて、音がなるのでそれが何の音か当てるゲームにしました。

自動的に音がなる仕組みは、透明の鍵盤を上から落として、下の鍵盤に当たったらその音が鳴るという仕組みです。鍵盤の位置はド〜上のドまで、8箇所の位置いずれか0〜7の間のランダムで落ちるようにすれば、ランダムで音がなるという訳です。

この時はまだ画像を透明にする方法を知らなくて、透明の画像を描いて、それを置きました。

後から知って、そんな簡単な方法があったのか・・となりましたが、こういうことがあると、その後から教えてもらった便利な方法はすぐ覚えて忘れません。

だから、forループを知らずに100個描いたら、forループを知ったなら感動してすぐ覚えるでしょうし、苦労して面倒な書き方をしていれば、関数の便利さも実感できます。自分なりの工夫の苦労も、無駄じゃないと思います。

ソースコードはこちら(自由研究:18ドレミ音当て)