bugfixes, offline mode
This commit is contained in:
parent
9af9c7867a
commit
9f544a32ab
|
|
@ -74,6 +74,8 @@
|
||||||
.school {
|
.school {
|
||||||
grid-area: school;
|
grid-area: school;
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
|
|
||||||
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.unit {
|
.unit {
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,8 @@ import { DebugView } from './views/DebugView'
|
||||||
|
|
||||||
export const App = observer(function () {
|
export const App = observer(function () {
|
||||||
|
|
||||||
|
console.dir(performance.now());
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="App">
|
<div className="App">
|
||||||
<StatsView />
|
<StatsView />
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@ export class Calendar {
|
||||||
public static deserialize(data: CalendarDto): Calendar {
|
public static deserialize(data: CalendarDto): Calendar {
|
||||||
const calendar = new Calendar();
|
const calendar = new Calendar();
|
||||||
|
|
||||||
|
calendar.day = data.day;
|
||||||
calendar.progress = Progress.deserialize(data.progress, true, calendar.handleProgress.bind(calendar));
|
calendar.progress = Progress.deserialize(data.progress, true, calendar.handleProgress.bind(calendar));
|
||||||
|
|
||||||
return calendar;
|
return calendar;
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,10 @@ export class Game {
|
||||||
makeAutoObservable(this);
|
makeAutoObservable(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public restart() {
|
||||||
|
this.school = new School();
|
||||||
|
}
|
||||||
|
|
||||||
public save(): void {
|
public save(): void {
|
||||||
const data = this.school.serialize();
|
const data = this.school.serialize();
|
||||||
localStorage.setItem('save', JSON.stringify(data))
|
localStorage.setItem('save', JSON.stringify(data))
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ import { Upgrades } from './upgrades';
|
||||||
import { PartialResourceSet, ResourceSet } from '../types/resources';
|
import { PartialResourceSet, ResourceSet } from '../types/resources';
|
||||||
import { addResourceSets, fullResourceSet, multiplyResourceSet, roundResourceSet, subtractResourceSets } from '../utils/resources';
|
import { addResourceSets, fullResourceSet, multiplyResourceSet, roundResourceSet, subtractResourceSets } from '../utils/resources';
|
||||||
import { v7 as uuid } from 'uuid';
|
import { v7 as uuid } from 'uuid';
|
||||||
import { GameClock } from '../utils/gameClock';
|
import { GameClock, nowTime } from '../utils/gameClock';
|
||||||
import { Calendar, CalendarDto } from './calendar';
|
import { Calendar, CalendarDto } from './calendar';
|
||||||
import { getRandomHumanName } from '../utils/humanNames';
|
import { getRandomHumanName } from '../utils/humanNames';
|
||||||
import { Time as Time } from './time';
|
import { Time as Time } from './time';
|
||||||
|
|
@ -50,12 +50,10 @@ export class School {
|
||||||
}
|
}
|
||||||
|
|
||||||
public tick(time: number) {
|
public tick(time: number) {
|
||||||
const scaledTime = time;
|
this.calendar.progress.tick(time);
|
||||||
|
|
||||||
this.calendar.progress.tick(scaledTime);
|
|
||||||
|
|
||||||
for (let unit of this.units)
|
for (let unit of this.units)
|
||||||
unit.progress.tick(scaledTime);
|
unit.progress.tick(time);
|
||||||
|
|
||||||
this.tps = GameClock.tps;
|
this.tps = GameClock.tps;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,10 +18,10 @@ export const upgrades: UpgradePrefab[] = [
|
||||||
{
|
{
|
||||||
id: 'moreStudents',
|
id: 'moreStudents',
|
||||||
name: "Больше учеников",
|
name: "Больше учеников",
|
||||||
description: (level) => `Увеличить количество учеников с ${level} до ${level + 1}`,
|
description: (level) => `Увеличить количество учеников с ${level + 1} до ${level + 2}`,
|
||||||
costToView: (level) => fullResourceSet(),
|
costToView: (level) => fullResourceSet(),
|
||||||
costToOpen: (level) => ({ reputation: 20 * (level / 10 + 1) }),
|
costToOpen: (level) => ({ reputation: 20 * (level / 10 + 1) }),
|
||||||
costToBuy: (level) => ({ gold: 10 }),
|
costToBuy: (level) => ({ gold: 10 * (level + 1) }),
|
||||||
execute: (level) => {
|
execute: (level) => {
|
||||||
game.school.increaseStudentCount();
|
game.school.increaseStudentCount();
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,10 @@
|
||||||
import { game } from "../model/game";
|
import { game } from "../model/game";
|
||||||
import { ExternalSignal } from "./mobx/externalSignal";
|
import { ExternalSignal } from "./mobx/externalSignal";
|
||||||
|
|
||||||
|
export function nowTime() {
|
||||||
|
return performance.timeOrigin + performance.now();
|
||||||
|
}
|
||||||
|
|
||||||
export class GameClock {
|
export class GameClock {
|
||||||
|
|
||||||
public static lastTime = 0;
|
public static lastTime = 0;
|
||||||
|
|
@ -9,27 +13,18 @@ export class GameClock {
|
||||||
|
|
||||||
public static readonly pausedSignal = new ExternalSignal('GameClock.paused');
|
public static readonly pausedSignal = new ExternalSignal('GameClock.paused');
|
||||||
|
|
||||||
// public static async start(): Promise<void> {
|
|
||||||
// let lastTime = performance.now();
|
|
||||||
|
|
||||||
// setInterval(() => {
|
|
||||||
// let now = performance.now();
|
|
||||||
// let delta = now - lastTime;
|
|
||||||
|
|
||||||
// school.tick(delta / 1000);
|
|
||||||
|
|
||||||
// lastTime = now;
|
|
||||||
// }, 33);
|
|
||||||
// }
|
|
||||||
|
|
||||||
public static start(): void {
|
public static start(): void {
|
||||||
const loop = (now: number) => {
|
this.lastTime = nowTime();
|
||||||
|
|
||||||
|
const loop = () => {
|
||||||
|
if (GameClock.paused)
|
||||||
|
return;
|
||||||
|
|
||||||
|
let now = nowTime();
|
||||||
|
|
||||||
let delta = now - GameClock.lastTime;
|
let delta = now - GameClock.lastTime;
|
||||||
GameClock.lastTime = now;
|
GameClock.lastTime = now;
|
||||||
|
|
||||||
if (GameClock.paused)
|
|
||||||
delta *= 0;
|
|
||||||
|
|
||||||
GameClock.frames.push(now);
|
GameClock.frames.push(now);
|
||||||
while (GameClock.frames[0] < now - 1000)
|
while (GameClock.frames[0] < now - 1000)
|
||||||
GameClock.frames.shift();
|
GameClock.frames.shift();
|
||||||
|
|
@ -63,12 +58,20 @@ export class GameClock {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static pause() {
|
public static pause() {
|
||||||
|
if (GameClock.paused)
|
||||||
|
return;
|
||||||
|
|
||||||
GameClock.paused = true;
|
GameClock.paused = true;
|
||||||
GameClock.pausedSignal.trigger();
|
GameClock.pausedSignal.trigger();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static resume() {
|
public static resume() {
|
||||||
|
if (!GameClock.paused)
|
||||||
|
return;
|
||||||
|
|
||||||
GameClock.paused = false;
|
GameClock.paused = false;
|
||||||
GameClock.pausedSignal.trigger();
|
GameClock.pausedSignal.trigger();
|
||||||
|
|
||||||
|
GameClock.start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,22 +0,0 @@
|
||||||
import { observer } from "mobx-react-lite";
|
|
||||||
import { school } from "../model/school";
|
|
||||||
import { Student } from "../model/student";
|
|
||||||
import { Owner } from "../model/owner";
|
|
||||||
import { OwnerUnitView } from "./OwnerUnitView";
|
|
||||||
import { IUnit } from "../types/unit";
|
|
||||||
|
|
||||||
export const UnitListView = observer(function () {
|
|
||||||
|
|
||||||
function renderUnit(unit: IUnit) {
|
|
||||||
if (unit instanceof Owner)
|
|
||||||
return <OwnerUnitView unit={unit} />
|
|
||||||
// // else if (unit instanceof Student)
|
|
||||||
// // return StudentView({ unit });
|
|
||||||
else
|
|
||||||
return '???';
|
|
||||||
}
|
|
||||||
|
|
||||||
return <ul>{
|
|
||||||
school.units.map((unit) => <li className="unit" key={unit.id}>{renderUnit(unit)}</li>)
|
|
||||||
}</ul>
|
|
||||||
});
|
|
||||||
|
|
@ -7,6 +7,10 @@ export const DebugView = observer(function () {
|
||||||
|
|
||||||
const [skipTime, setSkipTime] = useState<number>(5);
|
const [skipTime, setSkipTime] = useState<number>(5);
|
||||||
|
|
||||||
|
const isDebugMode = location.hostname === "localhost" ||
|
||||||
|
location.hostname === "127.0.0.1" ||
|
||||||
|
location.hostname === "[::1]";
|
||||||
|
|
||||||
function handleTimeScaleChange(event: ChangeEvent<HTMLInputElement>): void {
|
function handleTimeScaleChange(event: ChangeEvent<HTMLInputElement>): void {
|
||||||
game.school.time.setTimeScale(Number(event.target.value));
|
game.school.time.setTimeScale(Number(event.target.value));
|
||||||
}
|
}
|
||||||
|
|
@ -15,6 +19,10 @@ export const DebugView = observer(function () {
|
||||||
GameClock.skipTime(skipTime);
|
GameClock.skipTime(skipTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function handleRestartClick(): void {
|
||||||
|
game.restart();
|
||||||
|
}
|
||||||
|
|
||||||
function handleSaveClick(): void {
|
function handleSaveClick(): void {
|
||||||
game.save();
|
game.save();
|
||||||
}
|
}
|
||||||
|
|
@ -22,6 +30,7 @@ export const DebugView = observer(function () {
|
||||||
function handleLoadClick(): void {
|
function handleLoadClick(): void {
|
||||||
game.school.time.pause();
|
game.school.time.pause();
|
||||||
game.load();
|
game.load();
|
||||||
|
game.school.time.resume();
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleTickClick(): void {
|
function handleTickClick(): void {
|
||||||
|
|
@ -32,31 +41,40 @@ export const DebugView = observer(function () {
|
||||||
return <div className="debug">
|
return <div className="debug">
|
||||||
<div>
|
<div>
|
||||||
Время
|
Время
|
||||||
<div className="timeScale">
|
{
|
||||||
Масштаб
|
isDebugMode
|
||||||
<input
|
? <div className="timeScale">
|
||||||
type="range"
|
Масштаб
|
||||||
min={1}
|
<input
|
||||||
max={100}
|
type="range"
|
||||||
step={1}
|
min={1}
|
||||||
value={game.school.time.timeScale}
|
max={100}
|
||||||
onChange={handleTimeScaleChange}
|
step={1}
|
||||||
style={{ width: '100%' }}
|
value={game.school.time.timeScale}
|
||||||
/>
|
onChange={handleTimeScaleChange}
|
||||||
x{game.school.time.timeScale}
|
style={{ width: '100%' }}
|
||||||
</div>
|
/>
|
||||||
|
x{game.school.time.timeScale}
|
||||||
|
</div>
|
||||||
|
: <></>
|
||||||
|
}
|
||||||
{
|
{
|
||||||
game.school.time.paused
|
game.school.time.paused
|
||||||
? <button onClick={() => game.school.time.resume()}>|></button>
|
? <button onClick={() => game.school.time.resume()}>|></button>
|
||||||
: <button onClick={() => game.school.time.pause()}>||</button>
|
: <button onClick={() => game.school.time.pause()}>||</button>
|
||||||
|
}
|
||||||
|
{
|
||||||
|
isDebugMode
|
||||||
|
? <button onClick={handleSkipTime}>
|
||||||
|
<input type="number" value={skipTime} onChange={(e) => setSkipTime(Number(e.target.value))}></input>
|
||||||
|
Пропустить
|
||||||
|
</button>
|
||||||
|
: <></>
|
||||||
}
|
}
|
||||||
<button onClick={handleSkipTime}>
|
|
||||||
<input type="number" value={skipTime} onChange={(e) => setSkipTime(Number(e.target.value))}></input>
|
|
||||||
Пропустить
|
|
||||||
</button>
|
|
||||||
<button onClick={handleTickClick}>Tick</button>
|
<button onClick={handleTickClick}>Tick</button>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
|
<button onClick={handleRestartClick}>Restart</button>
|
||||||
<button onClick={handleSaveClick}>Save</button>
|
<button onClick={handleSaveClick}>Save</button>
|
||||||
<button onClick={handleLoadClick}>Load</button>
|
<button onClick={handleLoadClick}>Load</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -8,15 +8,6 @@ import { game } from "../model/game";
|
||||||
|
|
||||||
export const UnitListView = observer(function () {
|
export const UnitListView = observer(function () {
|
||||||
|
|
||||||
function renderUnit(unit: IUnit) {
|
|
||||||
if (unit instanceof Owner)
|
|
||||||
return <OwnerUnitView unit={unit} />
|
|
||||||
else if (unit instanceof Student)
|
|
||||||
return <StudentUnitView unit={unit} />
|
|
||||||
else
|
|
||||||
return '???';
|
|
||||||
}
|
|
||||||
|
|
||||||
return <div className="units">
|
return <div className="units">
|
||||||
<div className="owner">
|
<div className="owner">
|
||||||
<OwnerUnitView unit={game.school.owner} />
|
<OwnerUnitView unit={game.school.owner} />
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue