JavaScriptでもぐらたたき (DOM操作編)

SCORE
0
HP
10

JavaScriptのオブジェクト志向

DOM操作には処理時間がかかるため、ゲーム内ループで繰り返し使う要素は先に宣言しておく。

「もぐら」をEnemy(敵)オブジェクトと定義し、複数生成する。

EnemyオブジェクトのDOM要素をEnemyエレメントと関連付ける。

EnemyオブジェクトはCSSの絶対座標でランダム位置に要素を生成する。

ゲーム内のループ回数をカウントし、カウントが一定条件になったら表示・非表示を繰り返す。

Enemyオブジェクトオブジェクトは表示されるたびにランダムな位置に移動する。

Enemyオブジェクトをクリックするとスコアが増えて、Enemyエレメントは非表示になる。

Enemyオブジェクトを放置すると、HPが減少し、Enemyエレメントは非表示になる。

HPが0になるとゲームオーバー。ゲーム内ループを終了する。

時間制限は無し。ゲームオーバーになるまで延々と続けることができる。

view source

JavaScript

var Game = function(){
  this.is_end = false;

  this.area = $('#area');
  this.enemy_origin = $('#pre .enemy');
  this.enemys = [];
  this.timer = 0;

  this.score_ele = $('#score');
  this.score = 0;

  this.hp_ele = $('#hp');
  this.hp = 20;

  var that = this;

  this.init = function(){
    var enemy;
    for(var i=0; i<8;i++){
      enemy = new Enemy(this);
      enemy.ele = this.enemy_origin.clone();
      enemy.init();
      this.area.append(enemy.ele);
      this.enemys.push(enemy);

    }

    this.loop();
  }
  this.run = function(){
    for(var i=0; i<this.enemys.length;i++){
      this.enemys[i].run();
    }
  }
  this.end = function(){
    var message = 'GAME OVER !!!!';
    this.hp_ele.text(message);
    this.is_end = true;
    for(var i=0; i<this.enemys.length;i++){
      this.enemys[i].hide();
    }
    console.log(message);
  }
  this.loop = function(){
    this.timer ++;
    var timer_id = setTimeout(function(game){
      if(!game.hp){
        game.end();
      } else {
        game.run();
        game.loop();
      }
    }, 200, this);
  }

  this.addScore = function(){
    this.score++;
    this.score_ele.text(this.score);
    
  }
  this.damage = function(){
    this.hp--;
    this.hp_ele.text(this.hp);
  }
  this.punchEnemy = function(enemy){
    this.addScore();
    enemy.data('is_dead', true);
    enemy.remove();
  }
  this.hideEnemy = function(enemy){
    setTimeout(function(game, enemy){
      enemy.remove();
      if(!game.is_end){
        game.damage();
      }
    }, enemy.data('hide_time'), this, enemy);
  }
};
Game.prototype = {};




var Enemy = function(game){
  this.game = game;
  this.ele;
  this.x;
  this.y;
  this.count = 0;
  this.pop_time;
  this.hide_time;
  this.init = function(){
    this.count = parseInt(Math.random()*5)+2;
    this.ele.click($.proxy(function(){
      console.log('!!');
      game.addScore();
      this.fall();
    }, this));
  }
  this.run = function(){
    this.count--;
    //console.log(this.count);
    if(this.count === 0){
      this.fall();
    } else if(this.count === 2){
      this.attack();
    } else if(this.count === this.pop_time){
      this.pop();
    }
  }
  this.pop = function(game){
    this.x = parseInt(Math.random()*5) * 60;
    this.y = parseInt(Math.random()*5) * 60;
    this.hide_time = (parseInt(Math.random() * 15) + 9) * 100;
    this.ele.css({
      left : this.x,
      top : this.y
    }).show();
    console.log(this.x + ':' + this.y);
  }
  this.attack = function(){
    this.ele.addClass('attack');
    this.game.damage();
  }
  this.fall = function(game){
    this.count = parseInt(Math.random()*40)+9;
    
    this.pop_time= parseInt(Math.random()*9)+5;
    this.ele.removeClass('attack');
    this.hide();
  }
  this.hide = function(){
    this.ele.hide();
  }
}




$(function(){
  var game = new Game();
  $('#commands a').click(function(){
    $(this).remove();
    game.init();
    return false;
  });
});

CSS

#commands{
  margin:10px 20px;
}
#commands a{
  display:block;
  width:240px;
  height:40px;
  line-height:40px;
  text-align:center;
  text-decoration:none;
  font-size:32px;
  text-shadow:#000000 0px 0px 2px;
  background-color:#550000;
  background-image:-webkit-gradient(
    linear,
    left top,
    left bottom,
    from(#ee6666),
    to(#550000)
  );
  color:#ffffff;
  border-radius:12px;
}
#commands a:hover{
  background-image:-webkit-gradient(
    linear,
    left top,
    left bottom,
    from(#550000),
    to(#ee6666)
  );
}

#area{
  position:relative;
  left:;0px
  top:0px;
  width:320px;
  height:320px;
  background-color:#000000;
}
#pre{
  display:none;
}

dl#status{
  margin:10px;
  padding:10px 0px;
  border:4px solid #000000;
  border-radius:12px;
  width:320px;
  font-size:32px;
}
dl#status:after{
  content:"";
  display:block;
  clear:both;
}
dl#status dt{
  width:120px;
  margin:0px 20px;
  float:left;
  text-align:right;
}
dl#status dd{
  width:120px;
  margin:0px 20px;
  float:left;
  text-align:right;
  font-weight:bold;
}

#score{
  color:#0000aa;
}
#hp{
  color:#aa0000;
}

div.enemy{
  position:absolute;
  left:;0px
  top:0px;
  width:60px;
  height:60px;
  background-color:#999999;
  border-radius:50%;
  -webkit-transition-property: transform;
  -moz-transition-property: transform;
  -o-transition-property: transform;
  transition-property: transform;
  -webkit-transition-duration: 9s;
  -moz-transition-duration: 9s;
  -o-transition-duration: 9s;
  transition-duration: 9s;
}
div.enemy.before{
  -webkit-transform:translateX(20px);
}
div.enemy.fall{
  -webkit-transform:translateY(320px);
}

div.enemy.atack{
  background-color:#ff0000;
}
div.enemy.dead{
  display:none;
}

HTML

ページのソースを表示 : Ctrl+U , DevTools : F12

view-source:https://hi0a.com/demo/-js/js-whack-a-mole/

ABOUT

hi0a.com 「ひまアプリ」は無料で遊べるミニゲームや便利ツールを公開しています。

プログラミング言語の動作デモやWEBデザイン、ソースコード、フロントエンド等の開発者のための技術を公開しています。

必要な機能の関数をコピペ利用したり勉強に活用できます。

プログラムの動作サンプル結果は画面上部に出力表示されています。

環境:最新のブラウザ GoogleChrome / Windows / Android / iPhone 等の端末で動作確認しています。

画像素材や音素材は半分自作でフリー素材配布サイトも利用しています。LINK参照。

動く便利なものが好きなだけで技術自体に興味はないのでコードは汚いです。

途中放置や実験状態、仕様変更、API廃止等で動かないページもあります。