2011年6月26日日曜日

HTML5 - Canvas アニメーション ゲーム(2)

ゲーム(1)の改良版。右左で移動できて、上でジャンプできます。敵の熊達をよけながら、GUNで敵を全部倒せばクリアです。GUNはAボタンで撃てます。Blog上ではうまく動かないので、リンクはります。動作確認はパソコンのChrome,Firefoxで確認済みです。

http://endo-yuta2.appspot.com/practice3

code

<canvas id="game" width="400" height="400"></canvas>
<script type="text/javascript">
var canvas = document.getElementById("game");
var ctx = canvas.getContext("2d");

//敵の最大数
var ENEMY_COUNT = 5;

//画像の読み込み
//プレイヤーの画像読み込み
var img_player = new Image();
img_player.src = '/pic/Emoticons.png';

//敵画像の読み込み
var imgs = new Array();
imgs[0] = new Image();
imgs[0].src = '/pic/BlueToy_48x48.png'
imgs[1] = new Image();
imgs[1].src = '/pic/YellowToy_48x48.png'
imgs[2] = new Image();
imgs[2].src = '/pic/FireToy_48x48.png'
imgs[3] = new Image();
imgs[3].src = '/pic/GreenToy_48x48.png'

//プレイヤーのインスタンス作成
var player = new Player(ctx,img_player,0,368);

//最大数まで敵のインスタンスを作成
var enemys = new Array();
for(var i=0; i<ENEMY_COUNT; i++){
 //向きと早さをランダムに決める
 var vx = Math.random()*3; 
 var vy = Math.random()*3;
 //イメージをランダムに決める
 var img_no = Math.floor(Math.random()*4);
 //インスタンス作成
 enemys[i] = new Enemy(ctx,imgs[img_no],0,0,vx,vy);
}

//イメージロード後にメイン関数を繰り返し
var tm;
imgs[3].onload = function() { 
 tm = setInterval(main,10);
}

//メイン関数
function  main(){
 //画面のクリア
 ctx.clearRect(0,0,400,400);
 //当たり判定
 if(player.hit_enemy(enemys)){
  alert('GAME OVER...');
  clearInterval(tm);
  player.apear();
  for(var i=0; i<enemys.length; i++){
   enemys[i].apear();
  }
 }else{
  //プレイヤーのインスタンスの表示
  player.apear(); 
  
  //当たった弾のインデックス用
  var bullet_i;
  for(var i=0; i<enemys.length; i++){
   //敵と弾の当たり判定
   if(enemys.length -1 < i) break;
   bullet_i = enemys[i].hit_bullet(player);
   if(bullet_i == false){
    //敵のインスタンスの表示
    enemys[i].apear();    
   }else{
    //敵のパワーが1減る
    enemys[i].power --;
    if(enemys[i].power == 0) enemys.splice(i,1);
    //弾を削除
    player.bullet.splice(bullet_i-1,1);
   }
  }
 }
}

//敵クラス
function Enemy(ctx,img,x,y,vx,vy){
 var obj = this;
 obj.x = x ? x : 0;
 obj.y = y ? y : 0;
 obj.vx = vx ? vx : 2;
 obj.vy = vy ? vy : 1;
 obj.size = 32;
 
 //敵のパワー
 obj.power = 5;
  
 //敵を表示するメソッド
 obj.apear = function(){
  ctx.drawImage(img,obj.x,obj.y,obj.size,obj.size);
  obj.x = obj.x + obj.vx;
  obj.y = obj.y + obj.vy;
  //枠に到達したら折り返させる(速度の符号を反転)
  if(obj.x<=0||obj.x>=400-28) obj.vx = -obj.vx;
  if(obj.y<=0||obj.y>=400-30) obj.vy = -obj.vy;
 }
 
 //敵と弾の当たり判定メソッド
 obj.hit_bullet = function(player){
  var b_lx;
  var b_ty;
  var b_rx;
  var b_by;
  for(var i=0; i<player.bullet.length; i++){
   b_lx = player.bullet[i].x;
   b_ty = player.bullet[i].y;
   b_rx = b_lx + 4;
   b_by = b_ty + 4;
   if(obj.x < b_rx && b_lx < obj.x+20 && obj.y < b_by && b_ty <obj.y+26) return i+1;
  }
  return false;
 }
}

//プレイヤークラス
function Player(ctx,img,x,y){
 var obj = this;
 obj.x = x ? x : 0;
 obj.y = y ? y : 0;
 obj.vy = 5;
 obj.g = 0.1;
 obj.size = 32;
 
 //ジャンプ中か?フラグ
 obj.jump_status = false;
 //右移動中か?フラグ
 obj.right_status = false;
 //左移動中か?フラグ
 obj.left_status = false;
 //Gun撃っているか?フラグ
 obj.gun_status = false;
 //Gun制御フラグ(一定間隔で撃つためのカウンター)
 obj.gun_counter = 0;
 
 //Bulletインスタンスの配列の作成
 obj.bullet = new Array();
  
 //プレイヤーを表示するメソッド
 obj.apear = function(){
  ctx.drawImage(img,obj.x,obj.y,obj.size,obj.size);
  //ジャンプ
  if(obj.jump_status) obj.jump();
  //右移動
  if(obj.right_status) obj.right();
  //左移動
  if(obj.left_status) obj.left();
  //Gun 撃っている状態
  if(obj.gun_status){
   if(obj.gun_counter == 0){
    obj.bullet.push(new Bullet(obj));
    obj.gun() ;
    obj.gun_counter = 40;
   }else{
    obj.gun() ;
    obj.gun_counter --;
   }
  }
  //Gun 撃ち終わった状態
  if(! obj.gun_status && obj.bullet.length > 0){
   obj.gun();
   obj.gun_counter = 0;
  }
 }
 
 //Gunメソッド
 obj.gun = function(){
  for(var i = 0; i <obj.bullet.length; i++){
   //弾の数だけ弾を表示する。と同時に弾が外に出ていないか確認する
   if(obj.bullet.length -1 < i) break;
   if(!obj.bullet[i].shot()){
    //弾が外に出ている場合は、インタスタンスを削除する
    obj.bullet.splice(i,1);
   }
  }
 }
 
 //ジャンプメソッド
 obj.jump = function(){
  //jumpすると重力によって、-9.8m/s2速度が下がる
  obj.vy = obj.vy - obj.g;
  obj.y = obj.y - obj.vy;
  if(obj.y>=400-obj.size){
   obj.vy = 5;
   obj.y = 400-obj.size;
   obj.jump_status = false;
  } 
 }
 
 //右移動メソッド
 obj.right = function(){
  if(obj.x<400-32) obj.x = obj.x + 2.5;
 }
 
 //左移動メソッド
 obj.left = function(){
  if(obj.x>0) obj.x = obj.x - 2.5;
 }
 
 //敵との当たり判定メソッド
 obj.hit_enemy = function(enemys){
  var e_lx;
  var e_ty;
  var e_rx;
  var e_by;
  for(var i=0; i<enemys.length; i++){
   e_lx = enemys[i].x;
   e_ty = enemys[i].y;
   e_rx = e_lx + 20;
   e_by = e_ty + 26;
   if(obj.x < e_rx && e_lx < obj.x+28 && obj.y < e_by && e_ty <obj.y+28) return true;
  }
  return false;
 }
}

//Bulletクラス
function Bullet(player){
 var obj = this;
 obj.x = false;
 obj.y = false;
 obj.v = 5;
 
 //弾を表示するメソッド
 obj.shot = function(){
  if(obj.x && obj.y){
   obj.x = obj.x + obj.v;
   obj.y = obj.y - obj.v;
   //外に出ていたらfalseを返す
   if(obj.x<0 || obj.x>400 || obj.y <0 || obj.y >400){
    return false;
   }
  }else{
   obj.x = player.x+32;
   obj.y = player.y+14;
  }
  ctx.beginPath()
  ctx.fillStyle = 'orange';
  ctx.arc(obj.x+2, obj.y+2, 2, 0, 360,false);
  ctx.fill();
  return true;
 }
}

//キーコード
var KEY_LEFT = 37;
var KEY_RIGHT = 39;
var KEY_UP = 38;
var KEY_DOWN = 40;
var KEY_SPACE = 32;
var KEY_ENTER = 13;
var KEY_ESC = 27;
var KEY_A = 65;

//キー入力検出
$(window).keydown(function(e){
 //スペースか上を押したら...
 if(e.keyCode == KEY_SPACE || e.keyCode == KEY_UP){
  player.jump_status = true;
  return false;
 //左を押したら...
 }else if(e.keyCode == KEY_LEFT){
  player.left_status = true;
  player.right_status = false;
  return false;
 //右を押したら...
 }else if(e.keyCode == KEY_RIGHT){
  player.right_status = true;
  player.left_status = false;
  return true;
 //Aを押したら...
 }else if(e.keyCode == KEY_A){
  player.gun_status = true;
  return false;
 }
});

$(window).keyup(function(e){
 if(e.keyCode == KEY_LEFT){
  if(!player.jump_status) player.left_status = false;
  return false;
 }
 if(e.keyCode == KEY_RIGHT){
  if(!player.jump_status) player.right_status = false;
  return false;
 }
 if(e.keyCode == KEY_A){
  player.gun_status = false;
  return false;
 }
});
</script>

0 件のコメント:

コメントを投稿