2013-07-29 3 views
0

내가 지금 가지고있는 것과 내가 그것에 추가하려고하는 것을 설명하려고 노력합시다. 지금은 5000x3750의 배경 이미지 (지도)에 스프라이트 (플레이어)를 따라 500x899의 캔버스가 있습니다. 둘 다 같은 스프라이트 시트에 있습니다. 화살표 키를 누르면 플레이어의 스프라이트가지도를 따라 그 방향으로 이동하고 캔버스가 플레이어를 따라갑니다. -하지만 내가 원하는 것은 왼쪽/오른쪽 화살표 키를 사용하여 플레이어와 위쪽 키를 회전시켜 플레이어를 그 방향으로 이동시키는 것입니다. 여기 내 코드는, 그것은 많이하지만, 그것의 구성은 :화살표 키를 사용하여 스프라이트 시트에서 html5 캔버스로 스프라이트 회전하기. (2 차원 html5 캔버스)

// wrapper for "class" Rectangle 
    (function(){ 
     function Rectangle(left, top, width, height){ 
      this.left = left || 0; 
      this.top = top || 0; 
      this.right = (left + width) || 0; 
      this.bottom = (top + height) || 0; 
     } 

     Rectangle.prototype.set = function(left, top, width, height){ 
      this.left = left; 
      this.top = top; 
      this.width = width || this.width; 
      this.height = height || this.height; 
      this.right = (this.left + this.width); 
      this.bottom = (this.top + this.height); 
     } 

     Rectangle.prototype.within = function(r) { 
      return (r.left <= this.left && 
        r.right >= this.right && 
        r.top <= this.top && 
        r.bottom >= this.bottom); 
     }  

     Rectangle.prototype.overlaps = function(r) { 
      return (this.left < r.right && 
        r.left < this.right && 
        this.top < r.bottom && 
        r.top < this.bottom); 
     } 

     // add "class" Rectangle to our Game object 
     Game.Rectangle = Rectangle; 
    })(); 

    // wrapper for "class" Camera (avoid global objects) 
    (function(){ 

     // possibles axis to move the camera 
     var AXIS = { 
      NONE: "none", 
      HORIZONTAL: "horizontal", 
      VERTICAL: "vertical", 
      BOTH: "both" 
     }; 

     // Camera constructor 
     function Camera(xView, yView, canvasWidth, canvasHeight, worldWidth, worldHeight) 
     { 
      // position of camera (left-top coordinate) 
      this.xView = xView || 0; 
      this.yView = yView || 0; 

      // distance from followed object to border before camera starts move 
      this.xDeadZone = 0; // min distance to horizontal borders 
      this.yDeadZone = 0; // min distance to vertical borders 

      // viewport dimensions 
      this.wView = 800; 
      this.hView = 599;   

      // allow camera to move in vertical and horizontal axis 
      this.axis = AXIS.BOTH; 

      // object that should be followed 
      this.followed = null; 

      // rectangle that represents the viewport 
      this.viewportRect = new Game.Rectangle(this.xView, this.yView, this.wView, this.hView);    

      // rectangle that represents the world's boundary (room's boundary) 
      this.worldRect = new Game.Rectangle(this.xView, this.yView, this.wView, this.hView); 

     } 

     // gameObject needs to have "x" and "y" properties (as world(or room) position) 
     Camera.prototype.follow = function(gameObject, xDeadZone, yDeadZone) 
     {  
      this.followed = gameObject; 
      this.xDeadZone = xDeadZone; 
      this.yDeadZone = yDeadZone; 
     }     

     Camera.prototype.update = function() 
     { 
      // keep following the player (or other desired object) 
      if(this.followed != null) 
      {  
       if(this.axis == AXIS.HORIZONTAL || this.axis == AXIS.BOTH) 
       {  
        // moves camera on horizontal axis based on followed object position 
        if(this.followed.x - this.xView + this.xDeadZone > this.wView) 
         this.xView = this.followed.x - (this.wView - this.xDeadZone); 
        else if(this.followed.x - this.xDeadZone < this.xView) 
         this.xView = this.followed.x - this.xDeadZone; 

       } 
       if(this.axis == AXIS.VERTICAL || this.axis == AXIS.BOTH) 
       { 
        // moves camera on vertical axis based on followed object position 
        if(this.followed.y - this.yView + this.yDeadZone > this.hView) 
         this.yView = this.followed.y - (this.hView - this.yDeadZone); 
        else if(this.followed.y - this.yDeadZone < this.yView) 
         this.yView = this.followed.y - this.yDeadZone; 
       }      

      }  

      // update viewportRect 
      this.viewportRect.set(this.xView, this.yView); 

      // don't let camera leaves the world's boundary 
      if(!this.viewportRect.within(this.worldRect)) 
      { 
       if(this.viewportRect.left < this.worldRect.left) 
        this.xView = this.worldRect.left; 
       if(this.viewportRect.top < this.worldRect.top)     
        this.yView = this.worldRect.top; 
       if(this.viewportRect.right > this.worldRect.right) 
        this.xView = this.worldRect.right - this.wView; 
       if(this.viewportRect.bottom > this.worldRect.bottom)      
        this.yView = this.worldRect.bottom - this.hView; 
      } 

     } 

     // add "class" Camera to our Game object 
     Game.Camera = Camera; 

    })(); 

    // wrapper for "class" Player 
    (function(){ 
     function Player(x, y){ 
      // (x, y) = center of object 
      // ATTENTION: 
      // it represents the player position on the world(room), not the canvas position 
      this.x = x; 
      this.y = y; 
      // move speed in pixels per second 
      this.speed = 200;  

      // render properties 
      this.width = 85; 
      this.height = 80; 
     } 

     Player.prototype.update = function(step, worldWidth, worldHeight){ 
      // parameter step is the time between frames (in seconds) 

      // check controls and move the player accordingly 
      if(Game.controls.left) 
       this.x -= this.speed * step; 
      if(Game.controls.up) 
       this.y -= this.speed * step; 
      if(Game.controls.right) 
       this.x += this.speed * step; 
      if(Game.controls.down) 
       this.y += this.speed * step;   

      // don't let player leaves the world's boundary 
      if(this.x - this.width/2 < 0){ 
       this.x = this.width/2; 
      } 
      if(this.y - this.height/2 < 0){ 
       this.y = this.height/2; 
      } 
      if(this.x + this.width/2 > worldWidth){ 
       this.x = worldWidth - this.width/2; 
      } 
      if(this.y + this.height/2 > worldHeight){ 
       this.y = worldHeight - this.height/2; 
      } 
     } 

     Player.prototype.draw = function(context, xView, yView){ 
      context.save(); 
      // before draw we need to convert player world's position to canvas position 
      context.drawImage(imgSprite,1700,599, this.width, this.height,(this.x-this.width/2) - xView, (this.y-this.height/2) - yView, this.width, this.height); 
      context.restore(); 
      } 
     // add "class" Player to our Game object 
     Game.Player = Player; 
    })(); 


    // wrapper for "class" Map 
    (function(){ 
     function Map(width, height){ 
      // map dimensions 
      this.width = width; 
      this.height = height; 

      // map texture 
      this.image = null; 
     } 

     // generate an example of a large map 
     Map.prototype.generate = function(){ 
      this.x = 0; 
      this.y = 0; 
      var ctx = document.createElement("canvas").getContext("2d");   
      ctx.canvas.width = this.width; 
      ctx.canvas.height = this.height;  
      ctx.drawImage(imgSprite,0,2250,this.width,this.height,this.x,this.y,this.width,this.height);  


      ctx.restore(); 

      // store the generate map as this image texture 
      this.image = new Image(); 
      this.image.src = ctx.canvas.toDataURL("image/png");     

      // clear context 
      ctx = null; 
     } 

     // draw the map adjusted to camera 
     Map.prototype.draw = function(context, xView, yView){     
      var sx, sy, dx, dy; 
      var sWidth, sHeight, dWidth, dHeight; 

      // offset point to crop the image 
      sx = xView; 
      sy = yView; 

      // dimensions of cropped image   
      sWidth = context.canvas.width; 
      sHeight = context.canvas.height; 

      // if cropped image is smaller than canvas we need to change the source dimensions 
      if(this.image.width - sx < sWidth){ 
       sWidth = this.image.width - sx; 
      } 
      if(this.image.height - sy < sHeight){ 
       sHeight = this.image.height - sy; 
      } 

      // location on canvas to draw the croped image 
      dx = 0; 
      dy = 0; 
      // match destination with source to not scale the image 
      dWidth = sWidth; 
      dHeight = sHeight;         

      context.drawImage(this.image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);    
     } 

     // add "class" Map to our Game object 
     Game.Map = Map; 

    })(); 


    // Game Script 
    (function(){ 
     // prepaire our game canvas 
     var canvas = document.getElementById("gameCanvas"); 
     var context = canvas.getContext("2d"); 

     // game settings: 
     var FPS = 30; 
     var INTERVAL = 1000/FPS; // milliseconds 
     var STEP = INTERVAL/1000 // seconds 

     // setup an object that represents the room 
     var room = { 
      width: 5000, 
      height: 3750, 
      map: new Game.Map(5000, 3750) 
     }; 

     // generate a large image texture for the room 
     room.map.generate(); 

     // setup player 
     var player = new Game.Player(85, 80); 

     // setup the magic camera !!! 
     var camera = new Game.Camera(0, 0, 800, 599, room.width, room.height);  
     camera.follow(player, 800/2, 599/2); 

     // Game update function 
     var update = function(){    
      player.update(STEP, room.width, room.height); 
      camera.update(); 
     } 

     // Game draw function 
     var draw = function(){ 
      // clear the entire canvas 
      context.clearRect(0, 0, 800, 599); 

      // redraw all objects 
      room.map.draw(context, camera.xView, camera.yView);  
      player.draw(context, camera.xView, camera.yView);  
     } 

     // Game Loop 
     var gameLoop = function(){      
      update(); 
      draw(); 
     } 

     // <-- configure play/pause capabilities: 

     // I'll use setInterval instead of requestAnimationFrame for compatibility reason, 
     // but it's easy to change that. 

     var runningId = -1; 

    Game.play = function(){ 
     if(runningId == -1){ 
      runningId = setInterval(function(){ 
       gameLoop(); 
      }, INTERVAL); 
      console.log("play"); 
     } 
    } 

    Game.togglePause = function(){  
     if(runningId == -1){ 
      Game.play(); 
     } 
     else 
     { 
      clearInterval(runningId); 
      runningId = -1; 
      console.log("paused"); 
     } 
    } 
})(); 
// <-- configure Game controls: 
Game.controls = { 
    left: false, 
    up: false, 
    right: false, 
    down: false, 
}; 
window.addEventListener("keydown", function(e){ 
    switch(e.keyCode) 
    { 
     case 37: // left arrow 
      Game.controls.left = true; 
      break; 
     case 38: // up arrow 
      Game.controls.up = true; 
      break; 
     case 39: // right arrow 
      Game.controls.right = true; 
      break; 
     case 40: // down arrow 
      Game.controls.down = true; 
      break; 
    } 
}, false); 
window.addEventListener("keyup", function(e){ 
    switch(e.keyCode) 
    { 
     case 37: // left arrow 
      Game.controls.left = false; 
      break; 
     case 38: // up arrow 
      Game.controls.up = false; 
      break; 
     case 39: // right arrow 
      Game.controls.right = false; 
      break; 
     case 40: // down arrow 
       Game.controls.down = false; 
      break; 
     case 80: // key P pauses the game 
      Game.togglePause(); 
      break;  
     } 
    }, false); 
    // start the game when page is loaded 
    window.onload = function(){ 
     Game.play(); 
    } 

는 다시이 선수 모두를 수행 할 수있는 캔버스를 위해 작동하지만 지금은 화살표 키를 사용하여 플레이어 스프라이트를 회전하기 위해 노력하고있어. (내가 그들에게 그것이 작동하지 않았다마다 삭제 한 것처럼 미안 해요, 내가 회전에 대한 시도 정확히 무엇을 해달라고)

var thrust = 0; 
var rotation = 0; 
ctxPlayer.translate(this.width/2, this.height/2); 
ctxPlayer.rotate(this.angle); 
ctxPlayer.translate(this.x,this.y); 
if(Game.controls.left) 
this.angle =-3 

을 : I'v이 구글을 사용하고 너무 유사한 몇 가지 코드를 시도했다. 이것과 비슷한 코드를 사용하면 내가 가지고있는 유일한 회전은 좌표를 중심으로 거대한 원으로 회전하는 것입니다. (실제로 한 지점에서 회전하지 않고 키를 누르지 않아도됩니다.)

도움이나 조언은 정말 고맙습니다.

답변

2

작업 순서를 변경하십시오. 스프라이트를 먼저 회전시킨 다음 이동하십시오. 원하는 효과를 얻으려면 스프라이트의 중심이 0,0 (왼쪽 위)에 있어야합니다. 다음 코드는 이미 0,0에서 시작 가정

ctxPlayer.save(); 
ctxPlayer.translate(this.x,this.y); 
ctxPlayer.rotate(this.angle); 
ctxPlayer.translate(-this.width/2,-this.height/2); // before we draw the sprite lets set the anchor point to its center. 
ctxPlater.restore(); 

http://jsfiddle.net/LRpBM/

+0

I'v이 당신의 코드를 시도하지만 난 여전히 같은 문제를 (플레이어 단지 거대한 원형으로 회전) 데 문제가 있습니다. 다음은 내 플레이어 코드입니다 : ctxPlayer.drawImage (imgSprite, 1700,599, this.width, this.height, this.x-this.width/2) - xView, (this.y-this.height/2) - yView, this.width, this.height); 제안 사항이 있으십니까? – user2582299

+0

나는 바이올린을 만들었고 희망적으로는 여전히 당신에게 사용하고있다. – ericjbasti

관련 문제