2016-05-17 12 views
3

私はそれに関連する質問を見たことがありますが、私が探しているものを見つけることができないようです。私は本当に、キャンバスには本当に新しいので、いくつかの練習を得るために、私は非常に小さなプラットフォームのゲームエンジンを書く始めた。これまでのところ、私はジャンプして画面の周りを移動するために少し正方形を持っていますが、私の次のステップは、この小さな四角形に武器を与えることです。弾丸を作る方法についてのチュートリアルはたくさんありますが、(剣のような)近接武器の作り方については何もありません。これが私が達成したいことです。ここでキーを押したときにキャンバスに描画された矩形を回転させます

氏キューブ

enter image description here

ある氏キューブは武器を必要とします。私は私の更新機能にこれを追加することができます。

// Draw player 
ctx.fillStyle = player.fill 
ctx.fillRect(player.x, player.y, player.width, player.height); 

// Draw weapon 
ctx.fillStyle = "green"; 
ctx.fillRect(player.x + 20, player.y - 20, 8, 30); 

これは私に私の目的の外観を与える

enter image description here

ので、私はそうのようなキャンバスに武器を描いた、のx、yの値を使用してプレイヤーx、yの値として、それは常にキューブ氏に付随しています。もちろん、これらはある時点で適切なグラフィックスにスワップアウトされますが、これは本質的に目に見えないヒットボックスとして機能します。私の質問は次のとおりです。

この矩形を回転させる関数を作成するにはどうすればいいですか?それは私を本当に混乱させています。私が達成したいもののイメージはここにある:

enter image description here

これは、これまで私はJavaScriptでライブバージョンが

http://codepen.io/jcoulterdesign/pen/d6308fc86305d70c875c30f9452aa4d6?editors=1010

おかげでここで見つけることができます

// Platform game prototyping engine 

// Globals 

player_created = 0; 
environment = 0; 
debug_on = false; 

// Request frames 

(function() { 
    var requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame; 
    window.requestAnimationFrame = requestAnimationFrame; 
})(); 

/** 
    * New Game 
    * @desc Creates canvas and context then sets the height and width 
    * @param [string] canvas - Canvas ID in your HTML 
    * @param [integer] width - Canvas width 
    * @param [integer] height - Canvas height 
    * @param [string] bg - Canvas background color 
*/ 

function new_game(canvas,width,height){ 
    game = document.getElementById(canvas); 
    ctx = game.getContext("2d"); 
    game.width = width; 
    game.height = height; 

} 

/** 
    * New Player 
    * @desc Creates a single player on the canvas 
    * @param [integer] x - Player x position on canvas 
    * @param [integer] y - Player y position on canvas 
    * @param [integer] width - Player width 
    * @param [integer] height - Player height 
    * @param [integer] speed - Player movement speed 
    * @param [integer] jumpVel - Player jump amount 
    * @param [string] fill - Player fill color 
*/ 

function new_player(x,y,width,height,speed,jumpVel,fill){ 
    player = { 
     x: x, 
     y: y, 
     width: width, 
     height: height, 
     fill: fill, 
     speed:speed, 
     velX:0, 
     velY:0, 
     jumpVel:jumpVel, 
     jumping: false 
    } 
    keys = []; 

    ctx.fillStyle = player.fill; 
    ctx.fillRect(player.x, player.y, player.width, player.height); 
    ctx.fill(); 
    player_created = 1; 
} 

/** 
    * New Environment 
    * @desc Creates the game environment 
    * @param [integer] friction - Sets the environment platfrom friction 
    * @param [integer] gravity - Sets the environemnt gravity 
*/ 

function new_environment(friction,gravity){ 
    environment = { 
     friction: friction, 
     gravity: gravity 
    } 
    document.body.addEventListener("keydown", function(e) { 
     keys[e.keyCode] = true; 
    }); 
    document.body.addEventListener("keyup", function(e) { 
     keys[e.keyCode] = false; 
    }); 
} 

function debug(){ 
    ctx.font = "11px Verdana"; 
    ctx.fillStyle = "white"; 
    ctx.fillText('Velocity X: ' + player.velX,20,30); 
    ctx.fillText('Velocity Y: ' + player.velY,20,50); 
    ctx.fill(); 
} 

function update(){ 
    ctx.clearRect(0,0,game.width,game.height); 
    if(player_created == 1){ 

     // Draw player 
     ctx.fillStyle = player.fill 
     ctx.fillRect(player.x, player.y, player.width, player.height); 

     // Draw weapon 
     ctx.fillStyle = "green"; 
     ctx.fillRect(player.x + 20, player.y - 20, 8, 30); 

     if(environment == 0){ 
      console.log('%c No environment has been created! ', 'background: #222; color: #bada55'); 
     } 
     if (keys[38]) { 
      // up arrow or space 
      if(!player.jumping){ 
       player.jumping = true; 
       player.velY = -player.jumpVel; 
      } 
     } 
     if (keys[39]) { 
      player.velX =+ player.speed;   
     }  
     if (keys[37]) {     
      player.velX =- player.speed; 
     } 

     player.y += player.velY; 
     player.x += player.velX; 
     player.velY += environment.gravity; 
     player.velX *= environment.friction; 

     if (player.x >= game.width-player.width) { 
      player.x = game.width-player.width; 
     } else if (player.x <= 0) {   
      player.x = 0;  
     } 

     if(player.y >= game.height - player.height){ 
      player.y = game.height - player.height; 
      player.jumping = false; 
     } 
    } 
    if(debug_on == true){ 
     debug() 
    } 
    requestAnimationFrame(update); 
} 

window.addEventListener("load", function(){ 
    update(); 
}); 

new_game('game',600,600) 
new_player(250,250,20,20,4,20,'red') 
new_environment(.9,1) 

あらかじめ!

答えて

2

矩形を描画する前にctx.rotate()関数を使用して、回転を元に戻します。

は始めるためにあなたの例ではif(player_created == 1){行96の後に次のコードを追加します。

ctx.save(); // save current rotation and coordinates 
ctx.translate(player.x + player.width, player.y); // set canvas draw start to new rect coordinates 
ctx.rotate(Math.PI/4); // 45 degrees for example 
ctx.fillStyle = 'green'; 
ctx.fillRect(0, -25, 10, 30); // 10 by 30 rect, shifted 25 y up 
ctx.restore(); // restore to old rotation and coordinates 
ctx.fillStyle = 'red'; 
+0

これは素晴らしいです。だから私はキーを押すまでこれをフック私は時間の経過とともに回転値を変更することができます。言い換えれば、それはそれにスナップするのではなく、その回転にアニメーション化されますか? –

+1

ええ、アニメーションでは、現在の回転を変数に格納し、ボタンが押された時間に基づいて変数を増減させる必要があります。 すでにrequestAnimationFrameを使用しているため、更新関数の最初のパラメータでアニメーションを開始してから経過した時間がわかります。タイムスタンプをチェックするには 'function update(){'を 'function update(thisLoop){'とconsole.log(thisLoop)に変更してください。未定義の変数thisLoopを最初に実行しないようにするには、アニメーションの開始(例の行138)を次のように変更します: 'requestAnimationFrame(update);' – M4tini

+1

良い答えupvote。パフォーマンスに関する単なる一言: 'save&restore'は、変換と変換の変換だけでなく、すべてのコンテキストプロパティを保存して復元します。翻訳だけを元に戻して回転する方が効率的です。それは、元の変換を逆の順序で負の値で呼び出すことによって行います: 'ctx.rotate(-Math.PI/4); ctx.translate(-player.x-player.width、-player.y) 'です。あるいは、すべての変換を 'ctx.setTransform(1,0,0,1,0,0)'で "untransformed"にリセットする;-) – markE

関連する問題