Add a simple save system
This commit is contained in:
parent
d4dda5b3e4
commit
39309aa9e7
31
src/App.tsx
31
src/App.tsx
|
|
@ -1,10 +1,12 @@
|
|||
import React from 'react';
|
||||
import React, { useEffect } from 'react';
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from './components/CustomTabs';
|
||||
import { useGameTick } from './hooks/useGameTick';
|
||||
import Field from './components/Field';
|
||||
import Warehouse from './components/Warehouse';
|
||||
import Market from './components/Market';
|
||||
import { ActionCooldown } from './components/ActionCooldown';
|
||||
import { useGameStore } from './store/useGameStore';
|
||||
import { hasSaveInSlot } from './utils/saveSystem';
|
||||
|
||||
const appContainerStyle: React.CSSProperties = {
|
||||
maxWidth: '1200px',
|
||||
|
|
@ -20,6 +22,33 @@ const tabsListStyles: React.CSSProperties = {
|
|||
|
||||
function App() {
|
||||
useGameTick();
|
||||
const { saveToSlot, loadFromSlot } = useGameStore();
|
||||
|
||||
useEffect(() => {
|
||||
const handleKeyDown = (e: KeyboardEvent) => {
|
||||
const slot = {
|
||||
'1': 1,
|
||||
'2': 2,
|
||||
'3': 3,
|
||||
'!': 1,
|
||||
'@': 2,
|
||||
'#': 3
|
||||
}[e.key] ?? null
|
||||
|
||||
if (slot !== null) {
|
||||
if (e.shiftKey) {
|
||||
saveToSlot(slot);
|
||||
console.log(`Game saved to slot ${slot}`);
|
||||
} else if (hasSaveInSlot(slot)) {
|
||||
loadFromSlot(slot);
|
||||
console.log(`Game loaded from slot ${slot}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener('keydown', handleKeyDown)
|
||||
return () => window.removeEventListener('keydown', handleKeyDown)
|
||||
}, [saveToSlot, loadFromSlot])
|
||||
|
||||
return (
|
||||
<div>
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import {
|
|||
MARKET_ITEMS
|
||||
} from '../constants';
|
||||
import { GameState, PlotState } from '../types';
|
||||
import { saveGame, loadGame } from '../utils/saveSystem';
|
||||
|
||||
const initializeField = (size: number): PlotState[][] => {
|
||||
return Array(size).fill(0).map(() =>
|
||||
|
|
@ -31,6 +32,8 @@ export const useGameStore = create<GameState & {
|
|||
setActionCooldown: (cooldown: number) => void;
|
||||
buyItem: (itemId: string) => void;
|
||||
sellItem: (itemId: string) => void;
|
||||
saveToSlot: (slot: number) => void;
|
||||
loadFromSlot: (slot: number) => void;
|
||||
}>((set, get) => ({
|
||||
cash: INITIAL_CASH,
|
||||
inventory: INITIAL_INVENTORY,
|
||||
|
|
@ -40,6 +43,7 @@ export const useGameStore = create<GameState & {
|
|||
plots: initializeField(INITIAL_FIELD_SIZE),
|
||||
gameSpeed: INITIAL_GAME_SPEED,
|
||||
actionCooldown: 0,
|
||||
tickCount: 0,
|
||||
|
||||
assignCrop: (row, col, cropId) => {
|
||||
set(produce(state => {
|
||||
|
|
@ -137,11 +141,6 @@ export const useGameStore = create<GameState & {
|
|||
|
||||
tick: () => {
|
||||
set(produce(state => {
|
||||
// Update cooldown
|
||||
if (state.actionCooldown > 0) {
|
||||
state.actionCooldown = Math.max(0, state.actionCooldown - (COOLDOWN_DURATION / 20));
|
||||
}
|
||||
|
||||
// Update plots
|
||||
state.plots.forEach((row: PlotState[], rowIndex: number) => {
|
||||
row.forEach((plot: PlotState, colIndex: number) => {
|
||||
|
|
@ -162,6 +161,8 @@ export const useGameStore = create<GameState & {
|
|||
}
|
||||
});
|
||||
});
|
||||
|
||||
state.tickCount = state.tickCount + 1;
|
||||
}));
|
||||
},
|
||||
|
||||
|
|
@ -228,5 +229,18 @@ export const useGameStore = create<GameState & {
|
|||
state.cash += item.sellPrice;
|
||||
state.inventory[itemId] -= 1;
|
||||
}));
|
||||
},
|
||||
|
||||
saveToSlot: (slot: number) => {
|
||||
const state = get();
|
||||
const { plant, water, harvest, tick, assignCrop, upgradeField, setGameSpeed, setActionCooldown, buyItem, sellItem, saveToSlot, loadFromSlot, ...gameState } = state;
|
||||
saveGame(slot, gameState);
|
||||
},
|
||||
|
||||
loadFromSlot: (slot: number) => {
|
||||
const savedState = loadGame(slot);
|
||||
if (savedState) {
|
||||
set(savedState);
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
|
|
|||
29
src/utils/saveSystem.ts
Normal file
29
src/utils/saveSystem.ts
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
import { GameState } from '../types';
|
||||
|
||||
const SAVE_SLOT_PREFIX = 'dionysian_idle_save_';
|
||||
|
||||
export const saveGame = (slot: number, state: GameState) => {
|
||||
try {
|
||||
const saveData = JSON.stringify(state);
|
||||
localStorage.setItem(`${SAVE_SLOT_PREFIX}${slot}`, saveData);
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.error('Failed to save game:', error);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
export const loadGame = (slot: number): GameState | null => {
|
||||
try {
|
||||
const saveData = localStorage.getItem(`${SAVE_SLOT_PREFIX}${slot}`);
|
||||
if (!saveData) return null;
|
||||
return JSON.parse(saveData);
|
||||
} catch (error) {
|
||||
console.error('Failed to load game:', error);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
export const hasSaveInSlot = (slot: number): boolean => {
|
||||
return !!localStorage.getItem(`${SAVE_SLOT_PREFIX}${slot}`);
|
||||
};
|
||||
Loading…
Reference in a new issue