diff --git a/public/board.js b/public/board.js new file mode 100644 index 0000000..dc20c75 --- /dev/null +++ b/public/board.js @@ -0,0 +1,857 @@ +const ctx = canvas.getContext('2d'); +const canvasLeft = canvas.offsetLeft + canvas.clientLeft; +const canvasTop = canvas.offsetTop + canvas.clientTop; + +const cardWidth = 80; +const cardHeight = 120; + +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 playerShield = []; +let opponentShield = []; +let playerMana = []; +let opponentManaZone = []; + +let deckCount = 60; +let deckCountOpponent = 60; + +let cardsInOpponentsHand = 0; +const maxHandSize = 4; +const maxBoardSize = 3; +const maxShield = 4; + +let inspectCard = null; +let attackingCard = null; +let gameWin = 0; + +// 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.drawShield(); + this.drawShieldOpponent(); + + this.drawHand(); + this.drawOpponentHand(); + + this.drawMana(); + + this.drawPlayerNames('Nathan', 'Evil Nathan'); + + if(gameWin){ + this.drawWin(); + } + + this.drawInspectedCard(); + } + + drawWin(){ + var winBoard = new Shape({ + name: name, + x: 0, + y: canvas.height/2 - (canvas.height/4)/2, + width: canvas.width, + height: canvas.height/4, + fillStyle: '#CCC', + strokeStyle: '#00EEAA' + }); + winBoard.draw(); + + ctx.fillStyle = '#000'; + ctx.font = "bold 50pt Arial"; + ctx.fillText('WINNER', 200, 300); + ctx.font = "10pt Arial"; + } + + drawPlayerNames(playerName, opponentName = false){ + // Player Name + ctx.fillText(playerName, 50, canvas.height - 50); + + // Opponent's Name + if(!opponentName){ + // Just clear the name + }else{ + ctx.fillText(opponentName, canvas.width - (ctx.measureText(opponentName).width + 50), 50); + } + } + + // 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, border){ + // Card Colour + //console.log('drawCard card: '+JSON.stringify(array[arrayKey])); + let colourId = array[arrayKey].colour; + if(colourId == 0){ fill = '#EEE' } + else if(colourId == 1){ fill = '#0033EE' } + + if(array[arrayKey].tapped){ + border = '#E0BC00'; + console.log('drawCard tapped'); + } + + var cardClickable = new Shape({ + name: name, + x: positionX, + y: positionY, + width: width, + height: height, + fillStyle: fill, + strokeStyle: border + }); + + array[arrayKey]['clickable'] = cardClickable; + array[arrayKey]['clickable'].draw(); + + // Add image + // half circle for unit Set start angle to 0 and end angle to Math.PI. + // Ellipse for token (near full size) + // Octagon for spell + let cardImageContainer = new Shape({ + shape: 'semi', + name: 'cardImageContainer_'+name, + x: positionX+height/3, + y: positionY+width/2, + width: width*.9, + height: height*.9, + fillStyle: "#BBB" + }); + cardImageContainer.draw(); + + // Add card name + let fontSize = width/cardWidth*10; // 10 = baseFontSize of 10pt + ctx.font = "bold "+fontSize+"pt Arial"; + ctx.fillStyle = '#000'; + ctx.fillText( + array[arrayKey]['name'] + , positionX + (ctx.measureText(array[arrayKey]['name']/2).width) - width/4 + , positionY+height*.25 + ); + + // Add card type + ctx.fillText( + array[arrayKey]['type'] + , positionX + (ctx.measureText(array[arrayKey]['type']/2).width) - width/4 + , positionY+height*.7 + ); + // Add text/effect area + if(array[arrayKey]['effect'] !== null){ + ctx.fillText( + array[arrayKey]['effect'] + , positionX + (ctx.measureText(array[arrayKey]['effect']/2).width) - width/4 + , positionY+height*.8 + ); + } + // Attack + ctx.fillText( + array[arrayKey]['atk'] + , positionX + (ctx.measureText(array[arrayKey]['atk']).width) + , positionY+height*.95 + ); + // Add cost + ctx.fillText( + array[arrayKey]['cost'] + , positionX + (ctx.measureText(array[arrayKey]['cost']).width) + , positionY+height*.1 + ); + + // Unbold font for other draws + ctx.font = "10pt Arial"; + } + + drawDeck(){ + // Deck + clickableItems['deckSprite'] = new Shape({ + name: 'deck', + x: canvas.width-cardWidth*1.5-40, + y: canvas.height-cardHeight*1.5-60, + width: cardWidth*1.5, + height: cardHeight*1.5, + 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*.6, + y: canvas.height-cardHeight*.6, + width: cardWidth*.375, + height: cardHeight*.375, + fillStyle: "#FFF" + }); + deckCounterSprite.draw(); + + // TODO: Center in the circle + ctx.fillStyle = '#000'; + ctx.fillText(playerDeck.length, canvas.width-cardWidth*.6 - (ctx.measureText(playerDeck.length).width) + 7, canvas.height-cardHeight*.6 + 5); + } + drawDeckOpponent(){ + // Opponent's Deck + clickableItems['deckOpponentSprite'] = new Shape({ + name: 'deckOpponent', + x: 40, + y: 60, + width: cardWidth*1.5, + height: cardHeight*1.5, + fillStyle: "#FF0000" + }); + clickableItems['deckOpponentSprite'].draw(); + let deckCounterOpponentSprite = new Shape({ + shape: 'circle', + name: 'deckCounterOpponent', + x: cardWidth*1.5+(cardWidth*.375), + y: cardHeight*1.5+(cardHeight*.375), + width: cardWidth*.375, + height: cardHeight*.375, + fillStyle: "#FFF" + }); + deckCounterOpponentSprite.draw(); + + ctx.fillStyle = '#000'; + // TODO: Center in the circle + ctx.fillText(opponentDeck.length, cardWidth*1.5 + (ctx.measureText(opponentDeck.length).width) + 10, cardHeight*1.9); + } + + // 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 * (playerHand.length - (i+1)) - (cardPadding * (i+1))); + let positionY = canvas.height-cardWidth*1.5-20; + let width = cardWidth; + let height = cardHeight; + + 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 * (opponentHand.length - (i+1)) - (cardPadding * (i+1))); + let positionY = 20; + let width = cardWidth; + let height = cardHeight; + + this.drawCard(opponentHand, i, name, positionX, positionY, width, height, fill); + } + + } + + drawCards(){} + + // Draw a card, traditional TCG + drawACard(cardsToDraw = 1){ + // For loop so that animations will play each time (when they exist) + for(let draw = 0; draw < cardsToDraw; draw++){ + 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(cardsToDraw = 1){ + for(let draw = 0; draw < cardsToDraw; draw++){ + 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 * (playerBoard.length - (i+1)) - (cardPadding * (i+1))); + let positionY = canvas.height - cardHeight-30-(cardHeight); + let width = cardWidth; + let height = cardHeight; + let border = false; + + if(attackingCard !== null && playerBoard[i].name == attackingCard[0].name){ + border = '#FF0000'; + } + this.drawCard(playerBoard, i, name, positionX, positionY, width, height, fill, border); + } + } + + 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 * (opponentBoard.length - (i+1)) - (cardPadding * (i+1))); + let positionY = cardHeight + 30; + let width = cardWidth; + let height = cardHeight; + + 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]; + let manaUsed = []; + + // 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; + } + + if(cardPlayed.cost > playerMana.length){ + alert('Not enough mana'); + return 0; + }else{ + let canPlay = false; + let needsMana = 1; + let usedMana = 0; + playerMana.forEach(function(manaCard, key){ + if(cardPlayed.colour == manaCard.colour && manaCard.tapped == false && needsMana > usedMana){ + console.log(manaCard); + // Needs changing for multiple colour usage + // 2 red, 1 red + 1 blue, etc. + // Currently only gets one mana of the cards colour + manaUsed.push(key); + usedMana++; + canPlay = true; + } + }); + + if(!canPlay){ + alert('Mana conditions not met, right click hand unit to play as mana'); + return 0; + } + } + + // Tap mana to be used + manaUsed.forEach(function(cardKey, key){ + playerMana[cardKey].tapped = true; + }); + + console.log(playerMana); + + // 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(); + } + inspectOpponentBoard(index){ + // Get the card data + inspectCard = [opponentBoard, index]; + + this.drawBoard(); + } + drawInspectedCard(){ + if(inspectCard != null){ + let positionX = canvas.width/2 - cardWidth; + let positionY = canvas.height/2 - cardHeight; + let width = cardWidth*2; + let height = cardHeight*2; + + this.drawCard(inspectCard[0], inspectCard[1], name, positionX, positionY, width, height, '#D1D100'); + console.log('inspect'); + } + } + + // Selects the card that will be attacking + // Stop other actions besides selecting opponent/opponent unit + // Can cancel, will do later + startAttack(index){ + // Can probably combine attacking/inspect, and set another array element to 'attacking', 'inspecting', etc. + attackingCard = [playerBoard[index], index]; + this.drawBoard(); + } + // Do the attack + makeAttack(index, array = null, name = null){ + if(array == null){ array = opponentBoard; name = 'opponentBoard' } + console.log(name); + // If card attacked + // Compare attackingCard and defendingCard + + let defendingCard = array[index]; + + // If hitting shield, don't calc combat damage + if(name == 'opponentShield'){ + // This should tap the card first, then after all shields + // are tapped, THEN attacking destroys them + if(array[index].tapped){ + // Untap + array[index].tapped = false; + // Add to hand + opponentHand.push(array[index]); + // Remove from shield zone + array.splice(index, 1); + }else{ + array[index].tapped = true; + } + + playerBoard[attackingCard[1]].tapped = true; + this.endAttack(); + return 1; + } + + if(defendingCard.atk <= attackingCard[0].atk){ + array.splice(index, 1); + // Need to push to grave, etc. here in future too + } + if(attackingCard[0].atk <= defendingCard.atk){ + playerBoard.splice(attackingCard[1], 1); + }else{ + playerBoard[attackingCard[1]].tapped = true; + } + console.log('attacking'); + this.endAttack(); + + // If player attacked + // Compare life/remove life cards 5/10/15,1/2/3? + } + endAttack(){ + attackingCard = null; + if(opponentShield.length <= 0){ + gameWin = 1; + } + this.drawBoard(); + } + + // Like everything else, need to consolidate into one function that + // can work for both players, and even more for 2v2 3v1 combats, etc. + playShield(shieldsToPlay = 4){ + for(let shieldNo = 0; shieldNo < shieldsToPlay; shieldNo++){ + if(playerShield.length >= maxShield){ + alert('Shield zone full '+playerShield.length+'/'+maxShield); + 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 shield zone + playerShield.push(cardDrawn); + this.drawBoard(); + } + } + playShieldOpponent(shieldsToPlay = 4){ + for(let shieldNo = 0; shieldNo < shieldsToPlay; shieldNo++){ + if(opponentShield.length >= maxShield){ + alert('Shield zone full '+opponentShield.length+'/'+maxShield); + return 0; + } + + // Random card from deck, remove from deck, add to hand + let cardToDraw = Math.floor(Math.random() * deckCount); + let cardDrawn = opponentDeck[cardToDraw]; + // Remove from deck + opponentDeck.splice(cardToDraw, 1); + // Add to shield zone + opponentShield.push(cardDrawn); + this.drawBoard(); + } + } + drawShield(){ + for (let i = 0; i < playerShield.length; i++) { + + let name = 'playerShield_'+(i+1); + + let shieldMargin = 10; + let fromX = 60; + let fromY = 300; + let fill = '#'+i+i+'0000'; + let cWidth = cardWidth*.8; + let cHeight = cardHeight*.8; + let split = 0; + if(i>=2){ split = 1; } + + // i%2 0 = 0, 1 = 1, 2 = 0, 3 = 1 to prevent margin from X/Y axis, and just between cards + let positionX = (fromX+((i%2)*shieldMargin)) +(i%2*cWidth); + let positionY = canvas.height-fromY+(split*cHeight+(shieldMargin*split)); + let width = cWidth; + let height = cHeight; + + this.drawCard(playerShield, i, name, positionX, positionY, width, height, fill); + } + } + drawShieldOpponent(){ + for (let i = 0; i < opponentShield.length; i++) { + + let name = 'opponentShield_'+(i+1); + + let shieldMargin = 10; + let fromX = canvas.width-60; + let fromY = 300; + let fill = '#'+i+i+'0000'; + let cWidth = cardWidth*.8; + let cHeight = cardHeight*.8; + let split = 0; + if(i>=2){ split = 1; } + + // i%2 0 = 0, 1 = 1, 2 = 0, 3 = 1 to prevent margin from X/Y axis, and just between cards + let positionX = (fromX+((i%2)*shieldMargin))+(i%2*cWidth)-(cWidth*2); + let positionY = fromY+(split*cHeight+(shieldMargin*split))-(cHeight*2 + shieldMargin); + let width = cWidth; + let height = cHeight; + //console.log('i: '+i+' X: '+positionX+' Y: '+positionY); + + this.drawCard(opponentShield, i, name, positionX, positionY, width, height, fill); + } + } + + playMana(index, fromDeck = 0){ + let manaCard = null; + if(fromDeck){ + let cardToDraw = Math.floor(Math.random() * deckCount); + manaCard = playerDeck[cardToDraw]; + // Remove from deck + playerDeck.splice(cardToDraw, 1); + }else{ + manaCard = playerHand[index]; + playerHand.splice(index, 1); + } + + playerMana.push(manaCard); + + this.drawBoard(); + } + drawMana(){ + for (let i = 0; i < playerMana.length; i++) { + + let name = 'playerMana_'+(i+1); + + let manaMargin = 10; + let fromX = 60; + let fromY = 60; + let fill = '#BBB'; + let cWidth = cardWidth*.5; + let cHeight = cardHeight*.5; + let split = 0; + + // i%2 0 = 0, 1 = 1, 2 = 0, 3 = 1 to prevent margin from X/Y axis, and just between cards + let positionX = (fromX+manaMargin)+(i*cWidth-manaMargin); + let positionY = canvas.height-fromY; + let width = cWidth; + let height = cHeight; + + this.drawCard(playerMana, i, name, positionX, positionY, width, height, fill); + } + } +} + +// 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(); + +board.playShield(4); +board.playShieldOpponent(4); + +board.drawACard(3); + +canvas.addEventListener('contextmenu', function(event) { + event.preventDefault(); + + let specialEvent = false; + if(inspectCard !== null || attackingCard !== null || gameWin){ + specialEvent = true; + } + + var x = event.pageX - canvasLeft, + y = event.pageY - canvasTop; + + // # PLAYER HAND + playerHand.forEach(function(card, index){ + + let clickable = card.clickable; + + if(clickableCheck(x,y,clickable) && !specialEvent){ + board.playMana(index); + board.drawBoard(); + } + }); + // Return false to prevent context opening: https://stackoverflow.com/a/4236294 + return false; + +}, false); + +canvas.addEventListener('click', function(event) { + console.log('EVENT LISTENER'); + console.log(''); + + // specialEvent used to prevent eventTriggers if something specific + // is being done, attack needs to be made, inspecting card. + // Prevents user from doing other actions until completed or cancelled event + let specialEvent = false; + if(inspectCard !== null || attackingCard !== null || gameWin){ + specialEvent = true; + } + + var x = event.pageX - canvasLeft, + y = event.pageY - canvasTop; + + // Collision detection between clicked offset and clickableItems + // https://stackoverflow.com/a/9880302 + + if(inspectCard !== null){ + clickable = inspectCard[0][inspectCard[1]].clickable; + + if(clickableCheck(x,y,clickable)){ + console.log('clicked inspect card'); + + }else{ + console.log('not inspected card'); + // Stop inspecting card if player clicks off it + inspectCard = null; + board.drawBoard(); + } + } + + // # 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) && !specialEvent){ + board.drawACard(); + } + + // # OPPONENT DECK + clickable = clickableItems['deckOpponentSprite']; + + if(clickableCheck(x,y,clickable) && !specialEvent){ + board.drawACardOpponent(); + } + + // # PLAYER HAND + playerHand.forEach(function(card, index){ + + let clickable = card.clickable; + + if(clickableCheck(x,y,clickable) && !specialEvent){ + + 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(); + } + }); + + // # PLAYER BOARD + playerBoard.forEach(function(card, index){ + let clickable = card.clickable; + + if(clickableCheck(x,y,clickable)){ + if(attackingCard !== null && card == attackingCard[0]){ + board.endAttack(); + } + if(!specialEvent && card.tapped != true){ + board.startAttack(index); + } + board.drawBoard(); + } + }); + + // # OPPONENT BOARD + opponentBoard.forEach(function(card, index){ + let clickable = card.clickable; + + if(clickableCheck(x,y,clickable)){ + // Check if card if getting attacked + if(attackingCard !== null){ + board.makeAttack(index); + } + + if(!specialEvent){ + board.inspectOpponentBoard(index); + } + board.drawBoard(); + } + }); + // # OPPONENT SHIELD + opponentShield.forEach(function(card, index){ + let clickable = card.clickable; + + if(clickableCheck(x,y,clickable)){ + // Check if card if getting attacked + if(attackingCard !== null){ + board.makeAttack(index, opponentShield, 'opponentShield'); + } + 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++){ + // Randomise colour + let colour = Math.floor(Math.random() * 2); + let effect = Math.floor(Math.random() * 5); + if(effect == 0){ effect = 'effect here'; } else{ effect = null } + + deck.push({ + 'name':'CardName '+(i+1) + , 'cost':1 + , 'atk':1 + , 'def':1 + , 'rarity': 'common' + , 'effect':effect + , 'type':'human' + , 'colour':colour + , 'tapped':false + }); + } +} + +function untap(array){ + console.log(array); + array.forEach(function(card, key){ + array[key].tapped = false; + }); + board.drawBoard(); +} +function untapAll(){ + untap(playerMana); + untap(playerBoard); + untap(opponentShield); +} + diff --git a/public/index.html b/public/index.html index d53294d..3a95905 100644 --- a/public/index.html +++ b/public/index.html @@ -8,15 +8,19 @@ -

Rooms will not be HTML buttons eventually, but for now...

- - - +
+

Rooms will not be HTML buttons eventually, but for now...

+ + + +
+ + diff --git a/public/main.js b/public/main.js index 1086031..53be0b7 100644 --- a/public/main.js +++ b/public/main.js @@ -1,12 +1,5 @@ const socket = io({autoConnect: false}); const canvas = document.getElementById('canvas');; -const ctx = canvas.getContext('2d'); - -const cardWidth = 240; -const cardHeight = 360; - -const cards = new Image(); -const back = new Image(); let room; let hand = []; @@ -18,10 +11,7 @@ init(); function init() { console.log('init'); - ctx.font = "12px Arial"; - canvas.style.backgroundColor = 'rgb(143 153 150)'; - cards.src = 'images/deck.svg'; - back.src = 'images/uno.svg'; + // Init board here? Or keep in board JS? document.addEventListener('touchstart', onclick, false); document.addEventListener('click', onclick, false); @@ -125,11 +115,14 @@ function requestCreateRoom(){ socket.emit('requestCreateRoom', playerName); } function returnCreateRoom(data){ - + console.log(data); + if(!data.success){ + alert(data.message); + } } socket.on('returnCreateRoom', function (data) { console.log('<< returnCreateRoom'); - console.log(data); + returnCreateRoom(data); }); @@ -147,24 +140,8 @@ socket.on('responseJoinRoom', function (name) { if (name != 'error') { room = name; console.log('<< Room Response: ' + name); - - // Room Name - ctx.fillText(name, 0, 10); - - // Deck - deck = new Rectangle({ - name: 'deck', - x: canvas.width-cardWidth/2-40, - y: canvas.height-cardHeight/2-60, - width: cardWidth/2, - height: cardHeight/2, - fillStyle: "#FF0000" - }); - deck.draw(); - //ctx.fillRect(canvas.width-cardWidth/2-60, canvas.height/2-cardHeight/4, cardWidth/2, cardHeight/2); - - // Player Name - ctx.fillText(playerName, 100, 390); + alert('Commented out draw board, for UI stuff'); + //board.drawBoard(); } else { socket.disconnect(); alert('Rooms are full! Try again later'); diff --git a/public/shapes.js b/public/shapes.js index ec7cd21..d8db346 100644 --- a/public/shapes.js +++ b/public/shapes.js @@ -1,33 +1,71 @@ // https://stackoverflow.com/a/29676404 context = document.getElementById("canvas").getContext("2d"); -defaultFillStyle = '#000'; +let defaultFillStyle = '#000'; +let shapeDebug = true; +let shapeDebugColour = '#FF00FF'; -function Rectangle(params) { - this.name = params.name; - this.x = params.x || 0; - this.y = params.y || 0; - this.width = params.width || 0; - this.height = params.height || 0; - this.fillStyle = params.fillStyle || "#FFFFFF"; - this.strokeStyle = params.strokeStyle || "#000000"; - this.lineWidth = params.lineWidth || 0; -} - -Rectangle.prototype.draw = function () { - if (this.fillStyle) { - console.log('X: '+this.x+' Y: '+this.y); - console.log('W: '+this.width+' H: '+this.height); - } - if (this.fillStyle) { - context.fillStyle = this.fillStyle; - context.fillRect(this.x, this.y, this.width, this.height); - context.fillStyle = defaultFillStyle; // Reset back to default +class Shape extends Path2D{ + constructor(params){ + super(); + this.shape = params.shape || 'rectangle'; + this.name = params.name; + this.x = params.x || 0; + this.y = params.y || 0; + this.width = params.width || 0; + this.height = params.height || 0; + this.fillStyle = params.fillStyle || "#FFFFFF"; + this.strokeStyle = params.strokeStyle || false; + this.lineWidth = params.lineWidth || 0; } - if (this.strokeStyle && this.lineWidth) { - context.strokeStyle = this.strokeStyle; - context.lineWidth = this.lineWidth; - context.strokeRect(this.x, this.y, this.width, this.height); + draw(){ + //console.log('Draw Shape: '+this.name); + //console.log('X: '+this.x+' Y: '+this.y); + //console.log('W: '+this.width+' H: '+this.height); + //console.log(''); + + if (this.fillStyle) { + context.fillStyle = this.fillStyle; + 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); + } + context.fillStyle = defaultFillStyle; // Reset back to default + } + if (this.strokeStyle && this.lineWidth || shapeDebug) { + context.strokeStyle = this.strokeStyle; + context.lineWidth = this.lineWidth; + context.lineWidth = 2; + + if(!this.strokeStyle && shapeDebug){ + context.strokeStyle = shapeDebugColour; + } + 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.stroke(); + context.closePath(); + }else if(this.shape == 'semi'){ + context.beginPath(); + context.arc(this.x, this.y, this.width/2, Math.PI, 0); + context.stroke(); + context.closePath(); + }else if (this.shape == 'rectangle'){ + context.strokeRect(this.x, this.y, this.width, this.height); + } + context.strokeStyle = defaultFillStyle; + } } } diff --git a/public/style.css b/public/style.css index 926e58b..a9f53d6 100644 --- a/public/style.css +++ b/public/style.css @@ -9,6 +9,12 @@ canvas{ display: block; } +.wrap{ + margin: auto; + display: block; + width: 1000px; +} + .dib{display: inline-block; margin: 0; margin-bottom: 8px;} .joinRoomButtons li{