-
Notifications
You must be signed in to change notification settings - Fork 22
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
enhance development features; add DevConfigPanel, conditional renderi…
…ng for landscape elements, and AI Santa management based on dev configuration
- Loading branch information
Showing
7 changed files
with
400 additions
and
40 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,156 @@ | ||
import 'react'; | ||
import styled from 'styled-components'; | ||
import { useDevConfig, useDevMode } from './dev-config'; | ||
|
||
export function DevConfigPanel() { | ||
const isDevMode = useDevMode(); | ||
const [config, updateConfig] = useDevConfig(); | ||
|
||
if (!isDevMode) { | ||
return null; | ||
} | ||
|
||
const handleToggle = (key: keyof typeof config) => { | ||
updateConfig({ [key]: !config[key] }); | ||
}; | ||
|
||
return ( | ||
<Panel> | ||
<Title>Dev Configuration</Title> | ||
|
||
<Section> | ||
<SectionTitle>Game Features</SectionTitle> | ||
<ToggleContainer> | ||
<ToggleInput | ||
type="checkbox" | ||
checked={config.enableAISantas} | ||
onChange={() => handleToggle('enableAISantas')} | ||
/> | ||
AI Santas | ||
</ToggleContainer> | ||
</Section> | ||
|
||
<Section> | ||
<SectionTitle>Rendering</SectionTitle> | ||
<ToggleContainer> | ||
<ToggleInput type="checkbox" checked={config.renderSnow} onChange={() => handleToggle('renderSnow')} /> | ||
Snow Effects | ||
</ToggleContainer> | ||
<ToggleContainer> | ||
<ToggleInput type="checkbox" checked={config.renderFire} onChange={() => handleToggle('renderFire')} /> | ||
Fire Effects | ||
</ToggleContainer> | ||
<ToggleContainer> | ||
<ToggleInput type="checkbox" checked={config.renderTrees} onChange={() => handleToggle('renderTrees')} /> | ||
Trees | ||
</ToggleContainer> | ||
<ToggleContainer> | ||
<ToggleInput | ||
type="checkbox" | ||
checked={config.renderMountains} | ||
onChange={() => handleToggle('renderMountains')} | ||
/> | ||
Mountains | ||
</ToggleContainer> | ||
<ToggleContainer> | ||
<ToggleInput | ||
type="checkbox" | ||
checked={config.renderSnowGround} | ||
onChange={() => handleToggle('renderSnowGround')} | ||
/> | ||
Snow Ground | ||
</ToggleContainer> | ||
</Section> | ||
</Panel> | ||
); | ||
} | ||
|
||
const Panel = styled.div` | ||
position: fixed; | ||
top: 10px; | ||
right: 10px; | ||
background: rgba(0, 0, 0, 0.8); | ||
color: white; | ||
padding: 15px; | ||
border-radius: 8px; | ||
min-width: 200px; | ||
z-index: 1000; | ||
font-family: 'Arial', sans-serif; | ||
backdrop-filter: blur(5px); | ||
border: 1px solid rgba(255, 255, 255, 0.1); | ||
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); | ||
`; | ||
|
||
const Title = styled.h3` | ||
margin: 0 0 15px 0; | ||
font-size: 14px; | ||
text-transform: uppercase; | ||
letter-spacing: 1px; | ||
color: #fff; | ||
border-bottom: 1px solid rgba(255, 255, 255, 0.2); | ||
padding-bottom: 8px; | ||
`; | ||
|
||
const Section = styled.div` | ||
margin-bottom: 15px; | ||
&:last-child { | ||
margin-bottom: 0; | ||
} | ||
`; | ||
|
||
const SectionTitle = styled.h4` | ||
margin: 0 0 8px 0; | ||
font-size: 12px; | ||
color: rgba(255, 255, 255, 0.7); | ||
font-weight: normal; | ||
`; | ||
|
||
const ToggleContainer = styled.label` | ||
display: flex; | ||
align-items: center; | ||
margin-bottom: 8px; | ||
cursor: pointer; | ||
font-size: 12px; | ||
&:last-child { | ||
margin-bottom: 0; | ||
} | ||
&:hover { | ||
color: #4a9eff; | ||
} | ||
`; | ||
|
||
const ToggleInput = styled.input` | ||
margin-right: 8px; | ||
cursor: pointer; | ||
/* Custom checkbox styling */ | ||
appearance: none; | ||
width: 16px; | ||
height: 16px; | ||
border: 2px solid rgba(255, 255, 255, 0.3); | ||
border-radius: 3px; | ||
background: transparent; | ||
position: relative; | ||
&:checked { | ||
background: #4a9eff; | ||
border-color: #4a9eff; | ||
} | ||
&:checked::after { | ||
content: '✓'; | ||
position: absolute; | ||
color: white; | ||
font-size: 12px; | ||
top: 50%; | ||
left: 50%; | ||
transform: translate(-50%, -50%); | ||
} | ||
&:hover { | ||
border-color: #4a9eff; | ||
} | ||
`; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,153 @@ | ||
import { useEffect, useState } from 'react'; | ||
|
||
/** | ||
* Interface defining the development configuration options | ||
*/ | ||
export interface DevConfig { | ||
// AI Features | ||
enableAISantas: boolean; | ||
|
||
// Rendering Features | ||
renderSnow: boolean; | ||
renderFire: boolean; | ||
renderTrees: boolean; | ||
renderMountains: boolean; | ||
renderSnowGround: boolean; | ||
} | ||
|
||
/** | ||
* Default configuration values | ||
*/ | ||
const DEFAULT_CONFIG: DevConfig = { | ||
enableAISantas: true, | ||
renderSnow: true, | ||
renderFire: true, | ||
renderTrees: true, | ||
renderMountains: true, | ||
renderSnowGround: true, | ||
}; | ||
|
||
/** | ||
* Custom event for config updates | ||
*/ | ||
const CONFIG_UPDATE_EVENT = 'devConfigUpdate'; | ||
|
||
/** | ||
* Event interface for config updates | ||
*/ | ||
interface DevConfigUpdateEvent extends CustomEvent { | ||
detail: Partial<DevConfig>; | ||
} | ||
|
||
/** | ||
* Class managing the development configuration | ||
*/ | ||
class DevConfigManager { | ||
private config: DevConfig; | ||
private listeners: Set<(config: DevConfig) => void>; | ||
|
||
constructor() { | ||
this.config = { ...DEFAULT_CONFIG }; | ||
this.listeners = new Set(); | ||
this.initHashListener(); | ||
} | ||
|
||
/** | ||
* Initialize hash change listener for dev mode | ||
*/ | ||
private initHashListener() { | ||
window.addEventListener('hashchange', this.checkDevMode.bind(this)); | ||
this.checkDevMode(); // Initial check | ||
} | ||
|
||
/** | ||
* Check if dev mode is enabled via URL hash | ||
*/ | ||
private checkDevMode() { | ||
const isDevMode = window.location.hash.includes('#dev'); | ||
if (!isDevMode) { | ||
// Reset to default config when dev mode is disabled | ||
this.updateConfig(DEFAULT_CONFIG); | ||
} | ||
} | ||
|
||
/** | ||
* Get current configuration state | ||
*/ | ||
getConfig(): Readonly<DevConfig> { | ||
return { ...this.config }; | ||
} | ||
|
||
/** | ||
* Update configuration | ||
*/ | ||
updateConfig(updates: Partial<DevConfig>) { | ||
this.config = { | ||
...this.config, | ||
...updates, | ||
}; | ||
|
||
// Notify all listeners | ||
this.listeners.forEach((listener) => listener(this.getConfig())); | ||
|
||
// Dispatch custom event | ||
const event = new CustomEvent(CONFIG_UPDATE_EVENT, { | ||
detail: updates, | ||
}) as DevConfigUpdateEvent; | ||
window.dispatchEvent(event); | ||
} | ||
|
||
/** | ||
* Subscribe to configuration changes | ||
*/ | ||
subscribe(listener: (config: DevConfig) => void): () => void { | ||
this.listeners.add(listener); | ||
return () => this.listeners.delete(listener); | ||
} | ||
|
||
/** | ||
* Check if dev mode is currently active | ||
*/ | ||
isDevMode(): boolean { | ||
return window.location.hash.includes('#dev'); | ||
} | ||
} | ||
|
||
// Create singleton instance | ||
export const devConfig = new DevConfigManager(); | ||
|
||
/** | ||
* React hook for accessing dev configuration | ||
*/ | ||
export function useDevConfig(): [DevConfig, (updates: Partial<DevConfig>) => void] { | ||
const [config, setConfig] = useState<DevConfig>(devConfig.getConfig()); | ||
|
||
useEffect(() => { | ||
// Subscribe to config updates | ||
const unsubscribe = devConfig.subscribe((newConfig) => { | ||
setConfig(newConfig); | ||
}); | ||
|
||
return unsubscribe; | ||
}, []); | ||
|
||
return [config, (updates) => devConfig.updateConfig(updates)]; | ||
} | ||
|
||
/** | ||
* React hook for checking dev mode status | ||
*/ | ||
export function useDevMode(): boolean { | ||
const [isDevMode, setIsDevMode] = useState(devConfig.isDevMode()); | ||
|
||
useEffect(() => { | ||
const handleHashChange = () => { | ||
setIsDevMode(devConfig.isDevMode()); | ||
}; | ||
|
||
window.addEventListener('hashchange', handleHashChange); | ||
return () => window.removeEventListener('hashchange', handleHashChange); | ||
}, []); | ||
|
||
return isDevMode; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.