绘图工作正常,直到我决定使用多个画布。我有一个舞台画布,一个实体画布和一个对象画布。不过,我可能最终会将对象和实体画布结合起来。无论如何,正如你在下面看到的,我的英雄级别很好。然后我尝试使用相同的绘制函数创建一个实体类,但是当我调用该函数时它不会让我绘制。我的背景画布几乎有同样的问题。我还没有课程,但我会。但我尝试用舞台的上下文简单地绘制图像,它会破坏代码。
(我尝试设置一个JSFiddle,但我无法在那里获取图像。)
更新 我的问题的一半是由markE修复的。我目前唯一的问题是,我的entitiesCtx是唯一可以绘制图像/矩形的上下文。其他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
更新 我的问题的一半是由markE修复的。我目前唯一的问题是,我的entitiesCtx是唯一可以绘制图像/矩形的上下文。其他ctx只是无法绘制任何东西。我更新了代码。
答案 0 :(得分:1)
使用JS“类”在多个画布上绘制
[我扩展了我的答案,包括使用你的JS类的例子]
此示例说明了在画布上绘制图像的2个js类
还有一个图像加载器,以便在使用之前将所有图像完全加载。
在你的问题中,你只包括你的js级代码,没有关于你的项目的细节。
所以我使用你的Hero和Entity课程组建了我自己的项目(原谅我的自由)。
此图片显示了您所有3幅画布上的实体和英雄类动作......
这是包含以下内容的背景画布:
这是包含以下内容的舞台画布:
这是包含以下内容的实体画布:
Entity类控制并在画布上绘制图像:
以下是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);
}
Hero类在画布上控制和绘制spritesheets
以下是Hero类的代码:
// 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>