使用 PreloadJS 加载图像并将它们添加到 CreateJS 阶段
Posted
技术标签:
【中文标题】使用 PreloadJS 加载图像并将它们添加到 CreateJS 阶段【英文标题】:Using PreloadJS to load images and adding them to CreateJS stage 【发布时间】:2015-12-25 02:09:47 【问题描述】:我正在尝试用 javascript 创建一个 Tri Peaks Solitaire 游戏,使用 CreateJS 来帮助与 html 画布进行交互。我对编程并不完全陌生,因为我参加过 Java 和 C 的大学课程,但我对 Javascript 和 HTML 都很陌生。
我使用 Card 类和 Deck 类创建了大量的纸牌游戏,在一个 Javascript 文件中完成了图像添加、事件监听和游戏逻辑,但这导致了很多混乱、有点错误的代码我觉得需要清理。
我正在尝试为卡片表实现一个单独的类,它将是画布或舞台,它将绘制 4 行可玩卡片、库存堆和废物堆。我目前只是想让库存堆出现在画布上,但它没有发生。
我的问题是,为什么我的库存没有出现?此外,如您所见,创建卡片时正在加载卡片图像。我应该采取不同的做法吗?
卡类:
var Card = function(number)
this.isFaceUp = false;
//number for image file path
this.number = number;
this.value = Math.ceil( (this.number)/4 );
//back of the card is default image
this.initialize("images/" + 0 + ".png");
console.log("card created")
this.height = this.getBounds().height;
this.width = this.getBounds().width;
//load the card's front image
this.frontImage = new Image();
this.frontImage.src = ( this.getImagePath() );
;
Card.prototype = new createjs.Bitmap("images/" + this.number + ".png");
Card.prototype.getImagePath = function()
return "images/" + this.number + ".png";
;
Card.prototype.getValue = function ()
return this.value;
Card.prototype.flip = function()
// this.image = new Image();
// this.image.src = ( this.getImagePath() );
this.image = this.frontImage;
this.isFaceUp = true;
;
Card.prototype.getHeight = function()
return this.height;
;
Card.prototype.getWidth = function()
return this.width;
;
CardDeck 类:
function CardDeck()
//create empty array
this.deck = [];
//fill empty array
for(i=1; i<=52; i++)
//fill deck with cards, with i being the number of the card
this.deck[i-1] = new Card(i);
//shuffle deck
this.shuffle();
CardDeck.prototype.getCard = function()
if(this.deck.length < 1) alert("No cards in the deck");
return this.deck.pop();
;
CardDeck.prototype.getSize = function()
return this.deck.length;
;
CardDeck.prototype.shuffle = function()
for (i=0; i<this.deck.length; i++)
var randomIndex = Math.floor( Math.random()*this.deck.length );
var temp = this.deck[i];
this.deck[i] = this.deck[randomIndex];
this.deck[randomIndex] = temp;
;
CardDeck.prototype.getRemainingCards = function()
return this.deck.splice(0);
CardDeck.prototype.listCards = function()
for(i=0; i<this.deck.length; i++)
console.log(this.deck[i].number);
;
CardTable 类:
var CardTable = function(canvas)
this.initialize(canvas);
this.firstRow = [];
this.secondRow = [];
this.thirdRow = [];
this.fourthRow = [];
this.stockPile = [];
this.wastePile = [];
//startX is card width
this.startX = ( new Card(0) ).width*3;
//startY is half the card height
this.startY = ( new Card(0) ).height/2;
;
CardTable.prototype = new createjs.Stage();
CardTable.prototype.createStockPile = function(cards)
for(i=0; i<23; i++)
cards[i].x = 10;
cards[i].y = 50;
this.stockPile[i] = cards[i];
;
CardTable.prototype.addToWastePile = function(card)
card.x = startX + card.width;
card.y = startY;
this.wastePile.push(card);
this.addChild(card);
this.update();
;
CardTable.prototype.drawStockPile = function()
for(i=0; i<this.stockPile.length; i++)
console.log("this.stockPile[i]");
this.addChild(this.stockPile[i]);
this.update();
;
HTML 文件:
<html>
<head>
<title>Tri-Peaks Solitaire</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://code.createjs.com/easeljs-0.8.1.min.js"></script>
<script src="card.js"></script>
<script src="carddeck.js"></script>
<script src="cardtable.js"></script>
<script>
function init()
var canvas = document.getElementById("canvas");
var table = new CardTable("canvas");
deck = new CardDeck();
table.createStockPile(deck.getRemainingCards());
table.drawStockPile();
table.update();
</script>
</head>
<body onload="init()">
<h1>Tri-Peaks Solitaire</h1>
<canvas style='border: 5px solid green; background: url("images/background.jpg");'
id="canvas" >
</canvas>
</body>
</html>
PRELOADJS 更新:
var canvas = document.getElementById("canvas");
var stage = new createjs.Stage(canvas);
var gameDeck = new CardDeck();
var numbers = [];
var preloader;
var progressText = new createjs.Text("", "20px Arial","#FF0000");
progressText.x = 50;
progressText.y = 20;
stage.addChild(progressText);
stage.update();
setupManifest();
startPreload();
function setupManifest()
for(i=0; i<=52; i++)
console.log("manifest");
manifest.push( src:"images/" + i + ".png",
id: i );
numbers.push(i);
function startPreload()
preload = new createjs.LoadQueue(true);
preload.on("fileload", handleFileLoad);
preload.on("progress", handleFileProgress);
preload.on("complete", loadComplete);
preload.on("error", loadError);
preload.loadManifest(manifest);
function handleFileLoad(event)
console.log("A file has loaded of type: " + event.item.type);
//console.log(numbers.pop());
var cardNumber = numbers.pop();
var newCard = new Card(cardNumber);
//faces.push( new Image() );
//faces[ faces.length - 1 ].src = "images/" + cardNumber + ".png";
gameDeck.insertCard(newCard);
function loadError(evt)
console.log("error",evt.text);
function handleFileProgress(event)
progressText.text = (preload.progress*100|0) + " % Loaded";
stage.update();
function loadComplete(event)
console.log("Finished Loading Assets");
【问题讨论】:
【参考方案1】:您只是在创建卡片后立即更新关卡。卡片正在加载位图图像,这是一个需要时间的并发操作。因此,您渲染舞台的唯一时间是在图像加载之前。
我建议使用 PreloadJS 来预加载您的卡片图像。这也将让您更好地控制它们何时/如何加载,并让您在加载时向用户显示进度条或干扰项。
【讨论】:
感谢您的建议。我会试一试。 我试用了 PreloadJS,但遇到了类似的问题。除了背景图像之外,画布上没有显示任何内容。我目前只是尝试显示带有加载进度更新的文本,但没有显示任何内容。 你确定更新舞台了吗?除非您致电stage.update()
,否则舞台不会重绘
我在原始帖子的底部发布了新代码。添加进度文本子项后,我正在更新阶段。
insertCard
是做什么的?最好的方法是在加载卡片后创建您的套牌,或者至少在此时更新阶段。如果您仅在最初创建进度文本时进行更新,则不会显示任何内容。【参考方案2】:
我建议等待所有图像加载完毕,然后调用 stage.update()。或者使用createjs.Ticker.addEventListener("tick", handleTick);
事件处理程序为您更新舞台。
参考:http://www.createjs.com/docs/easeljs/classes/Ticker.html
【讨论】:
以上是关于使用 PreloadJS 加载图像并将它们添加到 CreateJS 阶段的主要内容,如果未能解决你的问题,请参考以下文章
PreloadJS getResult(spriteSheet)
HTML5 new Image() 图像需要加载后才能drawImage? 怎样保证多个Image对象都加载完成?