Skip to content

Commit

Permalink
selection control
Browse files Browse the repository at this point in the history
  • Loading branch information
Grzegorz Tańczyk committed Apr 21, 2024
1 parent c68fcee commit 89ec24b
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 12 deletions.
60 changes: 60 additions & 0 deletions games/nukes/src/controls/selection.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import React, { createContext, useContext, useReducer } from 'react';

import { LaunchSite } from '../world/world-state-types';

type SelectionDispatchAction =
| {
action: 'clear';
}
| {
action: 'set';
object: LaunchSite;
};

type Selection = {
selectedObject?: LaunchSite;
};

const initialSelection: Selection = {};

const selectionReducer: React.Reducer<Selection, SelectionDispatchAction> = (
selection: Selection,
action: SelectionDispatchAction,
) => {
if (action.action === 'clear') {
return initialSelection;
} else if (action.action === 'set') {
return { ...selection, selectedObject: action.object };
} else {
return selection;
}
};

// definition of react context for selection
const SelectionContext = createContext<Selection>(initialSelection);

// definition of dispatch function for selection context
const SelectionDispatchContext = createContext<React.Dispatch<SelectionDispatchAction>>(selectionReducer);

export function SelectionContextWrapper({ children }: { children: React.ReactNode }) {
const [selection, reducer] = useReducer(selectionReducer, initialSelection);

return (
<SelectionContext.Provider value={selection}>
<SelectionDispatchContext.Provider value={reducer}>{children}</SelectionDispatchContext.Provider>
</SelectionContext.Provider>
);
}

export function useObjectSelection(object: LaunchSite) {
const dispatch = useContext(SelectionDispatchContext);
const selection = useContext(SelectionContext);

return [selection.selectedObject?.id === object.id, () => dispatch({ action: 'set', object })] as const;
}

export function useClearSelection() {
const dispatch = useContext(SelectionDispatchContext);

return () => dispatch({ action: 'clear' });
}
38 changes: 26 additions & 12 deletions games/nukes/src/game-states/state-tech-world.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import styled from 'styled-components';
import { createWorldState } from '../world/world-state-create';
import { updateWorldState } from '../world/world-state-updates';
import { WorldState } from '../world/world-state-types';

import { SelectionContextWrapper } from '../controls/selection';
import { WorldStateRender } from '../render/world-state-render';

import { GameState, GameStateComponent } from './types';
Expand All @@ -17,20 +17,34 @@ const WorldComponent: GameStateComponent = ({ setGameState }) => {
);

return (
<StateContainer>
<div className="meta-controls">
<div>Timestamp: {worldState.timestamp}</div>
<div>
<button onClick={() => updateWorld(worldState, 1)}>+1 Second</button>
<button onClick={() => updateWorld(worldState, 10)}>+10 Seconds</button>
<button onClick={() => updateWorld(worldState, 60)}>+60 seconds</button>
</div>
</div>
<WorldStateRender state={worldState} />
</StateContainer>
<SelectionContextWrapper>
<StateContainer>
<TimeControls worldState={worldState} updateWorld={updateWorld} />
<WorldStateRender state={worldState} />
</StateContainer>
</SelectionContextWrapper>
);
};

function TimeControls({
worldState,
updateWorld,
}: {
worldState: WorldState;
updateWorld: (worldState: WorldState, deltaTime: number) => void;
}) {
return (
<div className="meta-controls">
<div>Timestamp: {worldState.timestamp}</div>
<div>
<button onClick={() => updateWorld(worldState, 1)}>+1 Second</button>
<button onClick={() => updateWorld(worldState, 10)}>+10 Seconds</button>
<button onClick={() => updateWorld(worldState, 60)}>+60 seconds</button>
</div>
</div>
);
}

const StateContainer = styled.div`
position: absolute;
left: 0;
Expand Down
11 changes: 11 additions & 0 deletions games/nukes/src/render/launch-site-render.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
import styled from 'styled-components';

import { LaunchSite } from '../world/world-state-types';
import { useObjectSelection } from '../controls/selection';

export function LaunchSiteRender({ launchSite }: { launchSite: LaunchSite }) {
const [isSelected, select] = useObjectSelection(launchSite);

return (
<LaunchSiteContainer
onClick={() => select()}
style={
{
'--x': launchSite.position.x,
'--y': launchSite.position.y,
} as React.CSSProperties
}
data-selected={isSelected}
/>
);
}
Expand All @@ -21,4 +26,10 @@ const LaunchSiteContainer = styled.div`
width: 5px;
height: 5px;
background: rgb(255, 0, 0);
cursor: pointer;
&[data-selected='true'] {
box-shadow: 0 0 10px 5px rgb(255, 0, 0);
}
`;
2 changes: 2 additions & 0 deletions games/nukes/src/world/world-state-updates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,7 @@ export function updateWorldState(state: WorldState, deltaTime: number): WorldSta
sectors: state.sectors,
};

// convert explosions to population changes

return result;
}

0 comments on commit 89ec24b

Please sign in to comment.