2013-08-18 3 views
0

Рисунок работал отлично, пока я не решил использовать несколько холстов. У меня есть холст сцены, холст объекта и холст объекта. Я, вероятно, в конечном итоге объединим объект и холст холста. В любом случае, как вы можете видеть ниже, мой класс героя рисует хорошо. Затем я попытался создать класс сущности с той же функцией draw, но не позволю мне рисовать, когда вызываю функцию. У меня почти такая же проблема с моим фоновым холстом. У меня еще нет класса для фона, но я это сделаю. Но я стараюсь просто рисовать изображение в контексте сцены, и он разбивает код.Проблемы с рисованием изображений с использованием нескольких холстов

(Я попытался создания JSFiddle, но я не смог бы получить изображения там.)

UPDATE Половина моего вопроса была зафиксирована MARKE. Единственная проблема, которую я сейчас имею, это мои сущностиCtx - единственный контекст, который может рисовать изображения/прямоугольники. Другие ctx просто не могут ничего рисовать. Помоги пожалуйста! Я обновил код.

var stage = document.getElementById('stage'); 
var ctxStage = stage.getContext('2d'); 
var entitiesStage = document.getElementById('entities'); 
var ctxEntities = entitiesStage.getContext('2d'); 
var bg = document.getElementById('bg'); 
var ctxBg = bg.getContext('2d'); 
var playerImg = new Image(); 
playerImg.src = 'res/player_sprite_sheet.png'; 
var bgImg = new Image(); 
bgImg.onload = function() { 
    ctxBg.drawImage(bgImg,0,0,80,50,-200,-90,1000,700); 
}; 
bgImg.src = 'res/background.png'; 
var consoleImg = new Image(); 
consoleImg.onload = function() { 
    ctxEntities.drawImage(consoleImg,0,0,80,50,20,20,1000,700); 
}; 
console.src = 'res/console.png'; 

var hero = new Hero(); 
var prop; 

var isPlaying = false; 

window.onload = init; 
var requestAnimFrame = window.requestAnimationFrame || 
         window.webkitRequestAnimationFrame || 
         window.mozRequestAnimationFrame || 
         window.oRequestAnimationFrame || 
         window.msRequestAnimationFrame || 
         function(callback) { 
          window.setTimeout(callback, 1000/60); 
         }; 

function init() { 
    console.debug('initializing...'); 

    document.addEventListener('keydown',keyDown,false); 
    document.addEventListener('keyup',keyUp,false); 

    ctxStage.imageSmoothingEnabled = false; 
    ctxStage.webkitImageSmoothingEnabled = false; 
    ctxStage.mozImageSmoothingEnabled = false; 
    ctxEntities.imageSmoothingEnabled = false; 
    ctxEntities.webkitImageSmoothingEnabled = false; 
    ctxEntities.mozImageSmoothingEnabled = false; 

    prop = new Entity(consoleImg,20,20,80,50,0,0); 

    startLoop(); 
} 

function startLoop(){ 
    console.debug('starting loop...'); 
    isPlaying = true; 
    loop(); 
} 

function stopLoop(){ 
    console.debug('stopping loop...'); 
    isPlaying = false; 
} 

function loop(){ 
    if(isPlaying){ 
     requestAnimFrame(loop); 
     draw(); 
     update(); 
    } 
} 

function update(){ 
    hero.update(); 
} 

function clearCtx(){ 
    ctxEntities.clearRect(0,0,stage.width,stage.height); 
} 

function draw(){ 
    clearCtx(); 
    ctxEntities.fillStyle = 'black'; 
    ctxEntities.fillRect(0,0,stage.width,stage.height); 
    ctxEntities.drawImage(bgImg,0,0,80,50,-200,-90,1000,700); 
    hero.draw(); 
    prop.draw(); 
} 


// hero class 
function Hero() { 
    this.xpos = 140; 
    this.ypos = 320; 
    this.srcX = 0; 
    this.srcY = 0; 
    this.width = 10; 
    this.height = 20; 
    this.scaleX = 50; 
    this.scaleY = 80; 
    this.isUpKey; 
    this.isDownKey; 
    this.isLeftKey; 
    this.isRightKey; 
    this.img = playerImg; 

    this.speed = 2; 
    this.defspeed = 3.5; 
    this.dir = 'right'; 
} 

Hero.prototype.draw = function() { 
    ctxEntities.drawImage(this.img,this.srcX,this.srcY,this.width,this.height,this.xpos,this.ypos,this.scaleX,this.scaleY); 
}; 

Hero.prototype.update = function() { 
    this.checkKeys(); 

    if(this.dir == 'right'){ 
     if(this.scaleX >= 0){ 
      this.srcX = 0; 
     } 
     if(this.scaleX >= 40){ 
      this.scaleX = 40; 
      this.speed = this.defspeed; 
     }else{ 
      this.xpos -= 2.3; 
      this.speed = 0; 
      this.scaleX += 5; 
     } 
    }else if(this.dir =='left'){ 
     if(this.scaleX <= 0){ 
      this.srcX = 10; 
     } 
     if(this.scaleX <= -40){ 
      this.scaleX = -40; 
      this.speed = this.defspeed; 
     }else{ 
      this.xpos += 2.3; 
      this.speed = 0; 
      this.scaleX -= 5; 
     } 
    } 
}; 

Hero.prototype.checkKeys = function() { 
    if(this.isLeftKey){ 
     this.xpos += -this.speed; 
     this.dir = 'left'; 
    } 
    if(this.isRightKey){ 
     this.xpos += this.speed; 
     this.dir = 'right'; 
    } 
}; 
// end of hero class 


// entity class 
function Entity(img,xpos,ypos,width,height,scaleX,scaleY){ 
    this.img = img; 
    this.xpos = xpos; 
    this.ypos = ypos; 
    this.width = width; 
    this.height = height; 
    this.scaleX = scaleX; 
    this.scaleY = scaleY; 
} 

Entity.prototype.draw = function(){ 
    ctxEntities.drawImage(this.img,0,0,this.width,this.height,this.xpos,this.ypos,this.scaleX,this.scaleY); 
}; 
// end of entity class 


// input handling 
function keyDown(e){ 
    var keyID = (e.keyCode) ? e.keyCode : e.which; 

    if(keyID == 38 || keyID == 87){ //w 
     e.preventDefault(); 
     hero.isUpKey = true; 
    } 
    if(keyID == 37 || keyID == 65){ //a 
     e.preventDefault(); 
     hero.isLeftKey = true; 
    } 
    if(keyID == 40 || keyID == 83){ //s 
     e.preventDefault(); 
     hero.isDownKey = true; 
    } 
    if(keyID == 39 || keyID == 68){ //d 
     e.preventDefault(); 
     hero.isRightKey = true; 
    } 
} 

function keyUp(e){ 
    var keyID = (e.keyCode) ? e.keyCode : e.which; 

    if(keyID == 38 || keyID == 87){ 
     hero.isUpKey = false; 
    } 
    if(keyID == 37 || keyID == 65){ 
     hero.isLeftKey = false; 
    } 
    if(keyID == 40 || keyID == 83){ 
     hero.isDownKey = false; 
    } 
    if(keyID == 39 || keyID == 68){ 
     hero.isRightKey = false; 
    } 
} 
// end of input handling 

UPDATE Половина моего вопроса была зафиксирована MARKE. Единственная проблема, которую я сейчас имею, это мои сущностиCtx - единственный контекст, который может рисовать изображения/прямоугольники. Другие ctx просто не могут ничего рисовать. Я обновил код.

ответ

1

Использование JS «классы», чтобы привлечь на множественной канве

[я расширил свой ответ включать пример использования ваших JS классов]

Этого примера иллюстрирует ваши 2 JS-классы, которые привлекают изображения на полотна

  • сущностей класс управления и рисует изображение на холсте.
  • Герой класс элементы управления и рисунки спрайтов на холсте.

Существует также загрузчик изображений, чтобы все ваши изображения были полностью загружены до их использования.

В ваш вопрос вы включили только свой код js-класса и никаких особенностей в своем проекте.

Итак, я составил свой собственный проект, используя классы Hero и Entity (простите, что я свободен).

Это изображение показывает ваши Entity и герой классов в действии рисунок на всех 3 ваших полотнах ...

enter image description here

Это фон холст, содержащий:

  • Небо -blue rect заполнения холста (небо)
  • Фон содержит 2 объекта класса объектов.
  • солнечное, которое представляет собой изображение, обернутое в объекте класса Entity
  • Стен, которая представляет собой изображение, обернутое в объекте класса Entity

enter image description here

Это этап холст, содержащий:

  • Пушка, являющаяся объектом класса Entity, который анимируется вверх и вниз

enter image description here

Это является лицо холстом, содержащий:

  • Кошка изображения является spritesheet изображения, завернутое в классе гегося объекте
  • Объект кошки одушевляет спрайты в ответ на пушечный объект
  • Кошка состоит из спрайта, который контролируется классом героя

enter image description here

Элементы управления класса сущностей и рисует изображение на холсте:

  • Изображение можно перемещать и масштабировать.
  • Класс Entity имеет 3 метода.
  • Entity.draw() нарисует изображение на канистре.
  • Entity.set() установит положение XY изображения на холсте.
  • Entity.scale() масштабирует изображение.

Вот код класса Entity: контроль класса

// Entity class 
function Entity(context,img,x,y){ 
    this.context=context; 
    this.img = img; 
    this.xpos = x; 
    this.ypos = y; 
    this.width = img.width; 
    this.height = img.height; 
    this.scaleX = img.width; 
    this.scaleY = img.height; 
} 

// Entity.set() 
Entity.prototype.set = function(x,y){ 
    this.xpos=x; 
    this.ypos=y; 
} 

// Entity.scale() 
Entity.prototype.scale = function(scaleX,scaleY){ 
    this.scaleX=scaleX; 
    this.scaleY=scaleY; 
} 

// Entity.draw() 
Entity.prototype.draw = function(){ 
    this.context.drawImage(this.img, 
     0,0,this.width,this.height, 
     this.xpos,this.ypos,this.scaleX,this.scaleY); 
} 

героя и рисует spritesheets на холсте

  • Отдельные спрайты тянут из spritesheet изображения.
  • Каждый спрайт определяется объектом, имеющим его x, y, ширину и высоту в пределах спрайта.
  • Спринты можно перемещать и масштабировать.
  • Класс Hero имеет 3 метода.
  • Hero.draw() нарисовал один из спрайтов на холсте.
  • Hero.set() установит, какой спрайт нарисован, и его положение XY на холсте
  • Hero.scale() масштабирует спрайт.

Вот код для класса героя:

// Hero class 
function Hero(context,img,spriteDefs) { 
    this.context=context; 
    this.spriteDefs=spriteDefs; 
    this.img = img; 
    this.xpos = 0; 
    this.ypos = 0; 
    this.srcX = 0; 
    this.srcY = 0; 
    this.width = img.width; 
    this.height = img.height; 
    this.scaleX = img.width; 
    this.scaleY = img.height; 
    this.isUpKey; 
    this.isDownKey; 
    this.isLeftKey; 
    this.isRightKey; 

    this.speed = 2; 
    this.defspeed = 3.5; 
    this.dir = 'right'; 
} 

// Hero.set() 
Hero.prototype.set = function(spriteNumber,x,y){ 
    // pull the specified sprite 
    var sprite=this.spriteDefs[spriteNumber]; 
    this.srcX=sprite.x; 
    this.srcY=sprite.y; 
    this.width=sprite.width; 
    this.height=sprite.height; 
    // default scale to 100% 
    this.scaleX=sprite.width; 
    this.scaleY=sprite.height; 
    this.xpos=x; 
    this.ypos=y; 
} 

// Hero.scale() 
Hero.prototype.scale = function(scaleX,scaleY){ 
    this.scaleX=scaleX; 
    this.scaleY=scaleY; 
} 

// Hero.draw() 
Hero.prototype.draw = function() { 
    this.context.drawImage(this.img, 
     this.srcX,this.srcY,this.width,this.height, 
     this.xpos,this.ypos,this.scaleX,this.scaleY); 
} 

Это образ загрузчика, который гарантирует, что все изображения будут загружены, прежде чем они используются

var imageURLs=[]; 
var imagesOK=0; 
var imgs=[]; 
imageURLs.push("cats.png"); 
imageURLs.push("cannonLifted.png"); 
imageURLs.push("brickwall.jpg"); 
imageURLs.push("sun.png"); 
loadAllImages(); 

function loadAllImages(){ 
    for (var i = 0; i < imageURLs.length; i++) { 
     var img = new Image(); 
     imgs.push(img); 
     img.onload = function(){ imagesOK++; imagesAllLoaded(); }; 
     img.src = imageURLs[i]; 
    }  
} 

var imagesAllLoaded = function() { 
    if (imagesOK==imageURLs.length) { 
    // all images are fully loaded an ready to use 
    cat=imgs[0]; 
    cannon=imgs[1]; 
    wall=imgs[2]; 
    sun=imgs[3]; 
    start(); 
    } 
}; 

Вот полный код и сценарий: http://jsfiddle.net/m1erickson/yCW9U/

<!doctype html> 
<html> 
<head> 
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css --> 
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script> 

<style> 
    body{ background-color: ivory; padding:20px; } 
    h3{ font-size:2em; } 
    #wrapper{ 
     position:relative; 
     width:350px; 
     height:400px; 
    } 
    #bg,#stage,#entities{ 
     position:absolute; top:0px; left:0px; 
     border:1px solid green; 
     width:100%; 
     height:100%; 
    } 
</style> 

<script> 
$(function(){ 


    ////////////////////////////// 
    // get context references 
    ////////////////////////////// 


    // stage 
    var stage = document.getElementById('stage'); 
    var ctxStage = stage.getContext('2d'); 
    // entities 
    var entitiesStage = document.getElementById('entities'); 
    var ctxEntities = entitiesStage.getContext('2d'); 
    // background 
    var bg = document.getElementById('bg'); 
    var ctxBg = bg.getContext('2d'); 


    ////////////////////////////// 
    // public variables 
    ////////////////////////////// 


    // images 
    var wall,cat,cannon,sun; 

    // display objectx 
    var sunEntity,wallEntity,cannonEntity,catHero; 

    // animation vars 
    var cannonX=65; 
    var cannonMove=-10; 
    var cannonMin=75; 
    var cannonMax=185; 
    var cannonY=185; 
    var cannonSafe=145; 

    // cat hero sprites 
    var catSpriteNames={ 
     laying:0, 
     layingX:250, 
     layingY:127, 
     standing:1, 
     standingX:165, 
     standingY:25 
    }; 
    var catSprites=[ 
     {x:80, y:30, width:67, height:48}, 
     {x:15, y:8, width:47, height:78} 
    ]; 


    ////////////////////////////// 
    // preload all images 
    ////////////////////////////// 


    var imageURLs=[]; 
    var imagesOK=0; 
    var imgs=[]; 
    imageURLs.push("https://dl.dropboxusercontent.com/u/139992952/stackoverflow/cats.png"); 
    imageURLs.push("https://dl.dropboxusercontent.com/u/139992952/stackoverflow/cannonLifted.png"); 
    imageURLs.push("https://dl.dropboxusercontent.com/u/139992952/stackoverflow/BrickWall.jpg"); 
    imageURLs.push("https://dl.dropboxusercontent.com/u/139992952/stackoverflow/sun.png"); 
    loadAllImages(); 

    function loadAllImages(){ 
     for (var i = 0; i < imageURLs.length; i++) { 
      var img = new Image(); 
      imgs.push(img); 
      img.onload = function(){ imagesOK++; imagesAllLoaded(); }; 
      img.src = imageURLs[i]; 
     }  
    } 

    var imagesAllLoaded = function() { 
     if (imagesOK==imageURLs.length) { 
     // all images are fully loaded an ready to use 
     cat=imgs[0]; 
     cannon=imgs[1]; 
     wall=imgs[2]; 
     sun=imgs[3]; 
     start(); 
     } 
    }; 


    ////////////////////////////// 
    // build the display objects 
    // and start animation 
    ////////////////////////////// 


    function start(){ 

     // static background (canvas: bg) 
     // rectangle=blue sky 
     ctxBg.rect(0,0,bg.width,bg.height); 
     ctxBg.fillStyle="skyblue"; 
     ctxBg.fill(); 
     // sun image @ 75% scale 
     sunEntity=new Entity(ctxBg,sun,185,15); 
     sunEntity.set(25,15); 
     sunEntity.scale(sun.width*.75,sun.height*.75); 
     sunEntity.draw(); 
     // wall image 
     wallEntity=new Entity(ctxBg,wall,250,bg.height-wall.height); 
     wallEntity.set(250,bg.height-wall.height,wall.width,wall.height); 
     wallEntity.draw(); 


     // stage (canvas: stage) 
     // contents: wall 
     cannonEntity=new Entity(ctxStage,cannon,cannonX,cannonY,cannon.width,cannon.height,cannon.width,cannon.height); 
     cannonEntity.draw(); 


     // entities (canvas: entities) 
     // contents: 
     catHero=new Hero(ctxEntities,cat,catSprites); 
     catHero.set(catSpriteNames.laying,catSpriteNames.layingX,catSpriteNames.layingY); 
     catHero.draw(); 

     animate(); 
    } 

    function animate(){ 

     cannonY+=cannonMove; 
     if(cannonY<cannonMin){ cannonY=cannonMin; cannonMove=-cannonMove; } 
     if(cannonY>cannonMax){ cannonY=cannonMax; cannonMove=-cannonMove; } 

     cannonEntity.context.clearRect(0,0,stage.width,stage.height); 
     cannonEntity.set(cannonX,cannonY); 
     cannonEntity.draw(); 

     if(cannonY>cannonSafe){ 
      catHero.set(catSpriteNames.laying,catSpriteNames.layingX,catSpriteNames.layingY); 
     }else{ 
      catHero.set(catSpriteNames.standing,catSpriteNames.standingX,cannonY-50); 
     } 
     catHero.context.clearRect(0,0,entities.width,entities.height); 
     catHero.draw() 


     window.setTimeout(function(){animate();},500); 
    } 


    // Hero class 
    function Hero(context,img,spriteDefs) { 
     this.context=context; 
     this.spriteDefs=spriteDefs; 
     this.img = img; 
     this.xpos = 0; 
     this.ypos = 0; 
     this.srcX = 0; 
     this.srcY = 0; 
     this.width = img.width; 
     this.height = img.height; 
     this.scaleX = img.width; 
     this.scaleY = img.height; 
     this.isUpKey; 
     this.isDownKey; 
     this.isLeftKey; 
     this.isRightKey; 

     this.speed = 2; 
     this.defspeed = 3.5; 
     this.dir = 'right'; 
    } 
    // Hero.set() 
    Hero.prototype.set = function(spriteNumber,x,y){ 
     // pull the specified sprite 
     var sprite=this.spriteDefs[spriteNumber]; 
     this.srcX=sprite.x; 
     this.srcY=sprite.y; 
     this.width=sprite.width; 
     this.height=sprite.height; 
     // default scale to 100% 
     this.scaleX=sprite.width; 
     this.scaleY=sprite.height; 
     this.xpos=x; 
     this.ypos=y; 
    } 
    // Hero.scale() 
    Hero.prototype.scale = function(scaleX,scaleY){ 
     this.scaleX=scaleX; 
     this.scaleY=scaleY; 
    } 
    // Hero.draw() 
    Hero.prototype.draw = function() { 
     this.context.drawImage(this.img, 
      this.srcX,this.srcY,this.width,this.height, 
      this.xpos,this.ypos,this.scaleX,this.scaleY); 
    } 


    // Entity class 
    function Entity(context,img,x,y){ 
     this.context=context; 
     this.img = img; 
     this.xpos = x; 
     this.ypos = y; 
     this.width = img.width; 
     this.height = img.height; 
     this.scaleX = img.width; 
     this.scaleY = img.height; 
    } 
    // Entity.set() 
    Entity.prototype.set = function(x,y){ 
     this.xpos=x; 
     this.ypos=y; 
    } 
    // Entity.scale() 
    Entity.prototype.scale = function(scaleX,scaleY){ 
     this.scaleX=scaleX; 
     this.scaleY=scaleY; 
    } 
    // Entity.draw() 
    Entity.prototype.draw = function(){ 
     this.context.drawImage(this.img, 
      0,0,this.width,this.height, 
      this.xpos,this.ypos,this.scaleX,this.scaleY); 
    } 

}); // end $(function(){}); 
</script> 

</head> 

<body> 
    <h3>Watch out Kitty!</h3><br> 
    <div id="wrapper"> 
     <canvas id="bg" width=350 height=400></canvas> 
     <canvas id="stage" width=350 height=400></canvas> 
     <canvas id="entities" width=350 height=400></canvas> 
    </div> 
</body> 
</html> 
+0

Спасибо! Эта фиксированная половина проблемы. Остаются только проблемы, связанные с тем, что мой ctxStage по-прежнему не рисует изображение, а моя поддержка (класса сущности) по-прежнему не рисует. Html/css не содержат ошибок. –

+0

Я добавил к своему ответу для объяснения ваших изображений. Вы должны указать время загрузки изображений, прежде чем пытаться рисовать их. Для этого вы можете использовать image.onload. – markE

+0

Я почти понял! Это только рисование на секунду. Он отлично работает, когда я рисую его с помощью ctxEntities; Однако ctxStage не может нарисовать изображение или прямоугольник. –