A flexible WebSocket-based touch/mouse controller system that allows you to control web games/applications from different devices. The system supports multiple simultaneous sessions, making it perfect for multiplayer installations or interactive displays.
https://touchcontroller.onrender.com/
- Real-time touch/mouse control
- Session-based connections
- QR code for easy mobile connection
- Support for multiple simultaneous sessions
- Visual feedback and debugging tools
- Auto-reconnection handling
- Cross-device compatibility
- Low latency communication
- Node.js (v14.0.0 or higher)
- npm (Node Package Manager)
- Clone the repository:
git clone <repository-url>
cd touch-controller
- Install dependencies:
npm install
- Start the server:
node server.js
- Access the application:
- Main interface:
http://localhost:3000
- Game screen:
http://localhost:3000/game.html
- Controller:
http://localhost:3000/controller.html
touch-controller/
โโโ server.js # WebSocket server and session management
โโโ package.json # Project dependencies
โโโ public/ # Static files
โโโ index.html # Landing page
โโโ game.html # Game display
โโโ controller.html # Touch controller
โโโ your-game/ # Your custom game files
- Create a new HTML file in the
public
folder:
<!DOCTYPE html>
<html>
<head>
<title>Your Game</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
/* Your game styles */
</style>
</head>
<body>
<div id="game-container">
<!-- Your game elements -->
</div>
<script>
// WebSocket connection setup
const wsProtocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
const ws = new WebSocket(`${wsProtocol}//${window.location.host}`);
ws.onopen = () => {
// Register as a game
ws.send(JSON.stringify({
type: 'register',
client: 'game',
sessionId: sessionId // Get from URL or create new
}));
};
// Handle controller input
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
if (data.type !== 'session_status' && data.type !== 'registered') {
handleGameInput(data);
}
};
function handleGameInput(data) {
// data contains:
// - x, y: Normalized coordinates (0-1)
// - type: Event type (touchstart, touchmove, etc.)
// - isDragging: Boolean indicating drag state
// - inputType: 'touch' or 'mouse'
// Your game input handling code here
}
</script>
</body>
</html>
- Add the WebSocket client code to your game:
class TouchController {
constructor(options = {}) {
this.onInput = options.onInput || (() => {});
this.setupWebSocket();
}
setupWebSocket() {
const wsProtocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
this.ws = new WebSocket(`${wsProtocol}//${window.location.host}`);
this.ws.onmessage = (event) => {
const data = JSON.parse(event.data);
if (data.type !== 'session_status' && data.type !== 'registered') {
this.onInput(data);
}
};
}
}
// Usage in your game:
const controller = new TouchController({
onInput: (data) => {
// Handle input in your game
// data.x, data.y - normalized coordinates (0-1)
// data.type - event type
// data.isDragging - drag state
}
});
// In your game code
class Game {
constructor() {
this.player = document.getElementById('player');
this.setupController();
}
setupController() {
this.controller = new TouchController({
onInput: (data) => {
// Convert normalized coordinates to game coordinates
const x = data.x * window.innerWidth;
const y = data.y * window.innerHeight;
// Move player
this.player.style.left = `${x}px`;
this.player.style.top = `${y}px`;
}
});
}
}
{
type: string, // Event type (touchstart, touchmove, etc.)
x: number, // Normalized X coordinate (0-1)
y: number, // Normalized Y coordinate (0-1)
inputType: string, // 'touch' or 'mouse'
isDragging: boolean,// Drag state
sessionId: string, // Session identifier
timestamp: number // Event timestamp
}
-
Session Management:
- Sessions are unique per game instance
- Controllers can only communicate with their assigned game
- Sessions expire after inactivity
-
Input Validation:
- All messages are validated before processing
- Coordinates are normalized (0-1)
- Rate limiting on input messages
- Touch events support
- Screen orientation handling
- Viewport optimization
- Prevent unwanted gestures
- Visual feedback
- Enable console logging:
const DEBUG = true;
if (DEBUG) {
ws.onmessage = (event) => {
console.log('Received:', event.data);
// ... rest of your code
};
}
- Monitor connection status:
- Check status display in top-left corner
- Watch browser console for WebSocket messages
- Monitor server console for connection logs
- Local Network:
node server.js
- Using Process Manager (PM2):
npm install -g pm2
pm2 start server.js
- On Render/Heroku:
- Push to GitHub
- Connect repository to hosting platform
- Deploy
- Fork the repository
- Create a feature branch
- Commit your changes
- Push to the branch
- Create a Pull Request
MIT License - Feel free to use in your projects