Advertisement
Guest User

Untitled

a guest
Feb 28th, 2021
77
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.74 KB | None | 0 0
  1. import nico
  2. import bumpy
  3. import strformat
  4. import fpn
  5. # moves when you do - theme
  6. # control two platforming characters at the same time, and get them into their respective holes
  7. # this shouldn't be messy at all :)
  8.  
  9. # player states
  10. type States {.pure.} = enum # can only use what i explicitly typed out
  11. Moving, Ground, Turnaround, Jump, Air, AirMoving
  12.  
  13. # base types
  14. type
  15. Vec2i = object
  16. x, y: int
  17. GameObject = ref object of RootObj
  18. position: Vec2i
  19. RectObj = ref object of GameObject
  20. width, height: int
  21. RectHitbox = ref object of RootObj
  22. transform : Rect
  23. isSolid : bool
  24. Player = ref object of RectObj
  25. state : States
  26. facingRight : bool
  27. hitbox: RectHitbox
  28. velocity: Vec2i
  29. # horizontal physics
  30. groundAccel: int
  31. maxGroundSpeed: int
  32. # vertical physics
  33. airAccel: int
  34. maxAirSpeed: int
  35. jumpForce: int
  36. terminalVelocity: int
  37. gravity: int
  38. # friction
  39. staticFriction: int # should be strong to stop quickly
  40. kineticFriction: int # should be weak to facilitate movement
  41. drag: int # air friction
  42.  
  43. # WILL REMOVE LATER - IS FOR TESTING PURPOSES
  44. fixedNum: fixedPoint32
  45.  
  46. PlayerInput = ref object of RootObj
  47. pressedLeft, pressedRight, jumpPressed : bool
  48.  
  49. # global variables (used for now)
  50.  
  51. var player : Player
  52. var playerInput : PlayerInput
  53.  
  54. var randomBox : RectHitbox
  55.  
  56. proc playerInit() =
  57. player = Player(
  58.  
  59. position : Vec2i(
  60. x : screenWidth div 2,
  61. y : screenHeight div 2
  62. ),
  63. width : 2,
  64. height : 2,
  65.  
  66. state : States.Ground,
  67. facingRight : false,
  68.  
  69. velocity : Vec2i(),
  70.  
  71. groundAccel : 2,
  72. maxGroundSpeed : 4,
  73.  
  74. airAccel : 2,
  75. maxAirSpeed : 4,
  76.  
  77. jumpForce : 10,
  78. terminalVelocity : 3,
  79. gravity : 2,
  80.  
  81. staticFriction : 5, # grounded friction
  82. kineticFriction : 1, # movement friction
  83. drag : 1, # air friction essentially
  84. )
  85.  
  86. player.hitbox = RectHitbox(
  87. transform : Rect(
  88. x : float32 player.position.x,
  89. y : float32 player.position.y,
  90. w : float32 player.width,
  91. h : float32 player.height
  92. ),
  93. isSolid : true,
  94. )
  95.  
  96. # TESTING ONLY
  97. player.fixedNum = initQ22_10()
  98. # END TESTING
  99.  
  100. playerInput = PlayerInput()
  101. playerInput.pressedLeft = false
  102. playerInput.pressedRight = false
  103. playerInput.jumpPressed = false
  104.  
  105. proc gameInit() =
  106. loadFont(0, "font.png")
  107.  
  108. playerInit()
  109.  
  110. # create hitbox
  111.  
  112. randomBox = RectHitbox(
  113. transform : Rect(
  114. x : 10,
  115. y : 90,
  116. w : 90,
  117. h : 5,
  118. ),
  119. isSolid : true,
  120. )
  121.  
  122. proc playerSetInput(player : Player, playerInput: PlayerInput) =
  123. playerInput.pressedLeft = btn(pcLeft)
  124. playerInput.pressedRight = btn(pcRight)
  125. playerInput.jumpPressed = btnp(pcA)
  126.  
  127.  
  128. proc playerMoveX(player : Player, playerInput: PlayerInput) =
  129. let accel =
  130. case player.state:
  131. of States.Moving: player.groundAccel
  132. of States.AirMoving: player.airAccel
  133. else: 0
  134.  
  135. let maxSpeed =
  136. case player.state:
  137. of States.Moving: player.maxGroundSpeed
  138. of States.AirMoving: player.maxAirSpeed
  139. else: 0
  140.  
  141. if playerInput.pressedLeft:
  142. player.velocity.x -= (if player.velocity.x - accel >= -maxSpeed: accel else: 0)
  143. if playerInput.pressedRight:
  144. player.velocity.x += (if player.velocity.x + accel <= maxSpeed: accel else: 0)
  145.  
  146.  
  147. proc playerFriction(player : Player) =
  148. let friction =
  149. case player.state:
  150. of States.Moving: player.kineticFriction
  151. of States.Ground, States.Turnaround: player.staticFriction
  152. of States.Air, States.AirMoving: player.drag
  153. else: 0
  154. if player.velocity.x < 0:
  155. if player.velocity.x + friction > 0:
  156. player.velocity.x = 0
  157. else:
  158. player.velocity.x += friction
  159. elif player.velocity.x > 0:
  160. if player.velocity.x - friction < 0:
  161. player.velocity.x = 0
  162. else:
  163. player.velocity.x -= friction
  164.  
  165.  
  166. proc playerJump(player : Player) =
  167. player.velocity.y -= player.jumpForce
  168.  
  169.  
  170.  
  171. proc playerGravity(player : Player) =
  172. player.velocity.y += (if player.velocity.y + player.gravity <= player.terminalVelocity: player.gravity else: 0)
  173.  
  174. proc playerCheckCollision(player : Player, randomBox : RectHitbox) : bool =
  175. if overlaps(player.hitbox.transform, randomBox.transform):
  176. player.velocity.y = 0
  177. return true
  178. else:
  179. return false
  180.  
  181. proc playerApplyVelocity(player : Player, dt: float32) =
  182. player.position.x += player.velocity.x
  183. player.position.y += player.velocity.y
  184.  
  185. proc playerUpdateHitbox(player: Player) =
  186. player.hitbox.transform.x = float player.position.x
  187. player.hitbox.transform.y = float player.position.y
  188.  
  189. proc playerUpdate(player: Player, dt: float32) =
  190. playerSetInput(player, playerInput)
  191.  
  192. template changeToJump =
  193. if (playerInput.jumpPressed):
  194. player.state = States.Jump
  195.  
  196. template checkForGround =
  197. if playerCheckCollision(player, randomBox):
  198. player.state = States.Ground
  199.  
  200. template checkForAir =
  201. if not playerCheckCollision(player, randomBox):
  202. player.state = States.Air
  203.  
  204. case player.state:
  205. of States.Ground:
  206. #echo "Ground"
  207. playerFriction(player)
  208.  
  209. if (playerInput.pressedLeft or playerInput.pressedRight):
  210. player.state = States.Moving
  211.  
  212. checkForAir()
  213. changeToJump()
  214. of States.Moving:
  215. playerMoveX(player, playerInput)
  216. playerFriction(player)
  217.  
  218. if (playerInput.pressedLeft or playerInput.pressedRight):
  219. # the follow is to facilitate non slippery turnarounds.
  220. if(playerInput.pressedRight != player.facingRight):
  221. player.state = States.Turnaround
  222. player.facingRight = playerInput.pressedRight
  223. else:
  224. player.state = States.Ground
  225.  
  226. checkForAir()
  227. changeToJump()
  228. of States.Turnaround:
  229. playerMoveX(player, playerInput)
  230. playerFriction(player)
  231.  
  232. if (playerInput.pressedLeft or playerInput.pressedRight):
  233. player.state = States.Moving
  234. else:
  235. player.state = States.Ground
  236.  
  237. checkForAir()
  238. changeToJump()
  239. of States.Jump:
  240. playerJump(player)
  241. player.state = States.Air
  242. of States.Air:
  243. #echo "Air"
  244. playerFriction(player)
  245. playerGravity(player)
  246.  
  247. if (playerInput.pressedLeft or playerInput.pressedRight):
  248. player.state = States.AirMoving
  249.  
  250. checkForGround()
  251. of States.AirMoving:
  252. playerMoveX(player, playerInput)
  253. playerFriction(player)
  254. playerGravity(player)
  255.  
  256. if not (playerInput.pressedLeft or playerInput.pressedRight):
  257. player.state = States.Air
  258.  
  259. checkForGround()
  260.  
  261. playerApplyVelocity(player, dt)
  262. playerUpdateHitbox(player)
  263.  
  264. proc gameUpdate(dt: float32) =
  265. playerUpdate(player, dt)
  266.  
  267. # TESTING ONLY
  268. echo fmt"{player.fixedNum.toFloat()}"
  269.  
  270.  
  271. proc drawPlayer() =
  272. boxfill(player.position.x, player.position.y, player.width, player.height)
  273.  
  274. proc gameDraw() =
  275. cls()
  276.  
  277. #sets color of both text and box
  278. setColor(3)
  279.  
  280. # render player
  281. drawPlayer()
  282.  
  283. # render random hitbox
  284. boxfill(randomBox.transform.x, randomBox.transform.y, randomBox.transform.w, randomBox.transform.h)
  285.  
  286. # render text
  287. var debugStr : string = fmt"Pos: ({player.position.x}, {player.position.y})"
  288. case player.state:
  289. of States.Ground: debugStr.add("State: Ground")
  290. of States.Moving: debugStr.add("State: Moving")
  291. of States.Turnaround: debugStr.add("State: Turnaround")
  292. of States.Jump: debugStr.add("State: Jump")
  293. of States.Air: debugStr.add("State: Air")
  294. of States.AirMoving: debugStr.add("State: AirMoving")
  295. printc(debugStr, screenWidth div 2, 2)
  296.  
  297. nico.init("myOrg", "myApp")
  298. nico.createWindow("myApp", 128, 128, 4, false)
  299. nico.run(gameInit, gameUpdate, gameDraw)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement