矩形在触地时振动。

huangapple go评论100阅读模式
英文:

rectangle vibrating when touching the ground

问题

大家好。我正在尝试学习关于瓦片地图中的碰撞。但是,我在y轴碰撞方面遇到了问题。当玩家矩形触碰地面时,它开始抖动。我一直在努力找出问题所在,但一直没有成功。有人可以帮助我吗?

这是我的代码:

英文:

everyone. I am trying to learn collisions in tilemaps. I am however having problems with the y-collision. when the player rectangle touches the ground, it starts to vibrate. I have been trying to figure out what the problem is, but to no avail. can someone help me?

Here is my code:

  1. import pygame
  2. from sys import exit
  3. pygame.init()
  4. screen = pygame.display.set_mode((800, 600))
  5. clock = pygame.time.Clock()
  6. class Player:
  7. def __init__(self, x, y):
  8. self.rect = pygame.Rect(x, y, 40, 40)
  9. self.rect.x = x
  10. self.rect.y = y
  11. self.vel = 4
  12. self.dx = 0
  13. self.dy = 0
  14. self.is_jump = False
  15. self.is_stand = False
  16. self.jump_count = 10
  17. def handle_input(self):
  18. key = pygame.key.get_pressed()
  19. if key[pygame.K_RIGHT]:
  20. self.dx = self.vel
  21. elif key[pygame.K_LEFT]:
  22. self.dx = -self.vel
  23. else:
  24. self.dx = 0
  25. if key[pygame.K_SPACE]:
  26. self.is_jump = True
  27. self.is_stand = False
  28. self.dy = -self.jump_count
  29. def update(self):
  30. self.handle_input()
  31. pygame.draw.rect(screen, (0, 255, 0), self.rect)
  32. self.rect.update(self.rect.x, self.rect.y, 40, 40)
  33. class Game:
  34. def __init__(self):
  35. self.map = [
  36. ["T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T"],
  37. ["T", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "T"],
  38. ["T", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "T"],
  39. ["T", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "T"],
  40. ["T", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "T"],
  41. ["T", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "T"],
  42. ["T", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "T"],
  43. ["T", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "T"],
  44. ["T", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "T", "T", "T", "T", "T", "T", "T"],
  45. ["T", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "T"],
  46. ["T", "T", "T", "T", "T", "T", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "T"],
  47. ["T", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "T"],
  48. ["T", "0", "P", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "T"],
  49. ["T", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "T"],
  50. ["T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T"]
  51. ]
  52. self.tiles = []
  53. for row_num, row in enumerate(self.map):
  54. for col_num, column in enumerate(row):
  55. if column == "T":
  56. rect = pygame.Rect(40*col_num, 40*row_num, 40, 40)
  57. self.tiles.append(rect)
  58. elif column == "P":
  59. self.player = Player(40*col_num, 40*row_num)
  60. self.gravity = 5
  61. self.grav_rate = 0.3
  62. def physics(self, obj):
  63. obj.dy += self.grav_rate
  64. if obj.dy > self.gravity:
  65. obj.dy = self.gravity
  66. for tile in self.tiles:
  67. coll_x = obj.rect.x + obj.dx, obj.rect.y, obj.rect.w, obj.rect.h - 1
  68. coll_y = obj.rect.x, obj.rect.y + obj.dy, obj.rect.w, obj.rect.h
  69. if tile.colliderect(coll_x):
  70. pygame.draw.rect(screen, (255, 255, 0), (tile.x, tile.y, 10, 10))
  71. if obj.dx < 0:
  72. obj.rect.left = tile.right
  73. elif obj.dx > 0:
  74. obj.rect.right = tile.left
  75. obj.dx = 0
  76. if tile.colliderect(coll_y):
  77. pygame.draw.rect(screen, (255, 255, 255), (tile.x, tile.y, 10, 10), 2)
  78. if obj.dy < 0:
  79. obj.dy = -obj.dy
  80. elif obj.dy > 0:
  81. obj.dy = 0
  82. obj.is_jump = False
  83. obj.is_stand = True
  84. obj.rect.bottom = tile.top
  85. # pygame.draw.rect(screen, (255, 255, 0), coll_x, 1)
  86. # pygame.draw.rect(screen, (255, 255, 255), coll_y, 1)
  87. obj.rect.x += obj.dx
  88. obj.rect.y += obj.dy
  89. def update(self):
  90. while True:
  91. screen.fill((0, 0, 0))
  92. for event in pygame.event.get():
  93. if event.type == pygame.QUIT:
  94. exit()
  95. for tile in self.tiles:
  96. pygame.draw.rect(screen, (255, 0, 0), tile)
  97. self.physics(self.player)
  98. self.player.update()
  99. pygame.display.update()
  100. clock.tick(60)
  101. g = Game()
  102. g.update()

答案1

得分: 0

你必须在进行碰撞检测和游戏物理运算之前更新玩家的位置:

  1. class Game:
  2. # [...]
  3. def physics(self, obj):
  4. obj.dy += self.grav_rate
  5. if obj.dy > self.gravity:
  6. obj.dy = self.gravity
  7. obj.rect.x += obj.dx # <-- 插入
  8. obj.rect.y += obj.dy
  9. for tile in self.tiles:
  10. coll_x = obj.rect.x + obj.dx, obj.rect.y, obj.rect.w, obj.rect.h - 1
  11. coll_y = obj.rect.x, obj.rect.y + obj.dy, obj.rect.w, obj.rect.h
  12. if tile.colliderect(coll_x):
  13. pygame.draw.rect(screen, (255, 255, 0), (tile.x, tile.y, 10, 10))
  14. if obj.dx < 0:
  15. obj.rect.left = tile.right
  16. elif obj.dx > 0:
  17. obj.rect.right = tile.left
  18. obj.dx = 0
  19. if tile.colliderect(coll_y):
  20. pygame.draw.rect(screen, (255, 255, 255), (tile.x, tile.y, 10, 10), 2)
  21. if obj.dy < 0:
  22. obj.dy = -obj.dy
  23. elif obj.dy > 0:
  24. obj.dy = 0
  25. obj.is_jump = False
  26. obj.is_stand = True
  27. obj.rect.bottom = tile.top
  28. # obj.rect.x += obj.dx <-- 删除
  29. # obj.rect.y += obj.dy
英文:

You must update the player's position before doing collision detection and game physics:

  1. class Game:
  2. # [...]
  3. def physics(self, obj):
  4. obj.dy += self.grav_rate
  5. if obj.dy &gt; self.gravity:
  6. obj.dy = self.gravity
  7. obj.rect.x += obj.dx #&lt;-- INSERT
  8. obj.rect.y += obj.dy
  9. for tile in self.tiles:
  10. coll_x = obj.rect.x + obj.dx, obj.rect.y, obj.rect.w, obj.rect.h - 1
  11. coll_y = obj.rect.x, obj.rect.y + obj.dy, obj.rect.w, obj.rect.h
  12. if tile.colliderect(coll_x):
  13. pygame.draw.rect(screen, (255, 255, 0), (tile.x, tile.y, 10, 10))
  14. if obj.dx &lt; 0:
  15. obj.rect.left = tile.right
  16. elif obj.dx &gt; 0:
  17. obj.rect.right = tile.left
  18. obj.dx = 0
  19. if tile.colliderect(coll_y):
  20. pygame.draw.rect(screen, (255, 255, 255), (tile.x, tile.y, 10, 10), 2)
  21. if obj.dy &lt; 0:
  22. obj.dy = -obj.dy
  23. elif obj.dy &gt; 0:
  24. obj.dy = 0
  25. obj.is_jump = False
  26. obj.is_stand = True
  27. obj.rect.bottom = tile.top
  28. # obj.rect.x += obj.dx &lt;-- DELETE
  29. # obj.rect.y += obj.dy

huangapple
  • 本文由 发表于 2023年6月19日 23:01:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/76507872.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定