he intentado hacer un par de apps para gestionar el tema de coordenadas X-Y de algunas cosas que tengo pensado incluir en Stardust y esto es lo que me ha salido que parece funcionar bien (aunque aun tengo que hacer algunas pruebas con Joe)
header file (hpp) de app SERVER
Código:
//---------------------------------------------------------------------------
#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <System.Classes.hpp>
#include <Vcl.Controls.hpp>
#include <Vcl.StdCtrls.hpp>
#include <Vcl.Forms.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published: // IDE-managed Components
void __fastcall OnUDPRead(TIdUDPListenerThread *ASender, const TIdBytes AData, TIdSocketHandle *ABinding);
// Declaración del método de evento
private: // User declarations
public: // User declarations
__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
Unit1.cpp de App SERVER
Código:
//---------------------------------------------------------------------------
#include <vcl.h>
#include <IdUDPServer.hpp>
#include <IdGlobal.hpp>
#include <IdSocketHandle.hpp>
#include <vector>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
TIdUDPServer *udpServer = new TIdUDPServer(NULL);
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
// Asegúrate de que el servidor UDP esté creado antes de asignar el evento
udpServer = new TIdUDPServer(this); // Asegúrate de inicializar el servidor
udpServer->DefaultPort = 55000; // Configura el puerto
udpServer->OnUDPRead = OnUDPRead; // Asigna el evento OnUDPRead
udpServer->Active = true; // Activa el servidor UDP
ShowMessage("Servidor UDP escuchando en el puerto " + IntToStr(55000));
}
//---------------------------------------------------------------------------
struct PosicionJugador {
int jugadorID;
int posX;
int posY;
};
// Vector para almacenar posiciones de los jugadores
std::vector<PosicionJugador> posicionesJugadores;
// Lista para almacenar las direcciones de los jugadores conectados
std::vector<TIdSocketHandle*> clientesConectados;
// Función para actualizar la posición de un jugador
void ActualizarPosicion(int jugadorID, int posX, int posY) {
bool encontrado = false;
// Busca al jugador en el vector
for (auto &jugador : posicionesJugadores) {
if (jugador.jugadorID == jugadorID) {
jugador.posX = posX;
jugador.posY = posY;
encontrado = true;
break;
}
}
// Si no lo encontró, lo agrega al vector
if (!encontrado) {
PosicionJugador nuevoJugador;
nuevoJugador.jugadorID = jugadorID;
nuevoJugador.posX = posX;
nuevoJugador.posY = posY;
posicionesJugadores.push_back(nuevoJugador);
}
}
void DifundirPosiciones(TIdUDPServer *udpServer) {
for (auto &cliente : clientesConectados) {
for (auto &jugador : posicionesJugadores) {
// Crear mensaje con las posiciones
String mensaje = IntToStr(jugador.jugadorID) + "|" + IntToStr(jugador.posX) + "|" + IntToStr(jugador.posY);
TIdBytes datos;
datos = ToBytes(mensaje);
// Envía la posición a cada cliente
udpServer->SendBuffer(cliente->PeerIP, cliente->PeerPort, datos);
}
}
}
// Implementación del evento OnUDPRead
void __fastcall TForm1::OnUDPRead(TIdUDPListenerThread *AThread, const TIdBytes AData, TIdSocketHandle *ABinding)
{
String mensaje = BytesToString(AData);
// Suponemos que el mensaje tiene el formato "JugadorID|PosX|PosY"
TStringList *listaDatos = new TStringList();
listaDatos->Delimiter = '|';
listaDatos->DelimitedText = mensaje;
if (listaDatos->Count == 3) {
int jugadorID = listaDatos->Strings[0].ToInt();
int posX = listaDatos->Strings[1].ToInt();
int posY = listaDatos->Strings[2].ToInt();
ShowMessage("Jugador " + IntToStr(jugadorID) + " en posición X: " + IntToStr(posX) + ", Y: " + IntToStr(posY));
}
delete listaDatos;
}
hpp de App CLIENTE
Código:
//---------------------------------------------------------------------------
#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <System.Classes.hpp>
#include <Vcl.Controls.hpp>
#include <Vcl.StdCtrls.hpp>
#include <Vcl.Forms.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published: // IDE-managed Components
TButton *Button1;
TButton *Button2;
TEdit *EditNombre;
TLabel *Label1;
TEdit *Edit1;
TLabel *Label2;
void __fastcall Button1Click(TObject *Sender);
void __fastcall Button2Click(TObject *Sender);
private: // User declarations
TIdUDPServer *udpServer = new TIdUDPServer(NULL);
void __fastcall OnUDPRead(TIdUDPListenerThread *ASender, const TIdBytes AData, TIdSocketHandle *AChannel);
TIdUDPClient *udpClient; // Declarar el cliente UDP
void __fastcall IniciarClienteUDP(TIdUDPClient *udpClient, const String &host, int puerto); // Declaración de la función
public: // User declarations
__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
Unit1.cpp de App Cliente:
Código:
//---------------------------------------------------------------------------
#include <vcl.h>
#include <IdUDPClient.hpp>
#include <IdUDPServer.hpp>
#include <IdGlobal.hpp>
#include <IdSocketHandle.hpp>
#include <vector>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
udpClient = new TIdUDPClient(this); // Inicializar el cliente UDP
// Inicializa el servidor UDP para recibir posiciones
// Asegúrate de que el servidor UDP esté creado antes de asignar el evento
udpServer = new TIdUDPServer(this); // Asegúrate de inicializar el servidor
udpServer->DefaultPort = 53; // Configura el puerto
udpServer->OnUDPRead = OnUDPRead; // Asigna el evento OnUDPRead
ShowMessage("Servidor UDP escuchando en el puerto " + IntToStr(55000));
udpServer->Active = true; // Activa el servidor UDP para recibir posiciones
}
//---------------------------------------------------------------------------
// Función para enviar la posición del jugador al servidor
void EnviarPosicion(TIdUDPClient *udpClient, int jugadorID, int posX, int posY) {
try {
String mensaje = IntToStr(jugadorID) + "|" + IntToStr(posX) + "|" + IntToStr(posY);
TIdBytes datos;
datos = ToBytes(mensaje);
udpClient->SendBuffer(datos);
ShowMessage("Posición enviada: " + mensaje);
} catch (const Exception &e) {
ShowMessage("Error al enviar posición: " + e.Message);
}
}
// Función que recibe las posiciones de los otros jugadores
void __fastcall TForm1::OnUDPRead(TIdUDPListenerThread *ASender, const TIdBytes AData, TIdSocketHandle *AChannel)
{
String mensaje = BytesToString(AData);
// Suponemos que el mensaje tiene el formato "JugadorID|PosX|PosY"
TStringList *listaDatos = new TStringList();
listaDatos->Delimiter = '|';
listaDatos->DelimitedText = mensaje;
if (listaDatos->Count == 3) {
int jugadorID = listaDatos->Strings[0].ToInt();
int posX = listaDatos->Strings[1].ToInt();
int posY = listaDatos->Strings[2].ToInt();
ShowMessage("Jugador " + IntToStr(jugadorID) + " en posición X: " + IntToStr(posX) + ", Y: " + IntToStr(posY));
}
delete listaDatos;
}
// Inicializa el cliente UDP para recibir posiciones
void __fastcall TForm1::IniciarClienteUDP(TIdUDPClient *udpClient, const String &host, int puerto) {
udpClient->Host = host;
udpClient->Port = puerto;
udpClient->Active = true; // Activa el cliente UDP
}
void __fastcall TForm1::Button1Click(TObject *Sender)
{
EnviarPosicion(udpClient, 7, 100, 80);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
String host = EditNombre->Text; // Cambia esto al host que desees
int puerto = Edit1->Text.ToInt(); // Cambia esto al puerto que desees
IniciarClienteUDP(udpClient, host, puerto); // Llama a la función
}
//---------------------------------------------------------------------------
