Advertisement
FaDaQ

Untitled

Mar 20th, 2022
753
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 16.63 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. from sys import exit as sysexit
  6.  
  7. pymunk.pygame_util.positive_y_is_up = False
  8.  
  9. WIDTH, HEIGHT = 1280, 720
  10. FPS = 60
  11.  
  12. # объявление всего необходимого
  13. pg.init()
  14.  
  15. display = pg.display.set_mode((WIDTH, HEIGHT), pg.RESIZABLE)
  16. pg.display.set_caption("Мячики с физикой на PyGame + Pymunk")
  17. clock = pg.time.Clock()
  18. draw_option = pymunk.pygame_util.DrawOptions(display)
  19.  
  20. space = pymunk.Space()
  21. space.gravity = 0, 2000
  22.  
  23. """ объекты """
  24. # платформы
  25. segment_shape = pymunk.Segment(space.static_body, (0, HEIGHT + 35), (WIDTH + 10000, HEIGHT + 35), 50)
  26. segment_shape.elasticity = 0.5
  27. segment_shape.friction = 0.5
  28. space.add(segment_shape)
  29.  
  30. verifyLimitCreation = False
  31. temp = []
  32.  
  33.  
  34. def createWindowLimits(create):
  35.     global temp
  36.     global verifyLimitCreation
  37.     if create:
  38.         temp = []
  39.         verifyLimitCreation = True
  40.         segment_shape = pymunk.Segment(space.static_body, (-35, 0), (-35, pg.display.get_window_size()[1]), 50)
  41.         segment_shape.elasticity = 0.5
  42.         segment_shape.friction = 0.5
  43.         temp.append(segment_shape)
  44.  
  45.         segment_shape = pymunk.Segment(space.static_body, (pg.display.get_window_size()[0] + 35, 0),
  46.                                        (pg.display.get_window_size()[0] + 35, pg.display.get_window_size()[1]), 50)
  47.         segment_shape.elasticity = 0.5
  48.         segment_shape.friction = 0.5
  49.         temp.append(segment_shape)
  50.  
  51.         segment_shape = pymunk.Segment(space.static_body, (0, 0 - 35), (pg.display.get_window_size()[0], 0 - 35), 50)
  52.         segment_shape.elasticity = 0.5
  53.         segment_shape.friction = 0.5
  54.         temp.append(segment_shape)
  55.         for i in temp:
  56.             space.add(i)
  57.     else:
  58.         for i in temp:
  59.             space.remove(i)
  60.         verifyLimitCreation = False
  61.  
  62.  
  63. # создать мячик
  64. ball_arr = []
  65. ball_size = 10
  66. ballSize_font = pg.font.SysFont('serif', 18)
  67. ballSize_fontRender = ballSize_font.render(f"Размер мячиков: {ball_size}(↑ or ↓)", True, (0, 0, 0))
  68. placePos_ballSizeFont = ballSize_fontRender.get_rect(topleft=(5, 18))
  69.  
  70. ball_elasticity = 0.5
  71. ballElasticity_font = pg.font.SysFont('serif', 18)
  72. ballElasticity_fontRender = ballElasticity_font.render(f"Коэф. упругости мячиков: {ball_elasticity}(F1 or F2)", True,
  73.                                                        (0, 0, 0))
  74. placePos_ballElasticityFont = ballElasticity_fontRender.get_rect(topleft=(5, 36))
  75.  
  76. ball_friction = 0.5
  77. ballFriction_font = pg.font.SysFont('serif', 18)
  78. ballFriction_fontRender = ballFriction_font.render(f"Трение мячиков: {ball_friction}(F3 or F4)", True, (0, 0, 0))
  79. placePos_ballFrictionFont = ballFriction_fontRender.get_rect(topleft=(5, 54))
  80.  
  81. ball_mass = 1
  82. ballMass_font = pg.font.SysFont('serif', 18)
  83. ballMass_fontRender = ballMass_font.render(f"Масса мячиков: {ball_mass}(F5 or F6)", True, (0, 0, 0))
  84. placePos_ballMassFont = ballMass_fontRender.get_rect(topleft=(5, 72))
  85.  
  86.  
  87. def createBall(mass, radius, position, elasticity, friction, color):
  88.     ball_mass, ball_radius = mass, radius
  89.     ball_moment = pymunk.moment_for_circle(ball_mass, 0, ball_radius)
  90.     ball_body = pymunk.Body(ball_mass, ball_moment)
  91.     ball_body.position = position
  92.     ball_shape = pymunk.Circle(ball_body, ball_radius)
  93.     ball_shape.elasticity = elasticity
  94.     ball_shape.friction = friction
  95.     ball_shape.color = color
  96.     space.add(ball_body, ball_shape)
  97.     ball_arr.append(ball_body)
  98.     ball_arr.append(ball_shape)
  99.  
  100.  
  101. # статическая линия для рисования платформ
  102. painter_line_arr = []
  103. # painter_line_arrTemp - нужен для запоминания удалённых объектов для их возвращения на сцену
  104. painter_line_arrTemp = []
  105. painter_line_size = 10
  106. painter_line_font = pg.font.SysFont('serif', 18)
  107. painter_line_fontRender = painter_line_font.render(f"Размер кисти препятствий: {painter_line_size}(→ or ←)", True,
  108.                                                    (0, 0, 0))
  109. placePos_painter_ballFont = painter_line_fontRender.get_rect(topleft=(5, 0))
  110.  
  111. # вот тут вот я РАНЬШЕ не понимал, в чём проблема и как заставить это работать(сейчас это работает)
  112. lastMousePos = None
  113. mousePressed = False
  114.  
  115.  
  116. def createPainterLine(radius, singleClickVerify):
  117.     if singleClickVerify == False:
  118.         segment_shape = pymunk.Segment(space.static_body, lastMousePos,
  119.                                        (pg.mouse.get_pos()[0], pg.mouse.get_pos()[1]), radius)
  120.         segment_shape.elasticity = 0.4
  121.         segment_shape.friction = 0.5
  122.         space.add(segment_shape)
  123.         painter_line_arr.append(segment_shape)
  124.     else:
  125.         segment_shape = pymunk.Segment(space.static_body, lastMousePos,
  126.                                        (pg.mouse.get_pos()[0] + 1, pg.mouse.get_pos()[1] + 1), radius)
  127.         segment_shape.elasticity = 0.4
  128.         segment_shape.friction = 0.5
  129.         space.add(segment_shape)
  130.         painter_line_arr.append(segment_shape)
  131.  
  132.  
  133. def deletePainterLine():
  134.     for i in range(0, len(painter_line_arr)):
  135.         space.remove(painter_line_arr[i])
  136.     painter_line_arr.clear()
  137.  
  138.  
  139. def deleteBalls():
  140.     for i in range(0, len(ball_arr)):
  141.         space.remove(ball_arr[i])
  142.     ball_arr.clear()
  143.  
  144.  
  145. def deleteRectangles():
  146.     for i in range(0, len(rectangle_arr)):
  147.         space.remove(rectangle_arr[i])
  148.     rectangle_arr.clear()
  149.  
  150.  
  151. # надпись с FPS
  152. fps_font = pg.font.SysFont('serif', 18)
  153. fps_fontRender = fps_font.render(f"FPS = {round(clock.get_fps(), 2)}", True, (0, 0, 0))
  154. display_rect = display.get_rect()
  155. placePos_fps_font = painter_line_fontRender.get_rect(topright=(pg.display.get_window_size()[0] + 220, 0))
  156.  
  157. # создать прямоугольник
  158. rectangle_arr = []
  159. rectangle_mass = 1
  160. rectangle_width = 30
  161. rectangle_height = 30
  162. rectangle_elasticity = 0.5
  163. rectangle_friction = 0.5
  164.  
  165. rect_font = pg.font.SysFont('serif', 18)
  166. rectWidth_fontRender = rect_font.render(f"Ширина прямоугольников: {rectangle_width}(F7 or F8)", True, (0, 0, 0))
  167. placePos_rectWidthFont = rectWidth_fontRender.get_rect(topleft=(320, 0))
  168.  
  169. rect_font = pg.font.SysFont('serif', 18)
  170. rectHeight_fontRender = rect_font.render(f"Высота прямоугольников: {rectangle_height}(F9 or F10)", True, (0, 0, 0))
  171. placePos_rectHeightFont = ballSize_fontRender.get_rect(topleft=(320, 18))
  172.  
  173.  
  174. def CreateRectangle(rectangle_mass, pos, rectangle_height, rectagle_width, rectangle_elasticity, rectangle_friction):
  175.     square_mass, square_size = rectangle_mass, (rectagle_width, rectangle_height)
  176.     square_moment = pymunk.moment_for_box(square_mass, square_size)
  177.     square_body = pymunk.Body(square_mass, square_moment)
  178.     square_body.position = pos
  179.     square_shape = pymunk.Poly.create_box(square_body, square_size)
  180.     square_shape.elasticity = rectangle_elasticity
  181.     square_shape.friction = rectangle_friction
  182.     square_shape.color = [randrange(256) for i in range(4)]
  183.     rectangle_arr.append(square_shape)
  184.     space.add(square_body, square_shape)
  185.  
  186. # надпись гравитации
  187. gravity = True
  188. gravity_font = pg.font.SysFont('serif', 18)
  189. gravity_fontRender = rect_font.render(f"Гравитация: {gravity}(G)", True, (0, 0, 0))
  190. placePos_Gravityfont = gravity_fontRender.get_rect(topright=(pg.display.get_window_size()[0] - 5, 18))
  191.  
  192.  
  193. while True:
  194.     display.fill((0, 160, 90))
  195.  
  196.     mouseKeys = pg.mouse.get_pressed()
  197.     keyboardKeys = pg.key.get_pressed()
  198.  
  199.     for event in pg.event.get():
  200.         if event.type == pg.QUIT:
  201.             sysexit()
  202.         elif event.type == pg.MOUSEBUTTONUP:
  203.             mousePressed = False
  204.             f1pressed = False
  205.         elif event.type == pg.MOUSEBUTTONDOWN:
  206.             if event.button == 1:
  207.                 createBall(ball_mass, ball_size, pg.mouse.get_pos(), ball_elasticity, ball_friction,
  208.                            [uniform(0, 255) for i in range(4)])
  209.             elif event.button == 3:
  210.                 singleClickVerify = True
  211.                 lastMousePos = pg.mouse.get_pos()
  212.                 createPainterLine(painter_line_size, singleClickVerify)
  213.                 mousePressed = True
  214.             elif event.button == 2:
  215.                 deletePainterLine()
  216.                 deleteBalls()
  217.                 deleteRectangles()
  218.         elif event.type == pg.MOUSEMOTION:
  219.             if mousePressed == True:
  220.                 singleClickVerify = False
  221.                 createPainterLine(painter_line_size, singleClickVerify)
  222.                 lastMousePos = pg.mouse.get_pos()
  223.         elif event.type == pg.WINDOWSIZECHANGED:
  224.             placePos_Gravityfont = gravity_fontRender.get_rect(topright=(pg.display.get_window_size()[0] - 5, 18))
  225.             placePos_fps_font = painter_line_fontRender.get_rect(topright=(pg.display.get_window_size()[0] + 220, 0))
  226.             space.remove(segment_shape)
  227.             segment_shape = pymunk.Segment(space.static_body, (1, pg.display.get_window_size()[1] + 35),
  228.                                            (pg.display.get_window_size()[0], pg.display.get_window_size()[1] + 35), 50)
  229.             segment_shape.elasticity = 0.5
  230.             segment_shape.friction = 0.5
  231.             space.add(segment_shape)
  232.  
  233.             if verifyLimitCreation:
  234.                 for i in temp:
  235.                     space.remove(i)
  236.                 createWindowLimits(True)
  237.         elif event.type == pg.KEYDOWN:
  238.             if event.key == pg.K_RIGHT:
  239.  
  240.                 painter_line_size += 1
  241.                 painter_line_fontRender = painter_line_font.render(
  242.                     f"Размер кисти препятствий: {painter_line_size}(→ or ←)", True,
  243.                     (0, 0, 0))
  244.  
  245.             elif event.key == K_LEFT:
  246.                 painter_line_size -= 1
  247.                 painter_line_fontRender = painter_line_font.render(
  248.                     f"Размер кисти препятствий: {painter_line_size}(→ or ←)", True,
  249.                     (0, 0, 0))
  250.  
  251.             elif event.key == K_UP:
  252.                 ball_size += 1
  253.                 ballSize_fontRender = ballSize_font.render(f"Размер мячиков: {ball_size}(↑ or ↓)", True, (0, 0, 0))
  254.             elif event.key == K_DOWN:
  255.                 ball_size -= 1
  256.                 ballSize_fontRender = ballSize_font.render(f"Размер мячиков: {ball_size}(↑ or ↓)", True, (0, 0, 0))
  257.             elif event.key == K_F1:
  258.                 f1pressed = True
  259.                 temp_elasticity = ball_elasticity
  260.                 temp_elasticity += 0.1
  261.                 ball_elasticity = round(temp_elasticity, 2)
  262.                 ballElasticity_fontRender = ballElasticity_font.render(
  263.                     f"Коэф. упругости мячиков: {ball_elasticity}(F1 or F2)", True, (0, 0, 0))
  264.             elif event.key == K_F2:
  265.                 temp_elasticity = ball_elasticity
  266.                 temp_elasticity -= 0.1
  267.                 ball_elasticity = round(temp_elasticity, 2)
  268.                 ballElasticity_fontRender = ballElasticity_font.render(
  269.                     f"Коэф. упругости мячиков: {ball_elasticity}(F1 or F2)", True, (0, 0, 0))
  270.                 del temp_elasticity
  271.             elif event.key == K_F5:
  272.                 temp_mass = ball_mass
  273.                 temp_mass += 0.1
  274.                 ball_mass = round(temp_mass, 2)
  275.                 ballMass_fontRender = ballMass_font.render(f"Масса мячиков: {ball_mass}(F5 or F6)", True,
  276.                                                            (0, 0, 0))
  277.                 del temp_mass
  278.             elif event.key == K_F6:
  279.                 temp_mass = ball_mass
  280.                 if temp_mass != 0.1:
  281.                     temp_mass -= 0.1
  282.                     ball_mass = round(temp_mass, 2)
  283.                     ballMass_fontRender = ballMass_font.render(f"Масса мячиков: {ball_mass}(F5 or F6)", True,
  284.                                                                (0, 0, 0))
  285.                     del temp_mass
  286.                 else:
  287.                     pass
  288.             elif event.key == K_F3:
  289.                 temp_friction = ball_friction
  290.                 temp_friction += 0.1
  291.                 ball_friction = round(temp_friction, 2)
  292.                 ballFriction_fontRender = ballFriction_font.render(f"Трение мячиков: {ball_friction}(F3 or F4)", True,
  293.                                                                    (0, 0, 0))
  294.                 del temp_friction
  295.             elif event.key == K_F4:
  296.                 temp_friction = ball_friction
  297.                 temp_friction -= 0.1
  298.                 ball_friction = round(temp_friction, 2)
  299.                 ballFriction_fontRender = ballFriction_font.render(f"Трение мячиков: {ball_friction}(F3 or F4)", True,
  300.                                                                    (0, 0, 0))
  301.                 del temp_friction
  302.             elif event.key == K_F7:
  303.                 rectangle_width += 1
  304.                 rectWidth_fontRender = rect_font.render(f"Ширина прямоугольников: {rectangle_width}(F7 or F8)", True,
  305.                                                         (0, 0, 0))
  306.             elif event.key == K_F8:
  307.                 rectangle_width -= 1
  308.                 rectWidth_fontRender = rect_font.render(f"Ширина прямоугольников: {rectangle_width}(F7 or F8)", True,
  309.                                                         (0, 0, 0))
  310.             elif event.key == K_F9:
  311.                 rectangle_height += 1
  312.                 rectHeight_fontRender = rect_font.render(f"Высота прямоугольников: {rectangle_height}(F9 or F10)", True,
  313.                                                          (0, 0, 0))
  314.             elif event.key == K_F10:
  315.                 rectangle_height -= 1
  316.                 rectHeight_fontRender = rect_font.render(f"Высота прямоугольников: {rectangle_height}(F9 or F10)", True,
  317.                                                          (0, 0, 0))
  318.             elif event.key == K_l:
  319.                 if verifyLimitCreation == False:
  320.                     createWindowLimits(True)
  321.                 else:
  322.                     createWindowLimits(False)
  323.             elif event.key == K_r:
  324.                 CreateRectangle(rectangle_mass, pg.mouse.get_pos(), rectangle_height, rectangle_width, ball_elasticity, ball_friction)
  325.             elif event.key == K_g:
  326.                 if gravity:
  327.                     space.gravity = 0, 0
  328.                     gravity = False
  329.                     gravity_fontRender = rect_font.render(f"Гравитация: {gravity}(G)", True, (0, 0, 0))
  330.                 else:
  331.                     space.gravity = 0, 2000
  332.                     gravity = True
  333.                     gravity_fontRender = rect_font.render(f"Гравитация: {gravity}(G)", True, (0, 0, 0))
  334.  
  335.     if mouseKeys[0] and keyboardKeys[K_LSHIFT]:
  336.         createBall(ball_mass, ball_size, pg.mouse.get_pos(), ball_elasticity, ball_friction,
  337.                    [uniform(0, 255) for i in range(4)])
  338.  
  339.     elif keyboardKeys[K_r] and keyboardKeys[K_LSHIFT]:
  340.         pass
  341.     if keyboardKeys[K_LCTRL] and keyboardKeys[K_z] and not keyboardKeys[K_LSHIFT]:
  342.         try:
  343.             space.remove(painter_line_arr[-1])
  344.             painter_line_arrTemp.append(painter_line_arr[-1])
  345.             painter_line_arr.pop(-1)
  346.         except IndexError:
  347.             painter_line_arrTemp.clear()
  348.             pass
  349.     if keyboardKeys[K_LCTRL] and keyboardKeys[K_z] and keyboardKeys[K_LSHIFT]:
  350.         try:
  351.             space.add(painter_line_arrTemp[-1])
  352.             painter_line_arr.append(painter_line_arrTemp[-1])
  353.             painter_line_arrTemp.pop(-1)
  354.         except:
  355.             pass
  356.     space.step(1 / FPS)
  357.     space.debug_draw(draw_option)
  358.  
  359.     display.blit(rectWidth_fontRender, placePos_rectWidthFont)
  360.     display.blit(rectHeight_fontRender, placePos_rectHeightFont)
  361.  
  362.     display.blit(painter_line_fontRender, placePos_painter_ballFont)
  363.     display.blit(ballSize_fontRender, placePos_ballSizeFont)
  364.     display.blit(ballElasticity_fontRender, placePos_ballElasticityFont)
  365.     display.blit(ballMass_fontRender, placePos_ballMassFont)
  366.     display.blit(ballFriction_fontRender, placePos_ballFrictionFont)
  367.  
  368.     display.blit(fps_fontRender, placePos_fps_font)
  369.     display.blit(gravity_fontRender, placePos_Gravityfont)
  370.  
  371.     pg.display.flip()
  372.     clock.tick(FPS)
  373.  
  374.     fps_fontRender = fps_font.render(f"FPS: {round(clock.get_fps(), 2)}", True, (0, 0, 0))
  375.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement