unit keys_m; interface uses game_m, level_m; const ArrowDownOrd = -80; ArrowLeftOrd = -75; ArrowRightOrd = -77; ArrowUpOrd = -72; CtrlCOrd = 3; CtrlZOrd = 26; EscOrd = 27; EnterOrd = 13; LowerNOrd = 110; LowerYOrd = 121; SpaceOrd = 32; UpperNOrd = 78; UpperYOrd = 89; OneOrd = 49; TwoOrd = 50; ThreeOrd = 51; UpperQOrd = 81; LowerQOrd = 113; { Debug } BOrd = 98; COrd = 99; LOrd = 108; { Debug } procedure HandleKey(var g: gameState; var level: levelState); implementation uses crt, graphics_m, trace_m, creature_m, debug_m; procedure GetKey(var keyCode: integer); var c: char; begin c := ReadKey; if c = #0 then begin c := ReadKey; keyCode := -ord(c) end else begin keyCode := ord(c) end end; procedure ChangeHamsterDelta(var h: creature; k: integer); begin h.dX := 0; h.dY := 0; case k of ArrowLeftOrd: h.dX := -h.movespeed; ArrowRightOrd: h.dX := h.movespeed; ArrowUpOrd: h.dY := -h.movespeed; ArrowDownOrd: h.dY := h.movespeed; SpaceOrd: StopCreature(h) end end; procedure HandleLevelKey(var g: gameState; var level: levelState; k: integer); begin {DEBUG} if k = BOrd then Print(level.a.borders); if k = COrd then Print(level.a.captured); if k = LOrd then begin GotoXY(2, 60); write(' '); GotoXY(2, 60); writeln(GetLength(level.t)); GotoXY(1, 1) end; {DEBUG} if (k = ArrowLeftOrd) or (k = ArrowRightOrd) or (k = ArrowUpOrd) or (k = ArrowDownOrd) or (k = SpaceOrd) then begin ChangeHamsterDelta(level.h, k) end; if k = EscOrd then g.curState := gamePause end; procedure PreviousMenuState(var g: gameState); begin if (g.curMenu = menuNewGame) and not g.levelInited then g.curMenu := menuKeyInfo else if g.curMenu = menuNewGame then g.curMenu := menuContinue else g.curMenu := pred(g.curMenu) end; procedure NextMenuState(var g: gameState); begin if (g.curMenu = menuKeyInfo) and not g.levelInited or (g.curMenu = menuContinue) then begin g.curMenu := menuNewGame end else begin g.curMenu := succ(g.curMenu) end end; procedure ChangeMenuState(var g: gameState; k: integer); begin case k of ArrowUpOrd: PreviousMenuState(g); ArrowDownOrd: NextMenuState(g) end end; procedure ChooseMenuNum(var g: gameState; k: integer); begin if (k = ThreeOrd) and not g.levelInited then exit; case k of OneOrd: begin g.newGame := true; g.level := 1; g.curState := gameLevelAnnounce end; TwoOrd: g.curState := gameKeyInfo; ThreeOrd: g.curState := gameContinueLevel end end; procedure ChooseMenuMarked(var g: gameState); begin case g.curMenu of menuNewGame: begin g.newGame := true; g.level := 1; g.curState := gameLevelAnnounce end; menuKeyInfo: g.curState := gameKeyInfo; menuContinue: g.curState := gameContinueLevel end end; procedure HandleMenuKey(var g: gameState; k: integer); begin if (k = ArrowUpOrd) or (k = ArrowDownOrd) then begin EraseMenuState(g.curMenu); ChangeMenuState(g, k); DrawMenuState(g.curMenu) end; if (k = OneOrd) or (k = TwoOrd) or (k = ThreeOrd) then ChooseMenuNum(g, k); if (k = EscOrd) or (k = UpperQOrd) or (k = LowerQOrd) then g.curState := gameExit; if (k = EnterOrd) or (k = SpaceOrd) then ChooseMenuMarked(g) end; procedure HandleGameOverKey(var g: gameState; k: integer); begin case k of UpperYOrd, LowerYOrd: g.curState := gameLevelAnnounce; UpperNOrd, LowerNOrd: g.curState := gameMenu; end end; procedure ChangeExitState(k: integer; var g: gameState); begin case k of ArrowRightOrd: NextExitState(g); ArrowLeftOrd: PreviousExitState(g) end end; procedure HandleExitKey(var g: gameState; k: integer); begin if (k = ArrowLeftOrd) or (k = ArrowRightOrd) then begin EraseExitState(g.curExit); ChangeExitState(k, g); DrawExitState(g.curExit); exit end; if (k = EnterOrd) or (k = SpaceOrd) then begin if g.curExit then g.shutdown := true else g.curExit := true; end; if (k = UpperYOrd) or (k = LowerYOrd) or (k = OneOrd) then g.shutdown := true; if (k = UpperNOrd) or (k = LowerNOrd) or (k = EscOrd) or (k = TwoOrd) then g.curExit := true; g.curState := gameMenu end; procedure HandlePauseKey(var g: gameState; k: integer); begin if (k = EscOrd) or (k = SpaceOrd) then g.curState := gameUnpauseLevel; if (k = UpperQOrd) or (k = LowerQOrd) then g.curState := gameMenu end; procedure HandleInfoKey(var g: gameState; k: integer); begin if (k = EscOrd) or (k = SpaceOrd) or (k = EnterOrd) or (k = UpperQOrd) or (k = LowerQOrd) then begin g.curState := gameMenu end end; procedure HandleSceneKey(var g: gameState; k: integer); begin if (k = EscOrd) or (k = SpaceOrd) or (k = EnterOrd) then g.skipScene := true end; procedure HandleGameCompleteKey(var g: gameState; k: integer); begin if (k = EscOrd) or (k = SpaceOrd) or (k = EnterOrd) then g.curState := gameMenu end; procedure HandleKey(var g: gameState; var level: levelState); var k: integer; begin GetKey(k); if (k = CtrlCOrd) or (k = CtrlZOrd) then begin g.shutdown := true; exit end; case g.curState of gameLevelComplete, gameLevelAnnounce: HandleSceneKey(g, k); gameLevelLoop: HandleLevelKey(g, level, k); gameExit: HandleExitKey(g, k); gameMenu: HandleMenuKey(g, k); gameKeyInfo: HandleInfoKey(g, k); gamePause: HandlePauseKey(g, k); gameOver: HandleGameOverKey(g, k); gameComplete: HandleGameCompleteKey(g, k) end end; end.