Advertisement
Guest User

Pymunk and PyGame - Physics Balls

a guest
Jan 1st, 2022
62
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 10.44 KB | None | 0 0
  1. import pygame as pg
  2. import pymunk.pygame_util
  3. from pygame.locals import *
  4. from random import uniform, randrange
  5. import sys
  6. from numba import njit
  7.  
  8. pymunk.pygame_util.positive_y_is_up = False
  9.  
  10. WIDTH, HEIGHT = 1280, 720
  11. FPS = 60
  12.  
  13. # объявление всего необходимого
  14. pg.init()
  15.  
  16. display = pg.display.set_mode((WIDTH, HEIGHT), pg.RESIZABLE)
  17. pg.display.set_caption("Мячики с физикой на PyGame + Pymunk")
  18. clock = pg.time.Clock()
  19. draw_option = pymunk.pygame_util.DrawOptions(display)
  20.  
  21. space = pymunk.Space()
  22. space.gravity = 0, 2000
  23.  
  24. """ объекты """
  25. # кубик
  26. box_mass, box_size = 1, (40, 30)
  27.  
  28. # платформа
  29. segment_shape = pymunk.Segment(space.static_body, (1, HEIGHT + 35), (WIDTH + 10000, HEIGHT + 35), 50)
  30. segment_shape.elasticity = 0.5
  31. segment_shape.friction = 0.5
  32. space.add(segment_shape)
  33.  
  34. # создать мячик
  35. ball_arr = []
  36. ball_size = 10
  37. ballSize_font = pg.font.SysFont('serif', 18)
  38. ballSize_fontRender = ballSize_font.render(f"Размер мячиков: {ball_size}(↑ or ↓)", True, (0, 0, 0))
  39. placePos_ballSizeFont = ballSize_fontRender.get_rect(topleft=(5, 18))
  40.  
  41. ball_elasticity = 0.5
  42. ballElasticity_font = pg.font.SysFont('serif', 18)
  43. ballElasticity_fontRender = ballElasticity_font.render(f"Коэф. упругости мячиков: {ball_elasticity}(F1 or F2)", True,
  44.                                                        (0, 0, 0))
  45. placePos_ballElasticityFont = ballElasticity_fontRender.get_rect(topleft=(5, 36))
  46.  
  47. ball_friction = 0.5
  48. ballFriction_font = pg.font.SysFont('serif', 18)
  49. ballFriction_fontRender = ballFriction_font.render(f"Трение мячиков: {ball_friction}(F3 or F4)", True, (0, 0, 0))
  50. placePos_ballFrictionFont = ballFriction_fontRender.get_rect(topleft=(5, 54))
  51.  
  52. ball_mass = 1
  53. ballMass_font = pg.font.SysFont('serif', 18)
  54. ballMass_fontRender = ballMass_font.render(f"Масса мячиков: {ball_mass}(F5 or F6)", True, (0, 0, 0))
  55. placePos_ballMassFont = ballMass_fontRender.get_rect(topleft=(5, 72))
  56.  
  57.  
  58. def createBall(mass, radius, position, elasticity, friction, color):
  59.     ball_mass, ball_radius = mass, radius
  60.     ball_moment = pymunk.moment_for_circle(ball_mass, 0, ball_radius)
  61.     ball_body = pymunk.Body(ball_mass, ball_moment)
  62.     ball_body.position = position
  63.     ball_shape = pymunk.Circle(ball_body, ball_radius)
  64.     ball_shape.elasticity = elasticity
  65.     ball_shape.friction = friction
  66.     ball_shape.color = color
  67.     space.add(ball_body, ball_shape)
  68.     ball_arr.append(ball_body)
  69.     ball_arr.append(ball_shape)
  70.  
  71. # threading.Thread(target=createBall).start()
  72. # статический мячик для рисования платформ
  73. painter_line_arr = []
  74. painter_line_size = 10
  75. painter_line_font = pg.font.SysFont('serif', 18)
  76. painter_line_fontRender = painter_line_font.render(f"Размер кисти препятствий: {painter_line_size}(→ or ←)", True,
  77.                                                    (0, 0, 0))
  78. placePos_painter_ballFont = painter_line_fontRender.get_rect(topleft=(5, 0))
  79.  
  80. # вот тут вот я РАНЬШЕ не понимал, в чём проблема и как заставить это работать(сейчас это работает)
  81. lastMousePos = None
  82. mousePressed = False
  83.  
  84. def createPainterLine(radius, singleClickVerify):
  85.     if singleClickVerify == False:
  86.         segment_shape = pymunk.Segment(space.static_body, lastMousePos,
  87.                                        (pg.mouse.get_pos()[0], pg.mouse.get_pos()[1]), radius)
  88.         segment_shape.elasticity = 0.4
  89.         segment_shape.friction = 0.5
  90.         space.add(segment_shape)
  91.         painter_line_arr.append(segment_shape)
  92.     else:
  93.         segment_shape = pymunk.Segment(space.static_body, lastMousePos,
  94.                                        (pg.mouse.get_pos()[0] + 1, pg.mouse.get_pos()[1] + 1), radius)
  95.         segment_shape.elasticity = 0.4
  96.         segment_shape.friction = 0.5
  97.         space.add(segment_shape)
  98.         painter_line_arr.append(segment_shape)
  99. def deletePainterLine():
  100.     for i in range(0, len(painter_line_arr)):
  101.         space.remove(painter_line_arr[i])
  102.     painter_line_arr.clear()
  103.  
  104. def deleteBalls():
  105.     for i in range(0, len(ball_arr)):
  106.         space.remove(ball_arr[i])
  107.     ball_arr.clear()
  108. # надпись с FPS
  109. fps_font = pg.font.SysFont('serif', 18)
  110. fps_fontRender = fps_font.render(f"FPS = {round(clock.get_fps(), 2)}", True, (0, 0, 0))
  111. display_rect = display.get_rect()
  112. placePos_fps_font = painter_line_fontRender.get_rect(topright=(pg.display.get_window_size()[0] + 220, 0))
  113.  
  114. # создать прямоугольник
  115.  
  116.  
  117.  
  118. while True:
  119.     display.fill((0, 160, 90))
  120.  
  121.     for event in pg.event.get():
  122.         if event.type == pg.QUIT:
  123.             sys.exit()
  124.         elif event.type == pg.MOUSEBUTTONUP:
  125.             mousePressed = False
  126.         elif event.type == pg.MOUSEBUTTONDOWN:
  127.             if event.button == 1:
  128.                 createBall(ball_mass, ball_size, pg.mouse.get_pos(), ball_elasticity, ball_friction,
  129.                            [uniform(0, 255) for i in range(4)])
  130.             elif event.button == 3:
  131.                 singleClickVerify = True
  132.                 lastMousePos = pg.mouse.get_pos()
  133.                 createPainterLine(painter_line_size, singleClickVerify)
  134.                 mousePressed = True
  135.             elif event.button == 2:
  136.                 deletePainterLine()
  137.                 deleteBalls()
  138.         elif event.type == pg.MOUSEMOTION:
  139.             if mousePressed == True:
  140.                 singleClickVerify = False
  141.                 createPainterLine(painter_line_size, singleClickVerify)
  142.                 lastMousePos = pg.mouse.get_pos()
  143.         elif event.type == pg.WINDOWSIZECHANGED:
  144.             placePos_fps_font = painter_line_fontRender.get_rect(topright=(pg.display.get_window_size()[0] + 220, 0))
  145.             space.remove(segment_shape)
  146.             segment_shape = pymunk.Segment(space.static_body, (1, pg.display.get_window_size()[1] + 35),
  147.                                            (pg.display.get_window_size()[0], pg.display.get_window_size()[1] + 35), 50)
  148.             segment_shape.elasticity = 0.5
  149.             segment_shape.friction = 0.5
  150.             space.add(segment_shape)
  151.         elif event.type == pg.KEYDOWN:
  152.             if event.key == pg.K_RIGHT:
  153.                 painter_line_size += 1
  154.                 painter_line_fontRender = painter_line_font.render(
  155.                     f"Размер кисти препятствий: {painter_line_size}(→ or ←)", True,
  156.                     (0, 0, 0))
  157.  
  158.             elif event.key == pg.K_LEFT:
  159.                 painter_line_size -= 1
  160.                 painter_line_fontRender = painter_line_font.render(
  161.                     f"Размер кисти препятствий: {painter_line_size}(→ or ←)", True,
  162.                     (0, 0, 0))
  163.  
  164.             elif event.key == pg.K_UP:
  165.                 ball_size += 1
  166.                 ballSize_fontRender = ballSize_font.render(f"Размер мячиков: {ball_size}(↑ or ↓)", True, (0, 0, 0))
  167.             elif event.key == pg.K_DOWN:
  168.                 ball_size -= 1
  169.                 ballSize_fontRender = ballSize_font.render(f"Размер мячиков: {ball_size}(↑ or ↓)", True, (0, 0, 0))
  170.             elif event.key == pg.K_F1:
  171.                 temp_elasticity = ball_elasticity
  172.                 temp_elasticity += 0.1
  173.                 ball_elasticity = round(temp_elasticity, 2)
  174.                 ballElasticity_fontRender = ballElasticity_font.render(
  175.                     f"Коэф. упругости мячиков: {ball_elasticity}(F1 or F2)", True, (0, 0, 0))
  176.             elif event.key == pg.K_F2:
  177.                 temp_elasticity = ball_elasticity
  178.                 temp_elasticity -= 0.1
  179.                 ball_elasticity = round(temp_elasticity, 2)
  180.                 ballElasticity_fontRender = ballElasticity_font.render(
  181.                     f"Коэф. упругости мячиков: {ball_elasticity}(F1 or F2)", True, (0, 0, 0))
  182.                 del temp_elasticity
  183.             elif event.key == pg.K_F5:
  184.                 temp_mass = ball_mass
  185.                 temp_mass += 0.1
  186.                 ball_mass = round(temp_mass, 2)
  187.                 ballMass_fontRender = ballMass_font.render(f"Масса мячиков: {ball_mass}(F5 or F6)", True,
  188.                                                            (0, 0, 0))
  189.                 del temp_mass
  190.             elif event.key == pg.K_F6:
  191.                 temp_mass = ball_mass
  192.                 temp_mass -= 0.1
  193.                 ball_mass = round(temp_mass, 2)
  194.                 ballMass_fontRender = ballMass_font.render(f"Масса мячиков: {ball_mass}(F5 or F6)", True,
  195.                                                            (0, 0, 0))
  196.                 del temp_mass
  197.             elif event.key == pg.K_F3:
  198.                 temp_friction = ball_friction
  199.                 temp_friction += 0.1
  200.                 ball_friction = round(temp_friction, 2)
  201.                 ballFriction_fontRender = ballFriction_font.render(f"Трение мячиков: {ball_friction}(F3 or F4)", True,
  202.                                                                    (0, 0, 0))
  203.                 del temp_friction
  204.             elif event.key == pg.K_F4:
  205.                 temp_friction = ball_friction
  206.                 temp_friction -= 0.1
  207.                 ball_friction = round(temp_friction, 2)
  208.                 ballFriction_fontRender = ballFriction_font.render(f"Трение мячиков: {ball_friction}(F3 or F4)", True,
  209.                                                                    (0, 0, 0))
  210.                 del temp_friction
  211.  
  212.     mouseKeys = pg.mouse.get_pressed()
  213.     keyboardKeys = pg.key.get_pressed()
  214.     if mouseKeys[0] and keyboardKeys[K_LSHIFT]:
  215.         createBall(ball_mass, ball_size, pg.mouse.get_pos(), ball_elasticity, ball_friction,
  216.                    [uniform(0, 255) for i in range(4)])
  217.  
  218.     space.step(1 / FPS)
  219.     space.debug_draw(draw_option)
  220.  
  221.     display.blit(painter_line_fontRender, placePos_painter_ballFont)
  222.     display.blit(ballSize_fontRender, placePos_ballSizeFont)
  223.     display.blit(ballElasticity_fontRender, placePos_ballElasticityFont)
  224.     display.blit(ballMass_fontRender, placePos_ballMassFont)
  225.     display.blit(ballFriction_fontRender, placePos_ballFrictionFont)
  226.  
  227.     display.blit(fps_fontRender, placePos_fps_font)
  228.  
  229.     pg.display.flip()
  230.     clock.tick(FPS)
  231.     fps_fontRender = fps_font.render(f"FPS: {round(clock.get_fps(), 2)}", True, (0, 0, 0))
  232.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement