const ctx = canvas.getContext('2d'); const canvasLeft = canvas.offsetLeft + canvas.clientLeft; const canvasTop = canvas.offsetTop + canvas.clientTop; const cardWidth = 240; const cardHeight = 360; const cards = new Image(); const back = new Image(); let clickableItems = []; // Make all clickableItems sit in the same clickableItems array // Not needed in a child, as loops will be on arrays below clickableItems['board'] = []; clickableItems['hand'] = []; clickableItems['opponentHand'] = []; // TODO: Uniform the arrays to player and opponent/different playesr let playerHand = []; let opponentHand = []; let playerBoard = []; let opponentBoard = []; let playerDeck = []; let opponentDeck = []; let deckCount = 60; let deckCountOpponent = 60; let cardsInOpponentsHand = 0; const maxHandSize = 4; const maxBoardSize = 3; // Gonna need lots of refactoring, and sorting class Board{ constructor(){ console.log('initBoard'); ctx.font = "12px Arial"; canvas.style.backgroundColor = 'rgb(143 153 150)'; cards.src = 'images/deck.svg'; back.src = 'images/uno.svg'; ctx.fillStyle = '#000'; } drawBoard(){ // Reset board ctx.clearRect(0, 0, canvas.width, canvas.height); // Room Name ctx.fillText(name, 0, 10); this.drawCardsOnBoard(); this.drawCardsOnBoardOpponent(); this.drawDeck(); this.drawDeckOpponent(); this.drawHand(); this.drawOpponentHand(); this.drawPlayerNames('Nathan', 'Evil Nathan'); } drawPlayerNames(playerName, opponentName = false){ // Player Name ctx.fillText(playerName, 50, canvas.height - 110); // Opponent's Name if(!opponentName){ // Just clear the name }else{ ctx.fillText(opponentName, canvas.width - (ctx.measureText(opponentName).width + 50), 110); } } // Draw Invidual Cards, called by other deck stuff // Might be put into a card class, makes sense, eh. drawCard(array, arrayKey, name, positionX, positionY, width, height, fill){ var cardClickable = new Shape({ name: name, x: positionX, y: positionY, width: width, height: height, fillStyle: fill }); array[arrayKey]['clickable'] = cardClickable; array[arrayKey]['clickable'].draw(); // Add card text ctx.fillStyle = '#000'; ctx.fillText( array[arrayKey]['name'] , positionX + (ctx.measureText(array[arrayKey]['name']/2).width) , positionY+20 ); } drawDeck(){ // Deck clickableItems['deckSprite'] = new Shape({ name: 'deck', x: canvas.width-cardWidth/2-40, y: canvas.height-cardHeight/2-60, width: cardWidth/2, height: cardHeight/2, fillStyle: "#0000FF" }); //ctx.fillRect(canvas.width-cardWidth/2-60, canvas.height/2-cardHeight/4, cardWidth/2, cardHeight/2); clickableItems['deckSprite'].draw(); let deckCounterSprite = new Shape({ shape: 'circle', name: 'deckCounter', x: canvas.width-cardWidth/5, y: canvas.height-cardHeight/5, width: cardWidth/8, height: cardHeight/8, fillStyle: "#FFF" }); deckCounterSprite.draw(); // TODO: Center in the circle ctx.fillStyle = '#000'; ctx.fillText(playerDeck.length, canvas.width-cardWidth/5 - (ctx.measureText(playerDeck.length).width) + 7, canvas.height-cardHeight/5 + 5); } drawDeckOpponent(){ // Opponent's Deck clickableItems['deckOpponentSprite'] = new Shape({ name: 'deckOpponent', x: 40, y: 60, width: cardWidth/2, height: cardHeight/2, fillStyle: "#FF0000" }); clickableItems['deckOpponentSprite'].draw(); let deckCounterOpponentSprite = new Shape({ shape: 'circle', name: 'deckCounterOpponent', x: cardWidth/2+(cardWidth/8), y: cardHeight/2+(cardHeight/8), width: cardWidth/8, height: cardHeight/8, fillStyle: "#FFF" }); deckCounterOpponentSprite.draw(); ctx.fillStyle = '#000'; // TODO: Center in the circle ctx.fillText(opponentDeck.length, cardWidth/2 + (ctx.measureText(opponentDeck.length).width) + 10, cardHeight/1.58); } // Naming's getting awkward here... // Draw the cards in hand drawHand(){ // Player Hand/Cards in Hand for (let i = 0; i < playerHand.length; i++) { let name = 'cardInHand_'+(i+1); let cardPadding = 10; let fill = '#'+i+i+'FF00'; // TODO: fix positionX, actually have some maffs let positionX = canvas.width/2 - ((cardWidth/4 * 2) * (playerHand.length - (i+1)) - (cardPadding * (i+1))); let positionY = canvas.height - cardHeight/2-20; let width = cardWidth/2; let height = cardHeight/2; this.drawCard(playerHand, i, name, positionX, positionY, width, height, fill); } } drawOpponentHand(){ // Opponents Hand/Cards in Hand for (let i = 0; i < opponentHand.length; i++) { let name = 'cardInOpponentsHand_'+(i+1); let cardPadding = 10; let fill = '#'+i+i+'DD00'; // TODO: fix positionX, actually have some maffs let positionX = canvas.width/2 - ((cardWidth/4 * 2) * (opponentHand.length - (i+1)) - (cardPadding * (i+1))); let positionY = 20; let width = cardWidth/2; let height = cardHeight/2; this.drawCard(opponentHand, i, name, positionX, positionY, width, height, fill); } } drawCards(){} // Draw a card, traditional TCG drawACard(){ if(playerHand.length >= maxHandSize){ alert('Hand full '+playerHand.length+'/'+maxHandSize); return 0; } // Random card from deck, remove from deck, add to hand let cardToDraw = Math.floor(Math.random() * deckCount); let cardDrawn = playerDeck[cardToDraw]; // Remove from deck playerDeck.splice(cardToDraw, 1); // Add to hand playerHand.push(cardDrawn); this.drawBoard(); } drawACardOpponent(){ if(opponentHand.length >= maxHandSize){ alert('Hand full '+opponentHand.length+'/'+maxHandSize); return 0; } // Random card from deck, remove from deck, add to hand let cardToDraw = Math.floor(Math.random() * deckCountOpponent); let cardDrawn = opponentDeck[cardToDraw]; // Remove from deck opponentDeck.splice(cardToDraw, 1); // Add to hand opponentHand.push(cardDrawn); this.drawBoard(); } drawCardsOnBoard(){ // DUPE OF DRAW PLAYER HAND FOR NOW!!! for (let i = 0; i < playerBoard.length; i++) { let name = 'cardOnBoard_'+(i+1); let cardPadding = 10; let fill = '#'+i+i+'CC00'; // TODO: fix positionX, actually have some maffs let positionX = canvas.width/2 - ((cardWidth/4 * 2) * (playerBoard.length - (i+1)) - (cardPadding * (i+1))); let positionY = canvas.height - cardHeight/2-20-(cardHeight/2); let width = cardWidth/2; let height = cardHeight/2; this.drawCard(playerBoard, i, name, positionX, positionY, width, height, fill); } } drawCardsOnBoardOpponent(){ for (let i = 0; i < opponentBoard.length; i++) { let name = 'cardOnBoardOpponent_'+(i+1); let cardPadding = 10; let fill = '#'+i+i+'AA00'; // TODO: fix positionX, actually have some maffs let positionX = canvas.width/2 - ((cardWidth/4 * 2) * (opponentBoard.length - (i+1)) - (cardPadding * (i+1))); let positionY = cardHeight/2; let width = cardWidth/2; let height = cardHeight/2; this.drawCard(opponentBoard, i, name, positionX, positionY, width, height, fill); } } // Currently only functionality in hand playCardToBoard(index){ // Get the card data let cardPlayed = playerHand[index]; // Check if there's space on board to play // TODO: Check this in back-end if(playerBoard.length >= maxBoardSize){ alert('No space on board to play card. '+playerBoard.length+'/'+maxBoardSize); return 0; } // Remove from hand playerHand.splice(index, 1); // Add to board playerBoard.push(cardPlayed); this.drawBoard(); } playCardToBoardFromDeckOpponent(){ // Random card from deck let cardToDraw = Math.floor(Math.random() * deckCount); let cardPlayed = opponentDeck[cardToDraw]; if(opponentBoard.length >= maxBoardSize){ alert('No space on board to play card. '+opponentBoard.length+'/'+maxBoardSize); return 0; } // Remove from deck opponentDeck.splice(cardToDraw, 1); // Add to board opponentBoard.push(cardPlayed); this.drawBoard(); } } // TEMP!! createDeckList(playerDeck, deckCount); createDeckList(opponentDeck, deckCountOpponent); // Run board commands here for testing let board = new Board; //board.initBoard(); // TEMP: Play a card on opponents board (from their deck) board.playCardToBoardFromDeckOpponent(); board.drawBoard(); canvas.addEventListener('click', function(event) { var x = event.pageX - canvasLeft, y = event.pageY - canvasTop; // Collision detection between clicked offset and clickableItems // https://stackoverflow.com/a/9880302 // # PLAYER DECK clickable = clickableItems['deckSprite']; // Want to loop clickables ideally, and call a function // that's set to them for click, hover, etc. // TODO: potentially loop all clickables, and do a check on clickable.name to differ event handling per-item // For now this will be fine, as it functions if(clickableCheck(x,y,clickable)){ board.drawACard(); } // # OPPONENT DECK clickable = clickableItems['deckOpponentSprite']; if(clickableCheck(x,y,clickable)){ board.drawACardOpponent(); } // # PLAYER HAND playerHand.forEach(function(card, index){ let clickable = card.clickable; if(clickableCheck(x,y,clickable)){ board.playCardToBoard(index); // This would actually fire off a socketIO doodad, that would then return // data, and redraw. But for now (UI test) // Add to board board.drawBoard(); } }); }, false); function clickableCheck(x,y,clickable){ // Debug Stuff let debug = false if(debug){ console.log(clickable.y+' <'); console.log(y+ '<') console.log(clickable.y+clickable.height); } if( y > clickable.y && y < clickable.y + clickable.height && x > clickable.x && x < clickable.x + clickable.width) { return true; } return false; } // TEMP: Create a deck of X different cards that can be drawn/played // for UI development, will be done on server and not shown to clients function createDeckList(deck, deckCount){ for(let i = 0; i < deckCount; i++){ deck.push({'name':'CardName '+(i+1), 'cost':1, 'atk':1, 'def':1, 'rarity': 'common', 'effect':null, 'type':'human'}); } }