Add cardFace/Sprite + print card front/back images

Added ECS elements for cardFace and cardSprite
Added spritesheet print into a clipping mask for cards
Added spritesheet print for cardBacks
Added a 'flip' function
develop
Nathan Steel 1 year ago
parent 0b0ce7ea5c
commit 2a3250d932

@ -5,8 +5,8 @@ const canvasTop = canvas.offsetTop + canvas.clientTop;
const cardWidth = 80; const cardWidth = 80;
const cardHeight = 120; const cardHeight = 120;
const cards = new Image(); const cardArt = new Image();
const back = new Image(); const cardBackArt = new Image();
// Counters to keep track of players, and boardElements, may be changed in future // Counters to keep track of players, and boardElements, may be changed in future
// But once game starts, will be const anyway, so shouldn't need passing // But once game starts, will be const anyway, so shouldn't need passing
@ -26,6 +26,8 @@ let size = {};
let cardStatus = {}; // tapped, attacking, inspected, untargettable (TODO:maybe used this instead of inEvent later) let cardStatus = {}; // tapped, attacking, inspected, untargettable (TODO:maybe used this instead of inEvent later)
let player = {}; let player = {};
let listPosition = {}; let listPosition = {};
let cardFace = {};
let cardSprite = {};
let inEvent = null; let inEvent = null;
// To disable drawing each time something changes // To disable drawing each time something changes
@ -43,8 +45,8 @@ class Board{
console.log('initBoard'); console.log('initBoard');
ctx.font = "12px Arial"; ctx.font = "12px Arial";
canvas.style.backgroundColor = 'rgb(143 153 150)'; canvas.style.backgroundColor = 'rgb(143 153 150)';
cards.src = 'images/deck.svg'; cardArt.src = 'images/cardArt.jpg';
back.src = 'images/uno.svg'; cardBackArt.src = 'images/cardBack.jpg';
ctx.fillStyle = '#000'; ctx.fillStyle = '#000';
} }
@ -164,10 +166,16 @@ class Board{
}); });
shape.draw(); shape.draw();
if(boardElement[itemKey] != 'realDeck'){ // TODO: isset, or differ between types // Draw the card face-up
this.printCardImage(itemKey); if(this.isFaceUp(itemKey)){
this.addCardImage(itemKey);
this.printCardDetails(itemKey); this.printCardDetails(itemKey);
}else{ }
if(!this.isFaceUp(itemKey)){
this.addCardBack(itemKey);
}
// If it's the deck, draw the circle surrounding it
if(boardElement[itemKey] == 'realDeck'){
// TODO: For realDeck only atm, also janked in. Seperate this... // TODO: For realDeck only atm, also janked in. Seperate this...
let counterx= positionX; let counterx= positionX;
let countery= positionY; let countery= positionY;
@ -194,33 +202,75 @@ class Board{
ctx.fillStyle = '#000'; ctx.fillStyle = '#000';
ctx.fillText(deckLength, textx, texty); ctx.fillText(deckLength, textx, texty);
} }
}
isFaceUp(itemKey){
if(cardFace[itemKey] == 1){
return true;
}
return false;
}
flipCard(itemKey){
if(cardFace[itemKey] == 1){
cardFace[itemKey] = 0;
}else{
cardFace[itemKey] = 1;
}
// TODO:Activate any flip effects, etc.
} }
printCardImage(itemKey){ printCardImage(itemKey){
let name = itemKey; // Not needed really anymore, but keeping for now
let positionX = position[itemKey][0]; let positionX = position[itemKey][0];
let positionY = position[itemKey][1]; let positionY = position[itemKey][1];
let width = size[itemKey][0]; let width = size[itemKey][0];
let height = size[itemKey][1]; let height = size[itemKey][1];
let fill = '#BBB'; // Draw the image into the clipping mask
let shape = 'semi'; // Will be decided based on cardData.something? (for unit, spell, etc) // image, dx,dy,dw,dh
// image, sx,sy, sw,sh,dx,dy,dw,dh
let spriteSheetX = 80*cardSprite[itemKey][0];
let spriteSheetY = 120*cardSprite[itemKey][1];
ctx.drawImage(cardArt, spriteSheetX,spriteSheetY, 80,120,positionX,positionY,width,height);
}
addCardImage(itemKey){
let positionX = position[itemKey][0];
let positionY = position[itemKey][1];
let width = size[itemKey][0];
let height = size[itemKey][1];
// Add 'image' shape, will need to blitz sprite here in the future (based on cardData.id) // Create the clipping shape
let cardImageContainer = new Shape({ let cardImageContainer = new Shape({
shape: 'semi', shape: 'unit',
name: 'cardImageContainer_'+name, name: 'cardImageContainer_'+name,
x: positionX+height/3, x: positionX+height/3,
y: positionY+width/2, y: positionY+width/2,
width: width*.9, width: width*.9,
height: height*.9, height: height*.9
fillStyle: fill
}); });
cardImageContainer.draw(); // Save canvas drawing, start the clip
cardImageContainer.startClip();
// Draw the actual image too // Print the image to canvas, within the clipping mask
this.printCardImage(itemKey);
// Restore the canvas draw post clip applied, to get everything else back too
cardImageContainer.endClip();
}
addCardBack(itemKey){
let positionX = position[itemKey][0];
let positionY = position[itemKey][1];
let width = size[itemKey][0];
let height = size[itemKey][1];
// Print the sleeve image to cardPosition
this.printCardBack(itemKey);
}
printCardBack(itemKey){
let positionX = position[itemKey][0];
let positionY = position[itemKey][1];
let width = size[itemKey][0];
let height = size[itemKey][1];
// TODO: CardBack/Sleeves as spritesheet like cardArt
ctx.drawImage(cardBackArt, 0,0, 80,120,positionX,positionY,width,height);
} }
printCardDetails(itemKey){ printCardDetails(itemKey){
let name = itemKey; // Not needed really anymore, but keeping for now let name = itemKey; // Not needed really anymore, but keeping for now
@ -425,8 +475,10 @@ class Board{
alert('Hand full '+elementLength+'/'+maxHandSize); alert('Hand full '+elementLength+'/'+maxHandSize);
return false; return false;
} }
let card = this.getItemKey('deck', 1, playerId);
// Move from players deck to hand, from position 1 (bottom deck) // Move from players deck to hand, from position 1 (bottom deck)
this.addFromBoardElement(playerId, 1, 'deck', 'hand', null, null); this.addFromBoardElement(playerId, 1, 'deck', 'hand', null, null);
this.flipCard(card);
} }
} }
@ -759,7 +811,11 @@ for(let currentPlayer = 0; currentPlayer <= players-1; currentPlayer++){
} }
// Draw the graphics of the board/game // Draw the graphics of the board/game
// Wait for the cardArt to load on first load
// Otherwise it'll be boxes, and art will flash in on first click event triggered
cardArt.onload = function(){
board.drawBoard(true); board.drawBoard(true);
};
// Right Click, Rightclick, rightclick, right click // Right Click, Rightclick, rightclick, right click
@ -961,6 +1017,7 @@ function createDecks(){
// In future want to remove, and add isset checks for non-used data // In future want to remove, and add isset checks for non-used data
cardStatus[itemCount] = null; cardStatus[itemCount] = null;
listPosition[itemCount] = null; listPosition[itemCount] = null;
cardFace[itemCount] = 0; // Deck is facedown, as there's no cardArt
itemCount++; itemCount++;
} }
@ -994,6 +1051,26 @@ function createDeckList(playerId){
player[itemCount] = playerId; player[itemCount] = playerId;
// Set the position in the deck (as was added), will be shuffled on game start // Set the position in the deck (as was added), will be shuffled on game start
listPosition[itemCount] = deckItem+1; listPosition[itemCount] = deckItem+1;
cardFace[itemCount] = 0; // Start with all cards face down
cardSprite[itemCount] = [0,0];
// Temp sprite set based on colour TODO: Change to set correct sprite from DB
console.log(cardData[itemCount].colour);
switch (cardData[itemCount].colour){
case 0: // White
cardSprite[itemCount] = [0,0];
break;
case 1: // Blue
cardSprite[itemCount] = [0,1];
break;
case 2: // Red
cardSprite[itemCount] = [1,0];
break;
case 3: // Green
cardSprite[itemCount] = [1,1];
break;
default:
break;
}
// Increment the itemCount to prevent overwriting stuff // Increment the itemCount to prevent overwriting stuff
itemCount++; itemCount++;
@ -1220,13 +1297,15 @@ function printECSData(items){
for(let item = 0; item < items.length; item++){ for(let item = 0; item < items.length; item++){
let itemKey = items[item]; let itemKey = items[item];
console.log( console.log(
'itemId: '+itemKey+"\n"+
'boardElement: '+boardElement[itemKey]+"\n"+ 'boardElement: '+boardElement[itemKey]+"\n"+
'cardData: '+cardData[itemKey]+"\n"+ 'cardData: '+cardData[itemKey]+"\n"+
'position: '+position[itemKey]+"\n"+ 'position: '+position[itemKey]+"\n"+
'size: '+size[itemKey]+"\n"+ 'size: '+size[itemKey]+"\n"+
'cardStatus: '+cardStatus[itemKey]+"\n"+ 'cardStatus: '+cardStatus[itemKey]+"\n"+
'player: '+player[itemKey]+"\n"+ 'player: '+player[itemKey]+"\n"+
'listPosition: '+listPosition[itemKey] 'listPosition: '+listPosition[itemKey]+"\n"+
'cardFace: '+cardFace[itemKey]
); );
} }
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

@ -64,8 +64,67 @@ class Shape extends Path2D{
}else if (this.shape == 'rectangle'){ }else if (this.shape == 'rectangle'){
context.strokeRect(this.x, this.y, this.width, this.height); context.strokeRect(this.x, this.y, this.width, this.height);
} }
else if (this.shape == 'unit'){
context.beginPath();
context.arc(this.x, this.y, this.width/2, Math.PI, 0);
// Start at bottom left of the semi
context.moveTo(this.x-this.width/2, this.y);
// Draw accross to bottom right of semi
context.lineTo(this.x+this.width/2, this.y);
// Draw down to the desired height
context.lineTo(this.x+this.width/2, this.y+this.height/3);
// Draw accross to that height, but aligned to left of semi
context.lineTo(this.x-this.width/2, this.y+this.height/3);
context.stroke();
context.closePath();
}
context.strokeStyle = defaultFillStyle; context.strokeStyle = defaultFillStyle;
} }
} }
startClip(shape = null){
// https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/clip#creating_a_complex_clipping_region
if(this.shape == 'circle'){
// X,Y,Radius, start, end
context.beginPath();
context.arc(this.x, this.y, this.width/2, 0, 2 * Math.PI);
context.fill();
context.closePath();
}else if(this.shape == 'semi'){
context.beginPath();
context.arc(this.x, this.y, this.width/2, Math.PI, 0);
context.fill();
context.closePath();
}else if (this.shape == 'rectangle'){
context.fillRect(this.x, this.y, this.width, this.height);
}
// This is one of the shapes for the card images to sit it
// TODO: Will be: unit,token,spell, etc. ALSO will have each shape for UI elements too
else if (this.shape == 'unit'){
context.beginPath();
context.arc(this.x, this.y, this.width/2, Math.PI, 0);
// Start at bottom left of the semi
context.moveTo(this.x-this.width/2, this.y);
// Draw accross to bottom right of semi
context.lineTo(this.x+this.width/2, this.y);
// Draw down to the desired height
context.lineTo(this.x+this.width/2, this.y+this.height/3);
// Draw accross to that height, but aligned to left of semi
context.lineTo(this.x-this.width/2, this.y+this.height/3);
context.fill();
context.closePath();
}
ctx.save(); // Save the canvas draw before the clip is applied
context.clip();
}
endClip(){
ctx.restore(); // Restore the canvas draw post clip applied, to get everything else back too
}
} }

Loading…
Cancel
Save