Advertisement
Daniel_leinaD

игра

Feb 4th, 2023 (edited)
664
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 10.85 KB | None | 0 0
  1. from direct.showbase.ShowBase import ShowBase
  2. from mapmanager import Mapmanager
  3. from hero import Hero
  4.  
  5.  
  6. class Game(ShowBase):
  7.     def __init__(self):
  8.         ShowBase.__init__(self)
  9.         self.land = Mapmanager()
  10.         x, y = self.land.loadLand("land.txt")
  11.         self.hero = Hero((x // 2, y // 2, 2), self.land)
  12.         base.camLens.setFov(90)
  13.  
  14.  
  15. game = Game()
  16. game.run()
  17.  
  18. Файл
  19. mapmanager.py
  20.  
  21.  
  22. class Mapmanager():
  23.     """ Управление картой """
  24.  
  25.     def __init__(self):
  26.         self.model = 'block'  # модель кубика лежит в файле block.egg
  27.         # # используются следующие текстуры:
  28.         self.texture = 'block.png'
  29.         self.colors = [
  30.             (0.2, 0.2, 0.35, 1),
  31.             (0.2, 0.5, 0.2, 1),
  32.             (0.7, 0.2, 0.2, 1),
  33.             (0.5, 0.3, 0.0, 1)
  34.         ]  # rgba
  35.         # создаём основной узел карты:
  36.         self.startNew()
  37.         # self.addBlock((0,10, 0))
  38.  
  39.     def startNew(self):
  40.         """создаёт основу для новой карты"""
  41.         self.land = render.attachNewNode("Land")  # узел, к которому привязаны все блоки карты
  42.  
  43.     def getColor(self, z):
  44.         if z < len(self.colors):
  45.             return self.colors[z]
  46.         else:
  47.             return self.colors[len(self.colors) - 1]
  48.  
  49.     def addBlock(self, position):
  50.         # создаём строительные блоки
  51.         self.block = loader.loadModel(self.model)
  52.         self.block.setTexture(loader.loadTexture(self.texture))
  53.         self.block.setPos(position)
  54.         self.color = self.getColor(int(position[2]))
  55.         self.block.setColor(self.color)
  56.  
  57.         self.block.setTag("at", str(position))
  58.  
  59.         self.block.reparentTo(self.land)
  60.  
  61.     def clear(self):
  62.         """обнуляет карту"""
  63.         self.land.removeNode()
  64.         self.startNew()
  65.  
  66.     def loadLand(self, filename):
  67.         """создаёт карту земли из текстового файла, возвращает её размеры"""
  68.         self.clear()
  69.         with open(filename) as file:
  70.             y = 0
  71.             for line in file:
  72.                 x = 0
  73.                 line = line.split(' ')
  74.                 for z in line:
  75.                     for z0 in range(int(z) + 1):
  76.                         block = self.addBlock((x, y, z0))
  77.                     x += 1
  78.                 y += 1
  79.         return x, y
  80.  
  81.     def findBlocks(self, pos):
  82.         return self.land.findAllMatches("=at=" + str(pos))
  83.  
  84.     def isEmpty(self, pos):
  85.         blocks = self.findBlocks(pos)
  86.         if blocks:
  87.             return False
  88.         else:
  89.             return True
  90.  
  91.     def findHighestEmpty(self, pos):
  92.         x, y, z = pos
  93.         z = 1
  94.         while not self.isEmpty((x, y, z)):
  95.             z += 1
  96.         return (x, y, z)
  97.  
  98.     def buildBlock(self, pos):
  99.         """Ставим блок с учётом гравитации: """
  100.         x, y, z = pos
  101.         new = self.findHighestEmpty(pos)
  102.         if new[2] <= z + 1:
  103.             self.addBlock(new)
  104.  
  105.     def delBlock(self, position):
  106.         """удаляет блоки в указанной позиции """
  107.         blocks = self.findBlocks(position)
  108.         for block in blocks:
  109.             block.removeNode()
  110.  
  111.     def delBlockFrom(self, position):
  112.         x, y, z = self.findHighestEmpty(position)
  113.         pos = x, y, z - 1
  114.         for block in self.findBlocks(pos):
  115.             block.removeNode()
  116.  
  117.  
  118. Файл
  119. hero.py
  120.  
  121. key_switch_camera = 'c'  # камера привязана к герою или нет
  122. key_switch_mode = 'z'  # можно проходить сквозь препятствия или нет
  123.  
  124. key_forward = 'w'  # шаг вперёд (куда смотрит камера)
  125. key_back = 's'  # шаг назад
  126. key_left = 'a'  # шаг влево (вбок от камеры)
  127. key_right = 'd'  # шаг вправо
  128. key_up = 'e'  # шаг вверх
  129. key_down = 'q'  # шаг вниз
  130.  
  131. key_turn_left = 'n'  # поворот камеры направо (а мира - налево)
  132. key_turn_right = 'm'  # поворот камеры налево (а мира - направо)
  133.  
  134. key_build = 'b'  # построить блок перед собой
  135. key_destroy = 'v'  # разрушить блок перед собой
  136.  
  137.  
  138. class Hero():
  139.     def __init__(self, pos, land):
  140.         self.land = land
  141.         self.mode = True  # режим прохождения сквозь всё
  142.         self.hero = loader.loadModel('smiley')
  143.         self.hero.setColor(1, 0.5, 0)
  144.         self.hero.setScale(0.3)
  145.         self.hero.setH(180)
  146.         self.hero.setPos(pos)
  147.         self.hero.reparentTo(render)
  148.         self.cameraBind()
  149.         self.accept_events()
  150.  
  151.     def cameraBind(self):
  152.         base.disableMouse()
  153.         # base.camera.setH(180)
  154.         base.camera.reparentTo(self.hero)
  155.         base.camera.setPos(0, 0, 1.5)
  156.         self.cameraOn = True
  157.  
  158.     def cameraUp(self):
  159.         pos = self.hero.getPos()
  160.         base.mouseInterfaceNode.setPos(-pos[0], -pos[1], -pos[2] - 3)
  161.         base.camera.reparentTo(render)
  162.         base.enableMouse()
  163.         self.cameraOn = False
  164.  
  165.     def changeView(self):
  166.         if self.cameraOn:
  167.             self.cameraUp()
  168.         else:
  169.             self.cameraBind()
  170.  
  171.     def turn_left(self):
  172.         self.hero.setH((self.hero.getH() + 5) % 360)
  173.  
  174.     def turn_right(self):
  175.         self.hero.setH((self.hero.getH() - 5) % 360)
  176.  
  177.     def look_at(self, angle):
  178.         ''' возвращает координаты, в которые переместится персонаж, стоящий в точке (x, y),
  179.        если он делает шаг в направлении angle'''
  180.  
  181.         x_from = round(self.hero.getX())
  182.         y_from = round(self.hero.getY())
  183.         z_from = round(self.hero.getZ())
  184.  
  185.         dx, dy = self.check_dir(angle)
  186.         x_to = x_from + dx
  187.         y_to = y_from + dy
  188.         return x_to, y_to, z_from
  189.  
  190.     def just_move(self, angle):
  191.         '''перемещается в нужные координаты в любом случае'''
  192.         pos = self.look_at(angle)
  193.         self.hero.setPos(pos)
  194.  
  195.     def move_to(self, angle):
  196.         if self.mode:
  197.             self.just_move(angle)
  198.         else:
  199.             self.try_move(angle)
  200.  
  201.     def check_dir(self, angle):
  202.         ''' возвращает округленные изменения координат X, Y,
  203.        соответствующие перемещению в сторону угла angle.
  204.        Координата Y уменьшается, если персонаж смотрит на угол 0,
  205.        и увеличивается, если смотрит на угол 180.  
  206.        Координата X увеличивается, если персонаж смотрит на угол 90,
  207.        и уменьшается, если смотрит на угол 270.  
  208.            угол 0 (от 0 до 20)      ->        Y - 1
  209.            угол 45 (от 25 до 65)    -> X + 1, Y - 1
  210.            угол 90 (от 70 до 110)   -> X + 1
  211.            от 115 до 155            -> X + 1, Y + 1
  212.            от 160 до 200            ->        Y + 1
  213.            от 205 до 245            -> X - 1, Y + 1
  214.            от 250 до 290            -> X - 1
  215.            от 290 до 335            -> X - 1, Y - 1
  216.            от 340                   ->        Y - 1  '''
  217.         if angle >= 0 and angle <= 20:
  218.             return (0, -1)
  219.         elif angle <= 65:
  220.             return (1, -1)
  221.         elif angle <= 110:
  222.             return (1, 0)
  223.         elif angle <= 155:
  224.             return (1, 1)
  225.         elif angle <= 200:
  226.             return (0, 1)
  227.         elif angle <= 245:
  228.             return (-1, 1)
  229.         elif angle <= 290:
  230.             return (-1, 0)
  231.         elif angle <= 335:
  232.             return (-1, -1)
  233.         else:
  234.             return (0, -1)
  235.  
  236.     def forward(self):
  237.         angle = (self.hero.getH()) % 360
  238.         self.move_to(angle)
  239.  
  240.     def back(self):
  241.         angle = (self.hero.getH() + 180) % 360
  242.         self.move_to(angle)
  243.  
  244.     def left(self):
  245.         angle = (self.hero.getH() + 90) % 360
  246.         self.move_to(angle)
  247.  
  248.     def right(self):
  249.         angle = (self.hero.getH() + 270) % 360
  250.         self.move_to(angle)
  251.  
  252.     def changeMode(self):
  253.         if self.mode:
  254.             self.mode = False
  255.         else:
  256.             self.mode = True
  257.  
  258.     def try_move(self, angle):
  259.         '''перемещается, если может'''
  260.         pos = self.look_at(angle)
  261.         if self.land.isEmpty(pos):
  262.             # перед нами свободно. Возможно, надо упасть вниз:
  263.             pos = self.land.findHighestEmpty(pos)
  264.             self.hero.setPos(pos)
  265.         else:
  266.             # перед нами занято. Если получится, заберёмся на этот блок:
  267.             pos = pos[0], pos[1], pos[2] + 1
  268.             if self.land.isEmpty(pos):
  269.                 self.hero.setPos(pos)
  270.                 # не получится забраться - стоим на месте
  271.  
  272.     def up(self):
  273.         if self.mode:
  274.             self.hero.setZ(self.hero.getZ() + 1)
  275.  
  276.     def down(self):
  277.         if self.mode and self.hero.getZ() > 1:
  278.             self.hero.setZ(self.hero.getZ() - 1)
  279.  
  280.     def build(self):
  281.         angle = self.hero.getH() % 360
  282.         pos = self.look_at(angle)
  283.         if self.mode:
  284.             self.land.addBlock(pos)
  285.         else:
  286.             self.land.buildBlock(pos)
  287.  
  288.     def destroy(self):
  289.         angle = self.hero.getH() % 360
  290.         pos = self.look_at(angle)
  291.         if self.mode:
  292.             self.land.delBlock(pos)
  293.         else:
  294.             self.land.delBlockFrom(pos)
  295.  
  296.     def accept_events(self):
  297.         base.accept(key_turn_left, self.turn_left)
  298.         base.accept(key_turn_left + '-repeat', self.turn_left)
  299.         base.accept(key_turn_right, self.turn_right)
  300.         base.accept(key_turn_right + '-repeat', self.turn_right)
  301.  
  302.         base.accept(key_forward, self.forward)
  303.         base.accept(key_forward + '-repeat', self.forward)
  304.         base.accept(key_back, self.back)
  305.         base.accept(key_back + '-repeat', self.back)
  306.         base.accept(key_left, self.left)
  307.         base.accept(key_left + '-repeat', self.left)
  308.         base.accept(key_right, self.right)
  309.         base.accept(key_right + '-repeat', self.right)
  310.  
  311.         base.accept(key_switch_camera, self.changeView)
  312.  
  313.         base.accept(key_switch_mode, self.changeMode)
  314.  
  315.         base.accept(key_up, self.up)
  316.         base.accept(key_up + '-repeat', self.up)
  317.         base.accept(key_down, self.down)
  318.         base.accept(key_down + '-repeat', self.down)
  319.  
  320.         base.accept(key_build, self.build)
  321.         base.accept(key_destroy, self.destroy)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement