import processing.net.*; // Llibreria per gestionar connexions de xarxa import javax.swing.JOptionPane; // Llibreria per mostrar finestres emergents (pop-ups) // -------------------------- // VARIABLES GLOBALS // -------------------------- // Declarem un objecte `Client` per gestionar la connexió al servidor Client client; // Declarem una variable per guardar el nom d'usuari del client String nomUsuari = ""; // Declarem una variable que ens farà de num aleatori String numAleatori; // Variable per guardar la IP del servidor String ipServidor = ""; String textEntrada = ""; // Variable per emmagatzemar el text escrit per l'usuari // Defineix el radi del pinzell float radiPinzell = 6; // Guarda l'últim punt enviat PVector ultimPuntEnviat = null; // Color inicial del pinzell en negre color codiColor = color(0); // Increment de tolerància per als botons petits float radiExtra = 10; // Array on guardarem les línies del dibuix ArrayList liniesRebudes = new ArrayList(); // Llista de línies rebudes long ultimTempsEnviament = 0; // Temps de l'últim enviament int intervalEnviament = 250; // Interval en mil·lisegons // Classe per representar les línies del dibuix amb radi i color class Linia { PVector inici; // Punt inicial de la línia PVector fi; // Punt final de la línia float radi; // Gruix de la línia int colorLinia; // Color de la línia Linia(PVector inici, PVector fi, float radi, int colorLinia) { this.inici = inici; this.fi = fi; this.radi = radi; this.colorLinia = colorLinia; } } // Configuració paleta de colors float rectangleX; // Coordenada X del rectangle de triar color float rectangleY = 20; // Coordenada Y del rectangle float rectangleWidth = 300; // Amplada del rectangle (paleta) float rectangleHeight = 40; // Alçada del rectangle (paleta) int[] paletaColors = { color(139, 69, 19), // Marró clar color(200, 50, 50), // granate color(255, 100, 0), // Taronja color(255, 255, 0), // Groc color(0, 255, 0), // Verd color(50, 200, 50), // Verd clar color(0, 255, 255), // Cian color(0, 0, 255), // Blau color(50, 50, 200), // Blau fosc color(128, 0, 128), // Lila color(255, 0, 255), // Magenta color(128, 128, 128), // Gris color(0, 0, 0), // Negre color(240, 240, 240), // Gris Clar (esborrar) color(255, 255, 255) // Blanc }; // -------------------------- // CONFIGURACIÓ DEL MENÚ // -------------------------- // Declarem colors per als botons del menú color colorUsuari = #D9B8E6; // Color del botó "Canvia el teu Nom d'Usuari" color colorCrearSala = #A6D8FF; // Color del botó "Crear Sala" color colorUnirSala = #BFF2C7; // Color del botó "Unir-se a Sala" // -------------------------- // VARIABLES DE CONTROL DE PANTALLA // -------------------------- // Declarem una variable per controlar quina pantalla s'està mostrant actualment String pantallaActual = "menu"; // Pot ser "menu", "crearSala", "unirSala" o "salaCreada" // -------------------------- // TEMPORITZADOR DE RECONNEXIÓ // -------------------------- // Declarem una variable per guardar el temps transcorregut des de l'últim intent de reconnexió int tempsReconnexio = 0; // Declarem una variable que defineix l'interval entre intents de reconnexió (en mil·lisegons) int intervalReconnexio = 5000; // 5 segons // -------------------------- // LLISTES PER GESTIONAR JUGADORS I PUNTS // -------------------------- // Declarem una llista per guardar els noms dels jugadors presents a la sala ArrayList llistaJugadors = new ArrayList(); // Declarem una variable per guardar el nom de la sala on està el client String nomSalaActual = ""; PVector ultimPunt = null; // Variable global per guardar el punt inicial d'una línia PFont fontGruixuda; // Font gruixuda per al títol PFont fontDefault; // Per guardar la font predeterminada // -------------------------- // SETUP: CONFIGURACIÓ INICIAL // -------------------------- // Funció que s'executa al principi per inicialitzar la configuració void setup() { size(1300, 700); // Defineix la mida de la finestra (ample x alt) frameRate(120); // Incrementa els FPS per capturar més moviments surface.setTitle("Pinturet"); // Defineix el títol de la finestra // Carrega fonts fontGruixuda = createFont("Arial Black", 64); // Font gruixuda per al títol // Guarda la font predeterminada fontDefault = createFont("Arial", 16); // Demana la IP del servidor ipServidor = promptIpServidor(); //Generem número aleatori que farem servir per el nom d'usuari inicial numAleatori = generarNumeroAleatori(); // Inicialitzem el nom d'usuari nomUsuari = "Usuari" + numAleatori; rectangleX = (width / 2) + 125; // Coordenada X del rectangle de triar color // Si no s'introdueix IP, no connecta if (ipServidor.equals("")) { println("No s'ha proporcionat cap IP. El client no iniciarà."); exit(); // Atura el programa } else { // Connecta amb el servidor connectarServidor(); } } // -------------------------- // DRAW: BUCLE PRINCIPAL // -------------------------- // Funció que es repeteix constantment per actualitzar la pantalla void draw() { background(240); // Pinta el fons de la finestra amb un color gris clar comprovarEstatConnexio(); // Comprova si el client està connectat al servidor // Gestiona les diferents pantalles segons l'estat actual del client if (client != null && client.active()) { // Si el client està connectat al servidor gestionarMissatgesServidor(); // Processa els missatges rebuts del servidor // Mostra la pantalla corresponent segons el valor de "pantallaActual" if (pantallaActual.equals("menu")) { carregarMenu(); // Carrega el menú principal } else if (pantallaActual.equals("crearSala")) { creaSala(); // Mostra la pantalla per crear una sala } else if (pantallaActual.equals("unirSala")) { unirSala(); // Mostra la pantalla per unir-se a una sala } else if (pantallaActual.equals("salaCreada")) { carregarPantallaSala(); // Mostra la pantalla de la sala activa } } else { mostrarMissatgeReconnexio(); // Mostra un missatge d'intent de reconnexió } // Funció que ens mostra els FPS. De moment desactivada. //mostrarFPS(); } // -------------------------- // FUNCIONS PER GESTIONAR EL MENÚ // -------------------------- // Funció que carrega i mostra el menú principal void carregarMenu() { // Dibuixa el títol de la pantalla fill(100); // Defineix el color del text (gris fosc) textAlign(CENTER, CENTER); // Centra el text horitzontalment i verticalment textSize(32); // Estableix la mida del text // Dibuixa el títol centrat a la part superior dibuixarTitol(width / 2, 60); // Dibuixa els botons del menú dibuixaBoto(width / 2, 200, 300, 60, colorUsuari, "Canvia el teu Nom d'Usuari", #502850); // Botó per canviar el nom d'usuari dibuixaBoto(width / 2, 300, 300, 60, colorCrearSala, "Crear Sala", #2B4B73); // Botó per crear una sala dibuixaBoto(width / 2, 400, 300, 60, colorUnirSala, "Unir-se a Sala", #2C4F2E); // Botó per unir-se a una sala // Funció que ens dibuixa el llapis logo dibuixarLlapis(width/2, 500); // Mostra un missatge de connexió amb el nom de l'usuari textSize(16); // Redueix la mida del text fill(150); // Defineix el color del text (gris clar) text("Connectat com a: " + nomUsuari + "\n Servidor: " + ipServidor, width / 2, height - 50); // Mostra el nom d'usuari a la part inferior de la pantalla } // -------------------------- // FUNCIONS PER GESTIONAR PANTALLES SECUNDÀRIES // -------------------------- // Funció que carrega la pantalla per crear una sala void creaSala() { background(240); // Estableix un color de fons gris clar fill(0); // Defineix el color del text (negre) textSize(32); // Estableix la mida del text textAlign(CENTER, CENTER); // Centra el text horitzontalment i verticalment text("Crear Sala", width / 2, height / 2); // Mostra el títol de la pantalla al centre // Envia una sol·licitud al servidor per crear una sala si el client està connectat if (client.active()) { // Comprova si el client està connectat client.write("CreaSala:Sala_" + nomUsuari + "\n"); // Envia el nom de la sala al servidor println("S'ha enviat la creació de la sala: Sala_" + nomUsuari); // Mostra un missatge de depuració } } // Funció que carrega la pantalla per unir-se a una sala void unirSala() { background(240); // Estableix un color de fons gris clar fill(0); // Defineix el color del text (negre) textSize(32); // Estableix la mida del text textAlign(CENTER, CENTER); // Centra el text horitzontalment i verticalment text("Unir-se a Sala", width / 2, height / 2); // Mostra el títol de la pantalla al centre } // -------------------------- // FUNCIONS PER DIBUIXAR ELEMENTS // -------------------------- // Funció per mostrar els FPS a la cantonada inferior esquerra void mostrarFPS() { fill(0); // Color del text textSize(16); // Mida del text textAlign(LEFT, TOP); // Alineació del text text("FPS: " + int(frameRate), 10, height-20); // Mostra els FPS al canvas } // Funció que dibuixa un botó personalitzat void dibuixaBoto(int x, int y, int w, int h, color botoColor, String textBoto, color textColor) { // Dibuixa una ombra darrere del botó per donar efecte de profunditat fill(200); // Defineix el color de l'ombra (gris clar) rectMode(CENTER); // Defineix que el rectangle es dibuixi des del centre rect(x + 5, y + 5, w, h, 10); // Dibuixa l'ombra lleugerament desplaçada // Dibuixa el botó principal fill(botoColor); // Defineix el color del botó stroke(0); // Defineix un contorn negre per al botó rect(x, y, w, h, 10); // Dibuixa el rectangle amb cantonades arrodonides // Dibuixa el text del botó fill(textColor); // Defineix el color del text textAlign(CENTER, CENTER); // Centra el text horitzontalment i verticalment textSize(18); // Defineix la mida del text text(textBoto, x, y); // Mostra el text centrat dins del botó } // Funció que dibuixa el títol del joc void dibuixarTitol(float x, float y) { String titol = "Pinturet online"; // Text del títol // Paleta de colors suaus color[] colorsTitol = { color(255, 102, 102), // Vermell suau color(255, 153, 102), // Taronja suau color(153, 204, 255), // Blau cel color(153, 255, 153), // Verd clar color(204, 153, 255), // Lila clar color(255, 204, 204) // Rosa suau }; // Canvia temporalment la font a la font gruixuda textFont(fontGruixuda); textAlign(CENTER, CENTER); // Centra el text textSize(100); // Mida del text // Ajusta la separació entre les lletres float separacio = 60; // Augmenta la separació entre les lletres float ampleTotal = (titol.length() - 1) * separacio; // Amplada total del text // Dibuixa cada lletra amb un contorn negre més gruixut for (int i = 0; i < titol.length(); i++) { fill(0); // Contorn negre for (int offsetX = -2; offsetX <= 2; offsetX++) { for (int offsetY = -2; offsetY <= 2; offsetY++) { text(titol.charAt(i), x - ampleTotal / 2 + i * separacio + offsetX, y + offsetY); } } } // Dibuixa cada lletra amb un color suau for (int i = 0; i < titol.length(); i++) { fill(colorsTitol[i % colorsTitol.length]); // Assigna un color a cada lletra text(titol.charAt(i), x - ampleTotal / 2 + i * separacio, y); // Text principal } // Torna a la font normal textFont(fontDefault); } // Funció que dibuixa el llapis que apareix en el menú principal void dibuixarLlapis(float x, float y) { rectMode(CENTER); // Defineix que els rectangles es dibuixen centrats // Cos del llapis fill(255, 223, 90); // Groc strokeWeight(1); rect(x, y + 50, 50, 100); // Rectangle cos del llapis (centrat) // Goma fill(255, 182, 193); // Rosa rect(x, y - 20, 50, 40); // Rectangle goma (centrat) // Banda fill(200); // Gris rect(x, y + 10, 50, 10); // Rectangle banda (centrat) // Punta del llapis fill(230, 180, 140); // Fusta triangle(x - 25, y + 100, x + 25, y + 100, x, y + 130); // Triangle fusta fill(50); // Negre triangle(x - 10, y + 120, x + 10, y + 120, x, y + 130); // Triangle punta // Ulls fill(0); // Negre ellipse(x - 10, y + 30, 10, 10); // Ull esquerre ellipse(x + 10, y + 30, 10, 10); // Ull dret fill(255); // Blanc ellipse(x - 8, y + 28, 3, 3); // Reflex ull esquerre ellipse(x + 12, y + 28, 3, 3); // Reflex ull dret // Somriure noFill(); stroke(0); strokeWeight(1); arc(x, y + 40, 20, 10, 0, PI); // Somriure rectMode(CORNER); // Defineix que els rectangles es dibuixen per defecte } // -------------------------- // GESTIÓ DEL RATOLÍ I TECLAT // -------------------------- // Funció que s'executa quan es fa clic amb el ratolí void mousePressed() { // Evita accions si el client no està connectat al servidor if (client == null || !client.active()) { return; // Si el client no està connectat, surt de la funció } if (mouseButton == LEFT) { // Gestiona accions a la pantalla principal (menú) if (pantallaActual.equals("menu")) { // Si es fa clic al botó "Canvia el teu Nom d'Usuari" if (mouseOverButton(width / 2, 200, 300, 60)) { nomUsuari = promptNomUsuari(); // Mostra un pop-up per introduir el nom d'usuari if (client.active() && !nomUsuari.equals("")) { // Si el client està actiu i el nom no està buit client.write("NOM:" + nomUsuari + "\n"); // Envia el nom al servidor println("Nom actualitzat i enviat al servidor: " + nomUsuari); // Missatge de depuració } } // Si es fa clic al botó "Crear Sala" else if (mouseOverButton(width / 2, 300, 300, 60)) { String nomSala = promptNomSala(); // Mostra un pop-up per introduir el nom de la sala if (client.active() && !nomSala.equals("")) { // Si el client està actiu i el nom no està buit client.write("CreaSala:" + nomSala + "\n"); // Envia la sol·licitud per crear una sala al servidor println("S'ha enviat la creació de la sala: " + nomSala); // Missatge de depuració } } // Si es fa clic al botó "Unir-se a Sala" else if (mouseOverButton(width / 2, 400, 300, 60)) { String nomSala = promptNomSala(); // Mostra un pop-up per introduir el nom de la sala if (client.active() && !nomSala.equals("")) { // Si el client està actiu i el nom no està buit client.write("UnirSala:" + nomSala + "\n"); // Envia la sol·licitud per unir-se a una sala al servidor println("S'ha enviat la sol·licitud per unir-se a la sala: " + nomSala); // Missatge de depuració } } } // Accions quan es fa clic a la pantalla "salaCreada" else if (pantallaActual.equals("salaCreada")) { // Detecta si el clic és sobre el botó "Torna al Menú" if (mouseX > width - 170 && mouseX < width - 20 && mouseY > height - 60 && mouseY < height - 20) { pantallaActual = "menu"; // Torna al menú principal client.write("SortirSala:" + nomUsuari + "\n"); //enviem al servidor que hem sortit de la sala liniesRebudes.clear(); // Buida totes les línies rebudes textEntrada = ""; // Eliminem localment la paraula println("Tornant al menú principal..."); } else if(mouseX > 20 && mouseX < 170 && mouseY > height - 60 && mouseY < height - 20){ //Si hem fet clic al botó de netejar el dibuix println("Eliminar dibuix"); client.write("EliminarDibuix:" + nomUsuari + "\n"); } else if (dist(mouseX, mouseY, width / 4 - 60, 40) <= 5 / 2 + radiExtra) { radiPinzell = 5; // Canvia el radi a 1 println("Pinzell més petit seleccionat: Radi = 1"); } // Comprova si l'usuari està seleccionant el pinzell petit else if (dist(mouseX, mouseY, width / 4, 40) <= 10 / 2 + radiExtra) { radiPinzell = 10; // Canvia el radi a 5 println("Pinzell petit seleccionat: Radi = 5"); } // Comprova si l'usuari està seleccionant el pinzell mitjà else if (dist(mouseX, mouseY, width / 4 + 60, 40) <= 20 / 2) { radiPinzell = 20; // Canvia el radi a 10 println("Pinzell mitjà seleccionat: Radi = 10"); } // Comprova si l'usuari està seleccionant el pinzell gran else if (dist(mouseX, mouseY, width / 4 + 140, 40) <= 40 / 2) { radiPinzell = 40; // Canvia el radi a 20 println("Pinzell gran seleccionat: Radi = 20"); } else if (mouseX > rectangleX && mouseX < rectangleX + rectangleWidth && mouseY > rectangleY && mouseY < rectangleY + rectangleHeight) { // Calcula l'índex del color seleccionat basant-se en la posició del clic float colorWidth = rectangleWidth / paletaColors.length; // Amplada de cada color dins de la paleta int index = int((mouseX - rectangleX) / colorWidth); // Determina quin color ha estat seleccionat if (index >= 0 && index < paletaColors.length) { // Comprova que l'índex és vàlid codiColor = paletaColors[index]; // Assigna el color seleccionat a la variable global } } } } } void mouseDragged() { if (pantallaActual.equals("salaCreada")) { if (mouseY > 70 && mouseY < height - 70 && mouseX > 20 && mouseX < width - 20) { if (mouseButton == LEFT) { // Si estem dibuixant if (ultimPunt == null) { // Si no hi ha punt inicial, estableix l'actual ultimPunt = new PVector(mouseX, mouseY); } else { // Comprova si ha passat l'interval d'enviament if (millis() - ultimTempsEnviament > intervalEnviament) { // Si hi ha un punt inicial, crea una línia PVector puntFinal = new PVector(mouseX, mouseY); if (client.active()) { String linia = "LINIA:" + ultimPunt.x + "," + ultimPunt.y + "," + puntFinal.x + "," + puntFinal.y + "," + radiPinzell + "," + codiColor + "\n"; client.write(linia); println("LINIA enviada: " + linia); } // Actualitza el punt inicial per continuar la línia ultimPunt = puntFinal; // Actualitza el temps d'enviament ultimTempsEnviament = millis(); } } } } } } void mouseReleased() { if (mouseButton == LEFT) { if (mouseY > 70 && mouseY < height - 70 && mouseX > 20 && mouseX < width - 20) { // Comprova si ultimPunt és null if (ultimPunt == null) { // Si és null, inicialitza amb les coordenades actuals del ratolí ultimPunt = new PVector(mouseX, mouseY); } // Crea el missatge de la línia var linia = "LINIA:" + ultimPunt.x + "," + ultimPunt.y + "," + mouseX + "," + mouseY + "," + radiPinzell + "," + codiColor + "\n"; client.write(linia); // Envia el missatge al servidor ultimPunt = null; // Reseteja el punt inicial quan s'allibera el ratolí } } } void keyPressed() { if (key == BACKSPACE) { // Elimina l'últim caràcter si l'usuari prem Backspace if (textEntrada.length() > 0) { textEntrada = textEntrada.substring(0, textEntrada.length() - 1); } } else if (key == ENTER || key == RETURN) { // Acció quan es prem Enter println("Text enviat: " + textEntrada); client.write("TEXT:" + textEntrada + "\n"); // Envia el text al servidor textEntrada = ""; // Reinicia el text després d'enviar-lo } else if (key == ' ') { // Afegeix un espai real a la cadena textEntrada += "·"; } else if (key != CODED) { // Afegeix el caràcter al text si no és una tecla especial textEntrada += key; } println("Text actual: " + textEntrada); // Mostra el text actualitzat client.write("TEXT:" + textEntrada + "\n"); // Envia el text al servidor } // -------------------------- // FUNCIONS D'AJUDA // -------------------------- // Funció per demanar la IP del servidor String promptIpServidor() { while (true) { // Manté un bucle fins que es proporciona una IP vàlida o es tanca String ip = JOptionPane.showInputDialog(null, "Servidor oficial\n213.195.120.83\n\nIntrodueix la IP del servidor","213.195.120.83"); if (ip == null) { // Comprova si s'ha clicat "Cancel·lar" o la "creueta" println("S'ha cancel·lat la introducció de la IP. El programa s'aturarà."); ip = "213.195.120.83"; exit(); // Tanca immediatament el programa } if (!ip.isEmpty()) { // Comprova que el camp no estigui buit return ip.trim(); // Retorna la IP si és vàlida } // Mostra un missatge si el camp és buit JOptionPane.showMessageDialog(null, "Has de proporcionar una IP vàlida.", "Error", JOptionPane.ERROR_MESSAGE); } } // Funció que mostra un pop-up per demanar el nom de la sala String promptNomSala() { // Mostra un quadre de text emergent per introduir el nom de la sala String nomSala = JOptionPane.showInputDialog("Introdueix el nom de la sala:"); //Generem número aleatori que farem servir per el nom d'usuari inicial numAleatori = generarNumeroAleatori(); // Si l'usuari no introdueix cap valor o tanca el pop-up, assigna un valor per defecte if (nomSala == null || nomSala.trim().equals("")) { nomSala = "Sala" + numAleatori; } return nomSala; // Retorna el nom de la sala introduït } // Funció que ens genera un num aleatori String generarNumeroAleatori() { int numero = (int) random(0, 1000000); // Genera un número entre 0 i 999999 return nf(numero, 6); // Formata el número amb 6 xifres (incloent zeros a l'esquerra) } // Funció que comprova si el ratolí està sobre un botó boolean mouseOverButton(int x, int y, int w, int h) { // Comprova si les coordenades del ratolí estan dins dels límits del botó return mouseX > x - w / 2 && mouseX < x + w / 2 && mouseY > y - h / 2 && mouseY < y + h / 2; } // -------------------------- // CONNEXIÓ AMB EL SERVIDOR // -------------------------- // Funció per connectar el client al servidor void connectarServidor() { println("Intentant connectar al servidor a la IP: " + ipServidor); // Mostra un missatge de depuració client = new Client(this, ipServidor, 5204); // Crea un client que es connecta al servidor local al port 5204 // Comprova si la connexió s'ha establert correctament if (client.active()) { println("Connectat correctament al servidor!"); // Missatge de confirmació client.write("NOM:" + nomUsuari + "\n"); // Envia el nom que hem generat al servidor } else { println("Error: No s'ha pogut connectar al servidor."); // Missatge d'error } } // -------------------------- // GESTIÓ DE LA CONNEXIÓ // -------------------------- // Funció per comprovar si el client està connectat al servidor void comprovarEstatConnexio() { // Si el client no està connectat, intenta reconnectar-se if (client == null || !client.active()) { reconnectarServidor(); } } // Funció que mostra un missatge quan s'està intentant reconnectar void mostrarMissatgeReconnexio() { fill(0); // Defineix el color del text (negre) textSize(24); // Defineix la mida del text textAlign(CENTER, CENTER); // Centra el text horitzontalment i verticalment text("Intentant connectar al servidor...", width / 2, height / 2); // Mostra el missatge al centre de la pantalla } // Funció per reconnectar-se al servidor void reconnectarServidor() { // Si ha passat més temps que l'interval definit, intenta reconnectar-se if (millis() - tempsReconnexio > intervalReconnexio) { println("Intentant reconnectar..."); // Mostra un missatge de depuració client = new Client(this, "127.0.0.1", 5204); // Crea un nou client per reconnectar-se al servidor tempsReconnexio = millis(); // Actualitza el temporitzador de reconnexió // Comprova si la reconnexió ha estat exitosa if (client != null && client.active()) { println("Reconnexió exitosa!"); // Missatge de confirmació client.write("NOM:" + nomUsuari + "\n"); // Envia el nom que hem generat al servidor } } } // -------------------------- // INTERACCIONS AMB L'USUARI // -------------------------- // Funció que mostra un pop-up per demanar el nom d'usuari String promptNomUsuari() { // Mostra un quadre de text emergent per introduir el nom d'usuari String nom = JOptionPane.showInputDialog("Introdueix el teu nom d'usuari:"); // Si l'usuari no introdueix cap valor o tanca el pop-up, assigna un valor per defecte if (nom == null || nom.trim().equals("")) { //Generem número aleatori que farem servir per el nom d'usuari inicial //numAleatori = generarNumeroAleatori(); nom = nomUsuari; } return nom; // Retorna el nom d'usuari introduït } // -------------------------- // GESTIÓ DE MISSATGES DEL SERVIDOR // -------------------------- // Funció que processa els missatges rebuts del servidor void gestionarMissatgesServidor() { String missatge = client.readString(); // Llegeix el missatge rebut del servidor if (missatge != null) { // Si hi ha un missatge missatge = trim(missatge); // Elimina espais o salts de línia no desitjats println("Missatge del servidor: " + missatge); // Mostra el missatge al terminal per depuració // Extreu el prefix del missatge (fins als dos punts ":") String prefix = missatge.contains(":") ? missatge.split(":")[0] : missatge; switch (prefix) { case "Sala creada correctament": // Processa el missatge de sala creada nomSalaActual = missatge.split(":")[1].trim(); // Assigna el nom de la sala pantallaActual = "salaCreada"; // Canvia la pantalla a la sala creada break; case "Sala trobada": // Processa el missatge de sala trobada nomSalaActual = missatge.split(":")[1].trim(); // Assigna el nom de la sala pantallaActual = "salaCreada"; // Canvia la pantalla a la sala println("S'ha entrat a la sala: " + nomSalaActual); // Mostra un missatge de confirmació break; case "JugadorsSala": // Processa la llista de jugadors llistaJugadors.clear(); // Buida la llista actual de jugadors String[] jugadors = missatge.split(":")[1].split(","); // Divideix el missatge en noms de jugadors for (String jugador : jugadors) { // Itera per cada jugador rebut if (!jugador.equals("")) { llistaJugadors.add(jugador); // Afegeix el jugador a la llista } } break; case "LINIA": String[] parts = missatge.substring(6).split(","); // Divideix les dades if (parts.length == 6) { // Comprova que hi ha 6 valors float x1 = Float.parseFloat(parts[0].trim()); float y1 = Float.parseFloat(parts[1].trim()); float x2 = Float.parseFloat(parts[2].trim()); float y2 = Float.parseFloat(parts[3].trim()); float radi = Float.parseFloat(parts[4].trim()); int colorLinia = Integer.parseInt(parts[5].trim()); println("Pintem linia: " + missatge); // Crea una nova línia i la guarda a la llista liniesRebudes.add(new Linia(new PVector(x1, y1), new PVector(x2, y2), radi, colorLinia)); /* // Dibuixa la línia amb el radi i el color stroke(colorLinia); // Defineix el color strokeWeight(radi); // Defineix el gruix line(x1, y1, x2, y2); // Dibuixa la línia */ } else { println("Missatge de línia mal format: " + missatge); } break; case "TEXT": // Processa les dades de dibuix textEntrada = missatge.substring(5); break; case "EliminarDibuix": // Processa l'ordre d'esborrar tot el dibuix println("Servidor:Eliminar dibuix"); //puntsRebuts.clear(); // Buida tots els punts rebuts liniesRebudes.clear(); // Buida totes les línies rebudes break; case "Error": // Processa un missatge d'error del servidor println("Error rebut del servidor: " + missatge); // Mostra l'error al terminal JOptionPane.showMessageDialog(null, missatge, "Error", JOptionPane.ERROR_MESSAGE); // Mostra l'error a l'usuari break; default: // Si no es reconeix el prefix println("Missatge desconegut rebut del servidor: " + missatge); break; } } } // -------------------------- // PANTALLA DE LA SALA // -------------------------- // Funció que gestiona el contingut gràfic quan el client està dins d'una sala void carregarPantallaSala() { // Definim el mode dels rectangles per iniciar des de la cantonada superior esquerra rectMode(CORNER); // Configurem el color de fons de la pantalla background(240); // Defineix el gruix de les línies strokeWeight(0); // -------------------------- // Dibuixem les línies rebudes // -------------------------- stroke(0); // Defineix el color de la línia (negre) fill(codiColor); for (Linia linia : liniesRebudes) { stroke(linia.colorLinia); // Defineix el color de la línia strokeWeight(linia.radi); // Defineix el gruix de la línia line(linia.inici.x, linia.inici.y, linia.fi.x, linia.fi.y); // Dibuixa la línia } // -------------------------- // Dibuixem eines canvi de radi i color // -------------------------- stroke(0); strokeWeight(1); fill(codiColor); ellipse(width / 4 - 60 , 40, 5, 5); // Pinzell més petit ellipse(width / 4 , 40, 10, 10); // Pinzell petit ellipse(width / 4 + 60 , 40, 20, 20); // Pinzell mitjà ellipse(width / 4 + 140, 40, 40, 40); // Pinzell gran strokeWeight(0); stroke(0); // -------------------------- // Nom de la sala // -------------------------- fill(160, 120, 160); // Defineix el color de fons del rectangle rect(25, 20, 180, 40, 10); // Dibuixa el rectangle arrodonit amb un marge superior de 20 píxels fill(0); // Defineix el color del text (negre) textAlign(LEFT, CENTER); // Alinea el text a l'esquerra i centrat verticalment textSize(18); // Defineix la mida del text text("Sala: " + nomSalaActual, 30, 40); // Mostra el nom de la sala actual ajustat a la nova posició /* // -------------------------- // Temporitzador (placeholder) // -------------------------- fill(160, 200, 255); // Defineix el color de fons del rectangle del temporitzador rect(width / 2 - 90, 20, 180, 40, 10); // Dibuixa el rectangle arrodonit centrat fill(0); // Defineix el color del text (negre) textAlign(CENTER, CENTER); // Centra el text horitzontalment i verticalment text("Temporitzador", width / 2, 40); // Mostra el text "Temporitzador" com a marcador de posició */ // -------------------------- // Llista de jugadors // -------------------------- fill(255, 180, 180); // Defineix el color de fons del rectangle de la llista de jugadors rect(width - 200, 20, 150, 200, 10); // Dibuixa el rectangle arrodonit per la llista de jugadors fill(0); // Defineix el color del text (negre) textSize(16); // Defineix la mida del text textAlign(LEFT, TOP); // Alinea el text a l'esquerra i a dalt text("Llista de Jugadors", width - 190, 30); // Mostra el títol "Llista de Jugadors" // Llista els noms dels jugadors int y = 90; // Coordenada vertical inicial per als jugadors for (String jugador : llistaJugadors) { text(jugador, width - 190, y); // Mostra el nom de cada jugador y += 20; // Incrementa la posició vertical per al següent jugador } // -------------------------- // Paleta de colors dins del rectangle // -------------------------- float colorWidth = rectangleWidth / paletaColors.length; // Amplada de cada color dins de la paleta for (int i = 0; i < paletaColors.length; i++) { fill(paletaColors[i]); // Defineix el color stroke(paletaColors[i]); rect(rectangleX + i * colorWidth, rectangleY, colorWidth, rectangleHeight); // Dibuixa cada color } // -------------------------- // Paraula a endevinar (placeholder) // -------------------------- fill(0); // Defineix el color del text (negre) textSize(24); // Defineix la mida del text gran textAlign(CENTER, CENTER); // Centra el text horitzontalment i verticalment text(textEntrada, width / 2, height - 50); // Mostra línies com a marcador de posició de la paraula textSize(16); // Defineix la mida del text petit text("Paraula a Endevinar", width / 2, height - 20); // Mostra el text "Paraula a Endevinar" strokeWeight(1); // -------------------------- // Botó per tornar al menú principal // -------------------------- fill(200, 100, 100); // Color del botó rect(width - 170, height - 60, 150, 40, 10); // Dibuixa el botó fill(0); textAlign(CENTER, CENTER); textSize(16); text("Torna al Menú", width - 95, height - 40); // Text dins del botó // Defineix el gruix de les línies strokeWeight(1); // -------------------------- // Botó per netejar el dibuix // -------------------------- fill(200, 100, 200); // Color del botó rect(20, height - 60, 150, 40, 10); // Posició i mida del botó (esquerra inferior) fill(0); textAlign(CENTER, CENTER); textSize(16); text("Neteja Dibuix", 95, height - 40); // Text centrat al botó }