Advertisement
Daniel_leinaD

йцуйцуйцу

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