Coverage for topdownengine/mobile_object/controller.py: 84%

37 statements  

« prev     ^ index     » next       coverage.py v7.15.2, created at 2026-07-24 02:27 +0000

1# Copyright (c) 2026 Shaurya Sharma 

2# SPDX-License-Identifier: MIT 

3 

4from topdownengine.controls import KeyboardInputManager 

5import pygame as pg 

6import math 

7from topdownengine import math as tde_math 

8from . import MobileObject 

9 

10class BaseController: 

11 "A base class for all MobileObject controllers." 

12 def update(self, mobile_object: MobileObject, dt: float) -> None: 

13 """Update function for MobileObject controllers. 

14  

15 Args: 

16 mobile_object (MobileObject): The MobileObject to update. 

17 dt (float): The deltatime. 

18 """ 

19 pass 

20 

21 def move(self, mobile_object: MobileObject, dt: float, dir: pg.Vector2) -> None: 

22 """Change a MobileObject's velocity using a given dir Vector. 

23  

24 Args: 

25 mobile_object (MobileObject): The MobileObject to move. 

26 dt (float): The deltatime. 

27 dir (pg.Vector2): Vector to move by. 

28 """ 

29 if dir.length() != 0: 

30 dir.normalize_ip() 

31 dir *= self.speed 

32 

33 dt_seconds = dt / 1000.0 

34 weight = 1.0 - math.exp(-self.snapping_speed * dt_seconds) 

35 mobile_object.velocity = tde_math.lerp(mobile_object.velocity, dir, weight) 

36 

37class StaticController(BaseController): 

38 "A MobileObject controller that keeps the MobileObject still." 

39 def update(self, mobile_object: MobileObject, dt: float) -> None: 

40 """Sets the MobileObject's velocity to (0, 0). 

41 

42 Args: 

43 mobile_object (MobileObject): The MobileObject to update. 

44 dt (float): The deltatime. 

45 """ 

46 mobile_object.velocity = pg.Vector2() 

47 

48class KeyboardInputController(BaseController): 

49 """A MobileObject controller that uses keyboard inputs. 

50  

51 Attributes: 

52 input_mgr (KeyboardInputManager): The input manager. 

53 speed (float): The speed. 

54 snapping_speed (float): The snapping speed. 

55 """ 

56 def __init__(self) -> None: 

57 "Initializes the input manager." 

58 self.input_mgr = KeyboardInputManager() 

59 self.speed = 2 

60 self.snapping_speed = 10.0 

61 

62 def update(self, mobile_object: MobileObject, dt: float) -> None: 

63 """Moves the MobileObject based on keyboard input. 

64  

65 Args: 

66 mobile_object (MobileObject): The MobileObject to update. 

67 dt (float): The deltatime. 

68 """ 

69 input = self.input_mgr.get_input() 

70 

71 if "Jump" in input: 

72 mobile_object.jump() 

73 

74 dir = pg.Vector2( 

75 int("Move Right" in input) - int("Move Left" in input), 

76 int("Move Down" in input) - int("Move Up" in input) 

77 ) 

78 self.move(mobile_object, dt, dir) 

79 

80class MovementAIController(BaseController): 

81 """A MobileObject controller that follows another MobileObject. 

82  

83 Attributes: 

84 target_mobile_object (MobileObject): The MobileObject to move toward. 

85 speed (float): The speed. 

86 snapping_speed (float): The snapping speed. 

87 """ 

88 def __init__(self, target_mobile_object: MobileObject) -> None: 

89 """Initialize the MovementAIController. 

90  

91 Args: 

92 target_mobile_object (MobileObject): The MobileObject to move toward. 

93 """ 

94 self.target_mobile_object = target_mobile_object 

95 self.speed = 1.5 

96 self.snapping_speed = 10.0 

97 

98 def update(self, mobile_object: MobileObject, dt: float) -> None: 

99 """Move the MobileObject towards the target. 

100  

101 Args: 

102 mobile_object (MobileObject): The MobileObject to update. 

103 dt (float): The deltatime. 

104 """ 

105 dir = self.target_mobile_object.position - mobile_object.position 

106 self.move(mobile_object, dt, dir)