hytopia-mobile
1
总安装量
1
周安装量
#45491
全站排名
安装命令
npx skills add https://github.com/abstrucked/hytopia-skills --skill hytopia-mobile
Agent 安装分布
opencode
1
claude-code
1
Skill 文档
HYTOPIA Mobile Support
This skill helps you implement mobile support in HYTOPIA SDK games.
Documentation: https://dev.hytopia.com/sdk-guides/mobile
When to Use This Skill
Use this skill when the user:
- Wants to add mobile controls to their game
- Needs to detect mobile devices
- Asks about touch input handling
- Wants to create responsive UI for mobile
- Needs cross-platform compatibility
- Asks about mobile-specific button layouts
Mobile Basics
Automatic Features
HYTOPIA handles automatically:
- Cross-platform play (mobile + desktop together)
- Game state consistency across devices
- Movement joystick (left 40% of screen)
- Camera control (right 60% of screen)
- Landscape orientation enforcement
What You Must Implement
- Custom action buttons (shoot, jump, interact)
- Mobile-optimized UI sizing
- Touch-friendly button layouts
Mobile Detection
CSS Detection
HYTOPIA adds .mobile class to <body> on mobile devices:
/* Desktop-only styles */
.desktop-controls {
display: block;
}
/* Hide desktop controls on mobile */
body.mobile .desktop-controls {
display: none;
}
/* Mobile-only styles */
.mobile-controls {
display: none;
}
body.mobile .mobile-controls {
display: flex;
}
JavaScript Detection
// Check if running on mobile
if (hytopia.isMobile) {
setupMobileUI();
} else {
setupDesktopUI();
}
// Conditional logic
function showControls() {
if (hytopia.isMobile) {
showTouchButtons();
} else {
showKeyboardHints();
}
}
Mobile Controls
Input Simulation
Use hytopia.pressInput() to simulate keyboard/mouse input:
// Simulate key press
hytopia.pressInput('space', true); // Key down
hytopia.pressInput('space', false); // Key up
// Simulate mouse click
hytopia.pressInput('ml', true); // Left mouse down
hytopia.pressInput('ml', false); // Left mouse up
hytopia.pressInput('mr', true); // Right mouse down
Creating Mobile Buttons
<script>
// Jump button
const jumpBtn = document.getElementById('jump-btn');
jumpBtn.addEventListener('touchstart', (e) => {
e.preventDefault(); // Prevent default touch behavior
jumpBtn.classList.add('active');
hytopia.pressInput(' ', true); // Space key
});
jumpBtn.addEventListener('touchend', (e) => {
e.preventDefault();
jumpBtn.classList.remove('active');
hytopia.pressInput(' ', false);
});
// Attack button
const attackBtn = document.getElementById('attack-btn');
attackBtn.addEventListener('touchstart', (e) => {
e.preventDefault();
attackBtn.classList.add('active');
hytopia.pressInput('ml', true); // Left click
});
attackBtn.addEventListener('touchend', (e) => {
e.preventDefault();
attackBtn.classList.remove('active');
hytopia.pressInput('ml', false);
});
</script>
Complete Mobile Control Layout
<div class="mobile-controls">
<a id="interact-btn" class="mobile-button">
<img src="{{CDN_ASSETS_URL}}/icons/interact.png" />
</a>
<a id="jump-btn" class="mobile-button">
<img src="{{CDN_ASSETS_URL}}/icons/jump.png" />
</a>
<a id="attack-btn" class="mobile-button">
<img src="{{CDN_ASSETS_URL}}/icons/attack.png" />
</a>
</div>
<style>
.mobile-controls {
display: none;
}
body.mobile .mobile-controls {
display: flex;
gap: 14px;
position: fixed;
bottom: 40px;
right: 40px;
}
.mobile-button {
background-color: rgba(0, 0, 0, 0.5);
border-radius: 50%;
width: 50px;
height: 50px;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.15s cubic-bezier(0.4, 0, 0.2, 1);
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
}
.mobile-button img {
width: 24px;
height: 24px;
filter: invert(1);
}
.mobile-button.active {
transform: scale(0.92);
background-color: rgba(0, 0, 0, 0.75);
}
</style>
<script>
document.querySelectorAll('.mobile-button').forEach(btn => {
const input = btn.dataset.input;
btn.addEventListener('touchstart', (e) => {
e.preventDefault();
btn.classList.add('active');
hytopia.pressInput(input, true);
});
btn.addEventListener('touchend', (e) => {
e.preventDefault();
btn.classList.remove('active');
hytopia.pressInput(input, false);
});
});
</script>
Responsive UI Design
Scaling for Mobile
/* Base UI */
.game-hud {
font-size: 16px;
padding: 10px;
}
/* Larger touch targets on mobile */
body.mobile .game-hud {
font-size: 20px;
padding: 16px;
}
/* Minimum touch target size: 44x44px */
body.mobile button,
body.mobile .touchable {
min-width: 44px;
min-height: 44px;
}
Hiding Desktop Elements
/* Keyboard hints - desktop only */
.keyboard-hint {
display: inline-block;
}
body.mobile .keyboard-hint {
display: none;
}
/* Simplify mobile UI */
body.mobile .detailed-stats {
display: none;
}
body.mobile .simple-stats {
display: block;
}
Safe Areas
/* Account for notches and rounded corners */
body.mobile .mobile-controls {
padding-bottom: env(safe-area-inset-bottom, 20px);
padding-right: env(safe-area-inset-right, 20px);
}
Testing Mobile UI
Browser Developer Tools
- Open game at play.hytopia.com
- Open Developer Tools (View â Developer Tools or right-click â Inspect)
- Click mobile device icon in dev tools toolbar
- Switch to landscape mode
- Refresh the page (required for mobile detection)
Testing Checklist
- Buttons are large enough (44px minimum)
- Buttons don’t overlap joystick area (left 40%)
- UI readable in landscape
- Touch feedback visible (active states)
- No accidental touches on UI while playing
- Important info visible above action buttons
Best Practices
- Design desktop first – Then adapt for mobile
- Use e.preventDefault() – Prevents unwanted browser behavior
- Large touch targets – Minimum 44x44px for buttons
- Visual feedback – Show active/pressed states
- Right side placement – Action buttons on right 60% of screen
- Avoid overlapping – Don’t place UI over joystick/camera areas
- Test on device – Browser simulation isn’t perfect
Common Input Keys
| Input | Key |
|---|---|
| Space/Jump | ' ' (space) |
| Left Click | 'ml' |
| Right Click | 'mr' |
| WASD | 'w', 'a', 's', 'd' |
| Interact | 'e' |
| Reload | 'r' |
| Sprint | 'shift' |
Common Mistakes
- Forgetting
e.preventDefault()in touch handlers - Making buttons too small for fingers
- Placing buttons over joystick area
- Not testing on actual mobile devices
- Forgetting to refresh after enabling device simulation