diff --git a/mod_pygame/moveimg.py b/mod_pygame/moveimg.py
new file mode 100644
index 0000000..f8a994e
--- /dev/null
+++ b/mod_pygame/moveimg.py
@@ -0,0 +1,193 @@
+"""
+    3.5 Вставка рисунков. Управление рисунков
+    https://stepik.org/lesson/937437/step/2?unit=943412
+
+    Задача: 
+    Попробуйте сделать управление объектом, который есть не просто прямоугольник, а, например, рисунок.
+
+    Зависимости: pygame pillow
+"""
+
+import pygame
+import os
+import shutil
+import tempfile
+import urllib.request
+from contextlib import contextmanager
+from typing import NamedTuple
+
+import PIL
+from PIL import Image, ImageDraw
+
+
+def download_asset(asset, path):
+    """
+    Загрузка картинок из репозитория
+    """
+    prefix = "https://gitea.b4tman.ru/temp/py_stepik/raw/branch/master/assets/"
+    print("Качаю картинку", asset, end=" ... ", flush=True)
+    try:
+        urllib.request.urlretrieve(prefix + asset, path)
+    except Exception:
+        print("не смог :(")
+        return False
+    print("скачал!")
+    return True
+
+
+def make_stub_image(path, name):
+    """Создание пустой картинки, на случай если скачать не получилось"""
+
+    img = PIL.Image.new("RGBA", (200, 200))
+    draw = ImageDraw.Draw(img)
+    draw.rectangle([(50, 50), (150, 150)], outline="black", width=2)
+    draw.line((50, 50, 150, 150), fill="red", width=2)
+    draw.line((50, 150, 150, 50), fill="red", width=2)
+    draw.text((50, 170), name, fill="blue")
+    img.save(path)
+
+
+@contextmanager
+def get_assets(names):
+    """Получение соответствия с расположением файлов картинок
+
+    Размер картинок нужно менять поэтому они всегда сохраняются во временные файлы.
+    """
+
+    assets_dir = "assets"
+    files = {}
+    # поиск файлов (загрузка если их нет) и создание временных
+    for asset in names:
+        _, ext = os.path.splitext(asset)
+        temppath = tempfile.mktemp(suffix=ext)
+        filepath = os.path.join(assets_dir, asset)
+        if os.path.isfile(filepath):
+            shutil.copyfile(filepath, temppath)
+        else:
+            if not download_asset(asset, temppath):
+                make_stub_image(temppath, asset)
+        files[asset] = temppath
+
+    # передача управления
+    yield files
+    # очистка
+    for _, filename in files.items():
+        try:
+            os.remove(filename)
+        except FileNotFoundError:
+            pass
+
+
+class Coords(NamedTuple):
+    """
+    Вспомогательный класс для упрощения работы с координатами
+    """
+
+    x: int | float
+    y: int | float
+
+    def __add__(self, other):
+        if isinstance(other, self.__class__):
+            return self.__class__(self.x + other.x, self.y + other.y)
+        if isinstance(other, (int, float)):
+            return self.__class__(self.x + other, self.y + other)
+        return NotImplemented
+
+    def __sub__(self, other):
+        if isinstance(other, self.__class__):
+            return self.__class__(self.x - other.x, self.y - other.y)
+        if isinstance(other, (int, float)):
+            return self.__class__(self.x - other, self.y - other)
+        return NotImplemented
+
+    def __floordiv__(self, other):
+        if isinstance(other, self.__class__):
+            return self.__class__(self.x // other.x, self.y // other.y)
+        if isinstance(other, (int, float)):
+            return self.__class__(self.x // other, self.y // other)
+        return NotImplemented
+
+    def __mul__(self, other):
+        if isinstance(other, self.__class__):
+            return self.__class__(self.x * other.x, self.y * other.y)
+        if isinstance(other, (int, float)):
+            return self.__class__(self.x * other, self.y * other)
+        return NotImplemented
+
+    def transform(self, ref: "Coords"):
+        return self * ref
+
+
+def resize_img(assets: dict, name: str, sz: Coords):
+    """
+    Изменение размера картинки и сохранение в файл
+    """
+    img = PIL.Image.open(assets[name])
+    if img.size != sz:
+        img = img.resize(sz)
+        img.save(assets[name])
+
+
+def choose_plural(amount, declensions):
+    """Возвращает количество объектов в виде строки
+    например 5 копеек, 1 копейка и т.д.
+    """
+    a = amount % 100
+    i = 2
+    if 10 < a < 20:
+        pass
+    elif a % 10 == 1:
+        i = 0
+    elif 1 < a % 10 < 5:
+        i = 1
+    return f"{amount} {declensions[i]}"
+
+
+def draw_background_image(screen, filename):
+    background = pygame.image.load(filename)
+    screen.blit(background, (0, 0))
+
+
+def game(assets):
+    pygame.init()
+    width, height = screen_sz = Coords(1000, 1000)
+    screen = pygame.display.set_mode(screen_sz)
+    pygame.display.set_caption("Движение рисунка на Pygame")
+
+    ghost_sz = screen_sz // 10
+
+    resize_img(assets, "bg1k.png", screen_sz)
+    speed = [2, 2]
+
+    resize_img(assets, "ghost.png", ghost_sz)
+    ghost = pygame.image.load(assets["ghost.png"])
+    ghostrect = ghost.get_rect()
+
+    running = True
+
+    while running:
+        for event in pygame.event.get():
+            if event.type == pygame.QUIT: 
+                running = False
+        ghostrect = ghostrect.move(speed)
+        if ghostrect.left < 0 or ghostrect.right > width:
+            speed[0] = -speed[0]
+        if ghostrect.top < 0 or ghostrect.bottom > height:
+            speed[1] = -speed[1]
+
+        draw_background_image(screen, assets["bg1k.png"])
+        screen.blit(ghost, ghostrect)
+        pygame.display.flip()
+
+    pygame.quit()
+
+
+def main():
+    assets = [
+        "bg1k.png",
+        "ghost.png",
+    ]
+    with get_assets(assets) as assets:
+        game(assets)
+
+main()
\ No newline at end of file