NyashniyVladya

RenPy. Передвижение объекта виртуальным стиком.

Apr 27th, 2018
281
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 6.45 KB | None | 0 0
  1.  
  2. init python:
  3.  
  4.     import pygame_sdl2 as pygame
  5.  
  6.     class __VirtualJoystick(renpy.Displayable):
  7.  
  8.         __author__ = u"Vladya"
  9.  
  10.         def __init__(self):
  11.             super(self.__class__, self).__init__()
  12.  
  13.             self.__stick_is_pressed = False
  14.             self.__size = None
  15.  
  16.             self.__xalign = self.__yalign = .5
  17.  
  18.         @property
  19.         def stick(self):
  20.             u"""
  21.            Забирать положение стика отсюда.
  22.            Формат возрата - кортеж (x, y).
  23.            Где каждое значение определяет множитель скорости передвижения
  24.            объекта от -1, до 1 ввключительно, по соответствующей оси.
  25.            """
  26.             return tuple(
  27.                 map(
  28.                     lambda a: ((a * 2.) - 1.),
  29.                     (self.__xalign, self.__yalign)
  30.                 )
  31.             )
  32.  
  33.         def get_circle(self, radius, color=u"fff"):
  34.             u"""
  35.            Программно отрисовывает круг.
  36.  
  37.            :radius:
  38.                Радиус круга.
  39.            :color:
  40.                Цвет кортежом, или в 16ричном виде.
  41.            """
  42.             radius = int(radius)
  43.             diameter = radius * 2
  44.             canvas = renpy.Render(diameter, diameter).canvas()
  45.             canvas.circle(color=color, pos=(radius, radius), radius=radius)
  46.             return (canvas.surf, diameter)
  47.  
  48.         def event(self, ev, x, y, st):
  49.  
  50.             if not self.__size:
  51.                 return
  52.  
  53.             w, h, x, y = map(float, (self.__size + (x, y)))
  54.  
  55.             if ev.type == pygame.MOUSEBUTTONDOWN:
  56.                 self.__stick_is_pressed = bool(
  57.                     ((.0 <= x <= w) and (.0 <= y <= h))
  58.                 )
  59.             elif ev.type == pygame.MOUSEBUTTONUP:
  60.                 self.__stick_is_pressed = False
  61.  
  62.             if self.__stick_is_pressed:
  63.                 self.__xalign, self.__yalign = map(
  64.                     lambda a: max(min(a, 1.), .0),
  65.                     ((x / w), (y / h))
  66.                 )
  67.             else:
  68.                 self.__xalign = self.__yalign = .5
  69.  
  70.         def render(self, width, height, st, at):
  71.  
  72.             circle_radius = min((width * .1), (height * .1))
  73.  
  74.             big_circle, bigD = self.get_circle(circle_radius)
  75.             smallMultipler = (.8 if self.__stick_is_pressed else 1.)
  76.             small_circle, smallD = self.get_circle(
  77.                 (circle_radius * .5 * smallMultipler),
  78.                 u"000"
  79.             )
  80.  
  81.             baseRenderObject = renpy.Render(bigD, bigD)
  82.  
  83.             baseRenderObject.blit(big_circle, (0, 0))
  84.             smallXPos, smallYPos = map(
  85.                 lambda align: int(((bigD * align) - (smallD * align))),
  86.                 (self.__xalign, self.__yalign)
  87.             )
  88.             baseRenderObject.blit(small_circle, (smallXPos, smallYPos))
  89.  
  90.             self.__size = (bigD, bigD)
  91.             return baseRenderObject
  92.  
  93.     class JoystickMove(renpy.Displayable):
  94.  
  95.         __author__ = u"Vladya"
  96.  
  97.         joystickAlign = (.05, .95)
  98.  
  99.         def __init__(self, child, time_speed=3.):
  100.             u"""
  101.            :child:
  102.                Объект, для перемещения.
  103.            :time_speed:
  104.                Время в секундах, на полное перемещение
  105.                от одного конца экрана, до другого.
  106.            """
  107.  
  108.             super(self.__class__, self).__init__()
  109.             self.__child = child
  110.             self.__joystick = __VirtualJoystick()
  111.             self.__time_speed = float(time_speed)
  112.  
  113.             self.__jxPos = self.__jyPos = 0
  114.  
  115.             self.__last_st = .0
  116.  
  117.             self.__childXAlign = self.__childYAlign = .5
  118.  
  119.         @property
  120.         def align(self):
  121.             u"""
  122.            Отсюда забирать текущее относительное положение на экране.
  123.            Тип данных: Кортеж вида (xalign, yalign).
  124.            """
  125.             return (self.__childXAlign, self.__childYAlign)
  126.  
  127.         def event(self, ev, x, y, st):
  128.             self.__joystick.event(
  129.                 ev,
  130.                 (x - self.__jxPos),
  131.                 (y - self.__jyPos),
  132.                 st
  133.             )
  134.  
  135.         def render(self, width, height, st, at):
  136.  
  137.             stickXSpeed, stickYSpeed = self.__joystick.stick
  138.             increment = (st - self.__last_st) / self.__time_speed
  139.             xIncrement = stickXSpeed * increment
  140.             yIncrement = stickYSpeed * increment
  141.             newX, newY = (
  142.                 (self.__childXAlign + xIncrement),
  143.                 (self.__childYAlign + yIncrement)
  144.             )
  145.  
  146.             self.__childXAlign, self.__childYAlign = map(
  147.                 lambda a: max(min(a, 1.), .0),
  148.                 (newX, newY)
  149.             )
  150.  
  151.             child = self.__child.render(width, height, st, at)
  152.  
  153.             childXSize, childYSize = child.get_size()
  154.  
  155.             childXPos = int(
  156.                 (
  157.                     (
  158.                         (width * self.__childXAlign)
  159.                     ) - (
  160.                         (childXSize * self.__childXAlign)
  161.                     )
  162.                 )
  163.             )
  164.             childYPos = int(
  165.                 (
  166.                     (
  167.                         (height * self.__childYAlign)
  168.                     ) - (
  169.                         (childYSize * self.__childYAlign)
  170.                     )
  171.                 )
  172.             )
  173.  
  174.             baseRenderObject = renpy.Render(*map(int, (width, height)))
  175.             joystick = self.__joystick.render(width, height, st, at)
  176.  
  177.             jw, jh = joystick.get_size()
  178.             jxAl, jyAl = self.joystickAlign
  179.             self.__jxPos = int(((width * jxAl) - (jw * jxAl)))
  180.             self.__jyPos = int(((height * jyAl) - (jh * jyAl)))
  181.  
  182.             baseRenderObject.blit(child, (childXPos, childYPos))
  183.             baseRenderObject.blit(joystick, (self.__jxPos, self.__jyPos))
  184.  
  185.             self.__last_st = st
  186.  
  187.             renpy.redraw(self, .0)
  188.  
  189.             return baseRenderObject
  190.  
  191.  
  192. label start:
  193.  
  194.     # Юзать либо как трансу, либо как обёртку для изображения.
  195.     show expression Text(u"Test 123", size=150) at JoystickMove
  196.     $ ui.interact()
  197.     return
Add Comment
Please, Sign In to add comment