feat: add responsive font sizing for mobile

- Add src/utils/responsive.js with fontSize() helper
- Mobile fonts scale 1.4x for better readability
- Update all scenes to use responsive font sizes
- Update deploy-k8s.sh with full deployment steps

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Thomas Richter
2026-02-04 23:50:29 +01:00
parent b0fb15fe7b
commit 1154a78908
7 changed files with 73 additions and 38 deletions

View File

@@ -1,10 +1,8 @@
#!/bin/bash
# Deploy whalehunting to Kubernetes via ArgoCD
# Prerequisites:
# 1. Create repo in Gitea: git.kube2.tricnet.de/admin/whalehunting
# 2. Push this repo to Gitea
# 3. Run this script to create the ArgoCD application
# Usage: ./deploy-k8s.sh [tag]
# Example: ./deploy-k8s.sh v1.2.0
set -e
@@ -15,34 +13,39 @@ IMAGE_TAG="${1:-latest}"
echo "=== Whalehunting Kubernetes Deployment ==="
echo ""
# Step 1: Build and push Docker image to Gitea registry
# Step 1: Build Docker image
echo "1. Building Docker image..."
docker build -t ${GITEA_URL}/admin/${REPO_NAME}:${IMAGE_TAG} .
# Step 2: Push image to registry
echo ""
echo "2. Pushing image to Gitea registry..."
echo " (You may need to: docker login ${GITEA_URL})"
docker push ${GITEA_URL}/admin/${REPO_NAME}:${IMAGE_TAG}
# Step 3: Update image tag in kustomization
echo ""
echo "3. Updating image tag in kustomization.yaml..."
sed -i "s/newTag: .*/newTag: ${IMAGE_TAG}/" k8s/kustomization.yaml
# Step 4: Commit and push to Gitea
echo ""
echo "4. Committing and pushing to Gitea..."
git add -A
git commit -m "deploy: update image to ${IMAGE_TAG}" || echo "No changes to commit"
git push origin master
# Step 5: Ensure ArgoCD application exists
echo ""
echo "5. Creating/updating ArgoCD application..."
echo "5. Ensuring ArgoCD application exists..."
ssh root@kube2.tricnet.de "kubectl apply -f -" < k8s/argocd-application.yaml
# Step 6: Wait for sync and check status
echo ""
echo "=== Deployment initiated ==="
echo "ArgoCD will sync automatically."
echo ""
echo "Check status:"
echo " ssh root@kube2.tricnet.de 'kubectl get application whalehunting -n argocd'"
echo "6. Checking deployment status..."
sleep 5
ssh root@kube2.tricnet.de "kubectl get application whalehunting -n argocd"
ssh root@kube2.tricnet.de "kubectl get pods -n whalehunting"
echo ""
echo "=== Deployment complete ==="
echo "Game URL: https://whalehunting.kube2.tricnet.de"

View File

@@ -1,4 +1,5 @@
import Phaser from 'phaser';
import { fontSize } from '../utils/responsive.js';
export default class HuntingScene extends Phaser.Scene {
constructor() {
@@ -196,7 +197,7 @@ export default class HuntingScene extends Phaser.Scene {
// Stats (fixed to screen)
this.statsText = this.add.text(20, 15, '', {
fontSize: '16px',
fontSize: fontSize(16),
fill: '#fff'
});
this.statsText.setScrollFactor(0);
@@ -204,7 +205,7 @@ export default class HuntingScene extends Phaser.Scene {
// Control mode indicator (fixed to screen, desktop only)
if (!this.isMobile) {
this.controlModeText = this.add.text(400, 15, 'Controls: MOUSE (TAB to switch)', {
fontSize: '16px',
fontSize: fontSize(16),
fill: '#ffff00'
}).setOrigin(0.5, 0);
this.controlModeText.setScrollFactor(0);
@@ -217,7 +218,7 @@ export default class HuntingScene extends Phaser.Scene {
returnBtn.setScrollFactor(0);
const returnText = this.add.text(750, 30, 'RETURN', {
fontSize: '14px',
fontSize: fontSize(14),
fill: '#fff'
}).setOrigin(0.5);
returnText.setScrollFactor(0);
@@ -239,7 +240,7 @@ export default class HuntingScene extends Phaser.Scene {
createInstructions() {
this.messageText = this.add.text(400, 570, '', {
fontSize: '16px',
fontSize: fontSize(16),
fill: '#fff',
backgroundColor: '#000000',
padding: { x: 10, y: 5 }

View File

@@ -1,3 +1,5 @@
import { fontSize } from '../utils/responsive.js';
export default class IntroScene extends Phaser.Scene {
constructor() {
super({ key: 'IntroScene' });
@@ -19,7 +21,7 @@ export default class IntroScene extends Phaser.Scene {
// Game title
const title = this.add.text(400, 150, 'WHALE HUNTING', {
fontSize: '56px',
fontSize: fontSize(56),
fill: '#ffffff',
fontStyle: 'bold'
}).setOrigin(0.5);
@@ -27,7 +29,7 @@ export default class IntroScene extends Phaser.Scene {
// Subtitle
this.add.text(400, 210, 'A Whaling Adventure on the High Seas', {
fontSize: '22px',
fontSize: fontSize(22),
fill: '#cccccc',
fontStyle: 'italic'
}).setOrigin(0.5);
@@ -43,7 +45,7 @@ export default class IntroScene extends Phaser.Scene {
buttonBg.setInteractive({ useHandCursor: true });
const buttonText = this.add.text(400, 400, 'SET SAIL', {
fontSize: '28px',
fontSize: fontSize(28),
fill: '#ffffff',
fontStyle: 'bold'
}).setOrigin(0.5);
@@ -73,7 +75,7 @@ export default class IntroScene extends Phaser.Scene {
// Instructions text
this.add.text(400, 530, 'Click to cast off and seek yer fortune!', {
fontSize: '16px',
fontSize: fontSize(16),
fill: '#ffff99'
}).setOrigin(0.5);
}

View File

@@ -1,4 +1,5 @@
import Phaser from 'phaser';
import { fontSize } from '../utils/responsive.js';
export default class MapScene extends Phaser.Scene {
constructor() {
@@ -16,7 +17,7 @@ export default class MapScene extends Phaser.Scene {
// Title
this.add.text(400, 30, 'Navigation Map - Choose Your Destination', {
fontSize: '24px',
fontSize: fontSize(24),
fill: '#fff',
fontStyle: 'bold'
}).setOrigin(0.5);
@@ -57,7 +58,7 @@ export default class MapScene extends Phaser.Scene {
closeButton.setStrokeStyle(2, 0xffffff);
const closeText = this.add.text(750, 50, 'CLOSE', {
fontSize: '16px',
fontSize: fontSize(16),
fill: '#fff'
}).setOrigin(0.5);
@@ -102,7 +103,7 @@ export default class MapScene extends Phaser.Scene {
// Location name
const text = this.add.text(x, y, name, {
fontSize: '12px',
fontSize: fontSize(12),
fill: '#fff',
fontStyle: 'bold',
align: 'center'
@@ -136,7 +137,7 @@ export default class MapScene extends Phaser.Scene {
panel.setStrokeStyle(2, 0xffffff);
this.inventoryText = this.add.text(20, 40, '', {
fontSize: '14px',
fontSize: fontSize(14),
fill: '#fff'
});
@@ -163,7 +164,7 @@ export default class MapScene extends Phaser.Scene {
this.messageBox.setStrokeStyle(2, 0xcccccc);
this.messageText = this.add.text(400, 560, '', {
fontSize: '16px',
fontSize: fontSize(16),
fill: '#fff',
wordWrap: { width: 740 },
align: 'center'

View File

@@ -1,4 +1,5 @@
import Phaser from 'phaser';
import { fontSize } from '../utils/responsive.js';
export default class ShipDeckScene extends Phaser.Scene {
constructor() {
@@ -21,7 +22,7 @@ export default class ShipDeckScene extends Phaser.Scene {
// Background - ship deck
this.add.rectangle(400, 300, 800, 600, 0x8B4513);
this.add.text(400, 30, 'The Deck - Yer Whaling Vessel', {
fontSize: '24px',
fontSize: fontSize(24),
fill: '#fff'
}).setOrigin(0.5);
@@ -34,7 +35,7 @@ export default class ShipDeckScene extends Phaser.Scene {
// Instructions
this.add.text(400, 560, 'Click on things to have a look, ye scurvy dog', {
fontSize: '16px',
fontSize: fontSize(16),
fill: '#ffff99'
}).setOrigin(0.5);
}
@@ -85,7 +86,7 @@ export default class ShipDeckScene extends Phaser.Scene {
this.penguinCage.setStrokeStyle(3, 0x000000);
this.penguinEmoji = this.add.text(650, 350, '🐧', {
fontSize: '32px'
fontSize: fontSize(32)
}).setOrigin(0.5);
// Hide penguin elements if not yet discovered
@@ -143,7 +144,7 @@ export default class ShipDeckScene extends Phaser.Scene {
// Add label only on first barrel
if (i === 0) {
const label = this.add.text(x, y, 'FUEL', {
fontSize: '12px',
fontSize: fontSize(12),
fill: '#fff'
}).setOrigin(0.5);
this.fuelBarrels.push(label);
@@ -201,7 +202,7 @@ export default class ShipDeckScene extends Phaser.Scene {
// Add label only on first barrel
if (i === 0) {
const label = this.add.text(x, y, 'OIL', {
fontSize: '12px',
fontSize: fontSize(12),
fill: '#fff'
}).setOrigin(0.5);
this.oilBarrels.push(label);
@@ -263,7 +264,7 @@ export default class ShipDeckScene extends Phaser.Scene {
panel.setStrokeStyle(2, 0xffffff);
this.inventoryText = this.add.text(20, 40, '', {
fontSize: '14px',
fontSize: fontSize(14),
fill: '#fff'
});
@@ -303,7 +304,7 @@ export default class ShipDeckScene extends Phaser.Scene {
this.messageBox.setStrokeStyle(2, 0xcccccc);
this.messageText = this.add.text(400, 500, 'Ahoy, matey! Welcome aboard. Have a look around the vessel.', {
fontSize: '16px',
fontSize: fontSize(16),
fill: '#fff',
wordWrap: { width: 740 },
align: 'center'

View File

@@ -1,4 +1,5 @@
import Phaser from 'phaser';
import { fontSize } from '../utils/responsive.js';
export default class TransitionScene extends Phaser.Scene {
constructor() {
@@ -30,7 +31,7 @@ export default class TransitionScene extends Phaser.Scene {
// Destination title
this.add.text(400, 360, content.title, {
fontSize: '32px',
fontSize: fontSize(32),
fill: '#ffffff',
fontStyle: 'bold',
stroke: '#000000',
@@ -39,7 +40,7 @@ export default class TransitionScene extends Phaser.Scene {
// Journey description
this.add.text(400, 430, content.description, {
fontSize: '18px',
fontSize: fontSize(18),
fill: '#ffffff',
align: 'center',
wordWrap: { width: 660 }
@@ -48,12 +49,12 @@ export default class TransitionScene extends Phaser.Scene {
// Fuel cost display (only if there's a cost)
if (this.fuelCost > 0) {
this.add.text(400, 500, `Fuel consumed: ${this.fuelCost} units`, {
fontSize: '16px',
fontSize: fontSize(16),
fill: '#ffff00'
}).setOrigin(0.5);
} else {
this.add.text(400, 500, 'The wind carries your sails...', {
fontSize: '16px',
fontSize: fontSize(16),
fill: '#cccccc',
fontStyle: 'italic'
}).setOrigin(0.5);
@@ -65,7 +66,7 @@ export default class TransitionScene extends Phaser.Scene {
continueBtn.setStrokeStyle(3, 0xffffff);
const btnText = this.add.text(400, 540, 'CONTINUE', {
fontSize: '20px',
fontSize: fontSize(20),
fill: '#fff',
fontStyle: 'bold'
}).setOrigin(0.5);
@@ -265,7 +266,7 @@ export default class TransitionScene extends Phaser.Scene {
const x = 200 + i * 200;
const y = 80 + Math.random() * 40;
const bird = this.add.text(x, y, 'v', {
fontSize: '20px',
fontSize: fontSize(20),
fill: '#ffffff'
});

26
src/utils/responsive.js Normal file
View File

@@ -0,0 +1,26 @@
// Responsive utilities for mobile-friendly text sizing
const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
// Font size multiplier for mobile devices
const MOBILE_SCALE = 1.4;
/**
* Get responsive font size - larger on mobile for better readability
* @param {number} baseSize - Base font size in pixels
* @returns {string} Font size string with 'px' suffix
*/
export function fontSize(baseSize) {
const size = isMobile ? Math.round(baseSize * MOBILE_SCALE) : baseSize;
return `${size}px`;
}
/**
* Check if running on mobile device
* @returns {boolean}
*/
export function checkMobile() {
return isMobile;
}
export default { fontSize, checkMobile, isMobile };