2011年6月20日月曜日

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

若干ゲームっぽくなってきたHTML5のCanvasアニメーションです。プレイヤーは青いボールに顔が書いてあるやつで、彼はカーソルキーで動かせます。上を押すとジャンプします。しかしジャンプしだしたら天井にぶつかって帰ってくるまで止まりません。右左を押すと右左に移動します。ジャンプ中も移動できます。敵はくま達です。くま達にぶつかった時点でゲームオーバーです。得点などはございません。ゲームオーバーになったらリロードするまでもはや動きません。

(やはりブログのトップページだと表示されない。。。見るときは単一ページからお願いします。)


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

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

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

//敵画像の読み込み
var imgs = new Array();
imgs[0] = new Image();
imgs[0].src = 'BlueToy_48x48.png'
imgs[1] = new Image();
imgs[1].src = 'YellowToy_48x48.png'
imgs[2] = new Image();
imgs[2].src = 'FireToy_48x48.png'
imgs[3] = new Image();
imgs[3].src = '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 hit_p_e = new Hit_player_enemy(player,enemys,ENEMY_COUNT);

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

//メイン関数
function  main(){
 //画面のクリア
 ctx.clearRect(0,0,400,400);
 //当たり判定
 if(hit_p_e.hit()){
  alert('GAME OVER...');
  clearInterval(tm);
  player.apear();
  for(var i=0; i<ENEMY_COUNT; i++){
   enemys[i].apear();
  }
 }else{
  //プレイヤーのインスタンスの表示
  player.apear(); 
  //敵のインスタンスの表示
  for(var i=0; i<ENEMY_COUNT; i++){
   enemys[i].apear();
  }
 }
}

//敵クラス
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.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;
 }
}

//プレイヤークラス
function Player(ctx,img,x,y){
 var obj = this;
 obj.x = x ? x : 0;
 obj.y = y ? y : 0;
 obj.vy = -3;
 obj.size = 32;
 
 //ジャンプ中か?フラグ
 obj.jump_status = false;
 //右移動中か?フラグ
 obj.right_status = false;
 //左移動中か?フラグ
 obj.left_status = false;
 
 //プレイヤーを表示するメソッド
 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();
 }
 
 //ジャンプメソッド
 obj.jump = function(){
  obj.y  = obj.y + obj.vy;
  if(obj.y<=0) obj.vy = -obj.vy;
  if(obj.y>=400-32){
   obj.jump_status = false;
   obj.vy = -obj.vy;
  } 
 }
 
 //右移動メソッド
 obj.right = function(){
  if(obj.x<400-32) obj.x = obj.x + 3;
 }
 
 //左移動メソッド
 obj.left = function(){
  if(obj.x>0) obj.x = obj.x - 3;
 }
}

//当たり判定クラス(プレイヤーと敵との当たり判定)
function Hit_player_enemy(player,enemys,enemy_count){
 var obj = this;
 //プレイヤーの位置の取得
 var p_lx;
 var p_ty;
 var p_rx;
 var p_by;
 //敵の位置の取得と当たり判定を敵の数繰り返す
 var e_lx;
 var e_ty;
 var e_rx;
 var e_by;
 
 //当たり判定メソッド
 obj.hit = function(){
  for(var i=0; i<enemy_count; i++){
   p_lx = player.x;
   p_ty = player.y;
   p_rx = p_lx + 28;
   p_by = p_ty +28;
   e_lx = enemys[i].x;
   //e_lx = enemys.x;
   e_ty = enemys[i].y;
   //e_ty = enemys.y;
   e_rx = e_lx + 20;
   e_by = e_ty + 26;
   if(p_lx < e_rx && e_lx < p_rx && p_ty < e_by && e_ty < p_by) return true;
  }
  return false;
 }
}

//キーコード
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;

//キー入力検出
$(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;
 }
});

</script>

0 件のコメント:

コメントを投稿