From 1da50c2fb442afa7f1a93bfe2cc9a1c776419713 Mon Sep 17 00:00:00 2001 From: Nathan Date: Fri, 4 Oct 2024 22:01:38 +0100 Subject: [PATCH] Board seperation, Shape changes, and event handler Split front-end JS into seperate files Change shape into a class that can do rect/circle rendering Add basic event handler for player deck. --- public/board.js | 149 ++++++++++++++++++++++++++++++++++++++++++++++ public/index.html | 13 ++-- public/main.js | 39 +++--------- public/shapes.js | 63 ++++++++++++-------- public/style.css | 6 ++ 5 files changed, 210 insertions(+), 60 deletions(-) create mode 100644 public/board.js diff --git a/public/board.js b/public/board.js new file mode 100644 index 0000000..1d5afec --- /dev/null +++ b/public/board.js @@ -0,0 +1,149 @@ +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 = []; +console.log(clickableItems); + + +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(){ + console.log('drawBoard'); + ctx.clearRect(0, 0, canvas.width, canvas.height); + // Room Name + ctx.fillText(name, 0, 10); + + this.drawDeck(); + this.drawDeckOpponent(); + + + this.drawPlayerNames('Nathan', 'Evil Nathan'); + } + + drawPlayerNames(playerName, opponentName = false){ + console.log('drawPlayerNames'); + + // 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); + } + } + + 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" + }); + clickableItems['deckSprite'].draw(); + let deckCounterSprite = new Circle({ + name: 'deckCounter', + x: canvas.width-cardWidth/5, + y: canvas.height-cardHeight/5, + width: cardWidth/8, + height: cardHeight/8, + fillStyle: "#FFF" + }); + deckCounterSprite.draw(); + let cardsInDeck = 60; + // TODO: Center in the circle + ctx.fillText(cardsInDeck, canvas.width-cardWidth/5 - (ctx.measureText(cardsInDeck).width) + 7, canvas.height-cardHeight/5 + 5); + //ctx.fillRect(canvas.width-cardWidth/2-60, canvas.height/2-cardHeight/4, cardWidth/2, cardHeight/2); + } + drawDeckOpponent(){ + // Opponent's Deck + let deckSprite = new Shape({ + name: 'deckOpponent', + x: 40, + y: 60, + width: cardWidth/2, + height: cardHeight/2, + fillStyle: "#FF0000" + }); + deckSprite.draw(); + let deckCounterSprite = new Shape({ + shape: 'circle', + name: 'deckCounterOpponent', + x: cardWidth/2+(cardWidth/8), + y: cardHeight/2+(cardHeight/8), + width: cardWidth/8, + height: cardHeight/8, + fillStyle: "#FFF" + }); + deckCounterSprite.draw(); + let cardsInDeck = 60; + // TODO: Center in the circle + ctx.fillStyle = '#000'; + ctx.strokeStyle = '#000'; + ctx.fillText(cardsInDeck, cardWidth/2 + (ctx.measureText(cardsInDeck).width) + 10, cardHeight/1.58); + } + + // Naming's getting awkward here... + // Draw the card + drawCardSprites(){ + + } + + drawCardSpritesOpponent(){ + + } + // Draw a card, traditional TCG + drawACard(){ + + } + drawACardOpponent(){ + + } +} + +// Run board commands here for testing +let board = new Board; +//board.initBoard(); + +board.drawBoard(); + +canvas.addEventListener('mousemove', function(event) { + var x = event.pageX - canvasLeft, + y = event.pageY - canvasTop; + + console.log('X: '+x+' Y: '+y); + + // Collision detection between clicked offset and clickableItems + // https://stackoverflow.com/a/9880302 + clickable = clickableItems['deckSprite']; + console.log(clickableItems['deckSprite']); + + if ( + y > clickable.y && y < clickable.y + clickable.height + && x > clickable.x && x < clickable.x + clickable.width + ) { + console.log('HUUUH'); + } + +}, false); + diff --git a/public/index.html b/public/index.html index d53294d..0cd06c6 100644 --- a/public/index.html +++ b/public/index.html @@ -8,15 +8,18 @@ -

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..10c4f68 100644 --- a/public/shapes.js +++ b/public/shapes.js @@ -3,31 +3,46 @@ context = document.getElementById("canvas").getContext("2d"); defaultFillStyle = '#000'; -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); +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 || "#000000"; + this.lineWidth = params.lineWidth || 0; } - if (this.fillStyle) { - context.fillStyle = this.fillStyle; - context.fillRect(this.x, this.y, this.width, this.height); - context.fillStyle = defaultFillStyle; // Reset back to default - } - 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('X: '+this.x+' Y: '+this.y); + //console.log('W: '+this.width+' H: '+this.height); + + if (this.fillStyle) { + context.fillStyle = this.fillStyle; + if(this.shape == 'circle'){ + // X,Y,Radius, start, end + context.arc(this.x, this.y, this.width/2, 0, 2 * Math.PI); + context.fill(); + }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) { + context.strokeStyle = this.strokeStyle; + context.lineWidth = this.lineWidth; + if(this.shape == 'circle'){ + // X,Y,Radius, start, end + context.arc(this.x, this.y, this.width/2, 0, 2 * Math.PI); + context.stroke(); + }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{