Droid Game 3D - Third Person Shooter!

Start in windows 7 32bit :

3.0.0 UPDATE! NEW MECHANICS OF LIGHT!

Add to main directory :
./shaders : shaders.zip

New code :

#!/usr/bin/env python
# -*- coding: utf_8 -*-

# Π‘ΠΎΠ·Π΄Π°Π½ΠΎ : 22 число, ΡΠ½Π²Π°Ρ€ΡŒ, 2021 Π³ΠΎΠ΄

# Π˜ΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΡƒΠ΅ΠΌ всС Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹Π΅ инструмСнты
from direct.showbase.ShowBase import ShowBase
from panda3d.core import CollisionTraverser, CollisionNode
from panda3d.core import CollisionHandlerPusher, CollisionSphere, CollisionInvSphere
from panda3d.core import Filename, AmbientLight, DirectionalLight
from panda3d.core import PandaNode, NodePath, Camera, TextNode
from direct.particles.Particles import Particles
from direct.particles.ParticleEffect import ParticleEffect
from panda3d.core import PointLight, Spotlight
from panda3d.core import CollideMask
from panda3d.core import loadPrcFileData
from panda3d.core import *
from direct.gui.OnscreenText import OnscreenText
from direct.gui.OnscreenImage import OnscreenImage
from direct.gui.DirectButton import DirectButton
from direct.gui.DirectSlider import DirectSlider
from direct.actor.Actor import Actor
import random
import sys
import time
import os
import math

VERSION = '3.0.0'

settings = ['window-title Droid Game ' +  VERSION]
            

loadPrcFileData('', settings[0]) # Π‘Π΄Π΅Π»Π°Π΅ΠΌ Π½Π΅ стандартный Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ (Π²ΠΎΠ·ΠΌΡ‘ΠΌ Π΅Π³ΠΎ ΠΈΠ· ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ settings)

# Π‘ΠΎΠ·Π΄Π°Π΄ΠΈΠΌ Π³Π»Π°Π²Π½Ρ‹ΠΉ класс нашСй ΠΈΠ³Ρ€Ρ‹
class DroidShooter(ShowBase):
    def __init__(self):
        ShowBase.__init__(self) # Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ всС сСлфы ΠΈΠ· direct
        self.speed = 800 # ΡΠΊΠΎΡ€ΠΎΡΡ‚ΡŒ двигатСля
        self.menu() # звпуск мСню
        
    def menu(self):
        
        base.enableParticles() # ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ эффСкт Π΄Ρ‹ΠΌΠ°

        self.win.setClearColor((0, 0, 0, 1)) # Π—Π°ΠΊΡ€Π°ΡˆΠΈΠ²Π°Π΅ΠΌ ΠΏΠΎΠ²Π΅Ρ€Ρ…Π½ΠΎΡΡ‚ΡŒ Ρ‡Ρ‘Ρ€Π½Ρ‹ΠΌ. Π”Π΅Π»ΠΎ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ Π² этом ΠΈΠ³Ρ€ΠΎΠ²ΠΎΠΌ Π΄Π²ΠΈΠΆΠΊΠ΅ ΠΏΠΎΠ²Π΅Ρ€Ρ…Π½ΠΎΡΡ‚ΡŒ Π·Π°ΠΊΡ€Π°ΡˆΠΈΠ²Π°Π΅Ρ‚ΡΡ сСрым.
        self.font = loader.loadFont('./fonts/doom_font.ttf') # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ ΡˆΡ€ΠΈΡ„Ρ‚ ΠΈΠ· ΠΈΠ³Ρ€Ρ‹ doom
        self.inst_font = loader.loadFont('./fonts/arial.ttf') # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ ΡˆΡ€ΠΈΡ„Ρ‚ arial

        self.crackSound = loader.loadMusic('./sounds/crack.wav') # Π·Π²ΡƒΠΊ Π²Π·Ρ€Ρ‹Π²Π° корабля
        self.shotSound = loader.loadMusic('./sounds/shot.wav') # Π·Π²ΡƒΠΊ выстрСла
        self.startSound = loader.loadMusic('./sounds/started.wav') # Π·Π²ΡƒΠΊ запуска
        self.errorSound = loader.loadMusic('./sounds/error.wav') # Π·Π²ΡƒΠΊ запуска
        self.errorSound.setVolume(1) # полная Π³Ρ€ΠΎΠΌΠΊΠΎΡΡ‚ΡŒ Π·Π²ΡƒΠΊΠ°
        self.startSound.setVolume(1) # полная Π³Ρ€ΠΎΠΌΠΊΠΎΡΡ‚ΡŒ Π·Π²ΡƒΠΊΠ°
        self.crackSound.setVolume(1) # полная Π³Ρ€ΠΎΠΌΠΊΠΎΡΡ‚ΡŒ Π·Π²ΡƒΠΊΠ°
        self.shotSound.setVolume(1) # полная Π³Ρ€ΠΎΠΌΠΊΠΎΡΡ‚ΡŒ Π·Π²ΡƒΠΊΠ°
        self.startSound.play() # ΠΈΠ³Ρ€Π°Π΅ΠΌ Π·Π²ΡƒΠΊ запуска ΠΈΠ³Ρ€Ρ‹

        self.button_start = DirectButton(pos=(0.7, 0, 0), text="CTAPT",
                                   scale=.3, pad=(.2, .2),
                                   command=self.load_game) # ΠΊΠ½ΠΎΠΏΠΊΠ° запуска ΠΈΠ³Ρ€Ρ‹

        self.slider_sun = DirectSlider(pos=(0.1, 0, .75), scale=0.8, value=0,
                                    command=self.set_sun_interval)


        self.title = self.addTitle("Droid game " + VERSION)
        
        # НапСчатаСм ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅
        self.inst1 = self.addInstructions(0.95, u"[ESC]: Π’Ρ‹Ρ…ΠΎΠ΄")
        self.inst2 = self.addInstructions(0.90, u"[Left Arrow]: ΠŸΠΎΠ²ΠΎΡ€ΠΎΡ‚ Π΄Ρ€ΠΎΠΈΠ΄Π° Π² Π»Π΅Π²ΠΎ")
        self.inst3 = self.addInstructions(0.85, u"[Right Arrow]: ΠŸΠΎΠ²ΠΎΡ€ΠΎΡ‚ Π΄Ρ€ΠΎΠΈΠ΄Π° Π² ΠΏΡ€Π°Π²ΠΎ")
        self.inst4 = self.addInstructions(0.80, u"[Up Arrow]: Π’ΠΏΠ΅Ρ€Π΅Π΄")
        self.inst5 = self.addInstructions(0.75, u"[a]: ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ Π² ΠΏΡ€Π°Π²ΠΎ")
        self.inst6 = self.addInstructions(0.70, u"[d]: ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ Π² Π»Π΅Π²ΠΎ")
        self.inst7 = self.addInstructions(0.65, u"[Left Arrow + Up arrow]: ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚ Π΄Ρ€ΠΎΠΈΠ΄Π° Π² Π»Π΅Π²ΠΎ ΠΈ Π²ΠΏΠ΅Ρ€Ρ‘Π΄")
        self.inst8 = self.addInstructions(0.60, u"[Right Arrow + Up arrow]: ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚ Π΄Ρ€ΠΎΠΈΠ΄Π° Π² ΠΏΡ€Π°Π²ΠΎ ΠΈ Π²ΠΏΠ΅Ρ€Ρ‘Π΄")
        self.inst9 = self.addInstructions(0.55, u"[a + Up arrow]: ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ Π² ΠΏΡ€Π°Π²ΠΎ ΠΈ Π²ΠΏΠ΅Ρ€Ρ‘Π΄")
        self.inst10 = self.addInstructions(0.50, u"[d + Up arrow]: ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ Π² Π»Π΅Π²ΠΎ ΠΈ Π²ΠΏΠ΅Ρ€Ρ‘Π΄")
        self.inst11 = self.addInstructions(0.45, u"[space]: ΡΡ‚Ρ€Π΅Π»ΡŒΠ±Π°")
        self.inst12 = self.addInstructions(0.35, u"[s]: Π΄ΠΎΡΡ‚Π°Ρ‚ΡŒ Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊ")
        self.inst13 = self.addInstructions(0.30, u"[w]: ΡƒΠ±Ρ€Π°Ρ‚ΡŒ ΠΎΡ€ΡƒΠΆΠΈΠ΅")
        self.inst14 = self.addInstructions(0.25, u"[f]: ΠΏΠΎΠ»Π½Ρ‹ΠΉ Ρ€Π°Π·Π³ΠΎΠ½(ОПАБНО!)")
        self.inst15 = self.addInstructions(0.20, u"[0]: ΠΏΠΎΠΆΠ°Ρ€ΠΎΡ‚ΡƒΡˆΠΈΡ‚Π΅Π»ΡŒΠ½Π°Ρ систСма")

        self.accept("escape", sys.exit) # ΠŸΡ€ΠΈ Π½Π°ΠΆΠ°Ρ‚ΠΈΠΈ клавиши Esc Π²Ρ‹Ρ…ΠΎΠ΄ΠΈΠΌ.

    def set_sun_interval(self):
        self.sun_interval = self.slider_sun.guiItem.getValue() * 500 # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ слайдСрноС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΡƒΠΌΠ½ΠΎΠΆΠ΅Π½ΠΎΠ΅ Π½Π° 500, Π΄Π° Ρ‚Ρ€Π°Ρ‡Ρƒ ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΡŽ Π½ΠΎ ΠΌΠ½Π΅ каТСтся ΠΌΠ½ΠΎΠ³ΠΈΠΌ ΠΏΠ»Π΅Π²Π°Ρ‚ΡŒ Π½Π° ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΡŽ мСню, ΠΈΠ±ΠΎ Ρ‚Π°ΠΊΠΎΠ³ΠΎ понятия просто Π½Π΅Ρ‚Ρƒ :)
        

    def load_game(self):
        self.button_start.hide() # ΡƒΠ΄Π°Π»ΠΈΠΌ ΠΊΠ½ΠΎΠΏΠΊΡƒ старта
        self.title.hide() # ΡƒΠ΄Π°Π»ΠΈΠΌ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ ΠΈΠ³Ρ€Ρ‹
        # ΡƒΠ΄Π°Π»ΠΈΠΌ ΠΊΠ½ΠΎΠΏΠΊΠΈ управлСния
        self.inst1.hide()
        self.inst2.hide()
        self.inst3.hide()
        self.inst4.hide()
        self.inst5.hide()
        self.inst6.hide()
        self.inst7.hide()
        self.inst8.hide()
        self.inst9.hide()
        self.inst10.hide()
        self.inst11.hide()
        self.inst12.hide()
        self.inst13.hide()
        self.inst14.hide()
        self.inst15.hide()
        self.slider_sun.hide() # удаляСм слайдСр солнца
        
        self.keyMap = {
            "left": 0, "right": 0, "forward": 0, "cam-left": 0, "cam-right": 0} # Π‘ΠΎΠ·Π΄Π°Π΄ΠΈΠΌ ΡΠ»ΠΎΠ²Π°Ρ€ΡŒ ΠΊΠ½ΠΎΠΏΠΎΠΊ, ΠΏΠΎ ΠΈΡ… Π½Π°ΠΆΠ°Ρ‚ΠΈΡŽ        

        # РисуСм Π·Π²Ρ‘Π·Π΄Ρ‹

        self.sky = loader.loadModel("./models/sky/solar_sky_sphere") # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ модСль космоса(это сфСра)

        self.sky_tex = loader.loadTexture("./tex/stars_1k_tex.jpg") # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ тСкстуру
        self.sky.setTexture(self.sky_tex, 1) # Π·Π°Ρ€Π΅Π½Π΄Π΅Ρ€ΠΈΠΌ тСкстуру Π½Π° Π½Π΅Π±ΠΎ
        self.sky.reparentTo(render) # ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ Π½Π΅Π±ΠΎ
        self.sky.setScale(40000) # Ρ€Π°ΡΡˆΠΈΡ€ΠΈΠΌ Π½Π΅Π±ΠΎ Π΄ΠΎ максимальной Π²Π΅Π»ΠΈΡ‡ΠΈΠ½Ρ‹ panda3d

        self.environ = loader.loadModel("models/world/falcon.egg") # Π—Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ ΡƒΠΆΠ΅ созданный Π² blender ΠΌΠΈΡ€.
        self.environ.reparentTo(render) # Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ модСль ΠΌΠΈΡ€Π° Π² ΠΎΠΊΠ½ΠΎ

        droidStartPos = (-1, 6, 1.5 ) # Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ ΡΡ‚Π°Ρ€Ρ‚ΠΎΠ²ΡƒΡŽ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π² ΠΌΠΈΡ€Π΅.
        enemyStartPos = (-6, 1, 0.5) # Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ°-Π΄Ρ€ΠΎΠΈΠ΄Π°.
        self.droid = Actor("models/player/seeker.egg") # Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ модСль ΠΈΠ³Ρ€ΠΎΠΊΠ° (созданная Π² blender)
        self.enemy = Actor("models/enemies/r2d2/r2d2.egg") # Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ модСль ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ° (созданная Π² blender)
        self.droid.reparentTo(render) # ΠŸΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Π΅ΠΌ модСль ΠΈΠ³Ρ€ΠΎΠΊΠ° Π² наш ΠΌΠΈΡ€.
        self.enemy.reparentTo(render) # ΠŸΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Π΅ΠΌ модСль ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ° Π² наш ΠΌΠΈΡ€.
        self.droid.setScale(1) # Π”Π΅Π»Π°Π΅ΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ€ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π½Π° 1
        self.enemy.setScale(1) # Π”Π΅Π»Π°Π΅ΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ€ ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ° Π½Π° 1
        self.droid.setPos(droidStartPos) # Π‘Ρ‚Π°Π²ΠΈΠΌ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π½Π° Ρ€Π°Π½Π΅Π΅ ΡΠΎΠ·Π΄Π°Π½ΡƒΡŽ Π½Π°ΠΌΠΈ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ
        self.enemy.setPos(enemyStartPos) # Π‘Ρ‚Π°Π²ΠΈΠΌ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ° Π½Π° Ρ€Π°Π½Π΅Π΅ ΡΠΎΠ·Π΄Π°Π½ΡƒΡŽ Π½Π°ΠΌΠΈ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ

        self.weapon = Actor('models/weapon/lightsaber.egg') # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ ΠΎΡ€ΡƒΠΆΠΈΠ΅
        self.bullet = Actor('models/weapon/bullet/bullet.egg.pz') # Π—Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ ΠΏΡƒΠ»ΡŽ
        self.flash = Actor('models/whishlyflash/handlamp.egg') # Π—Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊ
               
        self.weapon.reparentTo(render) # пСрСмСстим ΠΎΡ€ΡƒΠΆΠΈΠ΅ Π² наш ΠΌΠΈΡ€
        self.bullet.reparentTo(render) # пСрСмСстим ΠΏΡƒΠ»ΡŽ Π² ΠΌΠΈΡ€ Π½ΠΎ появится ΠΎΠ½Π° сама Π½Π΅ скоро
        self.flash.reparentTo(render) # пСрСмСстим Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊ Π² наш ΠΌΠΈΡ€
        self.weapon.setScale(.5) # Π·Π°Π΄Π°Π΄ΠΈΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ€ ΠΏΡƒΡˆΠΊΠΈ
        self.bullet.setScale(.5) # Π·Π°Π΄Π°Π΄ΠΈΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ€ ΠΏΡƒΠ»ΠΈ
        self.flash.setScale(.5) # Π·Π°Π΄Π°Π΄ΠΈΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ€ Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊΠ°
        

        self.weapon_pos = self.droid.getX(), self.droid.getY() + 0.7, 1 # ΠŸΠΎΠ·ΠΈΡ†ΠΈΡ ΠΏΡƒΡˆΠΊΠΈ
        
        self.weapon.setPos(self.weapon_pos) # ΠŸΠΎΠΌΠ΅ΡΡ‚ΠΈΠΌ ΠΎΡ€ΡƒΠΆΠΈΠ΅ Ρ‡ΡƒΡ‚ΡŒ Π²Ρ‹ΡˆΠ΅ ΠΈΠ³Ρ€ΠΎΠΊΠ°
        
        
        self.spotlight = camera.attachNewNode(Spotlight("spotlight")) # ΠšΠΎΠ½Ρ„ΠΈΠ³ΠΈ Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊΠ°
        self.spotlight.node().setColor((.3, .3, .3, 1))
        self.spotlight.node().setSpecularColor((0, 0, 0, 1))

        self.floater = NodePath(PandaNode("floater")) 
        self.floater.reparentTo(self.droid)
        self.floater.setZ(2.0)


        

        self.accept("escape", sys.exit) # ΠŸΡ€ΠΈ Π½Π°ΠΆΠ°Ρ‚ΠΈΠΈ клавиши Esc Π²Ρ‹Ρ…ΠΎΠ΄ΠΈΠΌ.
        
        self.accept("arrow_left", self.setKey, ["left", True]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ Π²Π»Π΅Π²ΠΎ - ΠΏΠΎΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π²Π»Π΅Π²ΠΎ
        self.accept("arrow_right", self.setKey, ["right", True]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ Π²ΠΏΡ€Π°Π²ΠΎ - ΠΏΠΎΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π²ΠΏΡ€Π°Π²ΠΎ
        self.accept("arrow_up", self.setKey, ["forward", True]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ Π²ΠΏΠ΅Ρ€Ρ‘Π΄ - ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄
        self.accept("a", self.setKey, ["cam-left", True]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ a - Ρ€Π°Π·Π²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΊΠ°ΠΌΠ΅Ρ€Ρƒ Π²ΠΎΠΊΡ€ΡƒΠ³ нашСй модСльки
        self.accept("d", self.setKey, ["cam-right", True]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ s - Ρ€Π°Π·Π²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΊΠ°ΠΌΠ΅Ρ€Ρƒ Π²ΠΎΠΊΡ€ΡƒΠ³ нашСй модСльки
        self.accept("arrow_left-up", self.setKey, ["left", False]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ Π²Π²Π΅Ρ€Ρ…+Π²Π»Π΅Π²ΠΎ - ΠΏΠΎΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π²Π»Π΅Π²ΠΎ ΠΈ ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄
        self.accept("arrow_right-up", self.setKey, ["right", False]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ Π²Π²Π΅Ρ€Ρ…+ΠΏΡ€Π°Π²ΠΎ - ΠΏΠΎΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π²ΠΏΡ€Π°Π²ΠΎ ΠΈ ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄
        self.accept("arrow_up-up", self.setKey, ["forward", False]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ Π²Π²Π΅Ρ€Ρ…+Π²Π²Π΅Ρ€ΡŠ - ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄ ΠΈ ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄
        self.accept("a-up", self.setKey, ["cam-left", False]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ a+Π²ΠΏΠ΅Ρ€Ρ‘Π΄ - ΠΏΠΎΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΊΠ°ΠΌΠ΅Ρ€Ρƒ Π²Π»Π΅Π²ΠΎ ΠΈ ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄
        self.accept("d-up", self.setKey, ["cam-right", False]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ s+Π²ΠΏΠ΅Ρ€Ρ‘Π΄ - ΠΏΠΎΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΊΠ°ΠΌΠ΅Ρ€Ρƒ Π²ΠΏΡ€Π°Π²ΠΎ ΠΈ ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄

        self.accept("space", self.shot) # ΠΏΡ€ΠΈ ΠΏΡ€ΠΎΠ±Π΅Π»Π΅ стрСляСм
        self.accept("s", self.toggleLights, [[self.spotlight]]) # Π’ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊ
        self.accept("w", self.weapon_hide) # ΠΏΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ w - ΡƒΠ±Π΅Ρ€Ρ‘ΠΌ ΠΎΡ€ΡƒΠΆΠΈΠ΅.

        base.enableParticles() # Π’ΠΊΠ»ΡŽΡ‡Π°Π΅ΠΌ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ Π΄Ρ‹ΠΌΠ°
        self.t = loader.loadModel("models/weapon/lightsaber.egg") # Π—Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ Π΅Ρ‰Ρ‘ ΠΎΡ€ΡƒΠΆΠΈΠ΅
        self.t.reparentTo(render) # ΠŸΠ΅Ρ€Π΅ΠΌΠ΅ΡΡ‚ΠΈΠΌ ΠΎΡ€ΡƒΠΆΠΈΠ΅ Π² наш ΠΌΠΈΡ€
        self.p = ParticleEffect() # Π’ΠΊΠ»ΡŽΡ‡ΠΈΠΌ эффСкт Π΄Ρ‹ΠΌΠ°
        self.accept('f', self.particle_start) # ΠΏΡ€ΠΈ Π½Π°ΠΆΠ°Ρ‚ΠΈΠΈ f(ΠΎΡ‚ force) -  Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ Ρ„Π°ΠΉΠ» Π΄Ρ‹ΠΌΠ° ΠΈ пСрСмСстим Π² ΠΊΠΎΠ½Ρ„ΠΈΠ³ Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΈΠΌΠ΅Π½Π½ΠΎ эта анимация стала ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ΠΌ Π΄Ρ‹ΠΌΠ°
        self.accept('0', self.fountain) # ΠΏΡ€ΠΈ  Π½Π°ΠΆΠ°Ρ‚ΠΈΠΈ ΠΊΠ½ΠΎΠΏΠΎΠΊ f+o(fountain) Π²ΠΊΠ»ΡŽΡ‡ΠΈΠΌ ΠΏΠΎΠΆΠ°Ρ€ΠΎΡ‚ΡƒΡˆΠΈΡ‚Π΅Π»ΡŒΠ½ΡƒΡŽ систСму

        self.accept('arrow_1+s', self.shot)

        taskMgr.add(self.move, "moveTask") # ДобавляСм Π·Π°Π΄Π°Ρ‡Ρƒ Π² наш Π΄Π²ΠΈΠΆΠΎΠΊ

        self.isMoving = False # Π‘Ρ‚Π°Π²ΠΈΠΌ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ isMoving Π½Π° False(Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΌΠ΅Π½ΡΡ‚ΡŒ это Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅) Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΈΠ³Ρ€ΠΎΠΊ ΠΈΠ·Π½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎ стоял.
        # Π”Π΅Π»Π°Π΅ΠΌ Ρ‚Π°ΠΊ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ свСт Π±Ρ‹Π» ΠΈΠ·Π½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎ Π²Ρ‹ΠΊΠ»ΡŽΡ‡Π΅Π½.
        self.disableMouse() # ΠžΡ‚ΠΊΠ»ΡŽΡ‡Π°Π΅ΠΌ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π΅Π½ΠΈΠ΅ Ρ‡Π΅Ρ€Π΅Π· ΠΌΡ‹ΡˆΠΊΡƒ
        self.camera.setPos(self.droid.getX(), self.droid.getY() + 1, 3) # Π‘Ρ‚Π°Π²ΠΈΠΌ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ Ρ‡ΡƒΡ‚ΡŒ большС ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ ΠΈΠ³Ρ€ΠΎΠΊΠ°

        self.black_light() # Π‘Π΄Π΅Π»Π°Π΅ΠΌ Π²Ρ‹ΠΊΠ»ΡŽΡ‡Π΅Π½Π½Ρ‹ΠΉ свСт

        self.state = 100 # БостояниС корабля
        self.state_info = OnscreenText(text='ΠΊΠΎΡ€Π°Π±Π»ΡŒ :' + str(self.state), pos=(0.5, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля
                
        self.check_loss() # ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ ΠΏΠΎΡ€Π°ΠΆΠ΅Π½ΠΈΠ΅
        self.hide_weapon = False # ΠŸΠΎΡΡ‚Π°Π²ΠΈΠΌ, Ρ‡Ρ‚ΠΎ ΠΎΡ€ΡƒΠΆΠΈΠ΅ Π½Π΅ ΡƒΠ±Ρ€Π°Π½ΠΎ
        self.steam_pos = random.randrange(0, 5), random.randrange(0, 5), random.randrange(0, 5)
        self.fountain_pos = random.randrange(0, 5), random.randrange(0, 5), random.randrange(0, 1)

        self.motor_pos1 = 25.238849639892578, 8.962211608886719, 1.5 # позиция ΠΏΠ΅Ρ€Π²ΠΎΠ³ΠΎ ΠΌΠΎΡ‚ΠΎΡ€Π°
        self.motor_pos2 = -20.676218032836914, 10.55816650390625, 1.5 # позиция Π²Ρ‚ΠΎΡ€ΠΎΠ³ΠΎ ΠΌΠΎΡ‚ΠΎΡ€Π°

        self.motor1 = self.loadParticleConfig('special_effects/steam_critic+/fireish.ptf', self.motor_pos1) # ΠΌΠΎΡ‚ΠΎΡ€ 1
        self.motor2 = self.loadParticleConfig('special_effects/steam_critic+/fireish.ptf', self.motor_pos2) # ΠΌΠΎΡ‚ΠΎΡ€ 2

        self.state_info2 = OnscreenText(text='', pos=(-0.8, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля

        self.force = False # ΠŸΠΎΡΡ‚Π°Π²ΠΈΠΌ, Ρ‡Ρ‚ΠΎ Π½Π΅ Ρ€Π°Π·Π³ΠΎΠ½ΡΠ»ΠΈΡΡŒ

        # ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ ΠΊΠΎΠ»Π»ΠΈΠ·ΠΈΠΈ
        
        self.cTrav = CollisionTraverser()
        pusher = CollisionHandlerPusher()
        
        environCenter = self.environ.getBounds().getCenter()
        environRad = self.environ.getBounds().getRadius()
        cNode = CollisionNode("environment")
        cNode.addSolid(CollisionInvSphere(environCenter, environRad))
        environC = self.environ.attachNewNode(cNode)
        
        droidCenter = self.droid.getBounds().getCenter()
        droidRad = self.droid.getBounds().getRadius()
        cNode = CollisionNode("droid")
        cNode.addSolid(CollisionSphere(droidCenter, droidRad))
        droidC = self.droid.attachNewNode(cNode)
        
        pusher.addCollider(droidC, self.droid)
        self.cTrav.addCollider(droidC, pusher)
        
        enemyCenter = self.enemy.getBounds().getCenter()
        enemyRad = self.enemy.getBounds().getRadius()
        cNode = CollisionNode("enemy")
        cNode.addSolid(CollisionSphere(enemyCenter, enemyRad))
        enemyC = self.enemy.attachNewNode(cNode)
        
        pusher.addCollider(enemyC, self.enemy)
        self.cTrav.addCollider(enemyC, pusher)

        # солнцС(новая ΠΌΠ΅Ρ…Π°Π½ΠΈΠΊΠ° освСщСния)
        sun = DirectionalLight("sun")
        sun.set_color_temperature(6000)
        sun.color = sun.color * 4
        sun_path = render.attach_new_node(sun)
        sun_path.set_pos(10, -10, -10)
        sun_path.look_at(0, 0, 0)
        sun_path.hprInterval(self.sun_interval, (sun_path.get_h(), sun_path.get_p() - 360, sun_path.get_r()), bakeInStart=True).loop()
        render.set_light(sun_path)

    def loadParticleConfig(self, filename, pos):
        self.p.cleanup()
        self.p = ParticleEffect()
        self.p.loadConfig(Filename(filename))

        self.p.start(self.t)
        self.p.setPos(pos)

    def particle_start(self):
        self.force = True # ΠŸΠΎΡΡ‚Π°Π²ΠΈΠΌ, Ρ‡Ρ‚ΠΎ ΠΌΡ‹ ΡƒΠΆΠ΅ Ρ€Π°Π·Π³ΠΎΠ½ΡΠ»ΠΈΡΡŒ
        # ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Π΅ΠΌ всС ΠΎΠ±ΡŒΠ΅ΠΊΡ‚Ρ‹ Π·Π° ΠΊΠΎΡ€Π°Π±Π»Ρ‘ΠΌ
        self.environ.setY(self.environ.getY() + self.speed) # нСсёмся Π²ΠΏΡ€Π°Π²ΠΎ
        self.droid.setY(self.droid.getY() + self.speed) # сдвигаСм Π΄Ρ€ΠΎΠΈΠ΄Π° Π·Π° ΠΊΠΎΡ€Π°Π±Π»Ρ‘ΠΌ
        self.enemy.setY(self.enemy.getY() + self.speed) # сдфигаСм ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ° Π·Π° ΠΊΠΎΡ€Π°Π±Π»Ρ‘ΠΌ
        self.weapon.setY(self.weapon.getY() + self.speed) # ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Π΅ΠΌ ΠΎΡ€ΡƒΠΆΠΈΠ΅
        self.flash.setY(self.flash.getY() + self.speed) # ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Π΅ΠΌ Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊ

        self.state -= 1 # сдСлаСм мСньшС ΠΎΡ‡ΠΊΠΎΠ²
        self.state_info.hide() # ΡƒΠ΄Π°Π»ΠΈΠΌ тСкстовыС ΠΎΡ‡ΠΊΠΈ

        camvec = self.droid.getPos() - self.camera.getPos()
        camvec.setZ(0)
        camdist = camvec.length()
        camvec.normalize()
        if camdist > 10.0:
            self.camera.setPos(self.camera.getPos() + camvec * (camdist - 10))
            camdist = 10.0
        if camdist < 5.0:
            self.camera.setPos(self.camera.getPos() - camvec * (5 - camdist))
            camdist = 5.0
            
        self.camera.lookAt(self.floater)
        
        if self.state != 10 and self.state > 10:
            self.state_info.hide() # ΡƒΠ±ΠΈΡ€Π°Π΅ΠΌ ΠΏΡ€Π΅Π΄Π΅Π΄ΡƒΡ‰Π΅Π΅ сообщСниС ΠΎ Тизнях корабля
            self.state_info = OnscreenText(text='ΠΊΠΎΡ€Π°Π±Π»ΡŒ :' + str(self.state), pos=(0.5, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля
            self.check_loss() # провСряСм ΠΏΠΎΡ€Π°ΠΆΠ΅Π½ΠΈΠ΅
            self.steam_pos = random.randrange(0, 5), random.randrange(0, 5) + 300, random.randrange(0, 5)
            self.loadParticleConfig('special_effects/steam/steam.ptf', self.steam_pos)
            self.errorSound.play() # ΠΈΠ³Ρ€Π°Π΅ΠΌ Π·Π²ΡƒΠΊ ошибки
            self.state_info2.hide() # ΡƒΠ±ΠΈΡ€Π°Π΅ΠΌ ΠΏΡ€Π΅Π΄Π΅Π΄ΡƒΡ‰Π΅Π΅ сообщСниС
            self.state_info2 = OnscreenText(text='Π΄Π²ΠΈΠ³Π°Ρ‚Π΅Π»ΡŒ нСисправСн', pos=(-0.8, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля
        else:
            self.state_info = OnscreenText(text='ΠΊΠΎΡ€Π°Π±Π»ΡŒ :' + str(self.state), pos=(0.5, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля
            self.check_loss() # провСряСм ΠΏΠΎΡ€Π°ΠΆΠ΅Π½ΠΈΠ΅
            self.steam_pos = random.randrange(0, 5), random.randrange(0, 5) + 300, random.randrange(0, 5)
            self.loadParticleConfig('special_effects/steam_critic/steam.ptf', self.steam_pos)
            self.errorSound.play() # ΠΈΠ³Ρ€Π°Π΅ΠΌ Π·Π²ΡƒΠΊ ошибки
            self.state_info2.hide()  # ΡƒΠ±ΠΈΡ€Π°Π΅ΠΌ ΠΏΡ€Π΅Π΄Π΅Π΄ΡƒΡ‰Π΅Π΅ сообщСниС
            self.state_info2 = OnscreenText(text='критичСскоС состояниС', pos=(-0.8, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля
    
        if self.state < 10:
            self.state_info.hide()
            self.state_info = OnscreenText(text='ΠΊΠΎΡ€Π°Π±Π»ΡŒ :' + str(self.state), pos=(0.5, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля
            self.check_loss() # провСряСм ΠΏΠΎΡ€Π°ΠΆΠ΅Π½ΠΈΠ΅
            self.steam_pos = random.randrange(0, 5), random.randrange(0, 5) + 300, random.randrange(0, 5)            
            self.loadParticleConfig('special_effects/steam_critic+/fireish.ptf', self.steam_pos)
            self.errorSound.play() # ΠΈΠ³Ρ€Π°Π΅ΠΌ Π·Π²ΡƒΠΊ ошибки
            self.state_info2.hide() # ΡƒΠ±ΠΈΡ€Π°Π΅ΠΌ ΠΏΡ€Π΅Π΄Π΅Π΄ΡƒΡ‰Π΅Π΅ сообщСниС
            self.state_info2 = OnscreenText(text='ΠΏΠ°Π΄Π°Π΅ΠΌ!', pos=(-0.8, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля


    def fountain(self):
        if self.force:
            if self.state != 100:
                self.state += 1
                self.state_info.hide()
                self.state_info = OnscreenText(text='ΠΊΠΎΡ€Π°Π±Π»ΡŒ :' + str(self.state), pos=(0.5, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля

            self.fountain_pos = random.randrange(0, 5), random.randrange(0, 5) + 500, random.randrange(0, 1)    
            self.loadParticleConfig('special_effects/fountain/fountain.ptf', self.fountain_pos)

        else :
            if self.state != 100:
                self.state += 1
                self.state_info.hide()
                self.state_info = OnscreenText(text='ΠΊΠΎΡ€Π°Π±Π»ΡŒ :' + str(self.state), pos=(0.5, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля

            self.fountain_pos = random.randrange(0, 5), random.randrange(0, 5), random.randrange(0, 1)    
            self.loadParticleConfig('special_effects/fountain/fountain.ptf', self.fountain_pos)
        
        
    def black_light(self):
        # Π’Ρ‹ΠΊΠ»ΡŽΡ‡Π΅Π½Ρ‹ΠΉ свСт
        ambientLight = AmbientLight("ambientLight")
        ambientLight.setColor((0, 0, 0, 1))
        directionalLight = DirectionalLight("directionalLight")
        directionalLight.setDirection((-5, -5, -5))
        directionalLight.setColor((1, 1, 1, 1))
        directionalLight.setSpecularColor((1, 1, 1, 1))
        render.setLight(render.attachNewNode(ambientLight))
        render.setLight(render.attachNewNode(directionalLight))

    def weapon_hide(self):
        # Π£Π±Ρ€Π°Ρ‚ΡŒ ΠΎΡ€ΡƒΠΆΠΈΠ΅
        self.hide_weapon = True
        self.weapon.hide()

    def toggleLights(self, lights):
        # Π‘ΠΏΠ΅Ρ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠ΅ освСщСниС
        if self.hide_weapon:
            for light in lights:
                if render.hasLight(light):
                    render.clearLight(light)
                else:
                    render.setLight(light)
            
            self.flash.setPos(self.weapon_pos)
        else:
            return


    def shot(self):
        dt = globalClock.getDt() + 0.5 # CΠΊΠΎΡ€ΠΎΡΡ‚ΡŒ двиТСния
        if not self.hide_weapon : # Ссли ΠΎΡ€ΡƒΠΆΠΈΠ΅ ΡƒΠ±Ρ€Π°Π½ΠΎ Ρ‚ΠΎ ΠΌΡ‹ Π½Π΅ ΠΌΠΎΠΆΠ΅ΠΌ ΡΡ‚Ρ€Π΅Π»ΡΡ‚ΡŒ
            self.shotSound.play() # ΠΈΠ³Ρ€Π°Π΅ΠΌ Π·Π²ΡƒΠΊ выстрСла
            self.bullet.setPos(self.weapon_pos) # ΠŸΡƒΠ»Ρ Π±ΡƒΠ΄Π΅Ρ‚ спавнится Π²Π½ΡƒΡ‚Ρ€ΠΈ ΠΏΡƒΡˆΠΊΠΈ
            self.bullet.setY(self.bullet, -11 * dt) # Π‘Π΄Π²ΠΈΠ³Π°Π΅ΠΌ ΠΏΡƒΠ»ΡŽ Π½Π° ΠΎΠ³Ρ€ΠΎΠΌΠ½ΠΎΠΉ скорости Π²ΠΏΠ΅Ρ€Ρ‘Π΄

    def check_loss(self):
        if self.state == 0: # Ссли ΠΆΠΈΠ·Π½Π΅ΠΉ Ρƒ корабля Π½Π΅ ΠΎΡΡ‚Π°Π»ΠΎΡΡŒ
            self.black_light() # Π²ΠΊΠ»ΡŽΡ‡ΠΈΠΌ Ρ‡Ρ‘Ρ€Π½Ρ‹ΠΉ свСт
            self.weapon_hide() # ΡƒΠ±Π΅Ρ€Ρ‘ΠΌ ΠΎΡ€ΡƒΠΆΠΈΠ΅
            self.info = OnscreenText(text='ΠΏΠΎΡ€Π°ΠΆΠ΅Π½ΠΈΠ΅', style=1, font=self.font,
                                     fg=(1,1,1,1),
                            pos=(-1.3, -0.5), align=TextNode.ALeft, scale=0.3) # напишСм ΠΎ ΠΏΠΎΡ€Π°ΠΆΠ΅Π½ΠΈΠΈ
            self.crackSound.play() # ΠΈΠ³Ρ€Π°Π΅ΠΌ Π·Π²ΡƒΠΊ Π²Π·Ρ€Ρ‹Π²Π°


    def setKey(self, key, value):
        self.keyMap[key] = value # Π”Π΅Π»Π°Π΅ΠΌ ΠΌΠ΅Ρ…aΠ½uΠ·ΠΌ наТатия клавиш.

    def move(self, task):

        ''' Π”Π΅Π»Π°Π΅ΠΌ Ρ„ΡƒΡ†Π½ΠΊΡ†ΠΈΡŽ двиТСния ΠΈΠ³Ρ€ΠΎΠΊΠ° '''

        dt = globalClock.getDt() - .005 # CΠΊΠΎΡ€ΠΎΡΡ‚ΡŒ двиТСния

        # ΠŸΠΎΠ²ΠΎΡ€ΠΎΡ‚ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ Π²Π»Π΅Π²ΠΎ ΠΈ Π²ΠΏΡ€Π°Π²ΠΎ

        if self.keyMap["cam-left"]:
            self.camera.setX(self.camera, -20 * dt) # МСняСм ΠΏΠΎΠ»ΠΎΠΆΠ΅Π½ΠΈΠΊΠ° ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ ΠΏΠΎ икс. Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ получаСтся илюзия ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚Π° ΡƒΠ³Π»Π° Π»ΡƒΡ‡Π°. Но Π½Π° самом Π΄Π΅Π»Π΅ ΠΊΠ°ΠΌΠ΅Ρ€Π° просто пСрСмСщаСтся.
        if self.keyMap["cam-right"]:
            self.camera.setX(self.camera, +20 * dt) # Π’ΠΎΠΆΠ΅ самоС, Ρ‡Ρ‚ΠΎ ΠΈ Π½Π°Π²Π΅Ρ€Ρ…Ρƒ.

        startpos = self.droid.getPos() # Π‘Π΄Π΅Π»Π°Π΅ΠΌ ΡƒΠ΄ΠΎΠ±Π½ΡƒΡŽ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ ΠΈΠ³Ρ€ΠΎΠΊΠ°

        if self.keyMap["left"]:
            self.droid.setH(self.droid.getH() + 300 * dt)
            self.enemy.setY(self.enemy, 1 * dt)
        if self.keyMap["right"]:
            self.droid.setH(self.droid.getH() - 300 * dt)
            self.enemy.setY(self.enemy, -1 * dt)
        if self.keyMap["forward"]:
            self.droid.setY(self.droid, -25 * dt)
            self.enemy.setX(self.enemy, 1 * dt)
            # Π‘Π΄Π΅Π»Π°Π΅ΠΌ ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½ΠΎΠ΅ условиС ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ ΡƒΠ±Ρ€Π°Π½ΠΎ ΠΎΡ€ΡƒΠΆΠΈΠ΅ ΠΈΠ»ΠΈ Π½Π΅Ρ‚
            if not self.hide_weapon:
                self.weapon_pos = self.droid.getX(), self.droid.getY() + 0.7, 3
                self.weapon.setPos(self.weapon_pos) # ОбновляСм ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΏΡƒΡˆΠΊΠΈ
            else:
                self.weapon_pos = self.droid.getX(), self.droid.getY() + 0.7, 3
                self.flash.setPos(self.weapon_pos)



        camvec = self.droid.getPos() - self.camera.getPos()
        camvec.setZ(0)
        camdist = camvec.length()
        camvec.normalize()
        if camdist > 10.0:
            self.camera.setPos(self.camera.getPos() + camvec * (camdist - 10))
            camdist = 10.0
        if camdist < 5.0:
            self.camera.setPos(self.camera.getPos() - camvec * (5 - camdist))
            camdist = 5.0
            
        self.camera.lookAt(self.floater)


        return task.cont

    def addInstructions(self, pos, msg):
        return OnscreenText(text=msg, style=1, fg=(1,1,1,1), font=self.inst_font, pos=(-1.3, pos), align=TextNode.ALeft, scale = .04, shadow=(0,0,0,1))

    def addTitle(self, text):
        return OnscreenText(text=text, style=1, fg=(1, 1, 1, 1), scale=0.2,
                            parent=base.a2dBottomRight, align=TextNode.ARight,
                            pos=(-0.1, 0.09), shadow=(0, 0, 0, 1), font=self.font)
    

droid = DroidShooter() # Π‘ΠΎΠ·Π΄Π°Π΄ΠΈΠΌ экзСмпляр класса нашСй ΠΈΠ³Ρ€Ρ‹
droid.run() # 3апустим ΠΈΠ³Ρ€Ρƒ


# Ρ€Π°Π·Ρ€ΠΎΠ±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ :
# Π“Π»Π°Π²Π½Ρ‹ΠΉ Π°Π²Ρ‚ΠΎΡ€ : ma3rx
# ΠŸΠΎΠΌΠΎΡ‰Π½ΠΈΠΊ : panda3dmastercoder( присоСдСнился ΠΊ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Ρƒ 31 января, 12:??)

Hi! I create 3.0.1 update!
Bug fix fountain!
New code :

#!/usr/bin/env python
# -*- coding: utf_8 -*-

# Π‘ΠΎΠ·Π΄Π°Π½ΠΎ : 22 число, ΡΠ½Π²Π°Ρ€ΡŒ, 2021 Π³ΠΎΠ΄

# Π˜ΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΡƒΠ΅ΠΌ всС Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹Π΅ инструмСнты
from direct.showbase.ShowBase import ShowBase
from panda3d.core import CollisionTraverser, CollisionNode
from panda3d.core import CollisionHandlerPusher, CollisionSphere, CollisionInvSphere
from panda3d.core import Filename, AmbientLight, DirectionalLight
from panda3d.core import PandaNode, NodePath, Camera, TextNode
from direct.particles.Particles import Particles
from direct.particles.ParticleEffect import ParticleEffect
from panda3d.core import PointLight, Spotlight
from panda3d.core import CollideMask
from panda3d.core import loadPrcFileData
from panda3d.core import *
from direct.gui.OnscreenText import OnscreenText
from direct.gui.OnscreenImage import OnscreenImage
from direct.gui.DirectButton import DirectButton
from direct.gui.DirectSlider import DirectSlider
from direct.actor.Actor import Actor
import random
import sys
import time
import os
import math

VERSION = '3.0.1'

settings = ['window-title Droid Game ' +  VERSION]
            

loadPrcFileData('', settings[0]) # Π‘Π΄Π΅Π»Π°Π΅ΠΌ Π½Π΅ стандартный Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ (Π²ΠΎΠ·ΠΌΡ‘ΠΌ Π΅Π³ΠΎ ΠΈΠ· ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ settings)

# Π‘ΠΎΠ·Π΄Π°Π΄ΠΈΠΌ Π³Π»Π°Π²Π½Ρ‹ΠΉ класс нашСй ΠΈΠ³Ρ€Ρ‹
class DroidShooter(ShowBase):
    def __init__(self):
        ShowBase.__init__(self) # Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ всС сСлфы ΠΈΠ· direct
        self.speed = 800 # ΡΠΊΠΎΡ€ΠΎΡΡ‚ΡŒ двигатСля
        self.menu() # звпуск мСню
        
    def menu(self):
        
        base.enableParticles() # ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ эффСкт Π΄Ρ‹ΠΌΠ°

        self.win.setClearColor((0, 0, 0, 1)) # Π—Π°ΠΊΡ€Π°ΡˆΠΈΠ²Π°Π΅ΠΌ ΠΏΠΎΠ²Π΅Ρ€Ρ…Π½ΠΎΡΡ‚ΡŒ Ρ‡Ρ‘Ρ€Π½Ρ‹ΠΌ. Π”Π΅Π»ΠΎ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ Π² этом ΠΈΠ³Ρ€ΠΎΠ²ΠΎΠΌ Π΄Π²ΠΈΠΆΠΊΠ΅ ΠΏΠΎΠ²Π΅Ρ€Ρ…Π½ΠΎΡΡ‚ΡŒ Π·Π°ΠΊΡ€Π°ΡˆΠΈΠ²Π°Π΅Ρ‚ΡΡ сСрым.
        self.font = loader.loadFont('./fonts/doom_font.ttf') # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ ΡˆΡ€ΠΈΡ„Ρ‚ ΠΈΠ· ΠΈΠ³Ρ€Ρ‹ doom
        self.inst_font = loader.loadFont('./fonts/arial.ttf') # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ ΡˆΡ€ΠΈΡ„Ρ‚ arial

        self.crackSound = loader.loadMusic('./sounds/crack.wav') # Π·Π²ΡƒΠΊ Π²Π·Ρ€Ρ‹Π²Π° корабля
        self.shotSound = loader.loadMusic('./sounds/shot.wav') # Π·Π²ΡƒΠΊ выстрСла
        self.startSound = loader.loadMusic('./sounds/started.wav') # Π·Π²ΡƒΠΊ запуска
        self.errorSound = loader.loadMusic('./sounds/error.wav') # Π·Π²ΡƒΠΊ запуска
        self.errorSound.setVolume(1) # полная Π³Ρ€ΠΎΠΌΠΊΠΎΡΡ‚ΡŒ Π·Π²ΡƒΠΊΠ°
        self.startSound.setVolume(1) # полная Π³Ρ€ΠΎΠΌΠΊΠΎΡΡ‚ΡŒ Π·Π²ΡƒΠΊΠ°
        self.crackSound.setVolume(1) # полная Π³Ρ€ΠΎΠΌΠΊΠΎΡΡ‚ΡŒ Π·Π²ΡƒΠΊΠ°
        self.shotSound.setVolume(1) # полная Π³Ρ€ΠΎΠΌΠΊΠΎΡΡ‚ΡŒ Π·Π²ΡƒΠΊΠ°
        self.startSound.play() # ΠΈΠ³Ρ€Π°Π΅ΠΌ Π·Π²ΡƒΠΊ запуска ΠΈΠ³Ρ€Ρ‹

        self.button_start = DirectButton(pos=(0.7, 0, 0), text="CTAPT",
                                   scale=.3, pad=(.2, .2),
                                   command=self.load_game) # ΠΊΠ½ΠΎΠΏΠΊΠ° запуска ΠΈΠ³Ρ€Ρ‹

        self.slider_sun = DirectSlider(pos=(0.1, 0, .75), scale=0.8, value=0,
                                    command=self.set_sun_interval)


        self.title = self.addTitle("Droid game " + VERSION)
        
        # НапСчатаСм ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅
        self.inst1 = self.addInstructions(0.95, u"[ESC]: Π’Ρ‹Ρ…ΠΎΠ΄")
        self.inst2 = self.addInstructions(0.90, u"[Left Arrow]: ΠŸΠΎΠ²ΠΎΡ€ΠΎΡ‚ Π΄Ρ€ΠΎΠΈΠ΄Π° Π² Π»Π΅Π²ΠΎ")
        self.inst3 = self.addInstructions(0.85, u"[Right Arrow]: ΠŸΠΎΠ²ΠΎΡ€ΠΎΡ‚ Π΄Ρ€ΠΎΠΈΠ΄Π° Π² ΠΏΡ€Π°Π²ΠΎ")
        self.inst4 = self.addInstructions(0.80, u"[Up Arrow]: Π’ΠΏΠ΅Ρ€Π΅Π΄")
        self.inst5 = self.addInstructions(0.75, u"[a]: ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ Π² ΠΏΡ€Π°Π²ΠΎ")
        self.inst6 = self.addInstructions(0.70, u"[d]: ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ Π² Π»Π΅Π²ΠΎ")
        self.inst7 = self.addInstructions(0.65, u"[Left Arrow + Up arrow]: ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚ Π΄Ρ€ΠΎΠΈΠ΄Π° Π² Π»Π΅Π²ΠΎ ΠΈ Π²ΠΏΠ΅Ρ€Ρ‘Π΄")
        self.inst8 = self.addInstructions(0.60, u"[Right Arrow + Up arrow]: ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚ Π΄Ρ€ΠΎΠΈΠ΄Π° Π² ΠΏΡ€Π°Π²ΠΎ ΠΈ Π²ΠΏΠ΅Ρ€Ρ‘Π΄")
        self.inst9 = self.addInstructions(0.55, u"[a + Up arrow]: ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ Π² ΠΏΡ€Π°Π²ΠΎ ΠΈ Π²ΠΏΠ΅Ρ€Ρ‘Π΄")
        self.inst10 = self.addInstructions(0.50, u"[d + Up arrow]: ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ Π² Π»Π΅Π²ΠΎ ΠΈ Π²ΠΏΠ΅Ρ€Ρ‘Π΄")
        self.inst11 = self.addInstructions(0.45, u"[space]: ΡΡ‚Ρ€Π΅Π»ΡŒΠ±Π°")
        self.inst12 = self.addInstructions(0.35, u"[s]: Π΄ΠΎΡΡ‚Π°Ρ‚ΡŒ Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊ")
        self.inst13 = self.addInstructions(0.30, u"[w]: ΡƒΠ±Ρ€Π°Ρ‚ΡŒ ΠΎΡ€ΡƒΠΆΠΈΠ΅")
        self.inst14 = self.addInstructions(0.25, u"[f]: ΠΏΠΎΠ»Π½Ρ‹ΠΉ Ρ€Π°Π·Π³ΠΎΠ½(ОПАБНО!)")
        self.inst15 = self.addInstructions(0.20, u"[0]: ΠΏΠΎΠΆΠ°Ρ€ΠΎΡ‚ΡƒΡˆΠΈΡ‚Π΅Π»ΡŒΠ½Π°Ρ систСма")

        self.accept("escape", sys.exit) # ΠŸΡ€ΠΈ Π½Π°ΠΆΠ°Ρ‚ΠΈΠΈ клавиши Esc Π²Ρ‹Ρ…ΠΎΠ΄ΠΈΠΌ.

    def set_sun_interval(self):
        self.sun_interval = self.slider_sun.guiItem.getValue() * 500 # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ слайдСрноС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΡƒΠΌΠ½ΠΎΠΆΠ΅Π½ΠΎΠ΅ Π½Π° 500, Π΄Π° Ρ‚Ρ€Π°Ρ‡Ρƒ ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΡŽ Π½ΠΎ ΠΌΠ½Π΅ каТСтся ΠΌΠ½ΠΎΠ³ΠΈΠΌ ΠΏΠ»Π΅Π²Π°Ρ‚ΡŒ Π½Π° ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΡŽ мСню, ΠΈΠ±ΠΎ Ρ‚Π°ΠΊΠΎΠ³ΠΎ понятия просто Π½Π΅Ρ‚Ρƒ :)
        

    def load_game(self):
        self.button_start.hide() # ΡƒΠ΄Π°Π»ΠΈΠΌ ΠΊΠ½ΠΎΠΏΠΊΡƒ старта
        self.title.hide() # ΡƒΠ΄Π°Π»ΠΈΠΌ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ ΠΈΠ³Ρ€Ρ‹
        # ΡƒΠ΄Π°Π»ΠΈΠΌ ΠΊΠ½ΠΎΠΏΠΊΠΈ управлСния
        self.inst1.hide()
        self.inst2.hide()
        self.inst3.hide()
        self.inst4.hide()
        self.inst5.hide()
        self.inst6.hide()
        self.inst7.hide()
        self.inst8.hide()
        self.inst9.hide()
        self.inst10.hide()
        self.inst11.hide()
        self.inst12.hide()
        self.inst13.hide()
        self.inst14.hide()
        self.inst15.hide()
        self.slider_sun.hide() # удаляСм слайдСр солнца
        
        self.keyMap = {
            "left": 0, "right": 0, "forward": 0, "cam-left": 0, "cam-right": 0} # Π‘ΠΎΠ·Π΄Π°Π΄ΠΈΠΌ ΡΠ»ΠΎΠ²Π°Ρ€ΡŒ ΠΊΠ½ΠΎΠΏΠΎΠΊ, ΠΏΠΎ ΠΈΡ… Π½Π°ΠΆΠ°Ρ‚ΠΈΡŽ        

        # РисуСм Π·Π²Ρ‘Π·Π΄Ρ‹

        self.sky = loader.loadModel("./models/sky/solar_sky_sphere") # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ модСль космоса(это сфСра)

        self.sky_tex = loader.loadTexture("./tex/stars_1k_tex.jpg") # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ тСкстуру
        self.sky.setTexture(self.sky_tex, 1) # Π·Π°Ρ€Π΅Π½Π΄Π΅Ρ€ΠΈΠΌ тСкстуру Π½Π° Π½Π΅Π±ΠΎ
        self.sky.reparentTo(render) # ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ Π½Π΅Π±ΠΎ
        self.sky.setScale(40000) # Ρ€Π°ΡΡˆΠΈΡ€ΠΈΠΌ Π½Π΅Π±ΠΎ Π΄ΠΎ максимальной Π²Π΅Π»ΠΈΡ‡ΠΈΠ½Ρ‹ panda3d

        self.environ = loader.loadModel("models/world/falcon.egg") # Π—Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ ΡƒΠΆΠ΅ созданный Π² blender ΠΌΠΈΡ€.
        self.environ.reparentTo(render) # Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ модСль ΠΌΠΈΡ€Π° Π² ΠΎΠΊΠ½ΠΎ

        droidStartPos = (-1, 6, 1.5 ) # Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ ΡΡ‚Π°Ρ€Ρ‚ΠΎΠ²ΡƒΡŽ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π² ΠΌΠΈΡ€Π΅.
        enemyStartPos = (-6, 1, 0.5) # Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ°-Π΄Ρ€ΠΎΠΈΠ΄Π°.
        self.droid = Actor("models/player/seeker.egg") # Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ модСль ΠΈΠ³Ρ€ΠΎΠΊΠ° (созданная Π² blender)
        self.enemy = Actor("models/enemies/r2d2/r2d2.egg") # Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ модСль ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ° (созданная Π² blender)
        self.droid.reparentTo(render) # ΠŸΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Π΅ΠΌ модСль ΠΈΠ³Ρ€ΠΎΠΊΠ° Π² наш ΠΌΠΈΡ€.
        self.enemy.reparentTo(render) # ΠŸΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Π΅ΠΌ модСль ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ° Π² наш ΠΌΠΈΡ€.
        self.droid.setScale(1) # Π”Π΅Π»Π°Π΅ΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ€ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π½Π° 1
        self.enemy.setScale(1) # Π”Π΅Π»Π°Π΅ΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ€ ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ° Π½Π° 1
        self.droid.setPos(droidStartPos) # Π‘Ρ‚Π°Π²ΠΈΠΌ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π½Π° Ρ€Π°Π½Π΅Π΅ ΡΠΎΠ·Π΄Π°Π½ΡƒΡŽ Π½Π°ΠΌΠΈ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ
        self.enemy.setPos(enemyStartPos) # Π‘Ρ‚Π°Π²ΠΈΠΌ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ° Π½Π° Ρ€Π°Π½Π΅Π΅ ΡΠΎΠ·Π΄Π°Π½ΡƒΡŽ Π½Π°ΠΌΠΈ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ

        self.weapon = Actor('models/weapon/lightsaber.egg') # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ ΠΎΡ€ΡƒΠΆΠΈΠ΅
        self.bullet = Actor('models/weapon/bullet/bullet.egg.pz') # Π—Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ ΠΏΡƒΠ»ΡŽ
        self.flash = Actor('models/whishlyflash/handlamp.egg') # Π—Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊ
               
        self.weapon.reparentTo(render) # пСрСмСстим ΠΎΡ€ΡƒΠΆΠΈΠ΅ Π² наш ΠΌΠΈΡ€
        self.bullet.reparentTo(render) # пСрСмСстим ΠΏΡƒΠ»ΡŽ Π² ΠΌΠΈΡ€ Π½ΠΎ появится ΠΎΠ½Π° сама Π½Π΅ скоро
        self.flash.reparentTo(render) # пСрСмСстим Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊ Π² наш ΠΌΠΈΡ€
        self.weapon.setScale(.5) # Π·Π°Π΄Π°Π΄ΠΈΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ€ ΠΏΡƒΡˆΠΊΠΈ
        self.bullet.setScale(.5) # Π·Π°Π΄Π°Π΄ΠΈΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ€ ΠΏΡƒΠ»ΠΈ
        self.flash.setScale(.5) # Π·Π°Π΄Π°Π΄ΠΈΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ€ Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊΠ°
        

        self.weapon_pos = self.droid.getX(), self.droid.getY() + 0.7, 1 # ΠŸΠΎΠ·ΠΈΡ†ΠΈΡ ΠΏΡƒΡˆΠΊΠΈ
        
        self.weapon.setPos(self.weapon_pos) # ΠŸΠΎΠΌΠ΅ΡΡ‚ΠΈΠΌ ΠΎΡ€ΡƒΠΆΠΈΠ΅ Ρ‡ΡƒΡ‚ΡŒ Π²Ρ‹ΡˆΠ΅ ΠΈΠ³Ρ€ΠΎΠΊΠ°
        
        
        self.spotlight = camera.attachNewNode(Spotlight("spotlight")) # ΠšΠΎΠ½Ρ„ΠΈΠ³ΠΈ Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊΠ°
        self.spotlight.node().setColor((.3, .3, .3, 1))
        self.spotlight.node().setSpecularColor((0, 0, 0, 1))

        self.floater = NodePath(PandaNode("floater")) 
        self.floater.reparentTo(self.droid)
        self.floater.setZ(2.0)


        

        self.accept("escape", sys.exit) # ΠŸΡ€ΠΈ Π½Π°ΠΆΠ°Ρ‚ΠΈΠΈ клавиши Esc Π²Ρ‹Ρ…ΠΎΠ΄ΠΈΠΌ.
        
        self.accept("arrow_left", self.setKey, ["left", True]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ Π²Π»Π΅Π²ΠΎ - ΠΏΠΎΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π²Π»Π΅Π²ΠΎ
        self.accept("arrow_right", self.setKey, ["right", True]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ Π²ΠΏΡ€Π°Π²ΠΎ - ΠΏΠΎΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π²ΠΏΡ€Π°Π²ΠΎ
        self.accept("arrow_up", self.setKey, ["forward", True]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ Π²ΠΏΠ΅Ρ€Ρ‘Π΄ - ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄
        self.accept("a", self.setKey, ["cam-left", True]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ a - Ρ€Π°Π·Π²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΊΠ°ΠΌΠ΅Ρ€Ρƒ Π²ΠΎΠΊΡ€ΡƒΠ³ нашСй модСльки
        self.accept("d", self.setKey, ["cam-right", True]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ s - Ρ€Π°Π·Π²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΊΠ°ΠΌΠ΅Ρ€Ρƒ Π²ΠΎΠΊΡ€ΡƒΠ³ нашСй модСльки
        self.accept("arrow_left-up", self.setKey, ["left", False]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ Π²Π²Π΅Ρ€Ρ…+Π²Π»Π΅Π²ΠΎ - ΠΏΠΎΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π²Π»Π΅Π²ΠΎ ΠΈ ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄
        self.accept("arrow_right-up", self.setKey, ["right", False]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ Π²Π²Π΅Ρ€Ρ…+ΠΏΡ€Π°Π²ΠΎ - ΠΏΠΎΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π²ΠΏΡ€Π°Π²ΠΎ ΠΈ ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄
        self.accept("arrow_up-up", self.setKey, ["forward", False]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ Π²Π²Π΅Ρ€Ρ…+Π²Π²Π΅Ρ€ΡŠ - ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄ ΠΈ ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄
        self.accept("a-up", self.setKey, ["cam-left", False]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ a+Π²ΠΏΠ΅Ρ€Ρ‘Π΄ - ΠΏΠΎΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΊΠ°ΠΌΠ΅Ρ€Ρƒ Π²Π»Π΅Π²ΠΎ ΠΈ ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄
        self.accept("d-up", self.setKey, ["cam-right", False]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ s+Π²ΠΏΠ΅Ρ€Ρ‘Π΄ - ΠΏΠΎΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΊΠ°ΠΌΠ΅Ρ€Ρƒ Π²ΠΏΡ€Π°Π²ΠΎ ΠΈ ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄

        self.accept("space", self.shot) # ΠΏΡ€ΠΈ ΠΏΡ€ΠΎΠ±Π΅Π»Π΅ стрСляСм
        self.accept("s", self.toggleLights, [[self.spotlight]]) # Π’ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊ
        self.accept("w", self.weapon_hide) # ΠΏΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ w - ΡƒΠ±Π΅Ρ€Ρ‘ΠΌ ΠΎΡ€ΡƒΠΆΠΈΠ΅.

        base.enableParticles() # Π’ΠΊΠ»ΡŽΡ‡Π°Π΅ΠΌ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ Π΄Ρ‹ΠΌΠ°
        self.t = loader.loadModel("models/weapon/lightsaber.egg") # Π—Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ Π΅Ρ‰Ρ‘ ΠΎΡ€ΡƒΠΆΠΈΠ΅
        self.t.reparentTo(render) # ΠŸΠ΅Ρ€Π΅ΠΌΠ΅ΡΡ‚ΠΈΠΌ ΠΎΡ€ΡƒΠΆΠΈΠ΅ Π² наш ΠΌΠΈΡ€
        self.p = ParticleEffect() # Π’ΠΊΠ»ΡŽΡ‡ΠΈΠΌ эффСкт Π΄Ρ‹ΠΌΠ°
        self.accept('f', self.particle_start) # ΠΏΡ€ΠΈ Π½Π°ΠΆΠ°Ρ‚ΠΈΠΈ f(ΠΎΡ‚ force) -  Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ Ρ„Π°ΠΉΠ» Π΄Ρ‹ΠΌΠ° ΠΈ пСрСмСстим Π² ΠΊΠΎΠ½Ρ„ΠΈΠ³ Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΈΠΌΠ΅Π½Π½ΠΎ эта анимация стала ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ΠΌ Π΄Ρ‹ΠΌΠ°
        self.accept('0', self.fountain) # ΠΏΡ€ΠΈ  Π½Π°ΠΆΠ°Ρ‚ΠΈΠΈ ΠΊΠ½ΠΎΠΏΠΎΠΊ f+o(fountain) Π²ΠΊΠ»ΡŽΡ‡ΠΈΠΌ ΠΏΠΎΠΆΠ°Ρ€ΠΎΡ‚ΡƒΡˆΠΈΡ‚Π΅Π»ΡŒΠ½ΡƒΡŽ систСму

        self.accept('arrow_1+s', self.shot)

        taskMgr.add(self.move, "moveTask") # ДобавляСм Π·Π°Π΄Π°Ρ‡Ρƒ Π² наш Π΄Π²ΠΈΠΆΠΎΠΊ

        self.isMoving = False # Π‘Ρ‚Π°Π²ΠΈΠΌ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ isMoving Π½Π° False(Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΌΠ΅Π½ΡΡ‚ΡŒ это Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅) Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΈΠ³Ρ€ΠΎΠΊ ΠΈΠ·Π½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎ стоял.
        # Π”Π΅Π»Π°Π΅ΠΌ Ρ‚Π°ΠΊ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ свСт Π±Ρ‹Π» ΠΈΠ·Π½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎ Π²Ρ‹ΠΊΠ»ΡŽΡ‡Π΅Π½.
        self.disableMouse() # ΠžΡ‚ΠΊΠ»ΡŽΡ‡Π°Π΅ΠΌ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π΅Π½ΠΈΠ΅ Ρ‡Π΅Ρ€Π΅Π· ΠΌΡ‹ΡˆΠΊΡƒ
        self.camera.setPos(self.droid.getX(), self.droid.getY() + 1, 3) # Π‘Ρ‚Π°Π²ΠΈΠΌ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ Ρ‡ΡƒΡ‚ΡŒ большС ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ ΠΈΠ³Ρ€ΠΎΠΊΠ°

        self.black_light() # Π‘Π΄Π΅Π»Π°Π΅ΠΌ Π²Ρ‹ΠΊΠ»ΡŽΡ‡Π΅Π½Π½Ρ‹ΠΉ свСт

        self.state = 100 # БостояниС корабля
        self.state_info = OnscreenText(text='ΠΊΠΎΡ€Π°Π±Π»ΡŒ :' + str(self.state), pos=(0.5, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля
                
        self.check_loss() # ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ ΠΏΠΎΡ€Π°ΠΆΠ΅Π½ΠΈΠ΅
        self.hide_weapon = False # ΠŸΠΎΡΡ‚Π°Π²ΠΈΠΌ, Ρ‡Ρ‚ΠΎ ΠΎΡ€ΡƒΠΆΠΈΠ΅ Π½Π΅ ΡƒΠ±Ρ€Π°Π½ΠΎ
        self.steam_pos = random.randrange(0, 5), random.randrange(0, 5), random.randrange(0, 5)
        self.fountain_pos = random.randrange(0, 5), random.randrange(0, 5), random.randrange(0, 1)

        self.motor_pos1 = 25.238849639892578, 8.962211608886719, 1.5 # позиция ΠΏΠ΅Ρ€Π²ΠΎΠ³ΠΎ ΠΌΠΎΡ‚ΠΎΡ€Π°
        self.motor_pos2 = -20.676218032836914, 10.55816650390625, 1.5 # позиция Π²Ρ‚ΠΎΡ€ΠΎΠ³ΠΎ ΠΌΠΎΡ‚ΠΎΡ€Π°

        self.motor1 = self.loadParticleConfig('special_effects/steam_critic+/fireish.ptf', self.motor_pos1) # ΠΌΠΎΡ‚ΠΎΡ€ 1
        self.motor2 = self.loadParticleConfig('special_effects/steam_critic+/fireish.ptf', self.motor_pos2) # ΠΌΠΎΡ‚ΠΎΡ€ 2

        self.state_info2 = OnscreenText(text='', pos=(-0.8, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля

        self.force = False # ΠŸΠΎΡΡ‚Π°Π²ΠΈΠΌ, Ρ‡Ρ‚ΠΎ Π½Π΅ Ρ€Π°Π·Π³ΠΎΠ½ΡΠ»ΠΈΡΡŒ

        # ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ ΠΊΠΎΠ»Π»ΠΈΠ·ΠΈΠΈ
        
        self.cTrav = CollisionTraverser()
        pusher = CollisionHandlerPusher()
        
        environCenter = self.environ.getBounds().getCenter()
        environRad = self.environ.getBounds().getRadius()
        cNode = CollisionNode("environment")
        cNode.addSolid(CollisionInvSphere(environCenter, environRad))
        environC = self.environ.attachNewNode(cNode)
        
        droidCenter = self.droid.getBounds().getCenter()
        droidRad = self.droid.getBounds().getRadius()
        cNode = CollisionNode("droid")
        cNode.addSolid(CollisionSphere(droidCenter, droidRad))
        droidC = self.droid.attachNewNode(cNode)
        
        pusher.addCollider(droidC, self.droid)
        self.cTrav.addCollider(droidC, pusher)
        
        enemyCenter = self.enemy.getBounds().getCenter()
        enemyRad = self.enemy.getBounds().getRadius()
        cNode = CollisionNode("enemy")
        cNode.addSolid(CollisionSphere(enemyCenter, enemyRad))
        enemyC = self.enemy.attachNewNode(cNode)
        
        pusher.addCollider(enemyC, self.enemy)
        self.cTrav.addCollider(enemyC, pusher)

        # солнцС(новая ΠΌΠ΅Ρ…Π°Π½ΠΈΠΊΠ° освСщСния)
        sun = DirectionalLight("sun")
        sun.set_color_temperature(6000)
        sun.color = sun.color * 4
        sun_path = render.attach_new_node(sun)
        sun_path.set_pos(10, -10, -10)
        sun_path.look_at(0, 0, 0)
        sun_path.hprInterval(self.sun_interval, (sun_path.get_h(), sun_path.get_p() - 360, sun_path.get_r()), bakeInStart=True).loop()
        render.set_light(sun_path)

    def loadParticleConfig(self, filename, pos):
        self.p.cleanup()
        self.p = ParticleEffect()
        self.p.loadConfig(Filename(filename))

        self.p.start(self.t)
        self.p.setPos(pos)

    def particle_start(self):
        self.force = True # ΠŸΠΎΡΡ‚Π°Π²ΠΈΠΌ, Ρ‡Ρ‚ΠΎ ΠΌΡ‹ ΡƒΠΆΠ΅ Ρ€Π°Π·Π³ΠΎΠ½ΡΠ»ΠΈΡΡŒ
        # ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Π΅ΠΌ всС ΠΎΠ±ΡŒΠ΅ΠΊΡ‚Ρ‹ Π·Π° ΠΊΠΎΡ€Π°Π±Π»Ρ‘ΠΌ
        self.environ.setY(self.environ.getY() + self.speed) # нСсёмся Π²ΠΏΡ€Π°Π²ΠΎ
        self.droid.setY(self.droid.getY() + self.speed) # сдвигаСм Π΄Ρ€ΠΎΠΈΠ΄Π° Π·Π° ΠΊΠΎΡ€Π°Π±Π»Ρ‘ΠΌ
        self.enemy.setY(self.enemy.getY() + self.speed) # сдфигаСм ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ° Π·Π° ΠΊΠΎΡ€Π°Π±Π»Ρ‘ΠΌ
        self.weapon.setY(self.weapon.getY() + self.speed) # ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Π΅ΠΌ ΠΎΡ€ΡƒΠΆΠΈΠ΅
        self.flash.setY(self.flash.getY() + self.speed) # ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Π΅ΠΌ Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊ

        self.state -= 1 # сдСлаСм мСньшС ΠΎΡ‡ΠΊΠΎΠ²
        self.state_info.hide() # ΡƒΠ΄Π°Π»ΠΈΠΌ тСкстовыС ΠΎΡ‡ΠΊΠΈ

        camvec = self.droid.getPos() - self.camera.getPos()
        camvec.setZ(0)
        camdist = camvec.length()
        camvec.normalize()
        if camdist > 10.0:
            self.camera.setPos(self.camera.getPos() + camvec * (camdist - 10))
            camdist = 10.0
        if camdist < 5.0:
            self.camera.setPos(self.camera.getPos() - camvec * (5 - camdist))
            camdist = 5.0
            
        self.camera.lookAt(self.floater)
        
        if self.state != 10 and self.state > 10:
            self.state_info.hide() # ΡƒΠ±ΠΈΡ€Π°Π΅ΠΌ ΠΏΡ€Π΅Π΄Π΅Π΄ΡƒΡ‰Π΅Π΅ сообщСниС ΠΎ Тизнях корабля
            self.state_info = OnscreenText(text='ΠΊΠΎΡ€Π°Π±Π»ΡŒ :' + str(self.state), pos=(0.5, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля
            self.check_loss() # провСряСм ΠΏΠΎΡ€Π°ΠΆΠ΅Π½ΠΈΠ΅
            self.steam_pos = random.randrange(0, 5), random.randrange(0, 5) + 300, random.randrange(0, 5)
            self.loadParticleConfig('special_effects/steam/steam.ptf', self.steam_pos)
            self.errorSound.play() # ΠΈΠ³Ρ€Π°Π΅ΠΌ Π·Π²ΡƒΠΊ ошибки
            self.state_info2.hide() # ΡƒΠ±ΠΈΡ€Π°Π΅ΠΌ ΠΏΡ€Π΅Π΄Π΅Π΄ΡƒΡ‰Π΅Π΅ сообщСниС
            self.state_info2 = OnscreenText(text='Π΄Π²ΠΈΠ³Π°Ρ‚Π΅Π»ΡŒ нСисправСн', pos=(-0.8, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля
        else:
            self.state_info = OnscreenText(text='ΠΊΠΎΡ€Π°Π±Π»ΡŒ :' + str(self.state), pos=(0.5, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля
            self.check_loss() # провСряСм ΠΏΠΎΡ€Π°ΠΆΠ΅Π½ΠΈΠ΅
            self.steam_pos = random.randrange(0, 5), random.randrange(0, 5) + 300, random.randrange(0, 5)
            self.loadParticleConfig('special_effects/steam_critic/steam.ptf', self.steam_pos)
            self.errorSound.play() # ΠΈΠ³Ρ€Π°Π΅ΠΌ Π·Π²ΡƒΠΊ ошибки
            self.state_info2.hide()  # ΡƒΠ±ΠΈΡ€Π°Π΅ΠΌ ΠΏΡ€Π΅Π΄Π΅Π΄ΡƒΡ‰Π΅Π΅ сообщСниС
            self.state_info2 = OnscreenText(text='критичСскоС состояниС', pos=(-0.8, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля
    
        if self.state < 10:
            self.state_info.hide()
            self.state_info = OnscreenText(text='ΠΊΠΎΡ€Π°Π±Π»ΡŒ :' + str(self.state), pos=(0.5, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля
            self.check_loss() # провСряСм ΠΏΠΎΡ€Π°ΠΆΠ΅Π½ΠΈΠ΅
            self.steam_pos = random.randrange(0, 5), random.randrange(0, 5) + 300, random.randrange(0, 5)            
            self.loadParticleConfig('special_effects/steam_critic+/fireish.ptf', self.steam_pos)
            self.errorSound.play() # ΠΈΠ³Ρ€Π°Π΅ΠΌ Π·Π²ΡƒΠΊ ошибки
            self.state_info2.hide() # ΡƒΠ±ΠΈΡ€Π°Π΅ΠΌ ΠΏΡ€Π΅Π΄Π΅Π΄ΡƒΡ‰Π΅Π΅ сообщСниС
            self.state_info2 = OnscreenText(text='ΠΏΠ°Π΄Π°Π΅ΠΌ!', pos=(-0.8, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля


    def fountain(self):
        self.state_info2.hide() # ΡƒΠ±ΠΈΡ€Π°Π΅ΠΌ тСкст опасности
        if self.force:
            if self.state != 100:
                self.state += 1
                self.state_info.hide()
                self.state_info = OnscreenText(text='ΠΊΠΎΡ€Π°Π±Π»ΡŒ :' + str(self.state), pos=(0.5, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля

            self.fountain_pos = random.randrange(0, 5), random.randrange(0, 5) + 500, random.randrange(0, 1)    
            self.loadParticleConfig('special_effects/fountain/fountain.ptf', self.fountain_pos)

        else :
            if self.state != 100:
                self.state += 1
                self.state_info.hide()
                self.state_info = OnscreenText(text='ΠΊΠΎΡ€Π°Π±Π»ΡŒ :' + str(self.state), pos=(0.5, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля

            self.fountain_pos = random.randrange(0, 5), random.randrange(0, 5), random.randrange(0, 1)    
            self.loadParticleConfig('special_effects/fountain/fountain.ptf', self.fountain_pos)
        
        
    def black_light(self):
        # Π’Ρ‹ΠΊΠ»ΡŽΡ‡Π΅Π½Ρ‹ΠΉ свСт
        ambientLight = AmbientLight("ambientLight")
        ambientLight.setColor((0, 0, 0, 1))
        directionalLight = DirectionalLight("directionalLight")
        directionalLight.setDirection((-5, -5, -5))
        directionalLight.setColor((1, 1, 1, 1))
        directionalLight.setSpecularColor((1, 1, 1, 1))
        render.setLight(render.attachNewNode(ambientLight))
        render.setLight(render.attachNewNode(directionalLight))

    def weapon_hide(self):
        # Π£Π±Ρ€Π°Ρ‚ΡŒ ΠΎΡ€ΡƒΠΆΠΈΠ΅
        self.hide_weapon = True
        self.weapon.hide()

    def toggleLights(self, lights):
        # Π‘ΠΏΠ΅Ρ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠ΅ освСщСниС
        if self.hide_weapon:
            for light in lights:
                if render.hasLight(light):
                    render.clearLight(light)
                else:
                    render.setLight(light)
            
            self.flash.setPos(self.weapon_pos)
        else:
            return


    def shot(self):
        dt = globalClock.getDt() + 0.5 # CΠΊΠΎΡ€ΠΎΡΡ‚ΡŒ двиТСния
        if not self.hide_weapon : # Ссли ΠΎΡ€ΡƒΠΆΠΈΠ΅ ΡƒΠ±Ρ€Π°Π½ΠΎ Ρ‚ΠΎ ΠΌΡ‹ Π½Π΅ ΠΌΠΎΠΆΠ΅ΠΌ ΡΡ‚Ρ€Π΅Π»ΡΡ‚ΡŒ
            self.shotSound.play() # ΠΈΠ³Ρ€Π°Π΅ΠΌ Π·Π²ΡƒΠΊ выстрСла
            self.bullet.setPos(self.weapon_pos) # ΠŸΡƒΠ»Ρ Π±ΡƒΠ΄Π΅Ρ‚ спавнится Π²Π½ΡƒΡ‚Ρ€ΠΈ ΠΏΡƒΡˆΠΊΠΈ
            self.bullet.setY(self.bullet, -11 * dt) # Π‘Π΄Π²ΠΈΠ³Π°Π΅ΠΌ ΠΏΡƒΠ»ΡŽ Π½Π° ΠΎΠ³Ρ€ΠΎΠΌΠ½ΠΎΠΉ скорости Π²ΠΏΠ΅Ρ€Ρ‘Π΄

    def check_loss(self):
        if self.state == 0: # Ссли ΠΆΠΈΠ·Π½Π΅ΠΉ Ρƒ корабля Π½Π΅ ΠΎΡΡ‚Π°Π»ΠΎΡΡŒ
            self.black_light() # Π²ΠΊΠ»ΡŽΡ‡ΠΈΠΌ Ρ‡Ρ‘Ρ€Π½Ρ‹ΠΉ свСт
            self.weapon_hide() # ΡƒΠ±Π΅Ρ€Ρ‘ΠΌ ΠΎΡ€ΡƒΠΆΠΈΠ΅
            self.info = OnscreenText(text='ΠΏΠΎΡ€Π°ΠΆΠ΅Π½ΠΈΠ΅', style=1, font=self.font,
                                     fg=(1,1,1,1),
                            pos=(-1.3, -0.5), align=TextNode.ALeft, scale=0.3) # напишСм ΠΎ ΠΏΠΎΡ€Π°ΠΆΠ΅Π½ΠΈΠΈ
            self.crackSound.play() # ΠΈΠ³Ρ€Π°Π΅ΠΌ Π·Π²ΡƒΠΊ Π²Π·Ρ€Ρ‹Π²Π°


    def setKey(self, key, value):
        self.keyMap[key] = value # Π”Π΅Π»Π°Π΅ΠΌ ΠΌΠ΅Ρ…aΠ½uΠ·ΠΌ наТатия клавиш.

    def move(self, task):

        ''' Π”Π΅Π»Π°Π΅ΠΌ Ρ„ΡƒΡ†Π½ΠΊΡ†ΠΈΡŽ двиТСния ΠΈΠ³Ρ€ΠΎΠΊΠ° '''

        dt = globalClock.getDt() - .005 # CΠΊΠΎΡ€ΠΎΡΡ‚ΡŒ двиТСния

        # ΠŸΠΎΠ²ΠΎΡ€ΠΎΡ‚ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ Π²Π»Π΅Π²ΠΎ ΠΈ Π²ΠΏΡ€Π°Π²ΠΎ

        if self.keyMap["cam-left"]:
            self.camera.setX(self.camera, -20 * dt) # МСняСм ΠΏΠΎΠ»ΠΎΠΆΠ΅Π½ΠΈΠΊΠ° ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ ΠΏΠΎ икс. Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ получаСтся илюзия ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚Π° ΡƒΠ³Π»Π° Π»ΡƒΡ‡Π°. Но Π½Π° самом Π΄Π΅Π»Π΅ ΠΊΠ°ΠΌΠ΅Ρ€Π° просто пСрСмСщаСтся.
        if self.keyMap["cam-right"]:
            self.camera.setX(self.camera, +20 * dt) # Π’ΠΎΠΆΠ΅ самоС, Ρ‡Ρ‚ΠΎ ΠΈ Π½Π°Π²Π΅Ρ€Ρ…Ρƒ.

        startpos = self.droid.getPos() # Π‘Π΄Π΅Π»Π°Π΅ΠΌ ΡƒΠ΄ΠΎΠ±Π½ΡƒΡŽ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ ΠΈΠ³Ρ€ΠΎΠΊΠ°

        if self.keyMap["left"]:
            self.droid.setH(self.droid.getH() + 300 * dt)
            self.enemy.setY(self.enemy, 1 * dt)
        if self.keyMap["right"]:
            self.droid.setH(self.droid.getH() - 300 * dt)
            self.enemy.setY(self.enemy, -1 * dt)
        if self.keyMap["forward"]:
            self.droid.setY(self.droid, -25 * dt)
            self.enemy.setX(self.enemy, 1 * dt)
            # Π‘Π΄Π΅Π»Π°Π΅ΠΌ ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½ΠΎΠ΅ условиС ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ ΡƒΠ±Ρ€Π°Π½ΠΎ ΠΎΡ€ΡƒΠΆΠΈΠ΅ ΠΈΠ»ΠΈ Π½Π΅Ρ‚
            if not self.hide_weapon:
                self.weapon_pos = self.droid.getX(), self.droid.getY() + 0.7, 3
                self.weapon.setPos(self.weapon_pos) # ОбновляСм ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΏΡƒΡˆΠΊΠΈ
            else:
                self.weapon_pos = self.droid.getX(), self.droid.getY() + 0.7, 3
                self.flash.setPos(self.weapon_pos)



        camvec = self.droid.getPos() - self.camera.getPos()
        camvec.setZ(0)
        camdist = camvec.length()
        camvec.normalize()
        if camdist > 10.0:
            self.camera.setPos(self.camera.getPos() + camvec * (camdist - 10))
            camdist = 10.0
        if camdist < 5.0:
            self.camera.setPos(self.camera.getPos() - camvec * (5 - camdist))
            camdist = 5.0
            
        self.camera.lookAt(self.floater)


        return task.cont

    def addInstructions(self, pos, msg):
        return OnscreenText(text=msg, style=1, fg=(1,1,1,1), font=self.inst_font, pos=(-1.3, pos), align=TextNode.ALeft, scale = .04, shadow=(0,0,0,1))

    def addTitle(self, text):
        return OnscreenText(text=text, style=1, fg=(1, 1, 1, 1), scale=0.2,
                            parent=base.a2dBottomRight, align=TextNode.ARight,
                            pos=(-0.1, 0.09), shadow=(0, 0, 0, 1), font=self.font)
    

droid = DroidShooter() # Π‘ΠΎΠ·Π΄Π°Π΄ΠΈΠΌ экзСмпляр класса нашСй ΠΈΠ³Ρ€Ρ‹
droid.run() # 3апустим ΠΈΠ³Ρ€Ρƒ


# Ρ€Π°Π·Ρ€ΠΎΠ±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ :
# Π“Π»Π°Π²Π½Ρ‹ΠΉ Π°Π²Ρ‚ΠΎΡ€ : ma3rx
# ΠŸΠΎΠΌΠΎΡ‰Π½ΠΈΠΊ : panda3dmastercoder( присоСдСнился ΠΊ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Ρƒ 31 января, 12:??)

3.0.2 update! I added cosmo-fighter.

Add to directory ./models : fighter.zip

New code :

#!/usr/bin/env python
# -*- coding: utf_8 -*-

# Π‘ΠΎΠ·Π΄Π°Π½ΠΎ : 22 число, ΡΠ½Π²Π°Ρ€ΡŒ, 2021 Π³ΠΎΠ΄

# Π˜ΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΡƒΠ΅ΠΌ всС Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹Π΅ инструмСнты
from direct.showbase.ShowBase import ShowBase
from panda3d.core import CollisionTraverser, CollisionNode
from panda3d.core import CollisionHandlerPusher, CollisionSphere, CollisionInvSphere
from panda3d.core import Filename, AmbientLight, DirectionalLight
from panda3d.core import PandaNode, NodePath, Camera, TextNode
from direct.particles.Particles import Particles
from direct.particles.ParticleEffect import ParticleEffect
from panda3d.core import PointLight, Spotlight
from panda3d.core import CollideMask
from panda3d.core import loadPrcFileData
from panda3d.core import *
from direct.gui.OnscreenText import OnscreenText
from direct.gui.OnscreenImage import OnscreenImage
from direct.gui.DirectButton import DirectButton
from direct.gui.DirectSlider import DirectSlider
from direct.actor.Actor import Actor
import random
import sys
import time
import os
import math

VERSION = '3.0.2'

settings = ['window-title Droid Game ' +  VERSION,
            'fullscreen 0']
            

loadPrcFileData('', settings[0]) # Π‘Π΄Π΅Π»Π°Π΅ΠΌ Π½Π΅ стандартный Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ (Π²ΠΎΠ·ΠΌΡ‘ΠΌ Π΅Π³ΠΎ ΠΈΠ· ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ settings)
loadPrcFileData('', settings[1]) # Π½Π΅ Π±ΡƒΠ΄Π΅ΠΌ Π΄Π΅Π»Π°Ρ‚ΡŒ полноэкранный Ρ€Π΅ΠΆΠΈΠΌ

# Π‘ΠΎΠ·Π΄Π°Π΄ΠΈΠΌ Π³Π»Π°Π²Π½Ρ‹ΠΉ класс нашСй ΠΈΠ³Ρ€Ρ‹
class DroidShooter(ShowBase):
    def __init__(self):
        ShowBase.__init__(self) # Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ всС сСлфы ΠΈΠ· direct
        self.speed = 1800 # ΡΠΊΠΎΡ€ΠΎΡΡ‚ΡŒ двигатСля
        self.menu() # звпуск мСню
        
    def menu(self):
        
        base.enableParticles() # ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ эффСкт Π΄Ρ‹ΠΌΠ°

        self.win.setClearColor((0, 0, 0, 1)) # Π—Π°ΠΊΡ€Π°ΡˆΠΈΠ²Π°Π΅ΠΌ ΠΏΠΎΠ²Π΅Ρ€Ρ…Π½ΠΎΡΡ‚ΡŒ Ρ‡Ρ‘Ρ€Π½Ρ‹ΠΌ. Π”Π΅Π»ΠΎ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ Π² этом ΠΈΠ³Ρ€ΠΎΠ²ΠΎΠΌ Π΄Π²ΠΈΠΆΠΊΠ΅ ΠΏΠΎΠ²Π΅Ρ€Ρ…Π½ΠΎΡΡ‚ΡŒ Π·Π°ΠΊΡ€Π°ΡˆΠΈΠ²Π°Π΅Ρ‚ΡΡ сСрым.
        self.font = loader.loadFont('./fonts/doom_font.ttf') # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ ΡˆΡ€ΠΈΡ„Ρ‚ ΠΈΠ· ΠΈΠ³Ρ€Ρ‹ doom
        self.inst_font = loader.loadFont('./fonts/arial.ttf') # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ ΡˆΡ€ΠΈΡ„Ρ‚ arial

        self.crackSound = loader.loadMusic('./sounds/crack.wav') # Π·Π²ΡƒΠΊ Π²Π·Ρ€Ρ‹Π²Π° корабля
        self.shotSound = loader.loadMusic('./sounds/shot.wav') # Π·Π²ΡƒΠΊ выстрСла
        self.startSound = loader.loadMusic('./sounds/started.wav') # Π·Π²ΡƒΠΊ запуска
        self.errorSound = loader.loadMusic('./sounds/error.wav') # Π·Π²ΡƒΠΊ запуска
        self.errorSound.setVolume(1) # полная Π³Ρ€ΠΎΠΌΠΊΠΎΡΡ‚ΡŒ Π·Π²ΡƒΠΊΠ°
        self.startSound.setVolume(1) # полная Π³Ρ€ΠΎΠΌΠΊΠΎΡΡ‚ΡŒ Π·Π²ΡƒΠΊΠ°
        self.crackSound.setVolume(1) # полная Π³Ρ€ΠΎΠΌΠΊΠΎΡΡ‚ΡŒ Π·Π²ΡƒΠΊΠ°
        self.shotSound.setVolume(1) # полная Π³Ρ€ΠΎΠΌΠΊΠΎΡΡ‚ΡŒ Π·Π²ΡƒΠΊΠ°
        self.startSound.play() # ΠΈΠ³Ρ€Π°Π΅ΠΌ Π·Π²ΡƒΠΊ запуска ΠΈΠ³Ρ€Ρ‹

        self.button_start = DirectButton(pos=(0.7, 0, 0), text="CTAPT",
                                   scale=.3, pad=(.2, .2),
                                   command=self.load_game) # ΠΊΠ½ΠΎΠΏΠΊΠ° запуска ΠΈΠ³Ρ€Ρ‹

        self.slider_sun = DirectSlider(pos=(0.1, 0, .75), scale=0.8, value=0,
                                    command=self.set_sun_interval)


        self.title = self.addTitle("Droid game " + VERSION)
        
        # НапСчатаСм ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅
        self.inst1 = self.addInstructions(0.95, u"[ESC]: Π’Ρ‹Ρ…ΠΎΠ΄")
        self.inst2 = self.addInstructions(0.90, u"[Left Arrow]: ΠŸΠΎΠ²ΠΎΡ€ΠΎΡ‚ Π΄Ρ€ΠΎΠΈΠ΄Π° Π² Π»Π΅Π²ΠΎ")
        self.inst3 = self.addInstructions(0.85, u"[Right Arrow]: ΠŸΠΎΠ²ΠΎΡ€ΠΎΡ‚ Π΄Ρ€ΠΎΠΈΠ΄Π° Π² ΠΏΡ€Π°Π²ΠΎ")
        self.inst4 = self.addInstructions(0.80, u"[Up Arrow]: Π’ΠΏΠ΅Ρ€Π΅Π΄")
        self.inst5 = self.addInstructions(0.75, u"[a]: ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ Π² ΠΏΡ€Π°Π²ΠΎ")
        self.inst6 = self.addInstructions(0.70, u"[d]: ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ Π² Π»Π΅Π²ΠΎ")
        self.inst7 = self.addInstructions(0.65, u"[Left Arrow + Up arrow]: ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚ Π΄Ρ€ΠΎΠΈΠ΄Π° Π² Π»Π΅Π²ΠΎ ΠΈ Π²ΠΏΠ΅Ρ€Ρ‘Π΄")
        self.inst8 = self.addInstructions(0.60, u"[Right Arrow + Up arrow]: ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚ Π΄Ρ€ΠΎΠΈΠ΄Π° Π² ΠΏΡ€Π°Π²ΠΎ ΠΈ Π²ΠΏΠ΅Ρ€Ρ‘Π΄")
        self.inst9 = self.addInstructions(0.55, u"[a + Up arrow]: ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ Π² ΠΏΡ€Π°Π²ΠΎ ΠΈ Π²ΠΏΠ΅Ρ€Ρ‘Π΄")
        self.inst10 = self.addInstructions(0.50, u"[d + Up arrow]: ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ Π² Π»Π΅Π²ΠΎ ΠΈ Π²ΠΏΠ΅Ρ€Ρ‘Π΄")
        self.inst11 = self.addInstructions(0.45, u"[space]: ΡΡ‚Ρ€Π΅Π»ΡŒΠ±Π°")
        self.inst12 = self.addInstructions(0.40, u"[s]: Π΄ΠΎΡΡ‚Π°Ρ‚ΡŒ Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊ")
        self.inst13 = self.addInstructions(0.35, u"[w]: ΡƒΠ±Ρ€Π°Ρ‚ΡŒ ΠΎΡ€ΡƒΠΆΠΈΠ΅")
        self.inst14 = self.addInstructions(0.30, u"[f]: ΠΏΠΎΠ»Π½Ρ‹ΠΉ Ρ€Π°Π·Π³ΠΎΠ½(ОПАБНО!)")
        self.inst15 = self.addInstructions(0.25, u"[0]: ΠΏΠΎΠΆΠ°Ρ€ΠΎΡ‚ΡƒΡˆΠΈΡ‚Π΅Π»ΡŒΠ½Π°Ρ систСма")

        self.accept("escape", sys.exit) # ΠŸΡ€ΠΈ Π½Π°ΠΆΠ°Ρ‚ΠΈΠΈ клавиши Esc Π²Ρ‹Ρ…ΠΎΠ΄ΠΈΠΌ.

    def set_sun_interval(self):
        self.sun_interval = self.slider_sun.guiItem.getValue() * 100 # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ слайдСрноС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΡƒΠΌΠ½ΠΎΠΆΠ΅Π½ΠΎΠ΅ Π½Π° 500, Π΄Π° Ρ‚Ρ€Π°Ρ‡Ρƒ ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΡŽ Π½ΠΎ ΠΌΠ½Π΅ каТСтся ΠΌΠ½ΠΎΠ³ΠΈΠΌ ΠΏΠ»Π΅Π²Π°Ρ‚ΡŒ Π½Π° ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΡŽ мСню, ΠΈΠ±ΠΎ Ρ‚Π°ΠΊΠΎΠ³ΠΎ понятия просто Π½Π΅Ρ‚Ρƒ :)
        

    def load_game(self):
        self.button_start.hide() # ΡƒΠ΄Π°Π»ΠΈΠΌ ΠΊΠ½ΠΎΠΏΠΊΡƒ старта
        self.title.hide() # ΡƒΠ΄Π°Π»ΠΈΠΌ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ ΠΈΠ³Ρ€Ρ‹
        # ΡƒΠ΄Π°Π»ΠΈΠΌ ΠΊΠ½ΠΎΠΏΠΊΠΈ управлСния
        self.inst1.hide()
        self.inst2.hide()
        self.inst3.hide()
        self.inst4.hide()
        self.inst5.hide()
        self.inst6.hide()
        self.inst7.hide()
        self.inst8.hide()
        self.inst9.hide()
        self.inst10.hide()
        self.inst11.hide()
        self.inst12.hide()
        self.inst13.hide()
        self.inst14.hide()
        self.inst15.hide()
        self.slider_sun.hide() # удаляСм слайдСр солнца
        
        self.keyMap = {
            "left": 0, "right": 0, "forward": 0, "cam-left": 0, "cam-right": 0} # Π‘ΠΎΠ·Π΄Π°Π΄ΠΈΠΌ ΡΠ»ΠΎΠ²Π°Ρ€ΡŒ ΠΊΠ½ΠΎΠΏΠΎΠΊ, ΠΏΠΎ ΠΈΡ… Π½Π°ΠΆΠ°Ρ‚ΠΈΡŽ        

        # РисуСм Π·Π²Ρ‘Π·Π΄Ρ‹

        self.sky = loader.loadModel("./models/sky/solar_sky_sphere") # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ модСль космоса(это сфСра)

        self.sky_tex = loader.loadTexture("./tex/stars_1k_tex.jpg") # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ тСкстуру
        self.sky.setTexture(self.sky_tex, 1) # Π·Π°Ρ€Π΅Π½Π΄Π΅Ρ€ΠΈΠΌ тСкстуру Π½Π° Π½Π΅Π±ΠΎ
        self.sky.reparentTo(render) # ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ Π½Π΅Π±ΠΎ
        self.sky.setScale(40000) # Ρ€Π°ΡΡˆΠΈΡ€ΠΈΠΌ Π½Π΅Π±ΠΎ Π΄ΠΎ максимальной Π²Π΅Π»ΠΈΡ‡ΠΈΠ½Ρ‹ panda3d

        self.environ = loader.loadModel("models/world/falcon.egg") # Π—Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ ΡƒΠΆΠ΅ созданный Π² blender ΠΌΠΈΡ€.
        self.environ.reparentTo(render) # Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ модСль ΠΌΠΈΡ€Π° Π² ΠΎΠΊΠ½ΠΎ

        droidStartPos = (-1, 0, 1.5 ) # Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ ΡΡ‚Π°Ρ€Ρ‚ΠΎΠ²ΡƒΡŽ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π² ΠΌΠΈΡ€Π΅.
        enemyStartPos = (-6, 1, 0.5) # Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ°-Π΄Ρ€ΠΎΠΈΠ΄Π°.
        self.droid = Actor("models/player/seeker.egg") # Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ модСль ΠΈΠ³Ρ€ΠΎΠΊΠ° (созданная Π² blender)
        self.enemy = Actor("models/enemies/r2d2/r2d2.egg") # Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ модСль ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ° (созданная Π² blender)
        self.droid.reparentTo(render) # ΠŸΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Π΅ΠΌ модСль ΠΈΠ³Ρ€ΠΎΠΊΠ° Π² наш ΠΌΠΈΡ€.
        self.enemy.reparentTo(render) # ΠŸΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Π΅ΠΌ модСль ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ° Π² наш ΠΌΠΈΡ€.
        self.droid.setScale(1) # Π”Π΅Π»Π°Π΅ΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ€ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π½Π° 1
        self.enemy.setScale(1) # Π”Π΅Π»Π°Π΅ΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ€ ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ° Π½Π° 1
        self.droid.setPos(droidStartPos) # Π‘Ρ‚Π°Π²ΠΈΠΌ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π½Π° Ρ€Π°Π½Π΅Π΅ ΡΠΎΠ·Π΄Π°Π½ΡƒΡŽ Π½Π°ΠΌΠΈ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ
        self.enemy.setPos(enemyStartPos) # Π‘Ρ‚Π°Π²ΠΈΠΌ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ° Π½Π° Ρ€Π°Π½Π΅Π΅ ΡΠΎΠ·Π΄Π°Π½ΡƒΡŽ Π½Π°ΠΌΠΈ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ

        self.weapon = Actor('models/weapon/lightsaber.egg') # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ ΠΎΡ€ΡƒΠΆΠΈΠ΅
        self.bullet = Actor('models/weapon/bullet/bullet.egg.pz') # Π—Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ ΠΏΡƒΠ»ΡŽ
        self.flash = Actor('models/whishlyflash/handlamp.egg') # Π—Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊ
               
        self.weapon.reparentTo(render) # пСрСмСстим ΠΎΡ€ΡƒΠΆΠΈΠ΅ Π² наш ΠΌΠΈΡ€
        self.bullet.reparentTo(render) # пСрСмСстим ΠΏΡƒΠ»ΡŽ Π² ΠΌΠΈΡ€ Π½ΠΎ появится ΠΎΠ½Π° сама Π½Π΅ скоро
        self.flash.reparentTo(render) # пСрСмСстим Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊ Π² наш ΠΌΠΈΡ€
        self.weapon.setScale(.5) # Π·Π°Π΄Π°Π΄ΠΈΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ€ ΠΏΡƒΡˆΠΊΠΈ
        self.bullet.setScale(.5) # Π·Π°Π΄Π°Π΄ΠΈΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ€ ΠΏΡƒΠ»ΠΈ
        self.flash.setScale(.5) # Π·Π°Π΄Π°Π΄ΠΈΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ€ Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊΠ°

        # враТСский ΠΈΡΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»ΡŒ
        self.fighter = Actor('models/fighter/fighter.egg')
        self.fighter.reparentTo(render)
        self.fighter.setPos(0, 90, 0)
                

        self.weapon_pos = self.droid.getX(), self.droid.getY() + 0.7, 1 # ΠŸΠΎΠ·ΠΈΡ†ΠΈΡ ΠΏΡƒΡˆΠΊΠΈ
        
        self.weapon.setPos(self.weapon_pos) # ΠŸΠΎΠΌΠ΅ΡΡ‚ΠΈΠΌ ΠΎΡ€ΡƒΠΆΠΈΠ΅ Ρ‡ΡƒΡ‚ΡŒ Π²Ρ‹ΡˆΠ΅ ΠΈΠ³Ρ€ΠΎΠΊΠ°
        
        
        self.spotlight = camera.attachNewNode(Spotlight("spotlight")) # ΠšΠΎΠ½Ρ„ΠΈΠ³ΠΈ Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊΠ°
        self.spotlight.node().setColor((.3, .3, .3, 1))
        self.spotlight.node().setSpecularColor((0, 0, 0, 1))

        self.floater = NodePath(PandaNode("floater")) 
        self.floater.reparentTo(self.droid)
        self.floater.setZ(2.0)

        self.accept("escape", sys.exit) # ΠŸΡ€ΠΈ Π½Π°ΠΆΠ°Ρ‚ΠΈΠΈ клавиши Esc Π²Ρ‹Ρ…ΠΎΠ΄ΠΈΠΌ.
        
        self.accept("arrow_left", self.setKey, ["left", True]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ Π²Π»Π΅Π²ΠΎ - ΠΏΠΎΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π²Π»Π΅Π²ΠΎ
        self.accept("arrow_right", self.setKey, ["right", True]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ Π²ΠΏΡ€Π°Π²ΠΎ - ΠΏΠΎΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π²ΠΏΡ€Π°Π²ΠΎ
        self.accept("arrow_up", self.setKey, ["forward", True]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ Π²ΠΏΠ΅Ρ€Ρ‘Π΄ - ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄
        self.accept("a", self.setKey, ["cam-left", True]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ a - Ρ€Π°Π·Π²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΊΠ°ΠΌΠ΅Ρ€Ρƒ Π²ΠΎΠΊΡ€ΡƒΠ³ нашСй модСльки
        self.accept("d", self.setKey, ["cam-right", True]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ s - Ρ€Π°Π·Π²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΊΠ°ΠΌΠ΅Ρ€Ρƒ Π²ΠΎΠΊΡ€ΡƒΠ³ нашСй модСльки
        self.accept("arrow_left-up", self.setKey, ["left", False]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ Π²Π²Π΅Ρ€Ρ…+Π²Π»Π΅Π²ΠΎ - ΠΏΠΎΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π²Π»Π΅Π²ΠΎ ΠΈ ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄
        self.accept("arrow_right-up", self.setKey, ["right", False]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ Π²Π²Π΅Ρ€Ρ…+ΠΏΡ€Π°Π²ΠΎ - ΠΏΠΎΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π²ΠΏΡ€Π°Π²ΠΎ ΠΈ ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄
        self.accept("arrow_up-up", self.setKey, ["forward", False]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ Π²Π²Π΅Ρ€Ρ…+Π²Π²Π΅Ρ€ΡŠ - ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄ ΠΈ ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄
        self.accept("a-up", self.setKey, ["cam-left", False]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ a+Π²ΠΏΠ΅Ρ€Ρ‘Π΄ - ΠΏΠΎΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΊΠ°ΠΌΠ΅Ρ€Ρƒ Π²Π»Π΅Π²ΠΎ ΠΈ ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄
        self.accept("d-up", self.setKey, ["cam-right", False]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ s+Π²ΠΏΠ΅Ρ€Ρ‘Π΄ - ΠΏΠΎΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΊΠ°ΠΌΠ΅Ρ€Ρƒ Π²ΠΏΡ€Π°Π²ΠΎ ΠΈ ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄

        self.accept("space", self.shot) # ΠΏΡ€ΠΈ ΠΏΡ€ΠΎΠ±Π΅Π»Π΅ стрСляСм
        self.accept("s", self.toggleLights, [[self.spotlight]]) # Π’ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊ
        self.accept("w", self.weapon_hide) # ΠΏΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ w - ΡƒΠ±Π΅Ρ€Ρ‘ΠΌ ΠΎΡ€ΡƒΠΆΠΈΠ΅.

        base.enableParticles() # Π’ΠΊΠ»ΡŽΡ‡Π°Π΅ΠΌ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ Π΄Ρ‹ΠΌΠ°
        self.t = loader.loadModel("models/weapon/lightsaber.egg") # Π—Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ Π΅Ρ‰Ρ‘ ΠΎΡ€ΡƒΠΆΠΈΠ΅
        self.t.reparentTo(render) # ΠŸΠ΅Ρ€Π΅ΠΌΠ΅ΡΡ‚ΠΈΠΌ ΠΎΡ€ΡƒΠΆΠΈΠ΅ Π² наш ΠΌΠΈΡ€
        self.p = ParticleEffect() # Π’ΠΊΠ»ΡŽΡ‡ΠΈΠΌ эффСкт Π΄Ρ‹ΠΌΠ°
        self.accept('f', self.particle_start) # ΠΏΡ€ΠΈ Π½Π°ΠΆΠ°Ρ‚ΠΈΠΈ f(ΠΎΡ‚ force) -  Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ Ρ„Π°ΠΉΠ» Π΄Ρ‹ΠΌΠ° ΠΈ пСрСмСстим Π² ΠΊΠΎΠ½Ρ„ΠΈΠ³ Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΈΠΌΠ΅Π½Π½ΠΎ эта анимация стала ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ΠΌ Π΄Ρ‹ΠΌΠ°
        self.accept('0', self.fountain) # ΠΏΡ€ΠΈ  Π½Π°ΠΆΠ°Ρ‚ΠΈΠΈ ΠΊΠ½ΠΎΠΏΠΎΠΊ f+o(fountain) Π²ΠΊΠ»ΡŽΡ‡ΠΈΠΌ ΠΏΠΎΠΆΠ°Ρ€ΠΎΡ‚ΡƒΡˆΠΈΡ‚Π΅Π»ΡŒΠ½ΡƒΡŽ систСму

        taskMgr.add(self.move, "moveTask") # ДобавляСм Π·Π°Π΄Π°Ρ‡Ρƒ Π² наш Π΄Π²ΠΈΠΆΠΎΠΊ

        self.isMoving = False # Π‘Ρ‚Π°Π²ΠΈΠΌ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ isMoving Π½Π° False(Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΌΠ΅Π½ΡΡ‚ΡŒ это Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅) Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΈΠ³Ρ€ΠΎΠΊ ΠΈΠ·Π½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎ стоял.
        # Π”Π΅Π»Π°Π΅ΠΌ Ρ‚Π°ΠΊ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ свСт Π±Ρ‹Π» ΠΈΠ·Π½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎ Π²Ρ‹ΠΊΠ»ΡŽΡ‡Π΅Π½.
        self.disableMouse() # ΠžΡ‚ΠΊΠ»ΡŽΡ‡Π°Π΅ΠΌ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π΅Π½ΠΈΠ΅ Ρ‡Π΅Ρ€Π΅Π· ΠΌΡ‹ΡˆΠΊΡƒ
        self.camera.setPos(self.droid.getX(), self.droid.getY() + 1, 3) # Π‘Ρ‚Π°Π²ΠΈΠΌ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ Ρ‡ΡƒΡ‚ΡŒ большС ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ ΠΈΠ³Ρ€ΠΎΠΊΠ°

        self.black_light() # Π‘Π΄Π΅Π»Π°Π΅ΠΌ Π²Ρ‹ΠΊΠ»ΡŽΡ‡Π΅Π½Π½Ρ‹ΠΉ свСт

        self.state = 100 # БостояниС корабля
        self.state_info = OnscreenText(text='ΠΊΠΎΡ€Π°Π±Π»ΡŒ :' + str(self.state), pos=(0.5, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля
                
        self.check_loss() # ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ ΠΏΠΎΡ€Π°ΠΆΠ΅Π½ΠΈΠ΅
        self.hide_weapon = False # ΠŸΠΎΡΡ‚Π°Π²ΠΈΠΌ, Ρ‡Ρ‚ΠΎ ΠΎΡ€ΡƒΠΆΠΈΠ΅ Π½Π΅ ΡƒΠ±Ρ€Π°Π½ΠΎ
        self.steam_pos = random.randrange(0, 5), random.randrange(0, 5), random.randrange(0, 5)
        self.fountain_pos = random.randrange(0, 5), random.randrange(0, 5), random.randrange(0, 1)

        self.motor_pos1 = 25.238849639892578, 8.962211608886719, 1.5 # позиция ΠΏΠ΅Ρ€Π²ΠΎΠ³ΠΎ ΠΌΠΎΡ‚ΠΎΡ€Π°
        self.motor_pos2 = -20.676218032836914, 10.55816650390625, 1.5 # позиция Π²Ρ‚ΠΎΡ€ΠΎΠ³ΠΎ ΠΌΠΎΡ‚ΠΎΡ€Π°

        self.motor1 = self.loadParticleConfig('special_effects/steam_critic+/fireish.ptf', self.motor_pos1) # ΠΌΠΎΡ‚ΠΎΡ€ 1
        self.motor2 = self.loadParticleConfig('special_effects/steam_critic+/fireish.ptf', self.motor_pos2) # ΠΌΠΎΡ‚ΠΎΡ€ 2

        self.state_info2 = OnscreenText(text='', pos=(-0.8, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля

        self.force = False # ΠŸΠΎΡΡ‚Π°Π²ΠΈΠΌ, Ρ‡Ρ‚ΠΎ Π½Π΅ Ρ€Π°Π·Π³ΠΎΠ½ΡΠ»ΠΈΡΡŒ

        # ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ ΠΊΠΎΠ»Π»ΠΈΠ·ΠΈΠΈ
        
        self.cTrav = CollisionTraverser()
        pusher = CollisionHandlerPusher()
        
        environCenter = self.environ.getBounds().getCenter()
        environRad = self.environ.getBounds().getRadius()
        cNode = CollisionNode("environment")
        cNode.addSolid(CollisionInvSphere(environCenter, environRad))
        environC = self.environ.attachNewNode(cNode)
        
        droidCenter = self.droid.getBounds().getCenter()
        droidRad = self.droid.getBounds().getRadius()
        cNode = CollisionNode("droid")
        cNode.addSolid(CollisionSphere(droidCenter, droidRad))
        droidC = self.droid.attachNewNode(cNode)
        
        pusher.addCollider(droidC, self.droid)
        self.cTrav.addCollider(droidC, pusher)
        
        enemyCenter = self.enemy.getBounds().getCenter()
        enemyRad = self.enemy.getBounds().getRadius()
        cNode = CollisionNode("enemy")
        cNode.addSolid(CollisionSphere(enemyCenter, enemyRad))
        enemyC = self.enemy.attachNewNode(cNode)

        pusher.addCollider(enemyC, self.enemy)
        self.cTrav.addCollider(enemyC, pusher)

        fighterCenter = self.fighter.getBounds().getCenter()
        fighterRad = self.fighter.getBounds().getRadius()
        cNode = CollisionNode("fighter")
        cNode.addSolid(CollisionSphere(fighterCenter, fighterRad))
        fighterC = self.fighter.attachNewNode(cNode)
        
        pusher.addCollider(fighterC, self.fighter)
        self.cTrav.addCollider(fighterC, pusher)

        # солнцС(новая ΠΌΠ΅Ρ…Π°Π½ΠΈΠΊΠ° освСщСния)
        sun = DirectionalLight("sun")
        sun.set_color_temperature(6000)
        sun.color = sun.color * 4
        sun_path = render.attach_new_node(sun)
        sun_path.set_pos(10, -10, -10)
        sun_path.look_at(0, 0, 0)
        sun_path.hprInterval(self.sun_interval, (sun_path.get_h(), sun_path.get_p() - 360, sun_path.get_r()), bakeInStart=True).loop()
        render.set_light(sun_path)

    def loadParticleConfig(self, filename, pos):
        self.p.cleanup()
        self.p = ParticleEffect()
        self.p.loadConfig(Filename(filename))

        self.p.start(self.t)
        self.p.setPos(pos)

    def particle_start(self):
        self.force = True # ΠŸΠΎΡΡ‚Π°Π²ΠΈΠΌ, Ρ‡Ρ‚ΠΎ ΠΌΡ‹ ΡƒΠΆΠ΅ Ρ€Π°Π·Π³ΠΎΠ½ΡΠ»ΠΈΡΡŒ
        # ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Π΅ΠΌ всС ΠΎΠ±ΡŒΠ΅ΠΊΡ‚Ρ‹ Π·Π° ΠΊΠΎΡ€Π°Π±Π»Ρ‘ΠΌ
        self.environ.setY(self.environ.getY() + self.speed) # нСсёмся Π²ΠΏΡ€Π°Π²ΠΎ
        self.droid.setY(self.droid.getY() + self.speed) # сдвигаСм Π΄Ρ€ΠΎΠΈΠ΄Π° Π·Π° ΠΊΠΎΡ€Π°Π±Π»Ρ‘ΠΌ
        self.enemy.setY(self.enemy.getY() + self.speed) # сдфигаСм ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ° Π·Π° ΠΊΠΎΡ€Π°Π±Π»Ρ‘ΠΌ
        self.weapon.setY(self.weapon.getY() + self.speed) # ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Π΅ΠΌ ΠΎΡ€ΡƒΠΆΠΈΠ΅
        self.flash.setY(self.flash.getY() + self.speed) # ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Π΅ΠΌ Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊ

        self.state -= 1 # сдСлаСм мСньшС ΠΎΡ‡ΠΊΠΎΠ²
        self.state_info.hide() # ΡƒΠ΄Π°Π»ΠΈΠΌ тСкстовыС ΠΎΡ‡ΠΊΠΈ

        camvec = self.droid.getPos() - self.camera.getPos()
        camvec.setZ(0)
        camdist = camvec.length()
        camvec.normalize()
        if camdist > 10.0:
            self.camera.setPos(self.camera.getPos() + camvec * (camdist - 10))
            camdist = 10.0
        if camdist < 5.0:
            self.camera.setPos(self.camera.getPos() - camvec * (5 - camdist))
            camdist = 5.0
            
        self.camera.lookAt(self.floater)
        
        if self.state != 10 and self.state > 10:
            self.state_info.hide() # ΡƒΠ±ΠΈΡ€Π°Π΅ΠΌ ΠΏΡ€Π΅Π΄Π΅Π΄ΡƒΡ‰Π΅Π΅ сообщСниС ΠΎ Тизнях корабля
            self.state_info = OnscreenText(text='ΠΊΠΎΡ€Π°Π±Π»ΡŒ :' + str(self.state), pos=(0.5, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля
            self.check_loss() # провСряСм ΠΏΠΎΡ€Π°ΠΆΠ΅Π½ΠΈΠ΅
            self.steam_pos = random.randrange(0, 5), random.randrange(0, 5) + 300, random.randrange(0, 5)
            self.loadParticleConfig('special_effects/steam/steam.ptf', self.steam_pos)
            self.errorSound.play() # ΠΈΠ³Ρ€Π°Π΅ΠΌ Π·Π²ΡƒΠΊ ошибки
            self.state_info2.hide() # ΡƒΠ±ΠΈΡ€Π°Π΅ΠΌ ΠΏΡ€Π΅Π΄Π΅Π΄ΡƒΡ‰Π΅Π΅ сообщСниС
            self.state_info2 = OnscreenText(text='Π΄Π²ΠΈΠ³Π°Ρ‚Π΅Π»ΡŒ нСисправСн', pos=(-0.8, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля
        else:
            self.state_info = OnscreenText(text='ΠΊΠΎΡ€Π°Π±Π»ΡŒ :' + str(self.state), pos=(0.5, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля
            self.check_loss() # провСряСм ΠΏΠΎΡ€Π°ΠΆΠ΅Π½ΠΈΠ΅
            self.steam_pos = random.randrange(0, 5), random.randrange(0, 5) + 300, random.randrange(0, 5)
            self.loadParticleConfig('special_effects/steam_critic/steam.ptf', self.steam_pos)
            self.errorSound.play() # ΠΈΠ³Ρ€Π°Π΅ΠΌ Π·Π²ΡƒΠΊ ошибки
            self.state_info2.hide()  # ΡƒΠ±ΠΈΡ€Π°Π΅ΠΌ ΠΏΡ€Π΅Π΄Π΅Π΄ΡƒΡ‰Π΅Π΅ сообщСниС
            self.state_info2 = OnscreenText(text='критичСскоС состояниС', pos=(-0.8, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля
    
        if self.state < 10:
            self.state_info.hide()
            self.state_info = OnscreenText(text='ΠΊΠΎΡ€Π°Π±Π»ΡŒ :' + str(self.state), pos=(0.5, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля
            self.check_loss() # провСряСм ΠΏΠΎΡ€Π°ΠΆΠ΅Π½ΠΈΠ΅
            self.steam_pos = random.randrange(0, 5), random.randrange(0, 5) + 300, random.randrange(0, 5)            
            self.loadParticleConfig('special_effects/steam_critic+/fireish.ptf', self.steam_pos)
            self.errorSound.play() # ΠΈΠ³Ρ€Π°Π΅ΠΌ Π·Π²ΡƒΠΊ ошибки
            self.state_info2.hide() # ΡƒΠ±ΠΈΡ€Π°Π΅ΠΌ ΠΏΡ€Π΅Π΄Π΅Π΄ΡƒΡ‰Π΅Π΅ сообщСниС
            self.state_info2 = OnscreenText(text='ΠΏΠ°Π΄Π°Π΅ΠΌ!', pos=(-0.8, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля


    def fountain(self):
        self.state_info2.hide() # ΡƒΠ±ΠΈΡ€Π°Π΅ΠΌ тСкст опасности
        if self.force:
            if self.state != 100:
                self.state += 1
                self.state_info.hide()
                self.state_info = OnscreenText(text='ΠΊΠΎΡ€Π°Π±Π»ΡŒ :' + str(self.state), pos=(0.5, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля

            self.fountain_pos = random.randrange(0, 5), random.randrange(0, 5) + 500, random.randrange(0, 1)    
            self.loadParticleConfig('special_effects/fountain/fountain.ptf', self.fountain_pos)

        else :
            if self.state != 100:
                self.state += 1
                self.state_info.hide()
                self.state_info = OnscreenText(text='ΠΊΠΎΡ€Π°Π±Π»ΡŒ :' + str(self.state), pos=(0.5, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля

            self.fountain_pos = random.randrange(0, 5), random.randrange(0, 5), random.randrange(0, 1)    
            self.loadParticleConfig('special_effects/fountain/fountain.ptf', self.fountain_pos)
        
        
    def black_light(self):
        # Π’Ρ‹ΠΊΠ»ΡŽΡ‡Π΅Π½Ρ‹ΠΉ свСт
        ambientLight = AmbientLight("ambientLight")
        ambientLight.setColor((0, 0, 0, 1))
        directionalLight = DirectionalLight("directionalLight")
        directionalLight.setDirection((-5, -5, -5))
        directionalLight.setColor((1, 1, 1, 1))
        directionalLight.setSpecularColor((1, 1, 1, 1))
        render.setLight(render.attachNewNode(ambientLight))
        render.setLight(render.attachNewNode(directionalLight))

    def weapon_hide(self):
        # Π£Π±Ρ€Π°Ρ‚ΡŒ ΠΎΡ€ΡƒΠΆΠΈΠ΅
        self.hide_weapon = True
        self.weapon.hide()

    def toggleLights(self, lights):
        # Π‘ΠΏΠ΅Ρ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠ΅ освСщСниС
        if self.hide_weapon:
            for light in lights:
                if render.hasLight(light):
                    render.clearLight(light)
                else:
                    render.setLight(light)
            
            self.flash.setPos(self.weapon_pos)
        else:
            return


    def shot(self):
        dt = globalClock.getDt() + 0.5 # CΠΊΠΎΡ€ΠΎΡΡ‚ΡŒ двиТСния
        if not self.hide_weapon : # Ссли ΠΎΡ€ΡƒΠΆΠΈΠ΅ ΡƒΠ±Ρ€Π°Π½ΠΎ Ρ‚ΠΎ ΠΌΡ‹ Π½Π΅ ΠΌΠΎΠΆΠ΅ΠΌ ΡΡ‚Ρ€Π΅Π»ΡΡ‚ΡŒ
            self.shotSound.play() # ΠΈΠ³Ρ€Π°Π΅ΠΌ Π·Π²ΡƒΠΊ выстрСла
            self.bullet.setPos(self.weapon_pos) # ΠŸΡƒΠ»Ρ Π±ΡƒΠ΄Π΅Ρ‚ спавнится Π²Π½ΡƒΡ‚Ρ€ΠΈ ΠΏΡƒΡˆΠΊΠΈ
            self.bullet.setY(self.bullet, -11 * dt) # Π‘Π΄Π²ΠΈΠ³Π°Π΅ΠΌ ΠΏΡƒΠ»ΡŽ Π½Π° ΠΎΠ³Ρ€ΠΎΠΌΠ½ΠΎΠΉ скорости Π²ΠΏΠ΅Ρ€Ρ‘Π΄

    def check_loss(self):
        if self.state == 0: # Ссли ΠΆΠΈΠ·Π½Π΅ΠΉ Ρƒ корабля Π½Π΅ ΠΎΡΡ‚Π°Π»ΠΎΡΡŒ
            self.black_light() # Π²ΠΊΠ»ΡŽΡ‡ΠΈΠΌ Ρ‡Ρ‘Ρ€Π½Ρ‹ΠΉ свСт
            self.weapon_hide() # ΡƒΠ±Π΅Ρ€Ρ‘ΠΌ ΠΎΡ€ΡƒΠΆΠΈΠ΅
            self.info = OnscreenText(text='ΠΏΠΎΡ€Π°ΠΆΠ΅Π½ΠΈΠ΅', style=1, font=self.font,
                                     fg=(1,1,1,1),
                            pos=(-1.3, -0.5), align=TextNode.ALeft, scale=0.3) # напишСм ΠΎ ΠΏΠΎΡ€Π°ΠΆΠ΅Π½ΠΈΠΈ
            self.crackSound.play() # ΠΈΠ³Ρ€Π°Π΅ΠΌ Π·Π²ΡƒΠΊ Π²Π·Ρ€Ρ‹Π²Π°


    def setKey(self, key, value):
        self.keyMap[key] = value # Π”Π΅Π»Π°Π΅ΠΌ ΠΌΠ΅Ρ…aΠ½uΠ·ΠΌ наТатия клавиш.

    def move(self, task):

        ''' Π”Π΅Π»Π°Π΅ΠΌ Ρ„ΡƒΡ†Π½ΠΊΡ†ΠΈΡŽ двиТСния ΠΈΠ³Ρ€ΠΎΠΊΠ° '''

        dt = globalClock.getDt() - .005 # CΠΊΠΎΡ€ΠΎΡΡ‚ΡŒ двиТСния

        # ΠŸΠΎΠ²ΠΎΡ€ΠΎΡ‚ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ Π²Π»Π΅Π²ΠΎ ΠΈ Π²ΠΏΡ€Π°Π²ΠΎ

        if self.keyMap["cam-left"]:
            self.camera.setX(self.camera, -20 * dt) # МСняСм ΠΏΠΎΠ»ΠΎΠΆΠ΅Π½ΠΈΠΊΠ° ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ ΠΏΠΎ икс. Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ получаСтся илюзия ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚Π° ΡƒΠ³Π»Π° Π»ΡƒΡ‡Π°. Но Π½Π° самом Π΄Π΅Π»Π΅ ΠΊΠ°ΠΌΠ΅Ρ€Π° просто пСрСмСщаСтся.
        if self.keyMap["cam-right"]:
            self.camera.setX(self.camera, +20 * dt) # Π’ΠΎΠΆΠ΅ самоС, Ρ‡Ρ‚ΠΎ ΠΈ Π½Π°Π²Π΅Ρ€Ρ…Ρƒ.

        startpos = self.droid.getPos() # Π‘Π΄Π΅Π»Π°Π΅ΠΌ ΡƒΠ΄ΠΎΠ±Π½ΡƒΡŽ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ ΠΈΠ³Ρ€ΠΎΠΊΠ°

        if self.keyMap["left"]:
            self.droid.setH(self.droid.getH() + 300 * dt)
            self.enemy.setY(self.enemy, 1 * dt)
        if self.keyMap["right"]:
            self.droid.setH(self.droid.getH() - 300 * dt)
            self.enemy.setY(self.enemy, -1 * dt)
        if self.keyMap["forward"]:
            self.droid.setY(self.droid, -25 * dt)
            self.enemy.setX(self.enemy, 1 * dt)
            # Π‘Π΄Π΅Π»Π°Π΅ΠΌ ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½ΠΎΠ΅ условиС ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ ΡƒΠ±Ρ€Π°Π½ΠΎ ΠΎΡ€ΡƒΠΆΠΈΠ΅ ΠΈΠ»ΠΈ Π½Π΅Ρ‚
            if not self.hide_weapon:
                self.weapon_pos = self.droid.getX(), self.droid.getY() + 0.7, 3
                self.weapon.setPos(self.weapon_pos) # ОбновляСм ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΏΡƒΡˆΠΊΠΈ
            else:
                self.weapon_pos = self.droid.getX(), self.droid.getY() + 0.7, 3
                self.flash.setPos(self.weapon_pos)

        

        camvec = self.droid.getPos() - self.camera.getPos() # Π²Π΅ΠΊΡ‚ΠΎΡ€ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹
        camvec.setZ(0) # 0 высота Π²Π΅ΠΊΡ‚ΠΎΡ€Π°
        camdist = camvec.length() # дистанция ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ ΠΎΡ‚ Π΄Ρ€ΠΎΠΈΠ΄Π°
        camvec.normalize() # Π½ΠΎΡ€ΠΌΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ Π²Π΅ΠΊΡ‚ΠΎΡ€ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹
        if camdist > 10.0: # Ссли дистанция ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ большС 10, Ρ‚ΠΎ смСщаСм ΠΊΠ°ΠΌΠ΅Ρ€Ρƒ Π·Π° Π΄Ρ€ΠΎΠΎΠΈΠ΄ΠΎΠΌ
            self.camera.setPos(self.camera.getPos() + camvec * (camdist - 10))
            camdist = 10.0 # Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ дистанция Π±ΡƒΠ΄Π΅Ρ‚ снова 10
        if camdist < 5.0: # Ссли дистагцтя ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ мСньшС 5, Ρ‚ΠΎ...
            self.camera.setPos(self.camera.getPos() - camvec * (5 - camdist)) # сдвигаСм ΠΊΠ°ΠΌΠ΅Ρ€Ρƒ
            camdist = 5.0 # всё обновляСм
            
        self.camera.lookAt(self.floater) # Π²ΠΎΡ‚ ΠΈ пригодился наш floater


        return task.cont # Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌ Π·Π°Π΄Π°Ρ‡Ρƒ

    def addInstructions(self, pos, msg):
        return OnscreenText(text=msg, style=1, fg=(1,1,1,1), font=self.inst_font, pos=(-1.3, pos), align=TextNode.ALeft, scale = .04, shadow=(0,0,0,1)) # Ѐункция ΠΎ Ρ‚ΠΎΠΌ, ΠΊΠ°ΠΊ ΡƒΠΏΡ€Π°Π²Π»ΡΡ‚ΡŒ

    def addTitle(self, text):
        return OnscreenText(text=text, style=1, fg=(1, 1, 1, 1), scale=0.2,
                            parent=base.a2dBottomRight, align=TextNode.ARight,
                            pos=(-0.1, 0.09), shadow=(0, 0, 0, 1), font=self.font) # Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ тСкстового Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ° с ΡˆΡ€ΠΈΡ„Ρ‚ΠΎΠΌ ΠΈ ΠΏΠΎΠ·ΠΈΡ†ΠΈΠ΅ΠΉ
    

droid = DroidShooter() # Π‘ΠΎΠ·Π΄Π°Π΄ΠΈΠΌ экзСмпляр класса нашСй ΠΈΠ³Ρ€Ρ‹
droid.run() # 3апустим ΠΈΠ³Ρ€Ρƒ


# Ρ€Π°Π·Ρ€ΠΎΠ±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ :
# Π“Π»Π°Π²Π½Ρ‹ΠΉ Π°Π²Ρ‚ΠΎΡ€ : ma3rx
# ΠŸΠΎΠΌΠΎΡ‰Π½ΠΈΠΊ : panda3dmastercoder( присоСдСнился ΠΊ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Ρƒ 31 января, 12:??)

Screenshot :

3.0.2.1 update! Bug fix fight and add collision for bullet.
New code :

#!/usr/bin/env python
# -*- coding: utf_8 -*-

# Π‘ΠΎΠ·Π΄Π°Π½ΠΎ : 22 число, ΡΠ½Π²Π°Ρ€ΡŒ, 2021 Π³ΠΎΠ΄

# Π˜ΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΡƒΠ΅ΠΌ всС Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹Π΅ инструмСнты
from direct.showbase.ShowBase import ShowBase
from panda3d.core import CollisionTraverser, CollisionNode
from panda3d.core import CollisionHandlerPusher, CollisionSphere, CollisionInvSphere
from panda3d.core import Filename, AmbientLight, DirectionalLight
from panda3d.core import PandaNode, NodePath, Camera, TextNode
from direct.particles.Particles import Particles
from direct.particles.ParticleEffect import ParticleEffect
from panda3d.core import PointLight, Spotlight
from panda3d.core import CollideMask
from panda3d.core import loadPrcFileData
from panda3d.core import *
from direct.gui.OnscreenText import OnscreenText
from direct.gui.OnscreenImage import OnscreenImage
from direct.gui.DirectButton import DirectButton
from direct.gui.DirectSlider import DirectSlider
from direct.actor.Actor import Actor
import random
import sys
import time
import os
import math

VERSION = '3.0.2.1'

settings = ['window-title Droid Game ' +  VERSION,
            'fullscreen 0']
            

loadPrcFileData('', settings[0]) # Π‘Π΄Π΅Π»Π°Π΅ΠΌ Π½Π΅ стандартный Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ (Π²ΠΎΠ·ΠΌΡ‘ΠΌ Π΅Π³ΠΎ ΠΈΠ· ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ settings)
loadPrcFileData('', settings[1]) # Π½Π΅ Π±ΡƒΠ΄Π΅ΠΌ Π΄Π΅Π»Π°Ρ‚ΡŒ полноэкранный Ρ€Π΅ΠΆΠΈΠΌ

# Π‘ΠΎΠ·Π΄Π°Π΄ΠΈΠΌ Π³Π»Π°Π²Π½Ρ‹ΠΉ класс нашСй ΠΈΠ³Ρ€Ρ‹
class DroidShooter(ShowBase):
    def __init__(self):
        ShowBase.__init__(self) # Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ всС сСлфы ΠΈΠ· direct
        self.speed = 1800 # ΡΠΊΠΎΡ€ΠΎΡΡ‚ΡŒ двигатСля
        self.menu() # звпуск мСню
        
    def menu(self):
        
        base.enableParticles() # ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ эффСкт Π΄Ρ‹ΠΌΠ°

        self.win.setClearColor((0, 0, 0, 1)) # Π—Π°ΠΊΡ€Π°ΡˆΠΈΠ²Π°Π΅ΠΌ ΠΏΠΎΠ²Π΅Ρ€Ρ…Π½ΠΎΡΡ‚ΡŒ Ρ‡Ρ‘Ρ€Π½Ρ‹ΠΌ. Π”Π΅Π»ΠΎ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ Π² этом ΠΈΠ³Ρ€ΠΎΠ²ΠΎΠΌ Π΄Π²ΠΈΠΆΠΊΠ΅ ΠΏΠΎΠ²Π΅Ρ€Ρ…Π½ΠΎΡΡ‚ΡŒ Π·Π°ΠΊΡ€Π°ΡˆΠΈΠ²Π°Π΅Ρ‚ΡΡ сСрым.
        self.font = loader.loadFont('./fonts/doom_font.ttf') # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ ΡˆΡ€ΠΈΡ„Ρ‚ ΠΈΠ· ΠΈΠ³Ρ€Ρ‹ doom
        self.inst_font = loader.loadFont('./fonts/arial.ttf') # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ ΡˆΡ€ΠΈΡ„Ρ‚ arial

        self.crackSound = loader.loadMusic('./sounds/crack.wav') # Π·Π²ΡƒΠΊ Π²Π·Ρ€Ρ‹Π²Π° корабля
        self.shotSound = loader.loadMusic('./sounds/shot.wav') # Π·Π²ΡƒΠΊ выстрСла
        self.startSound = loader.loadMusic('./sounds/started.wav') # Π·Π²ΡƒΠΊ запуска
        self.errorSound = loader.loadMusic('./sounds/error.wav') # Π·Π²ΡƒΠΊ запуска
        self.errorSound.setVolume(1) # полная Π³Ρ€ΠΎΠΌΠΊΠΎΡΡ‚ΡŒ Π·Π²ΡƒΠΊΠ°
        self.startSound.setVolume(1) # полная Π³Ρ€ΠΎΠΌΠΊΠΎΡΡ‚ΡŒ Π·Π²ΡƒΠΊΠ°
        self.crackSound.setVolume(1) # полная Π³Ρ€ΠΎΠΌΠΊΠΎΡΡ‚ΡŒ Π·Π²ΡƒΠΊΠ°
        self.shotSound.setVolume(1) # полная Π³Ρ€ΠΎΠΌΠΊΠΎΡΡ‚ΡŒ Π·Π²ΡƒΠΊΠ°
        self.startSound.play() # ΠΈΠ³Ρ€Π°Π΅ΠΌ Π·Π²ΡƒΠΊ запуска ΠΈΠ³Ρ€Ρ‹

        self.button_start = DirectButton(pos=(0.7, 0, 0), text="CTAPT",
                                   scale=.3, pad=(.2, .2),
                                   command=self.load_game) # ΠΊΠ½ΠΎΠΏΠΊΠ° запуска ΠΈΠ³Ρ€Ρ‹

        self.slider_sun = DirectSlider(pos=(0.1, 0, .75), scale=0.8, value=0,
                                    command=self.set_sun_interval)


        self.title = self.addTitle("Droid game " + VERSION)
        
        # НапСчатаСм ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅
        self.inst1 = self.addInstructions(0.95, u"[ESC]: Π’Ρ‹Ρ…ΠΎΠ΄")
        self.inst2 = self.addInstructions(0.90, u"[Left Arrow]: ΠŸΠΎΠ²ΠΎΡ€ΠΎΡ‚ Π΄Ρ€ΠΎΠΈΠ΄Π° Π² Π»Π΅Π²ΠΎ")
        self.inst3 = self.addInstructions(0.85, u"[Right Arrow]: ΠŸΠΎΠ²ΠΎΡ€ΠΎΡ‚ Π΄Ρ€ΠΎΠΈΠ΄Π° Π² ΠΏΡ€Π°Π²ΠΎ")
        self.inst4 = self.addInstructions(0.80, u"[Up Arrow]: Π’ΠΏΠ΅Ρ€Π΅Π΄")
        self.inst5 = self.addInstructions(0.75, u"[a]: ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ Π² ΠΏΡ€Π°Π²ΠΎ")
        self.inst6 = self.addInstructions(0.70, u"[d]: ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ Π² Π»Π΅Π²ΠΎ")
        self.inst7 = self.addInstructions(0.65, u"[Left Arrow + Up arrow]: ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚ Π΄Ρ€ΠΎΠΈΠ΄Π° Π² Π»Π΅Π²ΠΎ ΠΈ Π²ΠΏΠ΅Ρ€Ρ‘Π΄")
        self.inst8 = self.addInstructions(0.60, u"[Right Arrow + Up arrow]: ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚ Π΄Ρ€ΠΎΠΈΠ΄Π° Π² ΠΏΡ€Π°Π²ΠΎ ΠΈ Π²ΠΏΠ΅Ρ€Ρ‘Π΄")
        self.inst9 = self.addInstructions(0.55, u"[a + Up arrow]: ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ Π² ΠΏΡ€Π°Π²ΠΎ ΠΈ Π²ΠΏΠ΅Ρ€Ρ‘Π΄")
        self.inst10 = self.addInstructions(0.50, u"[d + Up arrow]: ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ Π² Π»Π΅Π²ΠΎ ΠΈ Π²ΠΏΠ΅Ρ€Ρ‘Π΄")
        self.inst11 = self.addInstructions(0.45, u"[space]: ΡΡ‚Ρ€Π΅Π»ΡŒΠ±Π°")
        self.inst12 = self.addInstructions(0.40, u"[s]: Π΄ΠΎΡΡ‚Π°Ρ‚ΡŒ Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊ")
        self.inst13 = self.addInstructions(0.35, u"[w]: ΡƒΠ±Ρ€Π°Ρ‚ΡŒ ΠΎΡ€ΡƒΠΆΠΈΠ΅")
        self.inst14 = self.addInstructions(0.30, u"[f]: ΠΏΠΎΠ»Π½Ρ‹ΠΉ Ρ€Π°Π·Π³ΠΎΠ½(ОПАБНО!)")
        self.inst15 = self.addInstructions(0.25, u"[0]: ΠΏΠΎΠΆΠ°Ρ€ΠΎΡ‚ΡƒΡˆΠΈΡ‚Π΅Π»ΡŒΠ½Π°Ρ систСма")

        self.accept("escape", sys.exit) # ΠŸΡ€ΠΈ Π½Π°ΠΆΠ°Ρ‚ΠΈΠΈ клавиши Esc Π²Ρ‹Ρ…ΠΎΠ΄ΠΈΠΌ.

    def set_sun_interval(self):
        self.sun_interval = self.slider_sun.guiItem.getValue() * 100 # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ слайдСрноС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΡƒΠΌΠ½ΠΎΠΆΠ΅Π½ΠΎΠ΅ Π½Π° 500, Π΄Π° Ρ‚Ρ€Π°Ρ‡Ρƒ ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΡŽ Π½ΠΎ ΠΌΠ½Π΅ каТСтся ΠΌΠ½ΠΎΠ³ΠΈΠΌ ΠΏΠ»Π΅Π²Π°Ρ‚ΡŒ Π½Π° ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΡŽ мСню, ΠΈΠ±ΠΎ Ρ‚Π°ΠΊΠΎΠ³ΠΎ понятия просто Π½Π΅Ρ‚Ρƒ :)
        

    def load_game(self):
        self.button_start.hide() # ΡƒΠ΄Π°Π»ΠΈΠΌ ΠΊΠ½ΠΎΠΏΠΊΡƒ старта
        self.title.hide() # ΡƒΠ΄Π°Π»ΠΈΠΌ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ ΠΈΠ³Ρ€Ρ‹
        # ΡƒΠ΄Π°Π»ΠΈΠΌ ΠΊΠ½ΠΎΠΏΠΊΠΈ управлСния
        self.inst1.hide()
        self.inst2.hide()
        self.inst3.hide()
        self.inst4.hide()
        self.inst5.hide()
        self.inst6.hide()
        self.inst7.hide()
        self.inst8.hide()
        self.inst9.hide()
        self.inst10.hide()
        self.inst11.hide()
        self.inst12.hide()
        self.inst13.hide()
        self.inst14.hide()
        self.inst15.hide()
        self.slider_sun.hide() # удаляСм слайдСр солнца
        
        self.keyMap = {
            "left": 0, "right": 0, "forward": 0, "cam-left": 0, "cam-right": 0} # Π‘ΠΎΠ·Π΄Π°Π΄ΠΈΠΌ ΡΠ»ΠΎΠ²Π°Ρ€ΡŒ ΠΊΠ½ΠΎΠΏΠΎΠΊ, ΠΏΠΎ ΠΈΡ… Π½Π°ΠΆΠ°Ρ‚ΠΈΡŽ        

        # РисуСм Π·Π²Ρ‘Π·Π΄Ρ‹

        self.sky = loader.loadModel("./models/sky/solar_sky_sphere") # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ модСль космоса(это сфСра)

        self.sky_tex = loader.loadTexture("./tex/stars_1k_tex.jpg") # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ тСкстуру
        self.sky.setTexture(self.sky_tex, 1) # Π·Π°Ρ€Π΅Π½Π΄Π΅Ρ€ΠΈΠΌ тСкстуру Π½Π° Π½Π΅Π±ΠΎ
        self.sky.reparentTo(render) # ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ Π½Π΅Π±ΠΎ
        self.sky.setScale(40000) # Ρ€Π°ΡΡˆΠΈΡ€ΠΈΠΌ Π½Π΅Π±ΠΎ Π΄ΠΎ максимальной Π²Π΅Π»ΠΈΡ‡ΠΈΠ½Ρ‹ panda3d

        self.environ = loader.loadModel("models/world/falcon.egg") # Π—Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ ΡƒΠΆΠ΅ созданный Π² blender ΠΌΠΈΡ€.
        self.environ.reparentTo(render) # Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ модСль ΠΌΠΈΡ€Π° Π² ΠΎΠΊΠ½ΠΎ

        droidStartPos = (-1, 0, 1.5 ) # Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ ΡΡ‚Π°Ρ€Ρ‚ΠΎΠ²ΡƒΡŽ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π² ΠΌΠΈΡ€Π΅.
        enemyStartPos = (-6, 1, 0.5) # Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ°-Π΄Ρ€ΠΎΠΈΠ΄Π°.
        self.droid = Actor("models/player/seeker.egg") # Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ модСль ΠΈΠ³Ρ€ΠΎΠΊΠ° (созданная Π² blender)
        self.enemy = Actor("models/enemies/r2d2/r2d2.egg") # Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ модСль ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ° (созданная Π² blender)
        self.droid.reparentTo(render) # ΠŸΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Π΅ΠΌ модСль ΠΈΠ³Ρ€ΠΎΠΊΠ° Π² наш ΠΌΠΈΡ€.
        self.enemy.reparentTo(render) # ΠŸΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Π΅ΠΌ модСль ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ° Π² наш ΠΌΠΈΡ€.
        self.droid.setScale(1) # Π”Π΅Π»Π°Π΅ΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ€ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π½Π° 1
        self.enemy.setScale(1) # Π”Π΅Π»Π°Π΅ΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ€ ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ° Π½Π° 1
        self.droid.setPos(droidStartPos) # Π‘Ρ‚Π°Π²ΠΈΠΌ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π½Π° Ρ€Π°Π½Π΅Π΅ ΡΠΎΠ·Π΄Π°Π½ΡƒΡŽ Π½Π°ΠΌΠΈ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ
        self.enemy.setPos(enemyStartPos) # Π‘Ρ‚Π°Π²ΠΈΠΌ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ° Π½Π° Ρ€Π°Π½Π΅Π΅ ΡΠΎΠ·Π΄Π°Π½ΡƒΡŽ Π½Π°ΠΌΠΈ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ

        self.weapon = Actor('models/weapon/lightsaber.egg') # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ ΠΎΡ€ΡƒΠΆΠΈΠ΅
        self.bullet = Actor('models/weapon/bullet/bullet.egg.pz') # Π—Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ ΠΏΡƒΠ»ΡŽ
        self.flash = Actor('models/whishlyflash/handlamp.egg') # Π—Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊ
               
        self.weapon.reparentTo(render) # пСрСмСстим ΠΎΡ€ΡƒΠΆΠΈΠ΅ Π² наш ΠΌΠΈΡ€
        self.bullet.reparentTo(render) # пСрСмСстим ΠΏΡƒΠ»ΡŽ Π² ΠΌΠΈΡ€ Π½ΠΎ появится ΠΎΠ½Π° сама Π½Π΅ скоро
        self.flash.reparentTo(render) # пСрСмСстим Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊ Π² наш ΠΌΠΈΡ€
        self.weapon.setScale(.5) # Π·Π°Π΄Π°Π΄ΠΈΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ€ ΠΏΡƒΡˆΠΊΠΈ
        self.bullet.setScale(.5) # Π·Π°Π΄Π°Π΄ΠΈΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ€ ΠΏΡƒΠ»ΠΈ
        self.flash.setScale(.5) # Π·Π°Π΄Π°Π΄ΠΈΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ€ Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊΠ°

        # враТСский ΠΈΡΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»ΡŒ
        self.fighter = Actor('models/fighter/fighter.egg') # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ ΠΌΠΎΠ΄Π΅Π»ΡŒΠΊΡƒ истрСбитСля
        self.fighter.reparentTo(render) # ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ ΠΈΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»ΡŒ
        self.fighter.setPos(0, 90, 0) # позиция истрСбитСля
                

        self.weapon_pos = self.droid.getX(), self.droid.getY() + 0.7, 1 # ΠŸΠΎΠ·ΠΈΡ†ΠΈΡ ΠΏΡƒΡˆΠΊΠΈ
        
        self.weapon.setPos(self.weapon_pos) # ΠŸΠΎΠΌΠ΅ΡΡ‚ΠΈΠΌ ΠΎΡ€ΡƒΠΆΠΈΠ΅ Ρ‡ΡƒΡ‚ΡŒ Π²Ρ‹ΡˆΠ΅ ΠΈΠ³Ρ€ΠΎΠΊΠ°
        
        
        self.spotlight = camera.attachNewNode(Spotlight("spotlight")) # ΠšΠΎΠ½Ρ„ΠΈΠ³ΠΈ Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊΠ°
        self.spotlight.node().setColor((.3, .3, .3, 1))
        self.spotlight.node().setSpecularColor((0, 0, 0, 1))

        self.floater = NodePath(PandaNode("floater")) 
        self.floater.reparentTo(self.droid)
        self.floater.setZ(2.0)

        self.accept("escape", sys.exit) # ΠŸΡ€ΠΈ Π½Π°ΠΆΠ°Ρ‚ΠΈΠΈ клавиши Esc Π²Ρ‹Ρ…ΠΎΠ΄ΠΈΠΌ.
        
        self.accept("arrow_left", self.setKey, ["left", True]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ Π²Π»Π΅Π²ΠΎ - ΠΏΠΎΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π²Π»Π΅Π²ΠΎ
        self.accept("arrow_right", self.setKey, ["right", True]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ Π²ΠΏΡ€Π°Π²ΠΎ - ΠΏΠΎΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π²ΠΏΡ€Π°Π²ΠΎ
        self.accept("arrow_up", self.setKey, ["forward", True]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ Π²ΠΏΠ΅Ρ€Ρ‘Π΄ - ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄
        self.accept("a", self.setKey, ["cam-left", True]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ a - Ρ€Π°Π·Π²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΊΠ°ΠΌΠ΅Ρ€Ρƒ Π²ΠΎΠΊΡ€ΡƒΠ³ нашСй модСльки
        self.accept("d", self.setKey, ["cam-right", True]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ s - Ρ€Π°Π·Π²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΊΠ°ΠΌΠ΅Ρ€Ρƒ Π²ΠΎΠΊΡ€ΡƒΠ³ нашСй модСльки
        self.accept("arrow_left-up", self.setKey, ["left", False]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ Π²Π²Π΅Ρ€Ρ…+Π²Π»Π΅Π²ΠΎ - ΠΏΠΎΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π²Π»Π΅Π²ΠΎ ΠΈ ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄
        self.accept("arrow_right-up", self.setKey, ["right", False]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ Π²Π²Π΅Ρ€Ρ…+ΠΏΡ€Π°Π²ΠΎ - ΠΏΠΎΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π²ΠΏΡ€Π°Π²ΠΎ ΠΈ ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄
        self.accept("arrow_up-up", self.setKey, ["forward", False]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ Π²Π²Π΅Ρ€Ρ…+Π²Π²Π΅Ρ€ΡŠ - ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄ ΠΈ ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄
        self.accept("a-up", self.setKey, ["cam-left", False]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ a+Π²ΠΏΠ΅Ρ€Ρ‘Π΄ - ΠΏΠΎΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΊΠ°ΠΌΠ΅Ρ€Ρƒ Π²Π»Π΅Π²ΠΎ ΠΈ ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄
        self.accept("d-up", self.setKey, ["cam-right", False]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ s+Π²ΠΏΠ΅Ρ€Ρ‘Π΄ - ΠΏΠΎΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΊΠ°ΠΌΠ΅Ρ€Ρƒ Π²ΠΏΡ€Π°Π²ΠΎ ΠΈ ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄

        self.accept("space", self.shot) # ΠΏΡ€ΠΈ ΠΏΡ€ΠΎΠ±Π΅Π»Π΅ стрСляСм
        self.accept("s", self.toggleLights, [[self.spotlight]]) # Π’ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊ
        self.accept("w", self.weapon_hide) # ΠΏΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ w - ΡƒΠ±Π΅Ρ€Ρ‘ΠΌ ΠΎΡ€ΡƒΠΆΠΈΠ΅.

        base.enableParticles() # Π’ΠΊΠ»ΡŽΡ‡Π°Π΅ΠΌ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ Π΄Ρ‹ΠΌΠ°
        self.t = loader.loadModel("models/weapon/lightsaber.egg") # Π—Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ Π΅Ρ‰Ρ‘ ΠΎΡ€ΡƒΠΆΠΈΠ΅
        self.t.reparentTo(render) # ΠŸΠ΅Ρ€Π΅ΠΌΠ΅ΡΡ‚ΠΈΠΌ ΠΎΡ€ΡƒΠΆΠΈΠ΅ Π² наш ΠΌΠΈΡ€
        self.p = ParticleEffect() # Π’ΠΊΠ»ΡŽΡ‡ΠΈΠΌ эффСкт Π΄Ρ‹ΠΌΠ°
        self.accept('f', self.particle_start) # ΠΏΡ€ΠΈ Π½Π°ΠΆΠ°Ρ‚ΠΈΠΈ f(ΠΎΡ‚ force) -  Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ Ρ„Π°ΠΉΠ» Π΄Ρ‹ΠΌΠ° ΠΈ пСрСмСстим Π² ΠΊΠΎΠ½Ρ„ΠΈΠ³ Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΈΠΌΠ΅Π½Π½ΠΎ эта анимация стала ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ΠΌ Π΄Ρ‹ΠΌΠ°
        self.accept('0', self.fountain) # ΠΏΡ€ΠΈ  Π½Π°ΠΆΠ°Ρ‚ΠΈΠΈ ΠΊΠ½ΠΎΠΏΠΎΠΊ f+o(fountain) Π²ΠΊΠ»ΡŽΡ‡ΠΈΠΌ ΠΏΠΎΠΆΠ°Ρ€ΠΎΡ‚ΡƒΡˆΠΈΡ‚Π΅Π»ΡŒΠ½ΡƒΡŽ систСму

        taskMgr.add(self.move, "moveTask") # ДобавляСм Π·Π°Π΄Π°Ρ‡Ρƒ Π² наш Π΄Π²ΠΈΠΆΠΎΠΊ

        self.isMoving = False # Π‘Ρ‚Π°Π²ΠΈΠΌ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ isMoving Π½Π° False(Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΌΠ΅Π½ΡΡ‚ΡŒ это Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅) Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΈΠ³Ρ€ΠΎΠΊ ΠΈΠ·Π½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎ стоял.
        # Π”Π΅Π»Π°Π΅ΠΌ Ρ‚Π°ΠΊ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ свСт Π±Ρ‹Π» ΠΈΠ·Π½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎ Π²Ρ‹ΠΊΠ»ΡŽΡ‡Π΅Π½.
        self.disableMouse() # ΠžΡ‚ΠΊΠ»ΡŽΡ‡Π°Π΅ΠΌ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π΅Π½ΠΈΠ΅ Ρ‡Π΅Ρ€Π΅Π· ΠΌΡ‹ΡˆΠΊΡƒ
        self.camera.setPos(self.droid.getX(), self.droid.getY() + 1, 3) # Π‘Ρ‚Π°Π²ΠΈΠΌ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ Ρ‡ΡƒΡ‚ΡŒ большС ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ ΠΈΠ³Ρ€ΠΎΠΊΠ°

        self.black_light() # Π‘Π΄Π΅Π»Π°Π΅ΠΌ Π²Ρ‹ΠΊΠ»ΡŽΡ‡Π΅Π½Π½Ρ‹ΠΉ свСт

        self.state = 100 # БостояниС корабля
        self.state_info = OnscreenText(text='ΠΊΠΎΡ€Π°Π±Π»ΡŒ :' + str(self.state), pos=(0.5, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля
                
        self.check_loss() # ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ ΠΏΠΎΡ€Π°ΠΆΠ΅Π½ΠΈΠ΅
        self.hide_weapon = False # ΠŸΠΎΡΡ‚Π°Π²ΠΈΠΌ, Ρ‡Ρ‚ΠΎ ΠΎΡ€ΡƒΠΆΠΈΠ΅ Π½Π΅ ΡƒΠ±Ρ€Π°Π½ΠΎ
        self.steam_pos = random.randrange(0, 5), random.randrange(0, 5), random.randrange(0, 5)
        self.fountain_pos = random.randrange(0, 5), random.randrange(0, 5), random.randrange(0, 1)

        self.motor_pos1 = 25.238849639892578, 8.962211608886719, 1.5 # позиция ΠΏΠ΅Ρ€Π²ΠΎΠ³ΠΎ ΠΌΠΎΡ‚ΠΎΡ€Π°
        self.motor_pos2 = -20.676218032836914, 10.55816650390625, 1.5 # позиция Π²Ρ‚ΠΎΡ€ΠΎΠ³ΠΎ ΠΌΠΎΡ‚ΠΎΡ€Π°

        self.motor1 = self.loadParticleConfig('special_effects/steam_critic+/fireish.ptf', self.motor_pos1) # ΠΌΠΎΡ‚ΠΎΡ€ 1
        self.motor2 = self.loadParticleConfig('special_effects/steam_critic+/fireish.ptf', self.motor_pos2) # ΠΌΠΎΡ‚ΠΎΡ€ 2

        self.state_info2 = OnscreenText(text='', pos=(-0.8, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля

        self.force = False # ΠŸΠΎΡΡ‚Π°Π²ΠΈΠΌ, Ρ‡Ρ‚ΠΎ Π½Π΅ Ρ€Π°Π·Π³ΠΎΠ½ΡΠ»ΠΈΡΡŒ

        # ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ ΠΊΠΎΠ»Π»ΠΈΠ·ΠΈΠΈ
        
        self.cTrav = CollisionTraverser()
        pusher = CollisionHandlerPusher()
        
        environCenter = self.environ.getBounds().getCenter()
        environRad = self.environ.getBounds().getRadius()
        cNode = CollisionNode("environment")
        cNode.addSolid(CollisionInvSphere(environCenter, environRad))
        environC = self.environ.attachNewNode(cNode)
        
        droidCenter = self.droid.getBounds().getCenter()
        droidRad = self.droid.getBounds().getRadius()
        cNode = CollisionNode("droid")
        cNode.addSolid(CollisionSphere(droidCenter, droidRad))
        droidC = self.droid.attachNewNode(cNode)
        
        pusher.addCollider(droidC, self.droid)
        self.cTrav.addCollider(droidC, pusher)
        
        enemyCenter = self.enemy.getBounds().getCenter()
        enemyRad = self.enemy.getBounds().getRadius()
        cNode = CollisionNode("enemy")
        cNode.addSolid(CollisionSphere(enemyCenter, enemyRad))
        enemyC = self.enemy.attachNewNode(cNode)

        pusher.addCollider(enemyC, self.enemy)
        self.cTrav.addCollider(enemyC, pusher)

        fighterCenter = self.fighter.getBounds().getCenter()
        fighterRad = self.fighter.getBounds().getRadius()
        cNode = CollisionNode("fighter")
        cNode.addSolid(CollisionSphere(fighterCenter, fighterRad))
        fighterC = self.fighter.attachNewNode(cNode)

        bulletCenter = self.bullet.getBounds().getCenter()
        bulletRad = self.bullet.getBounds().getRadius()
        cNode = CollisionNode("bullet")
        cNode.addSolid(CollisionSphere(bulletCenter, bulletRad))
        bulletC = self.bullet.attachNewNode(cNode)
        
        pusher.addCollider(bulletC, self.bullet)
        self.cTrav.addCollider(bulletC, pusher)

        # солнцС(новая ΠΌΠ΅Ρ…Π°Π½ΠΈΠΊΠ° освСщСния)
        sun = DirectionalLight("sun")
        sun.set_color_temperature(6000)
        sun.color = sun.color * 4
        sun_path = render.attach_new_node(sun)
        sun_path.set_pos(10, -10, -10)
        sun_path.look_at(0, 0, 0)
        sun_path.hprInterval(self.sun_interval, (sun_path.get_h(), sun_path.get_p() - 360, sun_path.get_r()), bakeInStart=True).loop()
        render.set_light(sun_path)

    def loadParticleConfig(self, filename, pos):
        self.p.cleanup()
        self.p = ParticleEffect()
        self.p.loadConfig(Filename(filename))

        self.p.start(self.t)
        self.p.setPos(pos)

    def particle_start(self):
        self.force = True # ΠŸΠΎΡΡ‚Π°Π²ΠΈΠΌ, Ρ‡Ρ‚ΠΎ ΠΌΡ‹ ΡƒΠΆΠ΅ Ρ€Π°Π·Π³ΠΎΠ½ΡΠ»ΠΈΡΡŒ
        # ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Π΅ΠΌ всС ΠΎΠ±ΡŒΠ΅ΠΊΡ‚Ρ‹ Π·Π° ΠΊΠΎΡ€Π°Π±Π»Ρ‘ΠΌ
        self.environ.setY(self.environ.getY() - self.speed) # нСсёмся Π²ΠΏΡ€Π°Π²ΠΎ
        self.droid.setY(self.droid.getY() - self.speed) # сдвигаСм Π΄Ρ€ΠΎΠΈΠ΄Π° Π·Π° ΠΊΠΎΡ€Π°Π±Π»Ρ‘ΠΌ
        self.enemy.setY(self.enemy.getY() - self.speed) # сдфигаСм ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ° Π·Π° ΠΊΠΎΡ€Π°Π±Π»Ρ‘ΠΌ
        self.weapon.setY(self.weapon.getY() - self.speed) # ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Π΅ΠΌ ΠΎΡ€ΡƒΠΆΠΈΠ΅
        self.flash.setY(self.flash.getY() - self.speed) # ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Π΅ΠΌ Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊ
        self.fighter.setY(self.fighter.getY() - self.speed) # ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Π΅ΠΌ ΠΈΡΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»ΡŒ

        self.state -= 1 # сдСлаСм мСньшС ΠΎΡ‡ΠΊΠΎΠ²
        self.state_info.hide() # ΡƒΠ΄Π°Π»ΠΈΠΌ тСкстовыС ΠΎΡ‡ΠΊΠΈ

        camvec = self.droid.getPos() - self.camera.getPos()
        camvec.setZ(0)
        camdist = camvec.length()
        camvec.normalize()
        if camdist > 10.0:
            self.camera.setPos(self.camera.getPos() + camvec * (camdist - 10))
            camdist = 10.0
        if camdist < 5.0:
            self.camera.setPos(self.camera.getPos() - camvec * (5 - camdist))
            camdist = 5.0
            
        self.camera.lookAt(self.floater)
        
        if self.state != 10 and self.state > 10:
            self.state_info.hide() # ΡƒΠ±ΠΈΡ€Π°Π΅ΠΌ ΠΏΡ€Π΅Π΄Π΅Π΄ΡƒΡ‰Π΅Π΅ сообщСниС ΠΎ Тизнях корабля
            self.state_info = OnscreenText(text='ΠΊΠΎΡ€Π°Π±Π»ΡŒ :' + str(self.state), pos=(0.5, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля
            self.check_loss() # провСряСм ΠΏΠΎΡ€Π°ΠΆΠ΅Π½ΠΈΠ΅
            self.steam_pos = random.randrange(0, 5), random.randrange(0, 5) + 300, random.randrange(0, 5)
            self.loadParticleConfig('special_effects/steam/steam.ptf', self.steam_pos)
            self.errorSound.play() # ΠΈΠ³Ρ€Π°Π΅ΠΌ Π·Π²ΡƒΠΊ ошибки
            self.state_info2.hide() # ΡƒΠ±ΠΈΡ€Π°Π΅ΠΌ ΠΏΡ€Π΅Π΄Π΅Π΄ΡƒΡ‰Π΅Π΅ сообщСниС
            self.state_info2 = OnscreenText(text='Π΄Π²ΠΈΠ³Π°Ρ‚Π΅Π»ΡŒ нСисправСн', pos=(-0.8, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля
        else:
            self.state_info = OnscreenText(text='ΠΊΠΎΡ€Π°Π±Π»ΡŒ :' + str(self.state), pos=(0.5, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля
            self.check_loss() # провСряСм ΠΏΠΎΡ€Π°ΠΆΠ΅Π½ΠΈΠ΅
            self.steam_pos = random.randrange(0, 5), random.randrange(0, 5) + 300, random.randrange(0, 5)
            self.loadParticleConfig('special_effects/steam_critic/steam.ptf', self.steam_pos)
            self.errorSound.play() # ΠΈΠ³Ρ€Π°Π΅ΠΌ Π·Π²ΡƒΠΊ ошибки
            self.state_info2.hide()  # ΡƒΠ±ΠΈΡ€Π°Π΅ΠΌ ΠΏΡ€Π΅Π΄Π΅Π΄ΡƒΡ‰Π΅Π΅ сообщСниС
            self.state_info2 = OnscreenText(text='критичСскоС состояниС', pos=(-0.8, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля
    
        if self.state < 10:
            self.state_info.hide()
            self.state_info = OnscreenText(text='ΠΊΠΎΡ€Π°Π±Π»ΡŒ :' + str(self.state), pos=(0.5, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля
            self.check_loss() # провСряСм ΠΏΠΎΡ€Π°ΠΆΠ΅Π½ΠΈΠ΅
            self.steam_pos = random.randrange(0, 5), random.randrange(0, 5) + 300, random.randrange(0, 5)            
            self.loadParticleConfig('special_effects/steam_critic+/fireish.ptf', self.steam_pos)
            self.errorSound.play() # ΠΈΠ³Ρ€Π°Π΅ΠΌ Π·Π²ΡƒΠΊ ошибки
            self.state_info2.hide() # ΡƒΠ±ΠΈΡ€Π°Π΅ΠΌ ΠΏΡ€Π΅Π΄Π΅Π΄ΡƒΡ‰Π΅Π΅ сообщСниС
            self.state_info2 = OnscreenText(text='ΠΏΠ°Π΄Π°Π΅ΠΌ!', pos=(-0.8, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля


    def fountain(self):
        self.state_info2.hide() # ΡƒΠ±ΠΈΡ€Π°Π΅ΠΌ тСкст опасности
        if self.force:
            if self.state != 100:
                self.state += 1
                self.state_info.hide()
                self.state_info = OnscreenText(text='ΠΊΠΎΡ€Π°Π±Π»ΡŒ :' + str(self.state), pos=(0.5, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля

            self.fountain_pos = random.randrange(0, 5), random.randrange(0, 5) + 500, random.randrange(0, 1)    
            self.loadParticleConfig('special_effects/fountain/fountain.ptf', self.fountain_pos)

        else :
            if self.state != 100:
                self.state += 1
                self.state_info.hide()
                self.state_info = OnscreenText(text='ΠΊΠΎΡ€Π°Π±Π»ΡŒ :' + str(self.state), pos=(0.5, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля

            self.fountain_pos = random.randrange(0, 5), random.randrange(0, 5), random.randrange(0, 1)    
            self.loadParticleConfig('special_effects/fountain/fountain.ptf', self.fountain_pos)
        
        
    def black_light(self):
        # Π’Ρ‹ΠΊΠ»ΡŽΡ‡Π΅Π½Ρ‹ΠΉ свСт
        ambientLight = AmbientLight("ambientLight")
        ambientLight.setColor((0, 0, 0, 1))
        directionalLight = DirectionalLight("directionalLight")
        directionalLight.setDirection((-5, -5, -5))
        directionalLight.setColor((1, 1, 1, 1))
        directionalLight.setSpecularColor((1, 1, 1, 1))
        render.setLight(render.attachNewNode(ambientLight))
        render.setLight(render.attachNewNode(directionalLight))

    def weapon_hide(self):
        # Π£Π±Ρ€Π°Ρ‚ΡŒ ΠΎΡ€ΡƒΠΆΠΈΠ΅
        self.hide_weapon = True
        self.weapon.hide()

    def toggleLights(self, lights):
        # Π‘ΠΏΠ΅Ρ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠ΅ освСщСниС
        if self.hide_weapon:
            for light in lights:
                if render.hasLight(light):
                    render.clearLight(light)
                else:
                    render.setLight(light)
            
            self.flash.setPos(self.weapon_pos)
        else:
            return


    def shot(self):
        dt = globalClock.getDt() + 0.5 # CΠΊΠΎΡ€ΠΎΡΡ‚ΡŒ двиТСния
        if not self.hide_weapon : # Ссли ΠΎΡ€ΡƒΠΆΠΈΠ΅ ΡƒΠ±Ρ€Π°Π½ΠΎ Ρ‚ΠΎ ΠΌΡ‹ Π½Π΅ ΠΌΠΎΠΆΠ΅ΠΌ ΡΡ‚Ρ€Π΅Π»ΡΡ‚ΡŒ
            self.shotSound.play() # ΠΈΠ³Ρ€Π°Π΅ΠΌ Π·Π²ΡƒΠΊ выстрСла
            self.bullet.setPos(self.weapon_pos) # ΠŸΡƒΠ»Ρ Π±ΡƒΠ΄Π΅Ρ‚ спавнится Π²Π½ΡƒΡ‚Ρ€ΠΈ ΠΏΡƒΡˆΠΊΠΈ
            self.bullet.setY(self.bullet, -11 * dt) # Π‘Π΄Π²ΠΈΠ³Π°Π΅ΠΌ ΠΏΡƒΠ»ΡŽ Π½Π° ΠΎΠ³Ρ€ΠΎΠΌΠ½ΠΎΠΉ скорости Π²ΠΏΠ΅Ρ€Ρ‘Π΄

    def check_loss(self):
        if self.state == 0: # Ссли ΠΆΠΈΠ·Π½Π΅ΠΉ Ρƒ корабля Π½Π΅ ΠΎΡΡ‚Π°Π»ΠΎΡΡŒ
            self.black_light() # Π²ΠΊΠ»ΡŽΡ‡ΠΈΠΌ Ρ‡Ρ‘Ρ€Π½Ρ‹ΠΉ свСт
            self.weapon_hide() # ΡƒΠ±Π΅Ρ€Ρ‘ΠΌ ΠΎΡ€ΡƒΠΆΠΈΠ΅
            self.info = OnscreenText(text='ΠΏΠΎΡ€Π°ΠΆΠ΅Π½ΠΈΠ΅', style=1, font=self.font,
                                     fg=(1,1,1,1),
                            pos=(-1.3, -0.5), align=TextNode.ALeft, scale=0.3) # напишСм ΠΎ ΠΏΠΎΡ€Π°ΠΆΠ΅Π½ΠΈΠΈ
            self.crackSound.play() # ΠΈΠ³Ρ€Π°Π΅ΠΌ Π·Π²ΡƒΠΊ Π²Π·Ρ€Ρ‹Π²Π°


    def setKey(self, key, value):
        self.keyMap[key] = value # Π”Π΅Π»Π°Π΅ΠΌ ΠΌΠ΅Ρ…aΠ½uΠ·ΠΌ наТатия клавиш.

    def move(self, task):

        ''' Π”Π΅Π»Π°Π΅ΠΌ Ρ„ΡƒΡ†Π½ΠΊΡ†ΠΈΡŽ двиТСния ΠΈΠ³Ρ€ΠΎΠΊΠ° '''

        dt = globalClock.getDt() - .005 # CΠΊΠΎΡ€ΠΎΡΡ‚ΡŒ двиТСния

        # ΠŸΠΎΠ²ΠΎΡ€ΠΎΡ‚ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ Π²Π»Π΅Π²ΠΎ ΠΈ Π²ΠΏΡ€Π°Π²ΠΎ

        if self.keyMap["cam-left"]:
            self.camera.setX(self.camera, -20 * dt) # МСняСм ΠΏΠΎΠ»ΠΎΠΆΠ΅Π½ΠΈΠΊΠ° ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ ΠΏΠΎ икс. Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ получаСтся илюзия ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚Π° ΡƒΠ³Π»Π° Π»ΡƒΡ‡Π°. Но Π½Π° самом Π΄Π΅Π»Π΅ ΠΊΠ°ΠΌΠ΅Ρ€Π° просто пСрСмСщаСтся.
        if self.keyMap["cam-right"]:
            self.camera.setX(self.camera, +20 * dt) # Π’ΠΎΠΆΠ΅ самоС, Ρ‡Ρ‚ΠΎ ΠΈ Π½Π°Π²Π΅Ρ€Ρ…Ρƒ.

        startpos = self.droid.getPos() # Π‘Π΄Π΅Π»Π°Π΅ΠΌ ΡƒΠ΄ΠΎΠ±Π½ΡƒΡŽ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ ΠΈΠ³Ρ€ΠΎΠΊΠ°

        if self.keyMap["left"]:
            self.droid.setH(self.droid.getH() + 300 * dt)
            self.enemy.setY(self.enemy, 1 * dt)
        if self.keyMap["right"]:
            self.droid.setH(self.droid.getH() - 300 * dt)
            self.enemy.setY(self.enemy, -1 * dt)
        if self.keyMap["forward"]:
            self.droid.setY(self.droid, -25 * dt)
            self.enemy.setX(self.enemy, 1 * dt)
            # Π‘Π΄Π΅Π»Π°Π΅ΠΌ ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½ΠΎΠ΅ условиС ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ ΡƒΠ±Ρ€Π°Π½ΠΎ ΠΎΡ€ΡƒΠΆΠΈΠ΅ ΠΈΠ»ΠΈ Π½Π΅Ρ‚
            if not self.hide_weapon:
                self.weapon_pos = self.droid.getX(), self.droid.getY() + 0.7, 3
                self.weapon.setPos(self.weapon_pos) # ОбновляСм ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΏΡƒΡˆΠΊΠΈ
            else:
                self.weapon_pos = self.droid.getX(), self.droid.getY() + 0.7, 3
                self.flash.setPos(self.weapon_pos)

        

        camvec = self.droid.getPos() - self.camera.getPos() # Π²Π΅ΠΊΡ‚ΠΎΡ€ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹
        camvec.setZ(0) # 0 высота Π²Π΅ΠΊΡ‚ΠΎΡ€Π°
        camdist = camvec.length() # дистанция ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ ΠΎΡ‚ Π΄Ρ€ΠΎΠΈΠ΄Π°
        camvec.normalize() # Π½ΠΎΡ€ΠΌΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ Π²Π΅ΠΊΡ‚ΠΎΡ€ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹
        if camdist > 10.0: # Ссли дистанция ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ большС 10, Ρ‚ΠΎ смСщаСм ΠΊΠ°ΠΌΠ΅Ρ€Ρƒ Π·Π° Π΄Ρ€ΠΎΠΎΠΈΠ΄ΠΎΠΌ
            self.camera.setPos(self.camera.getPos() + camvec * (camdist - 10))
            camdist = 10.0 # Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ дистанция Π±ΡƒΠ΄Π΅Ρ‚ снова 10
        if camdist < 5.0: # Ссли дистагцтя ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ мСньшС 5, Ρ‚ΠΎ...
            self.camera.setPos(self.camera.getPos() - camvec * (5 - camdist)) # сдвигаСм ΠΊΠ°ΠΌΠ΅Ρ€Ρƒ
            camdist = 5.0 # всё обновляСм
            
        self.camera.lookAt(self.floater) # Π²ΠΎΡ‚ ΠΈ пригодился наш floater


        return task.cont # Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌ Π·Π°Π΄Π°Ρ‡Ρƒ

    def addInstructions(self, pos, msg):
        return OnscreenText(text=msg, style=1, fg=(1,1,1,1), font=self.inst_font, pos=(-1.3, pos), align=TextNode.ALeft, scale = .04, shadow=(0,0,0,1)) # Ѐункция ΠΎ Ρ‚ΠΎΠΌ, ΠΊΠ°ΠΊ ΡƒΠΏΡ€Π°Π²Π»ΡΡ‚ΡŒ

    def addTitle(self, text):
        return OnscreenText(text=text, style=1, fg=(1, 1, 1, 1), scale=0.2,
                            parent=base.a2dBottomRight, align=TextNode.ARight,
                            pos=(-0.1, 0.09), shadow=(0, 0, 0, 1), font=self.font) # Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ тСкстового Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ° с ΡˆΡ€ΠΈΡ„Ρ‚ΠΎΠΌ ΠΈ ΠΏΠΎΠ·ΠΈΡ†ΠΈΠ΅ΠΉ
    

droid = DroidShooter() # Π‘ΠΎΠ·Π΄Π°Π΄ΠΈΠΌ экзСмпляр класса нашСй ΠΈΠ³Ρ€Ρ‹
droid.run() # 3апустим ΠΈΠ³Ρ€Ρƒ


# Ρ€Π°Π·Ρ€ΠΎΠ±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ :
# Π“Π»Π°Π²Π½Ρ‹ΠΉ Π°Π²Ρ‚ΠΎΡ€ : ma3rx
# ΠŸΠΎΠΌΠΎΡ‰Π½ΠΈΠΊ : panda3dmastercoder( присоСдСнился ΠΊ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Ρƒ 31 января, 12:??)

3.0.3 update! Fighter - new intelect!!

New code :

#!/usr/bin/env python
# -*- coding: utf_8 -*-

# Π‘ΠΎΠ·Π΄Π°Π½ΠΎ : 22 число, ΡΠ½Π²Π°Ρ€ΡŒ, 2021 Π³ΠΎΠ΄

# Π˜ΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΡƒΠ΅ΠΌ всС Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹Π΅ инструмСнты
from direct.showbase.ShowBase import ShowBase
from panda3d.core import CollisionTraverser, CollisionNode
from panda3d.core import CollisionHandlerPusher, CollisionSphere, CollisionInvSphere
from panda3d.core import Filename, AmbientLight, DirectionalLight
from panda3d.core import PandaNode, NodePath, Camera, TextNode
from direct.particles.Particles import Particles
from direct.particles.ParticleEffect import ParticleEffect
from panda3d.core import PointLight, Spotlight
from panda3d.core import CollideMask
from panda3d.core import loadPrcFileData
from panda3d.core import *
from direct.gui.OnscreenText import OnscreenText
from direct.gui.OnscreenImage import OnscreenImage
from direct.gui.DirectButton import DirectButton
from direct.gui.DirectSlider import DirectSlider
from direct.actor.Actor import Actor
import random
import sys
import time
import os
import math

VERSION = '3.0.3'

settings = ['window-title Droid Game ' +  VERSION,
            'fullscreen 0']
            

loadPrcFileData('', settings[0]) # Π‘Π΄Π΅Π»Π°Π΅ΠΌ Π½Π΅ стандартный Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ (Π²ΠΎΠ·ΠΌΡ‘ΠΌ Π΅Π³ΠΎ ΠΈΠ· ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ settings)
loadPrcFileData('', settings[1]) # Π½Π΅ Π±ΡƒΠ΄Π΅ΠΌ Π΄Π΅Π»Π°Ρ‚ΡŒ полноэкранный Ρ€Π΅ΠΆΠΈΠΌ

# Π‘ΠΎΠ·Π΄Π°Π΄ΠΈΠΌ Π³Π»Π°Π²Π½Ρ‹ΠΉ класс нашСй ΠΈΠ³Ρ€Ρ‹
class DroidShooter(ShowBase):
    def __init__(self):
        ShowBase.__init__(self) # Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ всС сСлфы ΠΈΠ· direct
        self.speed = 1800 # ΡΠΊΠΎΡ€ΠΎΡΡ‚ΡŒ двигатСля
        self.menu() # звпуск мСню
        
    def menu(self):
        
        base.enableParticles() # ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ эффСкт Π΄Ρ‹ΠΌΠ°

        self.win.setClearColor((0, 0, 0, 1)) # Π—Π°ΠΊΡ€Π°ΡˆΠΈΠ²Π°Π΅ΠΌ ΠΏΠΎΠ²Π΅Ρ€Ρ…Π½ΠΎΡΡ‚ΡŒ Ρ‡Ρ‘Ρ€Π½Ρ‹ΠΌ. Π”Π΅Π»ΠΎ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ Π² этом ΠΈΠ³Ρ€ΠΎΠ²ΠΎΠΌ Π΄Π²ΠΈΠΆΠΊΠ΅ ΠΏΠΎΠ²Π΅Ρ€Ρ…Π½ΠΎΡΡ‚ΡŒ Π·Π°ΠΊΡ€Π°ΡˆΠΈΠ²Π°Π΅Ρ‚ΡΡ сСрым.
        self.font = loader.loadFont('./fonts/doom_font.ttf') # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ ΡˆΡ€ΠΈΡ„Ρ‚ ΠΈΠ· ΠΈΠ³Ρ€Ρ‹ doom
        self.inst_font = loader.loadFont('./fonts/arial.ttf') # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ ΡˆΡ€ΠΈΡ„Ρ‚ arial

        self.crackSound = loader.loadMusic('./sounds/crack.wav') # Π·Π²ΡƒΠΊ Π²Π·Ρ€Ρ‹Π²Π° корабля
        self.shotSound = loader.loadMusic('./sounds/shot.wav') # Π·Π²ΡƒΠΊ выстрСла
        self.startSound = loader.loadMusic('./sounds/started.wav') # Π·Π²ΡƒΠΊ запуска
        self.errorSound = loader.loadMusic('./sounds/error.wav') # Π·Π²ΡƒΠΊ запуска
        self.errorSound.setVolume(1) # полная Π³Ρ€ΠΎΠΌΠΊΠΎΡΡ‚ΡŒ Π·Π²ΡƒΠΊΠ°
        self.startSound.setVolume(1) # полная Π³Ρ€ΠΎΠΌΠΊΠΎΡΡ‚ΡŒ Π·Π²ΡƒΠΊΠ°
        self.crackSound.setVolume(1) # полная Π³Ρ€ΠΎΠΌΠΊΠΎΡΡ‚ΡŒ Π·Π²ΡƒΠΊΠ°
        self.shotSound.setVolume(1) # полная Π³Ρ€ΠΎΠΌΠΊΠΎΡΡ‚ΡŒ Π·Π²ΡƒΠΊΠ°
        self.startSound.play() # ΠΈΠ³Ρ€Π°Π΅ΠΌ Π·Π²ΡƒΠΊ запуска ΠΈΠ³Ρ€Ρ‹

        self.button_start = DirectButton(pos=(0.7, 0, 0), text="CTAPT",
                                   scale=.3, pad=(.2, .2),
                                   command=self.load_game) # ΠΊΠ½ΠΎΠΏΠΊΠ° запуска ΠΈΠ³Ρ€Ρ‹

        self.slider_sun = DirectSlider(pos=(0.1, 0, .75), scale=0.8, value=0,
                                    command=self.set_sun_interval)


        self.title = self.addTitle("Droid game " + VERSION)
        
        # НапСчатаСм ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅
        self.inst1 = self.addInstructions(0.95, u"[ESC]: Π’Ρ‹Ρ…ΠΎΠ΄")
        self.inst2 = self.addInstructions(0.90, u"[Left Arrow]: ΠŸΠΎΠ²ΠΎΡ€ΠΎΡ‚ Π΄Ρ€ΠΎΠΈΠ΄Π° Π² Π»Π΅Π²ΠΎ")
        self.inst3 = self.addInstructions(0.85, u"[Right Arrow]: ΠŸΠΎΠ²ΠΎΡ€ΠΎΡ‚ Π΄Ρ€ΠΎΠΈΠ΄Π° Π² ΠΏΡ€Π°Π²ΠΎ")
        self.inst4 = self.addInstructions(0.80, u"[Up Arrow]: Π’ΠΏΠ΅Ρ€Π΅Π΄")
        self.inst5 = self.addInstructions(0.75, u"[a]: ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ Π² ΠΏΡ€Π°Π²ΠΎ")
        self.inst6 = self.addInstructions(0.70, u"[d]: ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ Π² Π»Π΅Π²ΠΎ")
        self.inst7 = self.addInstructions(0.65, u"[Left Arrow + Up arrow]: ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚ Π΄Ρ€ΠΎΠΈΠ΄Π° Π² Π»Π΅Π²ΠΎ ΠΈ Π²ΠΏΠ΅Ρ€Ρ‘Π΄")
        self.inst8 = self.addInstructions(0.60, u"[Right Arrow + Up arrow]: ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚ Π΄Ρ€ΠΎΠΈΠ΄Π° Π² ΠΏΡ€Π°Π²ΠΎ ΠΈ Π²ΠΏΠ΅Ρ€Ρ‘Π΄")
        self.inst9 = self.addInstructions(0.55, u"[a + Up arrow]: ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ Π² ΠΏΡ€Π°Π²ΠΎ ΠΈ Π²ΠΏΠ΅Ρ€Ρ‘Π΄")
        self.inst10 = self.addInstructions(0.50, u"[d + Up arrow]: ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ Π² Π»Π΅Π²ΠΎ ΠΈ Π²ΠΏΠ΅Ρ€Ρ‘Π΄")
        self.inst11 = self.addInstructions(0.45, u"[space]: ΡΡ‚Ρ€Π΅Π»ΡŒΠ±Π°")
        self.inst12 = self.addInstructions(0.40, u"[s]: Π΄ΠΎΡΡ‚Π°Ρ‚ΡŒ Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊ")
        self.inst13 = self.addInstructions(0.35, u"[w]: ΡƒΠ±Ρ€Π°Ρ‚ΡŒ ΠΎΡ€ΡƒΠΆΠΈΠ΅")
        self.inst14 = self.addInstructions(0.30, u"[f]: ΠΏΠΎΠ»Π½Ρ‹ΠΉ Ρ€Π°Π·Π³ΠΎΠ½(ОПАБНО!)")
        self.inst15 = self.addInstructions(0.25, u"[0]: ΠΏΠΎΠΆΠ°Ρ€ΠΎΡ‚ΡƒΡˆΠΈΡ‚Π΅Π»ΡŒΠ½Π°Ρ систСма")

        self.accept("escape", sys.exit) # ΠŸΡ€ΠΈ Π½Π°ΠΆΠ°Ρ‚ΠΈΠΈ клавиши Esc Π²Ρ‹Ρ…ΠΎΠ΄ΠΈΠΌ.

    def set_sun_interval(self):
        self.sun_interval = self.slider_sun.guiItem.getValue() * 100 # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ слайдСрноС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΡƒΠΌΠ½ΠΎΠΆΠ΅Π½ΠΎΠ΅ Π½Π° 500, Π΄Π° Ρ‚Ρ€Π°Ρ‡Ρƒ ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΡŽ Π½ΠΎ ΠΌΠ½Π΅ каТСтся ΠΌΠ½ΠΎΠ³ΠΈΠΌ ΠΏΠ»Π΅Π²Π°Ρ‚ΡŒ Π½Π° ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΡŽ мСню, ΠΈΠ±ΠΎ Ρ‚Π°ΠΊΠΎΠ³ΠΎ понятия просто Π½Π΅Ρ‚Ρƒ :)
        

    def load_game(self):
        self.button_start.hide() # ΡƒΠ΄Π°Π»ΠΈΠΌ ΠΊΠ½ΠΎΠΏΠΊΡƒ старта
        self.title.hide() # ΡƒΠ΄Π°Π»ΠΈΠΌ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ ΠΈΠ³Ρ€Ρ‹
        # ΡƒΠ΄Π°Π»ΠΈΠΌ ΠΊΠ½ΠΎΠΏΠΊΠΈ управлСния
        self.inst1.hide()
        self.inst2.hide()
        self.inst3.hide()
        self.inst4.hide()
        self.inst5.hide()
        self.inst6.hide()
        self.inst7.hide()
        self.inst8.hide()
        self.inst9.hide()
        self.inst10.hide()
        self.inst11.hide()
        self.inst12.hide()
        self.inst13.hide()
        self.inst14.hide()
        self.inst15.hide()
        self.slider_sun.hide() # удаляСм слайдСр солнца
        
        self.keyMap = {
            "left": 0, "right": 0, "forward": 0, "cam-left": 0, "cam-right": 0} # Π‘ΠΎΠ·Π΄Π°Π΄ΠΈΠΌ ΡΠ»ΠΎΠ²Π°Ρ€ΡŒ ΠΊΠ½ΠΎΠΏΠΎΠΊ, ΠΏΠΎ ΠΈΡ… Π½Π°ΠΆΠ°Ρ‚ΠΈΡŽ        

        # РисуСм Π·Π²Ρ‘Π·Π΄Ρ‹

        self.sky = loader.loadModel("./models/sky/solar_sky_sphere") # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ модСль космоса(это сфСра)

        self.sky_tex = loader.loadTexture("./tex/stars_1k_tex.jpg") # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ тСкстуру
        self.sky.setTexture(self.sky_tex, 1) # Π·Π°Ρ€Π΅Π½Π΄Π΅Ρ€ΠΈΠΌ тСкстуру Π½Π° Π½Π΅Π±ΠΎ
        self.sky.reparentTo(render) # ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ Π½Π΅Π±ΠΎ
        self.sky.setScale(40000) # Ρ€Π°ΡΡˆΠΈΡ€ΠΈΠΌ Π½Π΅Π±ΠΎ Π΄ΠΎ максимальной Π²Π΅Π»ΠΈΡ‡ΠΈΠ½Ρ‹ panda3d

        self.environ = loader.loadModel("models/world/falcon.egg") # Π—Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ ΡƒΠΆΠ΅ созданный Π² blender ΠΌΠΈΡ€.
        self.environ.reparentTo(render) # Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ модСль ΠΌΠΈΡ€Π° Π² ΠΎΠΊΠ½ΠΎ

        droidStartPos = (-1, 0, 1.5 ) # Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ ΡΡ‚Π°Ρ€Ρ‚ΠΎΠ²ΡƒΡŽ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π² ΠΌΠΈΡ€Π΅.
        enemyStartPos = (-6, 1, 0.5) # Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ°-Π΄Ρ€ΠΎΠΈΠ΄Π°.
        self.droid = Actor("models/player/seeker.egg") # Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ модСль ΠΈΠ³Ρ€ΠΎΠΊΠ° (созданная Π² blender)
        self.enemy = Actor("models/enemies/r2d2/r2d2.egg") # Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ модСль ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ° (созданная Π² blender)
        self.droid.reparentTo(render) # ΠŸΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Π΅ΠΌ модСль ΠΈΠ³Ρ€ΠΎΠΊΠ° Π² наш ΠΌΠΈΡ€.
        self.enemy.reparentTo(render) # ΠŸΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Π΅ΠΌ модСль ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ° Π² наш ΠΌΠΈΡ€.
        self.droid.setScale(1) # Π”Π΅Π»Π°Π΅ΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ€ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π½Π° 1
        self.enemy.setScale(1) # Π”Π΅Π»Π°Π΅ΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ€ ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ° Π½Π° 1
        self.droid.setPos(droidStartPos) # Π‘Ρ‚Π°Π²ΠΈΠΌ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π½Π° Ρ€Π°Π½Π΅Π΅ ΡΠΎΠ·Π΄Π°Π½ΡƒΡŽ Π½Π°ΠΌΠΈ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ
        self.enemy.setPos(enemyStartPos) # Π‘Ρ‚Π°Π²ΠΈΠΌ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ° Π½Π° Ρ€Π°Π½Π΅Π΅ ΡΠΎΠ·Π΄Π°Π½ΡƒΡŽ Π½Π°ΠΌΠΈ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ

        self.weapon = Actor('models/weapon/lightsaber.egg') # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ ΠΎΡ€ΡƒΠΆΠΈΠ΅
        self.bullet = Actor('models/weapon/bullet/bullet.egg.pz') # Π—Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ ΠΏΡƒΠ»ΡŽ
        self.flash = Actor('models/whishlyflash/handlamp.egg') # Π—Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊ
               
        self.weapon.reparentTo(render) # пСрСмСстим ΠΎΡ€ΡƒΠΆΠΈΠ΅ Π² наш ΠΌΠΈΡ€
        self.bullet.reparentTo(render) # пСрСмСстим ΠΏΡƒΠ»ΡŽ Π² ΠΌΠΈΡ€ Π½ΠΎ появится ΠΎΠ½Π° сама Π½Π΅ скоро
        self.flash.reparentTo(render) # пСрСмСстим Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊ Π² наш ΠΌΠΈΡ€
        self.weapon.setScale(.5) # Π·Π°Π΄Π°Π΄ΠΈΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ€ ΠΏΡƒΡˆΠΊΠΈ
        self.bullet.setScale(.5) # Π·Π°Π΄Π°Π΄ΠΈΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ€ ΠΏΡƒΠ»ΠΈ
        self.flash.setScale(.5) # Π·Π°Π΄Π°Π΄ΠΈΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ€ Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊΠ°

        # враТСский ΠΈΡΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»ΡŒ
        self.fighter = Actor('models/fighter/fighter.egg') # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ ΠΌΠΎΠ΄Π΅Π»ΡŒΠΊΡƒ истрСбитСля
        self.fighter.reparentTo(render) # ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ ΠΈΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»ΡŒ
        self.fighter.setPos(0, 90, 0) # позиция истрСбитСля
                

        self.weapon_pos = self.droid.getX(), self.droid.getY() + 0.7, 1 # ΠŸΠΎΠ·ΠΈΡ†ΠΈΡ ΠΏΡƒΡˆΠΊΠΈ
        
        self.weapon.setPos(self.weapon_pos) # ΠŸΠΎΠΌΠ΅ΡΡ‚ΠΈΠΌ ΠΎΡ€ΡƒΠΆΠΈΠ΅ Ρ‡ΡƒΡ‚ΡŒ Π²Ρ‹ΡˆΠ΅ ΠΈΠ³Ρ€ΠΎΠΊΠ°
        
        
        self.spotlight = camera.attachNewNode(Spotlight("spotlight")) # ΠšΠΎΠ½Ρ„ΠΈΠ³ΠΈ Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊΠ°
        self.spotlight.node().setColor((.3, .3, .3, 1))
        self.spotlight.node().setSpecularColor((0, 0, 0, 1))

        self.floater = NodePath(PandaNode("floater")) 
        self.floater.reparentTo(self.droid)
        self.floater.setZ(2.0)

        self.accept("escape", sys.exit) # ΠŸΡ€ΠΈ Π½Π°ΠΆΠ°Ρ‚ΠΈΠΈ клавиши Esc Π²Ρ‹Ρ…ΠΎΠ΄ΠΈΠΌ.
        
        self.accept("arrow_left", self.setKey, ["left", True]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ Π²Π»Π΅Π²ΠΎ - ΠΏΠΎΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π²Π»Π΅Π²ΠΎ
        self.accept("arrow_right", self.setKey, ["right", True]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ Π²ΠΏΡ€Π°Π²ΠΎ - ΠΏΠΎΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π²ΠΏΡ€Π°Π²ΠΎ
        self.accept("arrow_up", self.setKey, ["forward", True]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ Π²ΠΏΠ΅Ρ€Ρ‘Π΄ - ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄
        self.accept("a", self.setKey, ["cam-left", True]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ a - Ρ€Π°Π·Π²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΊΠ°ΠΌΠ΅Ρ€Ρƒ Π²ΠΎΠΊΡ€ΡƒΠ³ нашСй модСльки
        self.accept("d", self.setKey, ["cam-right", True]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ s - Ρ€Π°Π·Π²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΊΠ°ΠΌΠ΅Ρ€Ρƒ Π²ΠΎΠΊΡ€ΡƒΠ³ нашСй модСльки
        self.accept("arrow_left-up", self.setKey, ["left", False]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ Π²Π²Π΅Ρ€Ρ…+Π²Π»Π΅Π²ΠΎ - ΠΏΠΎΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π²Π»Π΅Π²ΠΎ ΠΈ ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄
        self.accept("arrow_right-up", self.setKey, ["right", False]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ Π²Π²Π΅Ρ€Ρ…+ΠΏΡ€Π°Π²ΠΎ - ΠΏΠΎΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π²ΠΏΡ€Π°Π²ΠΎ ΠΈ ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄
        self.accept("arrow_up-up", self.setKey, ["forward", False]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ Π²Π²Π΅Ρ€Ρ…+Π²Π²Π΅Ρ€ΡŠ - ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄ ΠΈ ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄
        self.accept("a-up", self.setKey, ["cam-left", False]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ a+Π²ΠΏΠ΅Ρ€Ρ‘Π΄ - ΠΏΠΎΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΊΠ°ΠΌΠ΅Ρ€Ρƒ Π²Π»Π΅Π²ΠΎ ΠΈ ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄
        self.accept("d-up", self.setKey, ["cam-right", False]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ s+Π²ΠΏΠ΅Ρ€Ρ‘Π΄ - ΠΏΠΎΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΊΠ°ΠΌΠ΅Ρ€Ρƒ Π²ΠΏΡ€Π°Π²ΠΎ ΠΈ ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄

        self.accept("space", self.shot) # ΠΏΡ€ΠΈ ΠΏΡ€ΠΎΠ±Π΅Π»Π΅ стрСляСм
        self.accept("s", self.toggleLights, [[self.spotlight]]) # Π’ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊ
        self.accept("w", self.weapon_hide) # ΠΏΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ w - ΡƒΠ±Π΅Ρ€Ρ‘ΠΌ ΠΎΡ€ΡƒΠΆΠΈΠ΅.

        base.enableParticles() # Π’ΠΊΠ»ΡŽΡ‡Π°Π΅ΠΌ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ Π΄Ρ‹ΠΌΠ°
        self.t = loader.loadModel("models/weapon/lightsaber.egg") # Π—Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ Π΅Ρ‰Ρ‘ ΠΎΡ€ΡƒΠΆΠΈΠ΅
        self.t.reparentTo(render) # ΠŸΠ΅Ρ€Π΅ΠΌΠ΅ΡΡ‚ΠΈΠΌ ΠΎΡ€ΡƒΠΆΠΈΠ΅ Π² наш ΠΌΠΈΡ€
        self.p = ParticleEffect() # Π’ΠΊΠ»ΡŽΡ‡ΠΈΠΌ эффСкт Π΄Ρ‹ΠΌΠ°
        self.accept('f', self.particle_start) # ΠΏΡ€ΠΈ Π½Π°ΠΆΠ°Ρ‚ΠΈΠΈ f(ΠΎΡ‚ force) -  Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ Ρ„Π°ΠΉΠ» Π΄Ρ‹ΠΌΠ° ΠΈ пСрСмСстим Π² ΠΊΠΎΠ½Ρ„ΠΈΠ³ Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΈΠΌΠ΅Π½Π½ΠΎ эта анимация стала ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ΠΌ Π΄Ρ‹ΠΌΠ°
        self.accept('0', self.fountain) # ΠΏΡ€ΠΈ  Π½Π°ΠΆΠ°Ρ‚ΠΈΠΈ ΠΊΠ½ΠΎΠΏΠΎΠΊ f+o(fountain) Π²ΠΊΠ»ΡŽΡ‡ΠΈΠΌ ΠΏΠΎΠΆΠ°Ρ€ΠΎΡ‚ΡƒΡˆΠΈΡ‚Π΅Π»ΡŒΠ½ΡƒΡŽ систСму

        taskMgr.add(self.move, "moveTask") # ДобавляСм Π·Π°Π΄Π°Ρ‡Ρƒ Π² наш Π΄Π²ΠΈΠΆΠΎΠΊ

        self.isMoving = False # Π‘Ρ‚Π°Π²ΠΈΠΌ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ isMoving Π½Π° False(Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΌΠ΅Π½ΡΡ‚ΡŒ это Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅) Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΈΠ³Ρ€ΠΎΠΊ ΠΈΠ·Π½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎ стоял.
        # Π”Π΅Π»Π°Π΅ΠΌ Ρ‚Π°ΠΊ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ свСт Π±Ρ‹Π» ΠΈΠ·Π½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎ Π²Ρ‹ΠΊΠ»ΡŽΡ‡Π΅Π½.
        self.disableMouse() # ΠžΡ‚ΠΊΠ»ΡŽΡ‡Π°Π΅ΠΌ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π΅Π½ΠΈΠ΅ Ρ‡Π΅Ρ€Π΅Π· ΠΌΡ‹ΡˆΠΊΡƒ
        self.camera.setPos(self.droid.getX(), self.droid.getY() + 1, 3) # Π‘Ρ‚Π°Π²ΠΈΠΌ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ Ρ‡ΡƒΡ‚ΡŒ большС ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ ΠΈΠ³Ρ€ΠΎΠΊΠ°

        self.black_light() # Π‘Π΄Π΅Π»Π°Π΅ΠΌ Π²Ρ‹ΠΊΠ»ΡŽΡ‡Π΅Π½Π½Ρ‹ΠΉ свСт

        self.state = 100 # БостояниС корабля
        self.state_info = OnscreenText(text='ΠΊΠΎΡ€Π°Π±Π»ΡŒ :' + str(self.state), pos=(0.5, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля
                
        self.check_loss() # ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ ΠΏΠΎΡ€Π°ΠΆΠ΅Π½ΠΈΠ΅
        self.hide_weapon = False # ΠŸΠΎΡΡ‚Π°Π²ΠΈΠΌ, Ρ‡Ρ‚ΠΎ ΠΎΡ€ΡƒΠΆΠΈΠ΅ Π½Π΅ ΡƒΠ±Ρ€Π°Π½ΠΎ
        self.steam_pos = random.randrange(0, 5), random.randrange(0, 5), random.randrange(0, 5)
        self.fountain_pos = random.randrange(0, 5), random.randrange(0, 5), random.randrange(0, 1)

        self.motor_pos1 = 25.238849639892578, 8.962211608886719, 1.5 # позиция ΠΏΠ΅Ρ€Π²ΠΎΠ³ΠΎ ΠΌΠΎΡ‚ΠΎΡ€Π°
        self.motor_pos2 = -20.676218032836914, 10.55816650390625, 1.5 # позиция Π²Ρ‚ΠΎΡ€ΠΎΠ³ΠΎ ΠΌΠΎΡ‚ΠΎΡ€Π°

        self.motor1 = self.loadParticleConfig('special_effects/steam_critic+/fireish.ptf', self.motor_pos1) # ΠΌΠΎΡ‚ΠΎΡ€ 1
        self.motor2 = self.loadParticleConfig('special_effects/steam_critic+/fireish.ptf', self.motor_pos2) # ΠΌΠΎΡ‚ΠΎΡ€ 2

        self.state_info2 = OnscreenText(text='', pos=(-0.8, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля

        self.force = False # ΠŸΠΎΡΡ‚Π°Π²ΠΈΠΌ, Ρ‡Ρ‚ΠΎ Π½Π΅ Ρ€Π°Π·Π³ΠΎΠ½ΡΠ»ΠΈΡΡŒ

        # ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ ΠΊΠΎΠ»Π»ΠΈΠ·ΠΈΠΈ
        
        self.cTrav = CollisionTraverser()
        pusher = CollisionHandlerPusher()
        
        environCenter = self.environ.getBounds().getCenter()
        environRad = self.environ.getBounds().getRadius()
        cNode = CollisionNode("environment")
        cNode.addSolid(CollisionInvSphere(environCenter, environRad))
        environC = self.environ.attachNewNode(cNode)
        
        droidCenter = self.droid.getBounds().getCenter()
        droidRad = self.droid.getBounds().getRadius()
        cNode = CollisionNode("droid")
        cNode.addSolid(CollisionSphere(droidCenter, droidRad))
        droidC = self.droid.attachNewNode(cNode)
        
        pusher.addCollider(droidC, self.droid)
        self.cTrav.addCollider(droidC, pusher)
        
        enemyCenter = self.enemy.getBounds().getCenter()
        enemyRad = self.enemy.getBounds().getRadius()
        cNode = CollisionNode("enemy")
        cNode.addSolid(CollisionSphere(enemyCenter, enemyRad))
        enemyC = self.enemy.attachNewNode(cNode)

        pusher.addCollider(enemyC, self.enemy)
        self.cTrav.addCollider(enemyC, pusher)

        fighterCenter = self.fighter.getBounds().getCenter()
        fighterRad = self.fighter.getBounds().getRadius()
        cNode = CollisionNode("fighter")
        cNode.addSolid(CollisionSphere(fighterCenter, fighterRad))
        fighterC = self.fighter.attachNewNode(cNode)

        bulletCenter = self.bullet.getBounds().getCenter()
        bulletRad = self.bullet.getBounds().getRadius()
        cNode = CollisionNode("bullet")
        cNode.addSolid(CollisionSphere(bulletCenter, bulletRad))
        bulletC = self.bullet.attachNewNode(cNode)
        
        pusher.addCollider(bulletC, self.bullet)
        self.cTrav.addCollider(bulletC, pusher)

        # солнцС(новая ΠΌΠ΅Ρ…Π°Π½ΠΈΠΊΠ° освСщСния)
        sun = DirectionalLight("sun")
        sun.set_color_temperature(6000)
        sun.color = sun.color * 4
        sun_path = render.attach_new_node(sun)
        sun_path.set_pos(10, -10, -10)
        sun_path.look_at(0, 0, 0)
        sun_path.hprInterval(self.sun_interval, (sun_path.get_h(), sun_path.get_p() - 360, sun_path.get_r()), bakeInStart=True).loop()
        render.set_light(sun_path)

    def fight_force(self):
        # сдвиТСниС истрСбитСля Π·Π° нашим ΠΊΠΎΡ€Π°Π±Π»Ρ‘ΠΌ(ΠΎΡ‡Π΅Π½ΡŒ простым способом я сдСлал Ρ‚Π°ΠΊ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΈΡΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»ΡŒ Π·Π°ΠΆΠΈΠΌΠ°Π» нас(Π»Π΅Ρ‚Π°Π» Π² нашСм ΠΊΠ²Π°Π΄Ρ€Π°Ρ‚Π΅)) ΠΈ Π·Π°ΠΆΠΈΠΌΠ°Π΅Ρ‚ ΠΎΠ½ Ρ€Π΅Π°Π»ΡŒΠ½ΠΎ, сблиТая ΠΊ Π½Π°ΠΌ свой ΠΊΠ²Π°Π΄Ρ€Π°Ρ‚
        self.fighter.setY(self.fighter.getY() - self.speed) 
        self.fighter.setX(self.fighter.getX() - 10)    

        print(self.fighter.getX())


    def loadParticleConfig(self, filename, pos):
        self.p.cleanup()
        self.p = ParticleEffect()
        self.p.loadConfig(Filename(filename))

        self.p.start(self.t)
        self.p.setPos(pos)

    def particle_start(self):
        self.force = True # ΠŸΠΎΡΡ‚Π°Π²ΠΈΠΌ, Ρ‡Ρ‚ΠΎ ΠΌΡ‹ ΡƒΠΆΠ΅ Ρ€Π°Π·Π³ΠΎΠ½ΡΠ»ΠΈΡΡŒ
        # ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Π΅ΠΌ всС ΠΎΠ±ΡŒΠ΅ΠΊΡ‚Ρ‹ Π·Π° ΠΊΠΎΡ€Π°Π±Π»Ρ‘ΠΌ
        self.environ.setY(self.environ.getY() - self.speed) # нСсёмся Π²ΠΏΡ€Π°Π²ΠΎ
        self.droid.setY(self.droid.getY() - self.speed) # сдвигаСм Π΄Ρ€ΠΎΠΈΠ΄Π° Π·Π° ΠΊΠΎΡ€Π°Π±Π»Ρ‘ΠΌ
        self.enemy.setY(self.enemy.getY() - self.speed) # сдфигаСм ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ° Π·Π° ΠΊΠΎΡ€Π°Π±Π»Ρ‘ΠΌ
        self.weapon.setY(self.weapon.getY() - self.speed) # ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Π΅ΠΌ ΠΎΡ€ΡƒΠΆΠΈΠ΅
        self.flash.setY(self.flash.getY() - self.speed) # ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Π΅ΠΌ Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊ
        self.fight_force()

        self.state -= 1 # сдСлаСм мСньшС ΠΎΡ‡ΠΊΠΎΠ²
        self.state_info.hide() # ΡƒΠ΄Π°Π»ΠΈΠΌ тСкстовыС ΠΎΡ‡ΠΊΠΈ

        camvec = self.droid.getPos() - self.camera.getPos()
        camvec.setZ(0)
        camdist = camvec.length()
        camvec.normalize()
        if camdist > 10.0:
            self.camera.setPos(self.camera.getPos() + camvec * (camdist - 10))
            camdist = 10.0
        if camdist < 5.0:
            self.camera.setPos(self.camera.getPos() - camvec * (5 - camdist))
            camdist = 5.0
            
        self.camera.lookAt(self.floater)
        
        if self.state != 10 and self.state > 10:
            self.state_info.hide() # ΡƒΠ±ΠΈΡ€Π°Π΅ΠΌ ΠΏΡ€Π΅Π΄Π΅Π΄ΡƒΡ‰Π΅Π΅ сообщСниС ΠΎ Тизнях корабля
            self.state_info = OnscreenText(text='ΠΊΠΎΡ€Π°Π±Π»ΡŒ :' + str(self.state), pos=(0.5, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля
            self.check_loss() # провСряСм ΠΏΠΎΡ€Π°ΠΆΠ΅Π½ΠΈΠ΅
            self.steam_pos = random.randrange(0, 5), random.randrange(0, 5) + 300, random.randrange(0, 5)
            self.loadParticleConfig('special_effects/steam/steam.ptf', self.steam_pos)
            self.errorSound.play() # ΠΈΠ³Ρ€Π°Π΅ΠΌ Π·Π²ΡƒΠΊ ошибки
            self.state_info2.hide() # ΡƒΠ±ΠΈΡ€Π°Π΅ΠΌ ΠΏΡ€Π΅Π΄Π΅Π΄ΡƒΡ‰Π΅Π΅ сообщСниС
            self.state_info2 = OnscreenText(text='Π΄Π²ΠΈΠ³Π°Ρ‚Π΅Π»ΡŒ нСисправСн', pos=(-0.8, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля
        else:
            self.state_info = OnscreenText(text='ΠΊΠΎΡ€Π°Π±Π»ΡŒ :' + str(self.state), pos=(0.5, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля
            self.check_loss() # провСряСм ΠΏΠΎΡ€Π°ΠΆΠ΅Π½ΠΈΠ΅
            self.steam_pos = random.randrange(0, 5), random.randrange(0, 5) + 300, random.randrange(0, 5)
            self.loadParticleConfig('special_effects/steam_critic/steam.ptf', self.steam_pos)
            self.errorSound.play() # ΠΈΠ³Ρ€Π°Π΅ΠΌ Π·Π²ΡƒΠΊ ошибки
            self.state_info2.hide()  # ΡƒΠ±ΠΈΡ€Π°Π΅ΠΌ ΠΏΡ€Π΅Π΄Π΅Π΄ΡƒΡ‰Π΅Π΅ сообщСниС
            self.state_info2 = OnscreenText(text='критичСскоС состояниС', pos=(-0.8, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля
    
        if self.state < 10:
            self.state_info.hide()
            self.state_info = OnscreenText(text='ΠΊΠΎΡ€Π°Π±Π»ΡŒ :' + str(self.state), pos=(0.5, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля
            self.check_loss() # провСряСм ΠΏΠΎΡ€Π°ΠΆΠ΅Π½ΠΈΠ΅
            self.steam_pos = random.randrange(0, 5), random.randrange(0, 5) + 300, random.randrange(0, 5)            
            self.loadParticleConfig('special_effects/steam_critic+/fireish.ptf', self.steam_pos)
            self.errorSound.play() # ΠΈΠ³Ρ€Π°Π΅ΠΌ Π·Π²ΡƒΠΊ ошибки
            self.state_info2.hide() # ΡƒΠ±ΠΈΡ€Π°Π΅ΠΌ ΠΏΡ€Π΅Π΄Π΅Π΄ΡƒΡ‰Π΅Π΅ сообщСниС
            self.state_info2 = OnscreenText(text='ΠΏΠ°Π΄Π°Π΅ΠΌ!', pos=(-0.8, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля


    def fountain(self):
        self.state_info2.hide() # ΡƒΠ±ΠΈΡ€Π°Π΅ΠΌ тСкст опасности
        if self.force:
            if self.state != 100:
                self.state += 1
                self.state_info.hide()
                self.state_info = OnscreenText(text='ΠΊΠΎΡ€Π°Π±Π»ΡŒ :' + str(self.state), pos=(0.5, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля

            self.fountain_pos = random.randrange(0, 5), random.randrange(0, 5) + 500, random.randrange(0, 1)    
            self.loadParticleConfig('special_effects/fountain/fountain.ptf', self.fountain_pos)

        else :
            if self.state != 100:
                self.state += 1
                self.state_info.hide()
                self.state_info = OnscreenText(text='ΠΊΠΎΡ€Π°Π±Π»ΡŒ :' + str(self.state), pos=(0.5, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля

            self.fountain_pos = random.randrange(0, 5), random.randrange(0, 5), random.randrange(0, 1)    
            self.loadParticleConfig('special_effects/fountain/fountain.ptf', self.fountain_pos)
        
        
    def black_light(self):
        # Π’Ρ‹ΠΊΠ»ΡŽΡ‡Π΅Π½Ρ‹ΠΉ свСт
        ambientLight = AmbientLight("ambientLight")
        ambientLight.setColor((0, 0, 0, 1))
        directionalLight = DirectionalLight("directionalLight")
        directionalLight.setDirection((-5, -5, -5))
        directionalLight.setColor((1, 1, 1, 1))
        directionalLight.setSpecularColor((1, 1, 1, 1))
        render.setLight(render.attachNewNode(ambientLight))
        render.setLight(render.attachNewNode(directionalLight))

    def weapon_hide(self):
        # Π£Π±Ρ€Π°Ρ‚ΡŒ ΠΎΡ€ΡƒΠΆΠΈΠ΅
        self.hide_weapon = True
        self.weapon.hide()

    def toggleLights(self, lights):
        # Π‘ΠΏΠ΅Ρ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠ΅ освСщСниС
        if self.hide_weapon:
            for light in lights:
                if render.hasLight(light):
                    render.clearLight(light)
                else:
                    render.setLight(light)
            
            self.flash.setPos(self.weapon_pos)
        else:
            return


    def shot(self):
        dt = globalClock.getDt() + 0.5 # CΠΊΠΎΡ€ΠΎΡΡ‚ΡŒ двиТСния
        if not self.hide_weapon : # Ссли ΠΎΡ€ΡƒΠΆΠΈΠ΅ ΡƒΠ±Ρ€Π°Π½ΠΎ Ρ‚ΠΎ ΠΌΡ‹ Π½Π΅ ΠΌΠΎΠΆΠ΅ΠΌ ΡΡ‚Ρ€Π΅Π»ΡΡ‚ΡŒ
            self.shotSound.play() # ΠΈΠ³Ρ€Π°Π΅ΠΌ Π·Π²ΡƒΠΊ выстрСла
            self.bullet.setPos(self.weapon_pos) # ΠŸΡƒΠ»Ρ Π±ΡƒΠ΄Π΅Ρ‚ спавнится Π²Π½ΡƒΡ‚Ρ€ΠΈ ΠΏΡƒΡˆΠΊΠΈ
            self.bullet.setY(self.bullet, -11 * dt) # Π‘Π΄Π²ΠΈΠ³Π°Π΅ΠΌ ΠΏΡƒΠ»ΡŽ Π½Π° ΠΎΠ³Ρ€ΠΎΠΌΠ½ΠΎΠΉ скорости Π²ΠΏΠ΅Ρ€Ρ‘Π΄

    def check_loss(self):
        if self.state == 0: # Ссли ΠΆΠΈΠ·Π½Π΅ΠΉ Ρƒ корабля Π½Π΅ ΠΎΡΡ‚Π°Π»ΠΎΡΡŒ
            self.black_light() # Π²ΠΊΠ»ΡŽΡ‡ΠΈΠΌ Ρ‡Ρ‘Ρ€Π½Ρ‹ΠΉ свСт
            self.weapon_hide() # ΡƒΠ±Π΅Ρ€Ρ‘ΠΌ ΠΎΡ€ΡƒΠΆΠΈΠ΅
            self.info = OnscreenText(text='ΠΏΠΎΡ€Π°ΠΆΠ΅Π½ΠΈΠ΅', style=1, font=self.font,
                                     fg=(1,1,1,1),
                            pos=(-1.3, -0.5), align=TextNode.ALeft, scale=0.3) # напишСм ΠΎ ΠΏΠΎΡ€Π°ΠΆΠ΅Π½ΠΈΠΈ
            self.crackSound.play() # ΠΈΠ³Ρ€Π°Π΅ΠΌ Π·Π²ΡƒΠΊ Π²Π·Ρ€Ρ‹Π²Π°


    def setKey(self, key, value):
        self.keyMap[key] = value # Π”Π΅Π»Π°Π΅ΠΌ ΠΌΠ΅Ρ…aΠ½uΠ·ΠΌ наТатия клавиш.

    def move(self, task):

        ''' Π”Π΅Π»Π°Π΅ΠΌ Ρ„ΡƒΡ†Π½ΠΊΡ†ΠΈΡŽ двиТСния ΠΈΠ³Ρ€ΠΎΠΊΠ° '''

        dt = globalClock.getDt() - .005 # CΠΊΠΎΡ€ΠΎΡΡ‚ΡŒ двиТСния

        # ΠŸΠΎΠ²ΠΎΡ€ΠΎΡ‚ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ Π²Π»Π΅Π²ΠΎ ΠΈ Π²ΠΏΡ€Π°Π²ΠΎ

        if self.keyMap["cam-left"]:
            self.camera.setX(self.camera, -20 * dt) # МСняСм ΠΏΠΎΠ»ΠΎΠΆΠ΅Π½ΠΈΠΊΠ° ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ ΠΏΠΎ икс. Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ получаСтся илюзия ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚Π° ΡƒΠ³Π»Π° Π»ΡƒΡ‡Π°. Но Π½Π° самом Π΄Π΅Π»Π΅ ΠΊΠ°ΠΌΠ΅Ρ€Π° просто пСрСмСщаСтся.
        if self.keyMap["cam-right"]:
            self.camera.setX(self.camera, +20 * dt) # Π’ΠΎΠΆΠ΅ самоС, Ρ‡Ρ‚ΠΎ ΠΈ Π½Π°Π²Π΅Ρ€Ρ…Ρƒ.

        startpos = self.droid.getPos() # Π‘Π΄Π΅Π»Π°Π΅ΠΌ ΡƒΠ΄ΠΎΠ±Π½ΡƒΡŽ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ ΠΈΠ³Ρ€ΠΎΠΊΠ°

        if self.keyMap["left"]:
            self.droid.setH(self.droid.getH() + 300 * dt)
            self.enemy.setY(self.enemy, 1 * dt)
        if self.keyMap["right"]:
            self.droid.setH(self.droid.getH() - 300 * dt)
            self.enemy.setY(self.enemy, -1 * dt)
        if self.keyMap["forward"]:
            self.droid.setY(self.droid, -25 * dt)
            self.enemy.setX(self.enemy, 1 * dt)
            # Π‘Π΄Π΅Π»Π°Π΅ΠΌ ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½ΠΎΠ΅ условиС ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ ΡƒΠ±Ρ€Π°Π½ΠΎ ΠΎΡ€ΡƒΠΆΠΈΠ΅ ΠΈΠ»ΠΈ Π½Π΅Ρ‚
            if not self.hide_weapon:
                self.weapon_pos = self.droid.getX(), self.droid.getY() + 0.7, 3
                self.weapon.setPos(self.weapon_pos) # ОбновляСм ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΏΡƒΡˆΠΊΠΈ
            else:
                self.weapon_pos = self.droid.getX(), self.droid.getY() + 0.7, 3
                self.flash.setPos(self.weapon_pos)


        camvec = self.droid.getPos() - self.camera.getPos() # Π²Π΅ΠΊΡ‚ΠΎΡ€ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹
        camvec.setZ(0) # 0 высота Π²Π΅ΠΊΡ‚ΠΎΡ€Π°
        camdist = camvec.length() # дистанция ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ ΠΎΡ‚ Π΄Ρ€ΠΎΠΈΠ΄Π°
        camvec.normalize() # Π½ΠΎΡ€ΠΌΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ Π²Π΅ΠΊΡ‚ΠΎΡ€ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹
        if camdist > 10.0: # Ссли дистанция ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ большС 10, Ρ‚ΠΎ смСщаСм ΠΊΠ°ΠΌΠ΅Ρ€Ρƒ Π·Π° Π΄Ρ€ΠΎΠΎΠΈΠ΄ΠΎΠΌ
            self.camera.setPos(self.camera.getPos() + camvec * (camdist - 10))
            camdist = 10.0 # Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ дистанция Π±ΡƒΠ΄Π΅Ρ‚ снова 10
        if camdist < 5.0: # Ссли дистагцтя ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ мСньшС 5, Ρ‚ΠΎ...
            self.camera.setPos(self.camera.getPos() - camvec * (5 - camdist)) # сдвигаСм ΠΊΠ°ΠΌΠ΅Ρ€Ρƒ
            camdist = 5.0 # всё обновляСм
            
        self.camera.lookAt(self.floater) # Π²ΠΎΡ‚ ΠΈ пригодился наш floater


        return task.cont # Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌ Π·Π°Π΄Π°Ρ‡Ρƒ

    def addInstructions(self, pos, msg):
        return OnscreenText(text=msg, style=1, fg=(1,1,1,1), font=self.inst_font, pos=(-1.3, pos), align=TextNode.ALeft, scale = .04, shadow=(0,0,0,1)) # Ѐункция ΠΎ Ρ‚ΠΎΠΌ, ΠΊΠ°ΠΊ ΡƒΠΏΡ€Π°Π²Π»ΡΡ‚ΡŒ

    def addTitle(self, text):
        return OnscreenText(text=text, style=1, fg=(1, 1, 1, 1), scale=0.2,
                            parent=base.a2dBottomRight, align=TextNode.ARight,
                            pos=(-0.1, 0.09), shadow=(0, 0, 0, 1), font=self.font) # Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ тСкстового Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ° с ΡˆΡ€ΠΈΡ„Ρ‚ΠΎΠΌ ΠΈ ΠΏΠΎΠ·ΠΈΡ†ΠΈΠ΅ΠΉ
    

droid = DroidShooter() # Π‘ΠΎΠ·Π΄Π°Π΄ΠΈΠΌ экзСмпляр класса нашСй ΠΈΠ³Ρ€Ρ‹
droid.run() # 3апустим ΠΈΠ³Ρ€Ρƒ


# Ρ€Π°Π·Ρ€ΠΎΠ±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ :
# Π“Π»Π°Π²Π½Ρ‹ΠΉ Π°Π²Ρ‚ΠΎΡ€ : ma3rx
# ΠŸΠΎΠΌΠΎΡ‰Π½ΠΈΠΊ : panda3dmastercoder( присоСдСнился ΠΊ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Ρƒ 31 января, 12:??)

3.0.3.1 update! Bug fix slider.

#!/usr/bin/env python
# -*- coding: utf_8 -*-

# Π‘ΠΎΠ·Π΄Π°Π½ΠΎ : 22 число, ΡΠ½Π²Π°Ρ€ΡŒ, 2021 Π³ΠΎΠ΄

# Π˜ΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΡƒΠ΅ΠΌ всС Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹Π΅ инструмСнты
from direct.showbase.ShowBase import ShowBase
from panda3d.core import CollisionTraverser, CollisionNode
from panda3d.core import CollisionHandlerPusher, CollisionSphere, CollisionInvSphere
from panda3d.core import Filename, AmbientLight, DirectionalLight
from panda3d.core import PandaNode, NodePath, Camera, TextNode
from direct.particles.Particles import Particles
from direct.particles.ParticleEffect import ParticleEffect
from panda3d.core import PointLight, Spotlight
from panda3d.core import CollideMask
from panda3d.core import loadPrcFileData
from panda3d.core import *
from direct.gui.OnscreenText import OnscreenText
from direct.gui.OnscreenImage import OnscreenImage
from direct.gui.DirectButton import DirectButton
from direct.gui.DirectSlider import DirectSlider
from direct.actor.Actor import Actor
import random
import sys
import time
import os
import math

VERSION = '3.0.3.1'

settings = ['window-title Droid Game ' +  VERSION,
            'fullscreen 0']
            

loadPrcFileData('', settings[0]) # Π‘Π΄Π΅Π»Π°Π΅ΠΌ Π½Π΅ стандартный Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ (Π²ΠΎΠ·ΠΌΡ‘ΠΌ Π΅Π³ΠΎ ΠΈΠ· ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ settings)
loadPrcFileData('', settings[1]) # Π½Π΅ Π±ΡƒΠ΄Π΅ΠΌ Π΄Π΅Π»Π°Ρ‚ΡŒ полноэкранный Ρ€Π΅ΠΆΠΈΠΌ

# Π‘ΠΎΠ·Π΄Π°Π΄ΠΈΠΌ Π³Π»Π°Π²Π½Ρ‹ΠΉ класс нашСй ΠΈΠ³Ρ€Ρ‹
class DroidShooter(ShowBase):
    def __init__(self):
        ShowBase.__init__(self) # Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ всС сСлфы ΠΈΠ· direct
        self.speed = 1800 # ΡΠΊΠΎΡ€ΠΎΡΡ‚ΡŒ двигатСля
        self.menu() # звпуск мСню
        
    def menu(self):
        
        base.enableParticles() # ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ эффСкт Π΄Ρ‹ΠΌΠ°

        self.win.setClearColor((0, 0, 0, 1)) # Π—Π°ΠΊΡ€Π°ΡˆΠΈΠ²Π°Π΅ΠΌ ΠΏΠΎΠ²Π΅Ρ€Ρ…Π½ΠΎΡΡ‚ΡŒ Ρ‡Ρ‘Ρ€Π½Ρ‹ΠΌ. Π”Π΅Π»ΠΎ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ Π² этом ΠΈΠ³Ρ€ΠΎΠ²ΠΎΠΌ Π΄Π²ΠΈΠΆΠΊΠ΅ ΠΏΠΎΠ²Π΅Ρ€Ρ…Π½ΠΎΡΡ‚ΡŒ Π·Π°ΠΊΡ€Π°ΡˆΠΈΠ²Π°Π΅Ρ‚ΡΡ сСрым.
        self.font = loader.loadFont('./fonts/doom_font.ttf') # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ ΡˆΡ€ΠΈΡ„Ρ‚ ΠΈΠ· ΠΈΠ³Ρ€Ρ‹ doom
        self.inst_font = loader.loadFont('./fonts/arial.ttf') # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ ΡˆΡ€ΠΈΡ„Ρ‚ arial

        self.crackSound = loader.loadMusic('./sounds/crack.wav') # Π·Π²ΡƒΠΊ Π²Π·Ρ€Ρ‹Π²Π° корабля
        self.shotSound = loader.loadMusic('./sounds/shot.wav') # Π·Π²ΡƒΠΊ выстрСла
        self.startSound = loader.loadMusic('./sounds/started.wav') # Π·Π²ΡƒΠΊ запуска
        self.errorSound = loader.loadMusic('./sounds/error.wav') # Π·Π²ΡƒΠΊ запуска
        self.errorSound.setVolume(1) # полная Π³Ρ€ΠΎΠΌΠΊΠΎΡΡ‚ΡŒ Π·Π²ΡƒΠΊΠ°
        self.startSound.setVolume(1) # полная Π³Ρ€ΠΎΠΌΠΊΠΎΡΡ‚ΡŒ Π·Π²ΡƒΠΊΠ°
        self.crackSound.setVolume(1) # полная Π³Ρ€ΠΎΠΌΠΊΠΎΡΡ‚ΡŒ Π·Π²ΡƒΠΊΠ°
        self.shotSound.setVolume(1) # полная Π³Ρ€ΠΎΠΌΠΊΠΎΡΡ‚ΡŒ Π·Π²ΡƒΠΊΠ°
        self.startSound.play() # ΠΈΠ³Ρ€Π°Π΅ΠΌ Π·Π²ΡƒΠΊ запуска ΠΈΠ³Ρ€Ρ‹

        self.button_start = DirectButton(pos=(0.7, 0, 0), text="CTAPT",
                                   scale=.3, pad=(.2, .2),
                                   command=self.load_game) # ΠΊΠ½ΠΎΠΏΠΊΠ° запуска ΠΈΠ³Ρ€Ρ‹

        self.slider_sun = DirectSlider(pos=(0.1, 0, .75), scale=0.8, value=0.5,
                                    command=self.set_sun_interval)


        self.title = self.addTitle("Droid game " + VERSION)
        
        # НапСчатаСм ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅
        self.inst1 = self.addInstructions(0.95, u"[ESC]: Π’Ρ‹Ρ…ΠΎΠ΄")
        self.inst2 = self.addInstructions(0.90, u"[Left Arrow]: ΠŸΠΎΠ²ΠΎΡ€ΠΎΡ‚ Π΄Ρ€ΠΎΠΈΠ΄Π° Π² Π»Π΅Π²ΠΎ")
        self.inst3 = self.addInstructions(0.85, u"[Right Arrow]: ΠŸΠΎΠ²ΠΎΡ€ΠΎΡ‚ Π΄Ρ€ΠΎΠΈΠ΄Π° Π² ΠΏΡ€Π°Π²ΠΎ")
        self.inst4 = self.addInstructions(0.80, u"[Up Arrow]: Π’ΠΏΠ΅Ρ€Π΅Π΄")
        self.inst5 = self.addInstructions(0.75, u"[a]: ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ Π² ΠΏΡ€Π°Π²ΠΎ")
        self.inst6 = self.addInstructions(0.70, u"[d]: ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ Π² Π»Π΅Π²ΠΎ")
        self.inst7 = self.addInstructions(0.65, u"[Left Arrow + Up arrow]: ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚ Π΄Ρ€ΠΎΠΈΠ΄Π° Π² Π»Π΅Π²ΠΎ ΠΈ Π²ΠΏΠ΅Ρ€Ρ‘Π΄")
        self.inst8 = self.addInstructions(0.60, u"[Right Arrow + Up arrow]: ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚ Π΄Ρ€ΠΎΠΈΠ΄Π° Π² ΠΏΡ€Π°Π²ΠΎ ΠΈ Π²ΠΏΠ΅Ρ€Ρ‘Π΄")
        self.inst9 = self.addInstructions(0.55, u"[a + Up arrow]: ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ Π² ΠΏΡ€Π°Π²ΠΎ ΠΈ Π²ΠΏΠ΅Ρ€Ρ‘Π΄")
        self.inst10 = self.addInstructions(0.50, u"[d + Up arrow]: ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ Π² Π»Π΅Π²ΠΎ ΠΈ Π²ΠΏΠ΅Ρ€Ρ‘Π΄")
        self.inst11 = self.addInstructions(0.45, u"[space]: ΡΡ‚Ρ€Π΅Π»ΡŒΠ±Π°")
        self.inst12 = self.addInstructions(0.40, u"[s]: Π΄ΠΎΡΡ‚Π°Ρ‚ΡŒ Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊ")
        self.inst13 = self.addInstructions(0.35, u"[w]: ΡƒΠ±Ρ€Π°Ρ‚ΡŒ ΠΎΡ€ΡƒΠΆΠΈΠ΅")
        self.inst14 = self.addInstructions(0.30, u"[f]: ΠΏΠΎΠ»Π½Ρ‹ΠΉ Ρ€Π°Π·Π³ΠΎΠ½(ОПАБНО!)")
        self.inst15 = self.addInstructions(0.25, u"[0]: ΠΏΠΎΠΆΠ°Ρ€ΠΎΡ‚ΡƒΡˆΠΈΡ‚Π΅Π»ΡŒΠ½Π°Ρ систСма")

        self.accept("escape", sys.exit) # ΠŸΡ€ΠΈ Π½Π°ΠΆΠ°Ρ‚ΠΈΠΈ клавиши Esc Π²Ρ‹Ρ…ΠΎΠ΄ΠΈΠΌ.

    def set_sun_interval(self):
        self.sun_interval = self.slider_sun.guiItem.getValue() * 100 # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ слайдСрноС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΡƒΠΌΠ½ΠΎΠΆΠ΅Π½ΠΎΠ΅ Π½Π° 500, Π΄Π° Ρ‚Ρ€Π°Ρ‡Ρƒ ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΡŽ Π½ΠΎ ΠΌΠ½Π΅ каТСтся ΠΌΠ½ΠΎΠ³ΠΈΠΌ ΠΏΠ»Π΅Π²Π°Ρ‚ΡŒ Π½Π° ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΡŽ мСню, ΠΈΠ±ΠΎ Ρ‚Π°ΠΊΠΎΠ³ΠΎ понятия просто Π½Π΅Ρ‚Ρƒ :)
        

    def load_game(self):
        self.button_start.hide() # ΡƒΠ΄Π°Π»ΠΈΠΌ ΠΊΠ½ΠΎΠΏΠΊΡƒ старта
        self.title.hide() # ΡƒΠ΄Π°Π»ΠΈΠΌ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ ΠΈΠ³Ρ€Ρ‹
        # ΡƒΠ΄Π°Π»ΠΈΠΌ ΠΊΠ½ΠΎΠΏΠΊΠΈ управлСния
        self.inst1.hide()
        self.inst2.hide()
        self.inst3.hide()
        self.inst4.hide()
        self.inst5.hide()
        self.inst6.hide()
        self.inst7.hide()
        self.inst8.hide()
        self.inst9.hide()
        self.inst10.hide()
        self.inst11.hide()
        self.inst12.hide()
        self.inst13.hide()
        self.inst14.hide()
        self.inst15.hide()
        self.slider_sun.hide() # удаляСм слайдСр солнца
        
        self.keyMap = {
            "left": 0, "right": 0, "forward": 0, "cam-left": 0, "cam-right": 0} # Π‘ΠΎΠ·Π΄Π°Π΄ΠΈΠΌ ΡΠ»ΠΎΠ²Π°Ρ€ΡŒ ΠΊΠ½ΠΎΠΏΠΎΠΊ, ΠΏΠΎ ΠΈΡ… Π½Π°ΠΆΠ°Ρ‚ΠΈΡŽ        

        # РисуСм Π·Π²Ρ‘Π·Π΄Ρ‹

        self.sky = loader.loadModel("./models/sky/solar_sky_sphere") # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ модСль космоса(это сфСра)

        self.sky_tex = loader.loadTexture("./tex/stars_1k_tex.jpg") # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ тСкстуру
        self.sky.setTexture(self.sky_tex, 1) # Π·Π°Ρ€Π΅Π½Π΄Π΅Ρ€ΠΈΠΌ тСкстуру Π½Π° Π½Π΅Π±ΠΎ
        self.sky.reparentTo(render) # ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ Π½Π΅Π±ΠΎ
        self.sky.setScale(40000) # Ρ€Π°ΡΡˆΠΈΡ€ΠΈΠΌ Π½Π΅Π±ΠΎ Π΄ΠΎ максимальной Π²Π΅Π»ΠΈΡ‡ΠΈΠ½Ρ‹ panda3d

        self.environ = loader.loadModel("models/world/falcon.egg") # Π—Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ ΡƒΠΆΠ΅ созданный Π² blender ΠΌΠΈΡ€.
        self.environ.reparentTo(render) # Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ модСль ΠΌΠΈΡ€Π° Π² ΠΎΠΊΠ½ΠΎ

        droidStartPos = (-1, 0, 1.5 ) # Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ ΡΡ‚Π°Ρ€Ρ‚ΠΎΠ²ΡƒΡŽ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π² ΠΌΠΈΡ€Π΅.
        enemyStartPos = (-6, 1, 0.5) # Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ°-Π΄Ρ€ΠΎΠΈΠ΄Π°.
        self.droid = Actor("models/player/seeker.egg") # Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ модСль ΠΈΠ³Ρ€ΠΎΠΊΠ° (созданная Π² blender)
        self.enemy = Actor("models/enemies/r2d2/r2d2.egg") # Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ модСль ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ° (созданная Π² blender)
        self.droid.reparentTo(render) # ΠŸΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Π΅ΠΌ модСль ΠΈΠ³Ρ€ΠΎΠΊΠ° Π² наш ΠΌΠΈΡ€.
        self.enemy.reparentTo(render) # ΠŸΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Π΅ΠΌ модСль ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ° Π² наш ΠΌΠΈΡ€.
        self.droid.setScale(1) # Π”Π΅Π»Π°Π΅ΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ€ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π½Π° 1
        self.enemy.setScale(1) # Π”Π΅Π»Π°Π΅ΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ€ ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ° Π½Π° 1
        self.droid.setPos(droidStartPos) # Π‘Ρ‚Π°Π²ΠΈΠΌ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π½Π° Ρ€Π°Π½Π΅Π΅ ΡΠΎΠ·Π΄Π°Π½ΡƒΡŽ Π½Π°ΠΌΠΈ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ
        self.enemy.setPos(enemyStartPos) # Π‘Ρ‚Π°Π²ΠΈΠΌ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ° Π½Π° Ρ€Π°Π½Π΅Π΅ ΡΠΎΠ·Π΄Π°Π½ΡƒΡŽ Π½Π°ΠΌΠΈ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ

        self.weapon = Actor('models/weapon/lightsaber.egg') # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ ΠΎΡ€ΡƒΠΆΠΈΠ΅
        self.bullet = Actor('models/weapon/bullet/bullet.egg.pz') # Π—Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ ΠΏΡƒΠ»ΡŽ
        self.flash = Actor('models/whishlyflash/handlamp.egg') # Π—Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊ
               
        self.weapon.reparentTo(render) # пСрСмСстим ΠΎΡ€ΡƒΠΆΠΈΠ΅ Π² наш ΠΌΠΈΡ€
        self.bullet.reparentTo(render) # пСрСмСстим ΠΏΡƒΠ»ΡŽ Π² ΠΌΠΈΡ€ Π½ΠΎ появится ΠΎΠ½Π° сама Π½Π΅ скоро
        self.flash.reparentTo(render) # пСрСмСстим Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊ Π² наш ΠΌΠΈΡ€
        self.weapon.setScale(.5) # Π·Π°Π΄Π°Π΄ΠΈΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ€ ΠΏΡƒΡˆΠΊΠΈ
        self.bullet.setScale(.5) # Π·Π°Π΄Π°Π΄ΠΈΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ€ ΠΏΡƒΠ»ΠΈ
        self.flash.setScale(.5) # Π·Π°Π΄Π°Π΄ΠΈΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ€ Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊΠ°

        # враТСский ΠΈΡΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»ΡŒ
        self.fighter = Actor('models/fighter/fighter.egg') # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ ΠΌΠΎΠ΄Π΅Π»ΡŒΠΊΡƒ истрСбитСля
        self.fighter.reparentTo(render) # ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ ΠΈΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»ΡŒ
        self.fighter.setPos(0, 90, 0) # позиция истрСбитСля
                

        self.weapon_pos = self.droid.getX(), self.droid.getY() + 0.7, 1 # ΠŸΠΎΠ·ΠΈΡ†ΠΈΡ ΠΏΡƒΡˆΠΊΠΈ
        
        self.weapon.setPos(self.weapon_pos) # ΠŸΠΎΠΌΠ΅ΡΡ‚ΠΈΠΌ ΠΎΡ€ΡƒΠΆΠΈΠ΅ Ρ‡ΡƒΡ‚ΡŒ Π²Ρ‹ΡˆΠ΅ ΠΈΠ³Ρ€ΠΎΠΊΠ°
        
        
        self.spotlight = camera.attachNewNode(Spotlight("spotlight")) # ΠšΠΎΠ½Ρ„ΠΈΠ³ΠΈ Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊΠ°
        self.spotlight.node().setColor((.3, .3, .3, 1))
        self.spotlight.node().setSpecularColor((0, 0, 0, 1))

        self.floater = NodePath(PandaNode("floater")) 
        self.floater.reparentTo(self.droid)
        self.floater.setZ(2.0)

        self.accept("escape", sys.exit) # ΠŸΡ€ΠΈ Π½Π°ΠΆΠ°Ρ‚ΠΈΠΈ клавиши Esc Π²Ρ‹Ρ…ΠΎΠ΄ΠΈΠΌ.
        
        self.accept("arrow_left", self.setKey, ["left", True]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ Π²Π»Π΅Π²ΠΎ - ΠΏΠΎΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π²Π»Π΅Π²ΠΎ
        self.accept("arrow_right", self.setKey, ["right", True]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ Π²ΠΏΡ€Π°Π²ΠΎ - ΠΏΠΎΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π²ΠΏΡ€Π°Π²ΠΎ
        self.accept("arrow_up", self.setKey, ["forward", True]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ Π²ΠΏΠ΅Ρ€Ρ‘Π΄ - ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄
        self.accept("a", self.setKey, ["cam-left", True]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ a - Ρ€Π°Π·Π²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΊΠ°ΠΌΠ΅Ρ€Ρƒ Π²ΠΎΠΊΡ€ΡƒΠ³ нашСй модСльки
        self.accept("d", self.setKey, ["cam-right", True]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ s - Ρ€Π°Π·Π²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΊΠ°ΠΌΠ΅Ρ€Ρƒ Π²ΠΎΠΊΡ€ΡƒΠ³ нашСй модСльки
        self.accept("arrow_left-up", self.setKey, ["left", False]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ Π²Π²Π΅Ρ€Ρ…+Π²Π»Π΅Π²ΠΎ - ΠΏΠΎΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π²Π»Π΅Π²ΠΎ ΠΈ ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄
        self.accept("arrow_right-up", self.setKey, ["right", False]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ Π²Π²Π΅Ρ€Ρ…+ΠΏΡ€Π°Π²ΠΎ - ΠΏΠΎΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π²ΠΏΡ€Π°Π²ΠΎ ΠΈ ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄
        self.accept("arrow_up-up", self.setKey, ["forward", False]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ Π²Π²Π΅Ρ€Ρ…+Π²Π²Π΅Ρ€ΡŠ - ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄ ΠΈ ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄
        self.accept("a-up", self.setKey, ["cam-left", False]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ a+Π²ΠΏΠ΅Ρ€Ρ‘Π΄ - ΠΏΠΎΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΊΠ°ΠΌΠ΅Ρ€Ρƒ Π²Π»Π΅Π²ΠΎ ΠΈ ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄
        self.accept("d-up", self.setKey, ["cam-right", False]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ s+Π²ΠΏΠ΅Ρ€Ρ‘Π΄ - ΠΏΠΎΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΊΠ°ΠΌΠ΅Ρ€Ρƒ Π²ΠΏΡ€Π°Π²ΠΎ ΠΈ ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄

        self.accept("space", self.shot) # ΠΏΡ€ΠΈ ΠΏΡ€ΠΎΠ±Π΅Π»Π΅ стрСляСм
        self.accept("s", self.toggleLights, [[self.spotlight]]) # Π’ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊ
        self.accept("w", self.weapon_hide) # ΠΏΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ w - ΡƒΠ±Π΅Ρ€Ρ‘ΠΌ ΠΎΡ€ΡƒΠΆΠΈΠ΅.

        base.enableParticles() # Π’ΠΊΠ»ΡŽΡ‡Π°Π΅ΠΌ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ Π΄Ρ‹ΠΌΠ°
        self.t = loader.loadModel("models/weapon/lightsaber.egg") # Π—Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ Π΅Ρ‰Ρ‘ ΠΎΡ€ΡƒΠΆΠΈΠ΅
        self.t.reparentTo(render) # ΠŸΠ΅Ρ€Π΅ΠΌΠ΅ΡΡ‚ΠΈΠΌ ΠΎΡ€ΡƒΠΆΠΈΠ΅ Π² наш ΠΌΠΈΡ€
        self.p = ParticleEffect() # Π’ΠΊΠ»ΡŽΡ‡ΠΈΠΌ эффСкт Π΄Ρ‹ΠΌΠ°
        self.accept('f', self.particle_start) # ΠΏΡ€ΠΈ Π½Π°ΠΆΠ°Ρ‚ΠΈΠΈ f(ΠΎΡ‚ force) -  Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ Ρ„Π°ΠΉΠ» Π΄Ρ‹ΠΌΠ° ΠΈ пСрСмСстим Π² ΠΊΠΎΠ½Ρ„ΠΈΠ³ Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΈΠΌΠ΅Π½Π½ΠΎ эта анимация стала ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ΠΌ Π΄Ρ‹ΠΌΠ°
        self.accept('0', self.fountain) # ΠΏΡ€ΠΈ  Π½Π°ΠΆΠ°Ρ‚ΠΈΠΈ ΠΊΠ½ΠΎΠΏΠΎΠΊ f+o(fountain) Π²ΠΊΠ»ΡŽΡ‡ΠΈΠΌ ΠΏΠΎΠΆΠ°Ρ€ΠΎΡ‚ΡƒΡˆΠΈΡ‚Π΅Π»ΡŒΠ½ΡƒΡŽ систСму

        taskMgr.add(self.move, "moveTask") # ДобавляСм Π·Π°Π΄Π°Ρ‡Ρƒ Π² наш Π΄Π²ΠΈΠΆΠΎΠΊ

        self.isMoving = False # Π‘Ρ‚Π°Π²ΠΈΠΌ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ isMoving Π½Π° False(Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΌΠ΅Π½ΡΡ‚ΡŒ это Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅) Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΈΠ³Ρ€ΠΎΠΊ ΠΈΠ·Π½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎ стоял.
        # Π”Π΅Π»Π°Π΅ΠΌ Ρ‚Π°ΠΊ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ свСт Π±Ρ‹Π» ΠΈΠ·Π½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎ Π²Ρ‹ΠΊΠ»ΡŽΡ‡Π΅Π½.
        self.disableMouse() # ΠžΡ‚ΠΊΠ»ΡŽΡ‡Π°Π΅ΠΌ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π΅Π½ΠΈΠ΅ Ρ‡Π΅Ρ€Π΅Π· ΠΌΡ‹ΡˆΠΊΡƒ
        self.camera.setPos(self.droid.getX(), self.droid.getY() + 1, 3) # Π‘Ρ‚Π°Π²ΠΈΠΌ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ Ρ‡ΡƒΡ‚ΡŒ большС ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ ΠΈΠ³Ρ€ΠΎΠΊΠ°

        self.black_light() # Π‘Π΄Π΅Π»Π°Π΅ΠΌ Π²Ρ‹ΠΊΠ»ΡŽΡ‡Π΅Π½Π½Ρ‹ΠΉ свСт

        self.state = 100 # БостояниС корабля
        self.state_info = OnscreenText(text='ΠΊΠΎΡ€Π°Π±Π»ΡŒ :' + str(self.state), pos=(0.5, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля
                
        self.check_loss() # ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ ΠΏΠΎΡ€Π°ΠΆΠ΅Π½ΠΈΠ΅
        self.hide_weapon = False # ΠŸΠΎΡΡ‚Π°Π²ΠΈΠΌ, Ρ‡Ρ‚ΠΎ ΠΎΡ€ΡƒΠΆΠΈΠ΅ Π½Π΅ ΡƒΠ±Ρ€Π°Π½ΠΎ
        self.steam_pos = random.randrange(0, 5), random.randrange(0, 5), random.randrange(0, 5)
        self.fountain_pos = random.randrange(0, 5), random.randrange(0, 5), random.randrange(0, 1)

        self.motor_pos1 = 25.238849639892578, 8.962211608886719, 1.5 # позиция ΠΏΠ΅Ρ€Π²ΠΎΠ³ΠΎ ΠΌΠΎΡ‚ΠΎΡ€Π°
        self.motor_pos2 = -20.676218032836914, 10.55816650390625, 1.5 # позиция Π²Ρ‚ΠΎΡ€ΠΎΠ³ΠΎ ΠΌΠΎΡ‚ΠΎΡ€Π°

        self.motor1 = self.loadParticleConfig('special_effects/steam_critic+/fireish.ptf', self.motor_pos1) # ΠΌΠΎΡ‚ΠΎΡ€ 1
        self.motor2 = self.loadParticleConfig('special_effects/steam_critic+/fireish.ptf', self.motor_pos2) # ΠΌΠΎΡ‚ΠΎΡ€ 2

        self.state_info2 = OnscreenText(text='', pos=(-0.8, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля

        self.force = False # ΠŸΠΎΡΡ‚Π°Π²ΠΈΠΌ, Ρ‡Ρ‚ΠΎ Π½Π΅ Ρ€Π°Π·Π³ΠΎΠ½ΡΠ»ΠΈΡΡŒ

        # ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ ΠΊΠΎΠ»Π»ΠΈΠ·ΠΈΠΈ
        
        self.cTrav = CollisionTraverser()
        pusher = CollisionHandlerPusher()
        
        environCenter = self.environ.getBounds().getCenter()
        environRad = self.environ.getBounds().getRadius()
        cNode = CollisionNode("environment")
        cNode.addSolid(CollisionInvSphere(environCenter, environRad))
        environC = self.environ.attachNewNode(cNode)
        
        droidCenter = self.droid.getBounds().getCenter()
        droidRad = self.droid.getBounds().getRadius()
        cNode = CollisionNode("droid")
        cNode.addSolid(CollisionSphere(droidCenter, droidRad))
        droidC = self.droid.attachNewNode(cNode)
        
        pusher.addCollider(droidC, self.droid)
        self.cTrav.addCollider(droidC, pusher)
        
        enemyCenter = self.enemy.getBounds().getCenter()
        enemyRad = self.enemy.getBounds().getRadius()
        cNode = CollisionNode("enemy")
        cNode.addSolid(CollisionSphere(enemyCenter, enemyRad))
        enemyC = self.enemy.attachNewNode(cNode)

        pusher.addCollider(enemyC, self.enemy)
        self.cTrav.addCollider(enemyC, pusher)

        fighterCenter = self.fighter.getBounds().getCenter()
        fighterRad = self.fighter.getBounds().getRadius()
        cNode = CollisionNode("fighter")
        cNode.addSolid(CollisionSphere(fighterCenter, fighterRad))
        fighterC = self.fighter.attachNewNode(cNode)

        bulletCenter = self.bullet.getBounds().getCenter()
        bulletRad = self.bullet.getBounds().getRadius()
        cNode = CollisionNode("bullet")
        cNode.addSolid(CollisionSphere(bulletCenter, bulletRad))
        bulletC = self.bullet.attachNewNode(cNode)
        
        pusher.addCollider(bulletC, self.bullet)
        self.cTrav.addCollider(bulletC, pusher)

        # солнцС(новая ΠΌΠ΅Ρ…Π°Π½ΠΈΠΊΠ° освСщСния)
        sun = DirectionalLight("sun")
        sun.set_color_temperature(6000)
        sun.color = sun.color * 4
        sun_path = render.attach_new_node(sun)
        sun_path.set_pos(10, -10, -10)
        sun_path.look_at(0, 0, 0)
        sun_path.hprInterval(self.sun_interval, (sun_path.get_h(), sun_path.get_p() - 360, sun_path.get_r()), bakeInStart=True).loop()
        render.set_light(sun_path)

    def fight_force(self):
        # сдвиТСниС истрСбитСля Π·Π° нашим ΠΊΠΎΡ€Π°Π±Π»Ρ‘ΠΌ(ΠΎΡ‡Π΅Π½ΡŒ простым способом я сдСлал Ρ‚Π°ΠΊ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΈΡΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»ΡŒ Π·Π°ΠΆΠΈΠΌΠ°Π» нас(Π»Π΅Ρ‚Π°Π» Π² нашСм ΠΊΠ²Π°Π΄Ρ€Π°Ρ‚Π΅)) ΠΈ Π·Π°ΠΆΠΈΠΌΠ°Π΅Ρ‚ ΠΎΠ½ Ρ€Π΅Π°Π»ΡŒΠ½ΠΎ, сблиТая ΠΊ Π½Π°ΠΌ свой ΠΊΠ²Π°Π΄Ρ€Π°Ρ‚
        self.fighter.setY(self.fighter.getY() - self.speed) 
        self.fighter.setX(self.fighter.getX() - 10)    

        print(self.fighter.getX())


    def loadParticleConfig(self, filename, pos):
        self.p.cleanup()
        self.p = ParticleEffect()
        self.p.loadConfig(Filename(filename))

        self.p.start(self.t)
        self.p.setPos(pos)

    def particle_start(self):
        self.force = True # ΠŸΠΎΡΡ‚Π°Π²ΠΈΠΌ, Ρ‡Ρ‚ΠΎ ΠΌΡ‹ ΡƒΠΆΠ΅ Ρ€Π°Π·Π³ΠΎΠ½ΡΠ»ΠΈΡΡŒ
        # ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Π΅ΠΌ всС ΠΎΠ±ΡŒΠ΅ΠΊΡ‚Ρ‹ Π·Π° ΠΊΠΎΡ€Π°Π±Π»Ρ‘ΠΌ
        self.environ.setY(self.environ.getY() - self.speed) # нСсёмся Π²ΠΏΡ€Π°Π²ΠΎ
        self.droid.setY(self.droid.getY() - self.speed) # сдвигаСм Π΄Ρ€ΠΎΠΈΠ΄Π° Π·Π° ΠΊΠΎΡ€Π°Π±Π»Ρ‘ΠΌ
        self.enemy.setY(self.enemy.getY() - self.speed) # сдфигаСм ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ° Π·Π° ΠΊΠΎΡ€Π°Π±Π»Ρ‘ΠΌ
        self.weapon.setY(self.weapon.getY() - self.speed) # ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Π΅ΠΌ ΠΎΡ€ΡƒΠΆΠΈΠ΅
        self.flash.setY(self.flash.getY() - self.speed) # ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Π΅ΠΌ Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊ
        self.fight_force()

        self.state -= 1 # сдСлаСм мСньшС ΠΎΡ‡ΠΊΠΎΠ²
        self.state_info.hide() # ΡƒΠ΄Π°Π»ΠΈΠΌ тСкстовыС ΠΎΡ‡ΠΊΠΈ

        camvec = self.droid.getPos() - self.camera.getPos()
        camvec.setZ(0)
        camdist = camvec.length()
        camvec.normalize()
        if camdist > 10.0:
            self.camera.setPos(self.camera.getPos() + camvec * (camdist - 10))
            camdist = 10.0
        if camdist < 5.0:
            self.camera.setPos(self.camera.getPos() - camvec * (5 - camdist))
            camdist = 5.0
            
        self.camera.lookAt(self.floater)
        
        if self.state != 10 and self.state > 10:
            self.state_info.hide() # ΡƒΠ±ΠΈΡ€Π°Π΅ΠΌ ΠΏΡ€Π΅Π΄Π΅Π΄ΡƒΡ‰Π΅Π΅ сообщСниС ΠΎ Тизнях корабля
            self.state_info = OnscreenText(text='ΠΊΠΎΡ€Π°Π±Π»ΡŒ :' + str(self.state), pos=(0.5, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля
            self.check_loss() # провСряСм ΠΏΠΎΡ€Π°ΠΆΠ΅Π½ΠΈΠ΅
            self.steam_pos = random.randrange(0, 5), random.randrange(0, 5) + 300, random.randrange(0, 5)
            self.loadParticleConfig('special_effects/steam/steam.ptf', self.steam_pos)
            self.errorSound.play() # ΠΈΠ³Ρ€Π°Π΅ΠΌ Π·Π²ΡƒΠΊ ошибки
            self.state_info2.hide() # ΡƒΠ±ΠΈΡ€Π°Π΅ΠΌ ΠΏΡ€Π΅Π΄Π΅Π΄ΡƒΡ‰Π΅Π΅ сообщСниС
            self.state_info2 = OnscreenText(text='Π΄Π²ΠΈΠ³Π°Ρ‚Π΅Π»ΡŒ нСисправСн', pos=(-0.8, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля
        else:
            self.state_info = OnscreenText(text='ΠΊΠΎΡ€Π°Π±Π»ΡŒ :' + str(self.state), pos=(0.5, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля
            self.check_loss() # провСряСм ΠΏΠΎΡ€Π°ΠΆΠ΅Π½ΠΈΠ΅
            self.steam_pos = random.randrange(0, 5), random.randrange(0, 5) + 300, random.randrange(0, 5)
            self.loadParticleConfig('special_effects/steam_critic/steam.ptf', self.steam_pos)
            self.errorSound.play() # ΠΈΠ³Ρ€Π°Π΅ΠΌ Π·Π²ΡƒΠΊ ошибки
            self.state_info2.hide()  # ΡƒΠ±ΠΈΡ€Π°Π΅ΠΌ ΠΏΡ€Π΅Π΄Π΅Π΄ΡƒΡ‰Π΅Π΅ сообщСниС
            self.state_info2 = OnscreenText(text='критичСскоС состояниС', pos=(-0.8, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля
    
        if self.state < 10:
            self.state_info.hide()
            self.state_info = OnscreenText(text='ΠΊΠΎΡ€Π°Π±Π»ΡŒ :' + str(self.state), pos=(0.5, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля
            self.check_loss() # провСряСм ΠΏΠΎΡ€Π°ΠΆΠ΅Π½ΠΈΠ΅
            self.steam_pos = random.randrange(0, 5), random.randrange(0, 5) + 300, random.randrange(0, 5)            
            self.loadParticleConfig('special_effects/steam_critic+/fireish.ptf', self.steam_pos)
            self.errorSound.play() # ΠΈΠ³Ρ€Π°Π΅ΠΌ Π·Π²ΡƒΠΊ ошибки
            self.state_info2.hide() # ΡƒΠ±ΠΈΡ€Π°Π΅ΠΌ ΠΏΡ€Π΅Π΄Π΅Π΄ΡƒΡ‰Π΅Π΅ сообщСниС
            self.state_info2 = OnscreenText(text='ΠΏΠ°Π΄Π°Π΅ΠΌ!', pos=(-0.8, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля


    def fountain(self):
        self.state_info2.hide() # ΡƒΠ±ΠΈΡ€Π°Π΅ΠΌ тСкст опасности
        if self.force:
            if self.state != 100:
                self.state += 1
                self.state_info.hide()
                self.state_info = OnscreenText(text='ΠΊΠΎΡ€Π°Π±Π»ΡŒ :' + str(self.state), pos=(0.5, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля

            self.fountain_pos = random.randrange(0, 5), random.randrange(0, 5) + 500, random.randrange(0, 1)    
            self.loadParticleConfig('special_effects/fountain/fountain.ptf', self.fountain_pos)

        else :
            if self.state != 100:
                self.state += 1
                self.state_info.hide()
                self.state_info = OnscreenText(text='ΠΊΠΎΡ€Π°Π±Π»ΡŒ :' + str(self.state), pos=(0.5, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля

            self.fountain_pos = random.randrange(0, 5), random.randrange(0, 5), random.randrange(0, 1)    
            self.loadParticleConfig('special_effects/fountain/fountain.ptf', self.fountain_pos)
        
        
    def black_light(self):
        # Π’Ρ‹ΠΊΠ»ΡŽΡ‡Π΅Π½Ρ‹ΠΉ свСт
        ambientLight = AmbientLight("ambientLight")
        ambientLight.setColor((0, 0, 0, 1))
        directionalLight = DirectionalLight("directionalLight")
        directionalLight.setDirection((-5, -5, -5))
        directionalLight.setColor((1, 1, 1, 1))
        directionalLight.setSpecularColor((1, 1, 1, 1))
        render.setLight(render.attachNewNode(ambientLight))
        render.setLight(render.attachNewNode(directionalLight))

    def weapon_hide(self):
        # Π£Π±Ρ€Π°Ρ‚ΡŒ ΠΎΡ€ΡƒΠΆΠΈΠ΅
        self.hide_weapon = True
        self.weapon.hide()

    def toggleLights(self, lights):
        # Π‘ΠΏΠ΅Ρ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠ΅ освСщСниС
        if self.hide_weapon:
            for light in lights:
                if render.hasLight(light):
                    render.clearLight(light)
                else:
                    render.setLight(light)
            
            self.flash.setPos(self.weapon_pos)
        else:
            return


    def shot(self):
        dt = globalClock.getDt() + 0.5 # CΠΊΠΎΡ€ΠΎΡΡ‚ΡŒ двиТСния
        if not self.hide_weapon : # Ссли ΠΎΡ€ΡƒΠΆΠΈΠ΅ ΡƒΠ±Ρ€Π°Π½ΠΎ Ρ‚ΠΎ ΠΌΡ‹ Π½Π΅ ΠΌΠΎΠΆΠ΅ΠΌ ΡΡ‚Ρ€Π΅Π»ΡΡ‚ΡŒ
            self.shotSound.play() # ΠΈΠ³Ρ€Π°Π΅ΠΌ Π·Π²ΡƒΠΊ выстрСла
            self.bullet.setPos(self.weapon_pos) # ΠŸΡƒΠ»Ρ Π±ΡƒΠ΄Π΅Ρ‚ спавнится Π²Π½ΡƒΡ‚Ρ€ΠΈ ΠΏΡƒΡˆΠΊΠΈ
            self.bullet.setY(self.bullet, -11 * dt) # Π‘Π΄Π²ΠΈΠ³Π°Π΅ΠΌ ΠΏΡƒΠ»ΡŽ Π½Π° ΠΎΠ³Ρ€ΠΎΠΌΠ½ΠΎΠΉ скорости Π²ΠΏΠ΅Ρ€Ρ‘Π΄

    def check_loss(self):
        if self.state == 0: # Ссли ΠΆΠΈΠ·Π½Π΅ΠΉ Ρƒ корабля Π½Π΅ ΠΎΡΡ‚Π°Π»ΠΎΡΡŒ
            self.black_light() # Π²ΠΊΠ»ΡŽΡ‡ΠΈΠΌ Ρ‡Ρ‘Ρ€Π½Ρ‹ΠΉ свСт
            self.weapon_hide() # ΡƒΠ±Π΅Ρ€Ρ‘ΠΌ ΠΎΡ€ΡƒΠΆΠΈΠ΅
            self.info = OnscreenText(text='ΠΏΠΎΡ€Π°ΠΆΠ΅Π½ΠΈΠ΅', style=1, font=self.font,
                                     fg=(1,1,1,1),
                            pos=(-1.3, -0.5), align=TextNode.ALeft, scale=0.3) # напишСм ΠΎ ΠΏΠΎΡ€Π°ΠΆΠ΅Π½ΠΈΠΈ
            self.crackSound.play() # ΠΈΠ³Ρ€Π°Π΅ΠΌ Π·Π²ΡƒΠΊ Π²Π·Ρ€Ρ‹Π²Π°


    def setKey(self, key, value):
        self.keyMap[key] = value # Π”Π΅Π»Π°Π΅ΠΌ ΠΌΠ΅Ρ…aΠ½uΠ·ΠΌ наТатия клавиш.

    def move(self, task):

        ''' Π”Π΅Π»Π°Π΅ΠΌ Ρ„ΡƒΡ†Π½ΠΊΡ†ΠΈΡŽ двиТСния ΠΈΠ³Ρ€ΠΎΠΊΠ° '''

        dt = globalClock.getDt() - .005 # CΠΊΠΎΡ€ΠΎΡΡ‚ΡŒ двиТСния

        # ΠŸΠΎΠ²ΠΎΡ€ΠΎΡ‚ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ Π²Π»Π΅Π²ΠΎ ΠΈ Π²ΠΏΡ€Π°Π²ΠΎ

        if self.keyMap["cam-left"]:
            self.camera.setX(self.camera, -20 * dt) # МСняСм ΠΏΠΎΠ»ΠΎΠΆΠ΅Π½ΠΈΠΊΠ° ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ ΠΏΠΎ икс. Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ получаСтся илюзия ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚Π° ΡƒΠ³Π»Π° Π»ΡƒΡ‡Π°. Но Π½Π° самом Π΄Π΅Π»Π΅ ΠΊΠ°ΠΌΠ΅Ρ€Π° просто пСрСмСщаСтся.
        if self.keyMap["cam-right"]:
            self.camera.setX(self.camera, +20 * dt) # Π’ΠΎΠΆΠ΅ самоС, Ρ‡Ρ‚ΠΎ ΠΈ Π½Π°Π²Π΅Ρ€Ρ…Ρƒ.

        startpos = self.droid.getPos() # Π‘Π΄Π΅Π»Π°Π΅ΠΌ ΡƒΠ΄ΠΎΠ±Π½ΡƒΡŽ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ ΠΈΠ³Ρ€ΠΎΠΊΠ°

        if self.keyMap["left"]:
            self.droid.setH(self.droid.getH() + 300 * dt)
            self.enemy.setY(self.enemy, 1 * dt)
        if self.keyMap["right"]:
            self.droid.setH(self.droid.getH() - 300 * dt)
            self.enemy.setY(self.enemy, -1 * dt)
        if self.keyMap["forward"]:
            self.droid.setY(self.droid, -25 * dt)
            self.enemy.setX(self.enemy, 1 * dt)
            # Π‘Π΄Π΅Π»Π°Π΅ΠΌ ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½ΠΎΠ΅ условиС ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ ΡƒΠ±Ρ€Π°Π½ΠΎ ΠΎΡ€ΡƒΠΆΠΈΠ΅ ΠΈΠ»ΠΈ Π½Π΅Ρ‚
            if not self.hide_weapon:
                self.weapon_pos = self.droid.getX(), self.droid.getY() + 0.7, 3
                self.weapon.setPos(self.weapon_pos) # ОбновляСм ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΏΡƒΡˆΠΊΠΈ
            else:
                self.weapon_pos = self.droid.getX(), self.droid.getY() + 0.7, 3
                self.flash.setPos(self.weapon_pos)


        camvec = self.droid.getPos() - self.camera.getPos() # Π²Π΅ΠΊΡ‚ΠΎΡ€ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹
        camvec.setZ(0) # 0 высота Π²Π΅ΠΊΡ‚ΠΎΡ€Π°
        camdist = camvec.length() # дистанция ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ ΠΎΡ‚ Π΄Ρ€ΠΎΠΈΠ΄Π°
        camvec.normalize() # Π½ΠΎΡ€ΠΌΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ Π²Π΅ΠΊΡ‚ΠΎΡ€ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹
        if camdist > 10.0: # Ссли дистанция ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ большС 10, Ρ‚ΠΎ смСщаСм ΠΊΠ°ΠΌΠ΅Ρ€Ρƒ Π·Π° Π΄Ρ€ΠΎΠΎΠΈΠ΄ΠΎΠΌ
            self.camera.setPos(self.camera.getPos() + camvec * (camdist - 10))
            camdist = 10.0 # Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ дистанция Π±ΡƒΠ΄Π΅Ρ‚ снова 10
        if camdist < 5.0: # Ссли дистагцтя ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ мСньшС 5, Ρ‚ΠΎ...
            self.camera.setPos(self.camera.getPos() - camvec * (5 - camdist)) # сдвигаСм ΠΊΠ°ΠΌΠ΅Ρ€Ρƒ
            camdist = 5.0 # всё обновляСм
            
        self.camera.lookAt(self.floater) # Π²ΠΎΡ‚ ΠΈ пригодился наш floater


        return task.cont # Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌ Π·Π°Π΄Π°Ρ‡Ρƒ

    def addInstructions(self, pos, msg):
        return OnscreenText(text=msg, style=1, fg=(1,1,1,1), font=self.inst_font, pos=(-1.3, pos), align=TextNode.ALeft, scale = .04, shadow=(0,0,0,1)) # Ѐункция ΠΎ Ρ‚ΠΎΠΌ, ΠΊΠ°ΠΊ ΡƒΠΏΡ€Π°Π²Π»ΡΡ‚ΡŒ

    def addTitle(self, text):
        return OnscreenText(text=text, style=1, fg=(1, 1, 1, 1), scale=0.2,
                            parent=base.a2dBottomRight, align=TextNode.ARight,
                            pos=(-0.1, 0.09), shadow=(0, 0, 0, 1), font=self.font) # Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ тСкстового Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ° с ΡˆΡ€ΠΈΡ„Ρ‚ΠΎΠΌ ΠΈ ΠΏΠΎΠ·ΠΈΡ†ΠΈΠ΅ΠΉ
    

droid = DroidShooter() # Π‘ΠΎΠ·Π΄Π°Π΄ΠΈΠΌ экзСмпляр класса нашСй ΠΈΠ³Ρ€Ρ‹
droid.run() # 3апустим ΠΈΠ³Ρ€Ρƒ


# Ρ€Π°Π·Ρ€ΠΎΠ±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ :
# Π“Π»Π°Π²Π½Ρ‹ΠΉ Π°Π²Ρ‚ΠΎΡ€ : ma3rx
# ΠŸΠΎΠΌΠΎΡ‰Π½ΠΈΠΊ : panda3dmastercoder( присоСдСнился ΠΊ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Ρƒ 31 января, 12:??)

Structure(no update!) :

./models :
./models/enemies : enemies.zip
./models/fighter : fighter.zip
./models/player : player.zip
./models/sky : sky.zip
./models/weapon : weapon.zip (234.3 KB)
./models/whishlyflash : whishlyflash.zip
./models/world : Now, download panda3d art from https://www.panda3d.org/download/noversion/art-gallery.zip
Go to the cat-environment folder. In it you will see a millenium falcon folder. Take all the files from it and put it in the directory ./models/world

./fonts : fonts.zip
./shaders : shaders.zip
./sounds : sounds.zip
./special_effects : special_effects.zip
./tex : tex.zip (95.1 KB)

droid.py :

#!/usr/bin/env python
# -*- coding: utf_8 -*-

# Π‘ΠΎΠ·Π΄Π°Π½ΠΎ : 22 число, ΡΠ½Π²Π°Ρ€ΡŒ, 2021 Π³ΠΎΠ΄

# Π˜ΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΡƒΠ΅ΠΌ всС Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹Π΅ инструмСнты
from direct.showbase.ShowBase import ShowBase
from panda3d.core import CollisionTraverser, CollisionNode
from panda3d.core import CollisionHandlerPusher, CollisionSphere, CollisionInvSphere
from panda3d.core import Filename, AmbientLight, DirectionalLight
from panda3d.core import PandaNode, NodePath, Camera, TextNode
from direct.particles.Particles import Particles
from direct.particles.ParticleEffect import ParticleEffect
from panda3d.core import PointLight, Spotlight
from panda3d.core import CollideMask
from panda3d.core import loadPrcFileData
from panda3d.core import *
from direct.gui.OnscreenText import OnscreenText
from direct.gui.OnscreenImage import OnscreenImage
from direct.gui.DirectButton import DirectButton
from direct.gui.DirectSlider import DirectSlider
from direct.actor.Actor import Actor
import random
import sys
import time
import os
import math


VERSION = '3.0.3.1'

settings = ['window-title Droid Game ' +  VERSION,
            'fullscreen 0']
            

loadPrcFileData('', settings[0]) # Π‘Π΄Π΅Π»Π°Π΅ΠΌ Π½Π΅ стандартный Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ (Π²ΠΎΠ·ΠΌΡ‘ΠΌ Π΅Π³ΠΎ ΠΈΠ· ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ settings)
loadPrcFileData('', settings[1]) # Π½Π΅ Π±ΡƒΠ΄Π΅ΠΌ Π΄Π΅Π»Π°Ρ‚ΡŒ полноэкранный Ρ€Π΅ΠΆΠΈΠΌ

# Π‘ΠΎΠ·Π΄Π°Π΄ΠΈΠΌ Π³Π»Π°Π²Π½Ρ‹ΠΉ класс нашСй ΠΈΠ³Ρ€Ρ‹
class DroidShooter(ShowBase):
    def __init__(self):
        ShowBase.__init__(self) # Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ всС сСлфы ΠΈΠ· direct
        self.speed = 1800 # ΡΠΊΠΎΡ€ΠΎΡΡ‚ΡŒ двигатСля
        self.menu() # звпуск мСню
        
    def menu(self):
        
        base.enableParticles() # ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ эффСкт Π΄Ρ‹ΠΌΠ°

        self.win.setClearColor((0, 0, 0, 1)) # Π—Π°ΠΊΡ€Π°ΡˆΠΈΠ²Π°Π΅ΠΌ ΠΏΠΎΠ²Π΅Ρ€Ρ…Π½ΠΎΡΡ‚ΡŒ Ρ‡Ρ‘Ρ€Π½Ρ‹ΠΌ. Π”Π΅Π»ΠΎ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ Π² этом ΠΈΠ³Ρ€ΠΎΠ²ΠΎΠΌ Π΄Π²ΠΈΠΆΠΊΠ΅ ΠΏΠΎΠ²Π΅Ρ€Ρ…Π½ΠΎΡΡ‚ΡŒ Π·Π°ΠΊΡ€Π°ΡˆΠΈΠ²Π°Π΅Ρ‚ΡΡ сСрым.
        self.font = loader.loadFont('./fonts/doom_font.ttf') # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ ΡˆΡ€ΠΈΡ„Ρ‚ ΠΈΠ· ΠΈΠ³Ρ€Ρ‹ doom
        self.inst_font = loader.loadFont('./fonts/arial.ttf') # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ ΡˆΡ€ΠΈΡ„Ρ‚ arial

        self.crackSound = loader.loadMusic('./sounds/crack.wav') # Π·Π²ΡƒΠΊ Π²Π·Ρ€Ρ‹Π²Π° корабля
        self.shotSound = loader.loadMusic('./sounds/shot.wav') # Π·Π²ΡƒΠΊ выстрСла
        self.startSound = loader.loadMusic('./sounds/started.wav') # Π·Π²ΡƒΠΊ запуска
        self.errorSound = loader.loadMusic('./sounds/error.wav') # Π·Π²ΡƒΠΊ запуска
        self.errorSound.setVolume(1) # полная Π³Ρ€ΠΎΠΌΠΊΠΎΡΡ‚ΡŒ Π·Π²ΡƒΠΊΠ°
        self.startSound.setVolume(1) # полная Π³Ρ€ΠΎΠΌΠΊΠΎΡΡ‚ΡŒ Π·Π²ΡƒΠΊΠ°
        self.crackSound.setVolume(1) # полная Π³Ρ€ΠΎΠΌΠΊΠΎΡΡ‚ΡŒ Π·Π²ΡƒΠΊΠ°
        self.shotSound.setVolume(1) # полная Π³Ρ€ΠΎΠΌΠΊΠΎΡΡ‚ΡŒ Π·Π²ΡƒΠΊΠ°
        self.startSound.play() # ΠΈΠ³Ρ€Π°Π΅ΠΌ Π·Π²ΡƒΠΊ запуска ΠΈΠ³Ρ€Ρ‹

        self.button_start = DirectButton(pos=(0.7, 0, 0), text="CTAPT",
                                   scale=.3, pad=(.2, .2),
                                   command=self.load_game) # ΠΊΠ½ΠΎΠΏΠΊΠ° запуска ΠΈΠ³Ρ€Ρ‹

        self.slider_sun = DirectSlider(pos=(0.1, 0, .75), scale=0.8, value=0.5,
                                    command=self.set_sun_interval)


        self.title = self.addTitle("Droid game " + VERSION)
        
        # НапСчатаСм ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅
        self.inst1 = self.addInstructions(0.95, u"[ESC]: Π’Ρ‹Ρ…ΠΎΠ΄")
        self.inst2 = self.addInstructions(0.90, u"[Left Arrow]: ΠŸΠΎΠ²ΠΎΡ€ΠΎΡ‚ Π΄Ρ€ΠΎΠΈΠ΄Π° Π² Π»Π΅Π²ΠΎ")
        self.inst3 = self.addInstructions(0.85, u"[Right Arrow]: ΠŸΠΎΠ²ΠΎΡ€ΠΎΡ‚ Π΄Ρ€ΠΎΠΈΠ΄Π° Π² ΠΏΡ€Π°Π²ΠΎ")
        self.inst4 = self.addInstructions(0.80, u"[Up Arrow]: Π’ΠΏΠ΅Ρ€Π΅Π΄")
        self.inst5 = self.addInstructions(0.75, u"[a]: ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ Π² ΠΏΡ€Π°Π²ΠΎ")
        self.inst6 = self.addInstructions(0.70, u"[d]: ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ Π² Π»Π΅Π²ΠΎ")
        self.inst7 = self.addInstructions(0.65, u"[Left Arrow + Up arrow]: ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚ Π΄Ρ€ΠΎΠΈΠ΄Π° Π² Π»Π΅Π²ΠΎ ΠΈ Π²ΠΏΠ΅Ρ€Ρ‘Π΄")
        self.inst8 = self.addInstructions(0.60, u"[Right Arrow + Up arrow]: ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚ Π΄Ρ€ΠΎΠΈΠ΄Π° Π² ΠΏΡ€Π°Π²ΠΎ ΠΈ Π²ΠΏΠ΅Ρ€Ρ‘Π΄")
        self.inst9 = self.addInstructions(0.55, u"[a + Up arrow]: ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ Π² ΠΏΡ€Π°Π²ΠΎ ΠΈ Π²ΠΏΠ΅Ρ€Ρ‘Π΄")
        self.inst10 = self.addInstructions(0.50, u"[d + Up arrow]: ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ Π² Π»Π΅Π²ΠΎ ΠΈ Π²ΠΏΠ΅Ρ€Ρ‘Π΄")
        self.inst11 = self.addInstructions(0.45, u"[space]: ΡΡ‚Ρ€Π΅Π»ΡŒΠ±Π°")
        self.inst12 = self.addInstructions(0.40, u"[s]: Π΄ΠΎΡΡ‚Π°Ρ‚ΡŒ Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊ")
        self.inst13 = self.addInstructions(0.35, u"[w]: ΡƒΠ±Ρ€Π°Ρ‚ΡŒ ΠΎΡ€ΡƒΠΆΠΈΠ΅")
        self.inst14 = self.addInstructions(0.30, u"[f]: ΠΏΠΎΠ»Π½Ρ‹ΠΉ Ρ€Π°Π·Π³ΠΎΠ½(ОПАБНО!)")
        self.inst15 = self.addInstructions(0.25, u"[0]: ΠΏΠΎΠΆΠ°Ρ€ΠΎΡ‚ΡƒΡˆΠΈΡ‚Π΅Π»ΡŒΠ½Π°Ρ систСма")

        self.accept("escape", sys.exit) # ΠŸΡ€ΠΈ Π½Π°ΠΆΠ°Ρ‚ΠΈΠΈ клавиши Esc Π²Ρ‹Ρ…ΠΎΠ΄ΠΈΠΌ.

    def set_sun_interval(self):
        self.sun_interval = self.slider_sun.guiItem.getValue() * 100 # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ слайдСрноС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΡƒΠΌΠ½ΠΎΠΆΠ΅Π½ΠΎΠ΅ Π½Π° 500, Π΄Π° Ρ‚Ρ€Π°Ρ‡Ρƒ ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΡŽ Π½ΠΎ ΠΌΠ½Π΅ каТСтся ΠΌΠ½ΠΎΠ³ΠΈΠΌ ΠΏΠ»Π΅Π²Π°Ρ‚ΡŒ Π½Π° ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΡŽ мСню, ΠΈΠ±ΠΎ Ρ‚Π°ΠΊΠΎΠ³ΠΎ понятия просто Π½Π΅Ρ‚Ρƒ :)
        

    def load_game(self):
        self.button_start.hide() # ΡƒΠ΄Π°Π»ΠΈΠΌ ΠΊΠ½ΠΎΠΏΠΊΡƒ старта
        self.title.hide() # ΡƒΠ΄Π°Π»ΠΈΠΌ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ ΠΈΠ³Ρ€Ρ‹
        # ΡƒΠ΄Π°Π»ΠΈΠΌ ΠΊΠ½ΠΎΠΏΠΊΠΈ управлСния
        self.inst1.hide()
        self.inst2.hide()
        self.inst3.hide()
        self.inst4.hide()
        self.inst5.hide()
        self.inst6.hide()
        self.inst7.hide()
        self.inst8.hide()
        self.inst9.hide()
        self.inst10.hide()
        self.inst11.hide()
        self.inst12.hide()
        self.inst13.hide()
        self.inst14.hide()
        self.inst15.hide()
        self.slider_sun.hide() # удаляСм слайдСр солнца
        
        self.keyMap = {
            "left": 0, "right": 0, "forward": 0, "cam-left": 0, "cam-right": 0} # Π‘ΠΎΠ·Π΄Π°Π΄ΠΈΠΌ ΡΠ»ΠΎΠ²Π°Ρ€ΡŒ ΠΊΠ½ΠΎΠΏΠΎΠΊ, ΠΏΠΎ ΠΈΡ… Π½Π°ΠΆΠ°Ρ‚ΠΈΡŽ        

        # РисуСм Π·Π²Ρ‘Π·Π΄Ρ‹

        self.sky = loader.loadModel("./models/sky/solar_sky_sphere") # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ модСль космоса(это сфСра)

        self.sky_tex = loader.loadTexture("./tex/stars_1k_tex.jpg") # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ тСкстуру
        self.sky.setTexture(self.sky_tex, 1) # Π·Π°Ρ€Π΅Π½Π΄Π΅Ρ€ΠΈΠΌ тСкстуру Π½Π° Π½Π΅Π±ΠΎ
        self.sky.reparentTo(render) # ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ Π½Π΅Π±ΠΎ
        self.sky.setScale(40000) # Ρ€Π°ΡΡˆΠΈΡ€ΠΈΠΌ Π½Π΅Π±ΠΎ Π΄ΠΎ максимальной Π²Π΅Π»ΠΈΡ‡ΠΈΠ½Ρ‹ panda3d

        self.environ = loader.loadModel("models/world/falcon.egg") # Π—Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ ΡƒΠΆΠ΅ созданный Π² blender ΠΌΠΈΡ€.
        self.environ.reparentTo(render) # Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ модСль ΠΌΠΈΡ€Π° Π² ΠΎΠΊΠ½ΠΎ

        droidStartPos = (-1, 0, 1.5 ) # Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ ΡΡ‚Π°Ρ€Ρ‚ΠΎΠ²ΡƒΡŽ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π² ΠΌΠΈΡ€Π΅.
        enemyStartPos = (-6, 1, 0.5) # Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ°-Π΄Ρ€ΠΎΠΈΠ΄Π°.
        self.droid = Actor("models/player/seeker.egg") # Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ модСль ΠΈΠ³Ρ€ΠΎΠΊΠ° (созданная Π² blender)
        self.enemy = Actor("models/enemies/r2d2/r2d2.egg") # Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ модСль ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ° (созданная Π² blender)
        self.droid.reparentTo(render) # ΠŸΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Π΅ΠΌ модСль ΠΈΠ³Ρ€ΠΎΠΊΠ° Π² наш ΠΌΠΈΡ€.
        self.enemy.reparentTo(render) # ΠŸΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Π΅ΠΌ модСль ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ° Π² наш ΠΌΠΈΡ€.
        self.droid.setScale(1) # Π”Π΅Π»Π°Π΅ΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ€ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π½Π° 1
        self.enemy.setScale(1) # Π”Π΅Π»Π°Π΅ΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ€ ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ° Π½Π° 1
        self.droid.setPos(droidStartPos) # Π‘Ρ‚Π°Π²ΠΈΠΌ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π½Π° Ρ€Π°Π½Π΅Π΅ ΡΠΎΠ·Π΄Π°Π½ΡƒΡŽ Π½Π°ΠΌΠΈ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ
        self.enemy.setPos(enemyStartPos) # Π‘Ρ‚Π°Π²ΠΈΠΌ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ° Π½Π° Ρ€Π°Π½Π΅Π΅ ΡΠΎΠ·Π΄Π°Π½ΡƒΡŽ Π½Π°ΠΌΠΈ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ

        self.weapon = Actor('models/weapon/lightsaber.egg') # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ ΠΎΡ€ΡƒΠΆΠΈΠ΅
        self.bullet = Actor('models/weapon/bullet/bullet.egg.pz') # Π—Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ ΠΏΡƒΠ»ΡŽ
        self.flash = Actor('models/whishlyflash/handlamp.egg') # Π—Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊ
               
        self.weapon.reparentTo(render) # пСрСмСстим ΠΎΡ€ΡƒΠΆΠΈΠ΅ Π² наш ΠΌΠΈΡ€
        self.bullet.reparentTo(render) # пСрСмСстим ΠΏΡƒΠ»ΡŽ Π² ΠΌΠΈΡ€ Π½ΠΎ появится ΠΎΠ½Π° сама Π½Π΅ скоро
        self.flash.reparentTo(render) # пСрСмСстим Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊ Π² наш ΠΌΠΈΡ€
        self.weapon.setScale(.5) # Π·Π°Π΄Π°Π΄ΠΈΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ€ ΠΏΡƒΡˆΠΊΠΈ
        self.bullet.setScale(.5) # Π·Π°Π΄Π°Π΄ΠΈΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ€ ΠΏΡƒΠ»ΠΈ
        self.flash.setScale(.5) # Π·Π°Π΄Π°Π΄ΠΈΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ€ Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊΠ°

        # враТСский ΠΈΡΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»ΡŒ
        self.fighter = Actor('models/fighter/fighter.egg') # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ ΠΌΠΎΠ΄Π΅Π»ΡŒΠΊΡƒ истрСбитСля
        self.fighter.reparentTo(render) # ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ ΠΈΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»ΡŒ
        self.fighter.setPos(0, 90, 0) # позиция истрСбитСля
                

        self.weapon_pos = self.droid.getX(), self.droid.getY() + 0.7, 1 # ΠŸΠΎΠ·ΠΈΡ†ΠΈΡ ΠΏΡƒΡˆΠΊΠΈ
        
        self.weapon.setPos(self.weapon_pos) # ΠŸΠΎΠΌΠ΅ΡΡ‚ΠΈΠΌ ΠΎΡ€ΡƒΠΆΠΈΠ΅ Ρ‡ΡƒΡ‚ΡŒ Π²Ρ‹ΡˆΠ΅ ΠΈΠ³Ρ€ΠΎΠΊΠ°
        
        
        self.spotlight = camera.attachNewNode(Spotlight("spotlight")) # ΠšΠΎΠ½Ρ„ΠΈΠ³ΠΈ Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊΠ°
        self.spotlight.node().setColor((.3, .3, .3, 1))
        self.spotlight.node().setSpecularColor((0, 0, 0, 1))

        self.floater = NodePath(PandaNode("floater")) 
        self.floater.reparentTo(self.droid)
        self.floater.setZ(2.0)

        self.accept("escape", sys.exit) # ΠŸΡ€ΠΈ Π½Π°ΠΆΠ°Ρ‚ΠΈΠΈ клавиши Esc Π²Ρ‹Ρ…ΠΎΠ΄ΠΈΠΌ.
        
        self.accept("arrow_left", self.setKey, ["left", True]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ Π²Π»Π΅Π²ΠΎ - ΠΏΠΎΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π²Π»Π΅Π²ΠΎ
        self.accept("arrow_right", self.setKey, ["right", True]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ Π²ΠΏΡ€Π°Π²ΠΎ - ΠΏΠΎΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π²ΠΏΡ€Π°Π²ΠΎ
        self.accept("arrow_up", self.setKey, ["forward", True]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ Π²ΠΏΠ΅Ρ€Ρ‘Π΄ - ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄
        self.accept("a", self.setKey, ["cam-left", True]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ a - Ρ€Π°Π·Π²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΊΠ°ΠΌΠ΅Ρ€Ρƒ Π²ΠΎΠΊΡ€ΡƒΠ³ нашСй модСльки
        self.accept("d", self.setKey, ["cam-right", True]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ s - Ρ€Π°Π·Π²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΊΠ°ΠΌΠ΅Ρ€Ρƒ Π²ΠΎΠΊΡ€ΡƒΠ³ нашСй модСльки
        self.accept("arrow_left-up", self.setKey, ["left", False]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ Π²Π²Π΅Ρ€Ρ…+Π²Π»Π΅Π²ΠΎ - ΠΏΠΎΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π²Π»Π΅Π²ΠΎ ΠΈ ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄
        self.accept("arrow_right-up", self.setKey, ["right", False]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ Π²Π²Π΅Ρ€Ρ…+ΠΏΡ€Π°Π²ΠΎ - ΠΏΠΎΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π²ΠΏΡ€Π°Π²ΠΎ ΠΈ ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄
        self.accept("arrow_up-up", self.setKey, ["forward", False]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ Π²Π²Π΅Ρ€Ρ…+Π²Π²Π΅Ρ€ΡŠ - ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄ ΠΈ ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄
        self.accept("a-up", self.setKey, ["cam-left", False]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ a+Π²ΠΏΠ΅Ρ€Ρ‘Π΄ - ΠΏΠΎΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΊΠ°ΠΌΠ΅Ρ€Ρƒ Π²Π»Π΅Π²ΠΎ ΠΈ ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄
        self.accept("d-up", self.setKey, ["cam-right", False]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ s+Π²ΠΏΠ΅Ρ€Ρ‘Π΄ - ΠΏΠΎΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΊΠ°ΠΌΠ΅Ρ€Ρƒ Π²ΠΏΡ€Π°Π²ΠΎ ΠΈ ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄

        self.accept("space", self.shot) # ΠΏΡ€ΠΈ ΠΏΡ€ΠΎΠ±Π΅Π»Π΅ стрСляСм
        self.accept("s", self.toggleLights, [[self.spotlight]]) # Π’ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊ
        self.accept("w", self.weapon_hide) # ΠΏΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ w - ΡƒΠ±Π΅Ρ€Ρ‘ΠΌ ΠΎΡ€ΡƒΠΆΠΈΠ΅.

        base.enableParticles() # Π’ΠΊΠ»ΡŽΡ‡Π°Π΅ΠΌ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ Π΄Ρ‹ΠΌΠ°
        self.t = loader.loadModel("models/weapon/lightsaber.egg") # Π—Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ Π΅Ρ‰Ρ‘ ΠΎΡ€ΡƒΠΆΠΈΠ΅
        self.t.reparentTo(render) # ΠŸΠ΅Ρ€Π΅ΠΌΠ΅ΡΡ‚ΠΈΠΌ ΠΎΡ€ΡƒΠΆΠΈΠ΅ Π² наш ΠΌΠΈΡ€
        self.p = ParticleEffect() # Π’ΠΊΠ»ΡŽΡ‡ΠΈΠΌ эффСкт Π΄Ρ‹ΠΌΠ°
        self.accept('f', self.particle_start) # ΠΏΡ€ΠΈ Π½Π°ΠΆΠ°Ρ‚ΠΈΠΈ f(ΠΎΡ‚ force) -  Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ Ρ„Π°ΠΉΠ» Π΄Ρ‹ΠΌΠ° ΠΈ пСрСмСстим Π² ΠΊΠΎΠ½Ρ„ΠΈΠ³ Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΈΠΌΠ΅Π½Π½ΠΎ эта анимация стала ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ΠΌ Π΄Ρ‹ΠΌΠ°
        self.accept('0', self.fountain) # ΠΏΡ€ΠΈ  Π½Π°ΠΆΠ°Ρ‚ΠΈΠΈ ΠΊΠ½ΠΎΠΏΠΎΠΊ f+o(fountain) Π²ΠΊΠ»ΡŽΡ‡ΠΈΠΌ ΠΏΠΎΠΆΠ°Ρ€ΠΎΡ‚ΡƒΡˆΠΈΡ‚Π΅Π»ΡŒΠ½ΡƒΡŽ систСму

        taskMgr.add(self.move, "moveTask") # ДобавляСм Π·Π°Π΄Π°Ρ‡Ρƒ Π² наш Π΄Π²ΠΈΠΆΠΎΠΊ

        self.isMoving = False # Π‘Ρ‚Π°Π²ΠΈΠΌ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ isMoving Π½Π° False(Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΌΠ΅Π½ΡΡ‚ΡŒ это Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅) Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΈΠ³Ρ€ΠΎΠΊ ΠΈΠ·Π½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎ стоял.
        # Π”Π΅Π»Π°Π΅ΠΌ Ρ‚Π°ΠΊ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ свСт Π±Ρ‹Π» ΠΈΠ·Π½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎ Π²Ρ‹ΠΊΠ»ΡŽΡ‡Π΅Π½.
        self.disableMouse() # ΠžΡ‚ΠΊΠ»ΡŽΡ‡Π°Π΅ΠΌ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π΅Π½ΠΈΠ΅ Ρ‡Π΅Ρ€Π΅Π· ΠΌΡ‹ΡˆΠΊΡƒ
        self.camera.setPos(self.droid.getX(), self.droid.getY() + 1, 3) # Π‘Ρ‚Π°Π²ΠΈΠΌ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ Ρ‡ΡƒΡ‚ΡŒ большС ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ ΠΈΠ³Ρ€ΠΎΠΊΠ°

        self.black_light() # Π‘Π΄Π΅Π»Π°Π΅ΠΌ Π²Ρ‹ΠΊΠ»ΡŽΡ‡Π΅Π½Π½Ρ‹ΠΉ свСт

        self.state = 100 # БостояниС корабля
        self.state_info = OnscreenText(text='ΠΊΠΎΡ€Π°Π±Π»ΡŒ :' + str(self.state), pos=(0.5, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля
                
        self.check_loss() # ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ ΠΏΠΎΡ€Π°ΠΆΠ΅Π½ΠΈΠ΅
        self.hide_weapon = False # ΠŸΠΎΡΡ‚Π°Π²ΠΈΠΌ, Ρ‡Ρ‚ΠΎ ΠΎΡ€ΡƒΠΆΠΈΠ΅ Π½Π΅ ΡƒΠ±Ρ€Π°Π½ΠΎ
        self.steam_pos = random.randrange(0, 5), random.randrange(0, 5), random.randrange(0, 5)
        self.fountain_pos = random.randrange(0, 5), random.randrange(0, 5), random.randrange(0, 1)

        self.motor_pos1 = 25.238849639892578, 8.962211608886719, 1.5 # позиция ΠΏΠ΅Ρ€Π²ΠΎΠ³ΠΎ ΠΌΠΎΡ‚ΠΎΡ€Π°
        self.motor_pos2 = -20.676218032836914, 10.55816650390625, 1.5 # позиция Π²Ρ‚ΠΎΡ€ΠΎΠ³ΠΎ ΠΌΠΎΡ‚ΠΎΡ€Π°

        self.motor1 = self.loadParticleConfig('special_effects/steam_critic+/fireish.ptf', self.motor_pos1) # ΠΌΠΎΡ‚ΠΎΡ€ 1
        self.motor2 = self.loadParticleConfig('special_effects/steam_critic+/fireish.ptf', self.motor_pos2) # ΠΌΠΎΡ‚ΠΎΡ€ 2

        self.state_info2 = OnscreenText(text='', pos=(-0.8, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля

        self.force = False # ΠŸΠΎΡΡ‚Π°Π²ΠΈΠΌ, Ρ‡Ρ‚ΠΎ Π½Π΅ Ρ€Π°Π·Π³ΠΎΠ½ΡΠ»ΠΈΡΡŒ

        # ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ ΠΊΠΎΠ»Π»ΠΈΠ·ΠΈΠΈ
        
        self.cTrav = CollisionTraverser()
        pusher = CollisionHandlerPusher()
        
        environCenter = self.environ.getBounds().getCenter()
        environRad = self.environ.getBounds().getRadius()
        cNode = CollisionNode("environment")
        cNode.addSolid(CollisionInvSphere(environCenter, environRad))
        environC = self.environ.attachNewNode(cNode)
        
        droidCenter = self.droid.getBounds().getCenter()
        droidRad = self.droid.getBounds().getRadius()
        cNode = CollisionNode("droid")
        cNode.addSolid(CollisionSphere(droidCenter, droidRad))
        droidC = self.droid.attachNewNode(cNode)
        
        pusher.addCollider(droidC, self.droid)
        self.cTrav.addCollider(droidC, pusher)
        
        enemyCenter = self.enemy.getBounds().getCenter()
        enemyRad = self.enemy.getBounds().getRadius()
        cNode = CollisionNode("enemy")
        cNode.addSolid(CollisionSphere(enemyCenter, enemyRad))
        enemyC = self.enemy.attachNewNode(cNode)

        pusher.addCollider(enemyC, self.enemy)
        self.cTrav.addCollider(enemyC, pusher)

        fighterCenter = self.fighter.getBounds().getCenter()
        fighterRad = self.fighter.getBounds().getRadius()
        cNode = CollisionNode("fighter")
        cNode.addSolid(CollisionSphere(fighterCenter, fighterRad))
        fighterC = self.fighter.attachNewNode(cNode)

        bulletCenter = self.bullet.getBounds().getCenter()
        bulletRad = self.bullet.getBounds().getRadius()
        cNode = CollisionNode("bullet")
        cNode.addSolid(CollisionSphere(bulletCenter, bulletRad))
        bulletC = self.bullet.attachNewNode(cNode)

        bulletCenter = self.bullet.getBounds().getCenter()
        bulletRad = self.bullet.getBounds().getRadius()
        cNode = CollisionNode("bullet")
        cNode.addSolid(CollisionSphere(bulletCenter, bulletRad))
        bulletC = self.bullet.attachNewNode(cNode)
        
        pusher.addCollider(bulletC, self.bullet)
        self.cTrav.addCollider(bulletC, pusher)

        # солнцС(новая ΠΌΠ΅Ρ…Π°Π½ΠΈΠΊΠ° освСщСния)
        sun = DirectionalLight("sun")
        sun.set_color_temperature(6000)
        sun.color = sun.color * 4
        sun_path = render.attach_new_node(sun)
        sun_path.set_pos(10, -10, -10)
        sun_path.look_at(0, 0, 0)
        sun_path.hprInterval(self.sun_interval, (sun_path.get_h(), sun_path.get_p() - 360, sun_path.get_r()), bakeInStart=True).loop()
        render.set_light(sun_path)

    def fight_force(self):
        # сдвиТСниС истрСбитСля Π·Π° нашим ΠΊΠΎΡ€Π°Π±Π»Ρ‘ΠΌ(ΠΎΡ‡Π΅Π½ΡŒ простым способом я сдСлал Ρ‚Π°ΠΊ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΈΡΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»ΡŒ Π·Π°ΠΆΠΈΠΌΠ°Π» нас(Π»Π΅Ρ‚Π°Π» Π² нашСм ΠΊΠ²Π°Π΄Ρ€Π°Ρ‚Π΅)) ΠΈ Π·Π°ΠΆΠΈΠΌΠ°Π΅Ρ‚ ΠΎΠ½ Ρ€Π΅Π°Π»ΡŒΠ½ΠΎ, сблиТая ΠΊ Π½Π°ΠΌ свой ΠΊΠ²Π°Π΄Ρ€Π°Ρ‚
        self.fighter.setY(self.fighter.getY() - self.speed) 
        self.fighter.setX(self.fighter.getX() - 10)    

        print(self.fighter.getX())


    def loadParticleConfig(self, filename, pos):
        self.p.cleanup()
        self.p = ParticleEffect()
        self.p.loadConfig(Filename(filename))

        self.p.start(self.t)
        self.p.setPos(pos)

    def particle_start(self):
        self.force = True # ΠŸΠΎΡΡ‚Π°Π²ΠΈΠΌ, Ρ‡Ρ‚ΠΎ ΠΌΡ‹ ΡƒΠΆΠ΅ Ρ€Π°Π·Π³ΠΎΠ½ΡΠ»ΠΈΡΡŒ
        # ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Π΅ΠΌ всС ΠΎΠ±ΡŒΠ΅ΠΊΡ‚Ρ‹ Π·Π° ΠΊΠΎΡ€Π°Π±Π»Ρ‘ΠΌ
        self.environ.setY(self.environ.getY() - self.speed) # нСсёмся Π²ΠΏΡ€Π°Π²ΠΎ
        self.droid.setY(self.droid.getY() - self.speed) # сдвигаСм Π΄Ρ€ΠΎΠΈΠ΄Π° Π·Π° ΠΊΠΎΡ€Π°Π±Π»Ρ‘ΠΌ
        self.enemy.setY(self.enemy.getY() - self.speed) # сдфигаСм ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ° Π·Π° ΠΊΠΎΡ€Π°Π±Π»Ρ‘ΠΌ
        self.weapon.setY(self.weapon.getY() - self.speed) # ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Π΅ΠΌ ΠΎΡ€ΡƒΠΆΠΈΠ΅
        self.flash.setY(self.flash.getY() - self.speed) # ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Π΅ΠΌ Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊ
        self.fight_force()

        self.state -= 1 # сдСлаСм мСньшС ΠΎΡ‡ΠΊΠΎΠ²
        self.state_info.hide() # ΡƒΠ΄Π°Π»ΠΈΠΌ тСкстовыС ΠΎΡ‡ΠΊΠΈ
        
        if self.state != 10 and self.state > 10:
            self.state_info.hide() # ΡƒΠ±ΠΈΡ€Π°Π΅ΠΌ ΠΏΡ€Π΅Π΄Π΅Π΄ΡƒΡ‰Π΅Π΅ сообщСниС ΠΎ Тизнях корабля
            self.state_info = OnscreenText(text='ΠΊΠΎΡ€Π°Π±Π»ΡŒ :' + str(self.state), pos=(0.5, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля
            self.check_loss() # провСряСм ΠΏΠΎΡ€Π°ΠΆΠ΅Π½ΠΈΠ΅
            self.steam_pos = random.randrange(0, 5), random.randrange(0, 5) + 300, random.randrange(0, 5)
            self.loadParticleConfig('special_effects/steam/steam.ptf', self.steam_pos)
            self.errorSound.play() # ΠΈΠ³Ρ€Π°Π΅ΠΌ Π·Π²ΡƒΠΊ ошибки
            self.state_info2.hide() # ΡƒΠ±ΠΈΡ€Π°Π΅ΠΌ ΠΏΡ€Π΅Π΄Π΅Π΄ΡƒΡ‰Π΅Π΅ сообщСниС
            self.state_info2 = OnscreenText(text='Π΄Π²ΠΈΠ³Π°Ρ‚Π΅Π»ΡŒ нСисправСн', pos=(-0.8, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля
        else:
            self.state_info = OnscreenText(text='ΠΊΠΎΡ€Π°Π±Π»ΡŒ :' + str(self.state), pos=(0.5, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля
            self.check_loss() # провСряСм ΠΏΠΎΡ€Π°ΠΆΠ΅Π½ΠΈΠ΅
            self.steam_pos = random.randrange(0, 5), random.randrange(0, 5) + 300, random.randrange(0, 5)
            self.loadParticleConfig('special_effects/steam_critic/steam.ptf', self.steam_pos)
            self.errorSound.play() # ΠΈΠ³Ρ€Π°Π΅ΠΌ Π·Π²ΡƒΠΊ ошибки
            self.state_info2.hide()  # ΡƒΠ±ΠΈΡ€Π°Π΅ΠΌ ΠΏΡ€Π΅Π΄Π΅Π΄ΡƒΡ‰Π΅Π΅ сообщСниС
            self.state_info2 = OnscreenText(text='критичСскоС состояниС', pos=(-0.8, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля
    
        if self.state < 10:
            self.state_info.hide()
            self.state_info = OnscreenText(text='ΠΊΠΎΡ€Π°Π±Π»ΡŒ :' + str(self.state), pos=(0.5, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля
            self.check_loss() # провСряСм ΠΏΠΎΡ€Π°ΠΆΠ΅Π½ΠΈΠ΅
            self.steam_pos = random.randrange(0, 5), random.randrange(0, 5) + 300, random.randrange(0, 5)            
            self.loadParticleConfig('special_effects/steam_critic+/fireish.ptf', self.steam_pos)
            self.errorSound.play() # ΠΈΠ³Ρ€Π°Π΅ΠΌ Π·Π²ΡƒΠΊ ошибки
            self.state_info2.hide() # ΡƒΠ±ΠΈΡ€Π°Π΅ΠΌ ΠΏΡ€Π΅Π΄Π΅Π΄ΡƒΡ‰Π΅Π΅ сообщСниС
            self.state_info2 = OnscreenText(text='ΠΏΠ°Π΄Π°Π΅ΠΌ!', pos=(-0.8, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля


    def fountain(self):
        self.state_info2.hide() # ΡƒΠ±ΠΈΡ€Π°Π΅ΠΌ тСкст опасности
        if self.force:
            if self.state != 100:
                self.state += 1
                self.state_info.hide()
                self.state_info = OnscreenText(text='ΠΊΠΎΡ€Π°Π±Π»ΡŒ :' + str(self.state), pos=(0.5, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля

            self.fountain_pos = random.randrange(0, 5), random.randrange(0, 5) + 500, random.randrange(0, 1)    
            self.loadParticleConfig('special_effects/fountain/fountain.ptf', self.fountain_pos)

        else :
            if self.state != 100:
                self.state += 1
                self.state_info.hide()
                self.state_info = OnscreenText(text='ΠΊΠΎΡ€Π°Π±Π»ΡŒ :' + str(self.state), pos=(0.5, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля

            self.fountain_pos = random.randrange(0, 5), random.randrange(0, 5), random.randrange(0, 1)    
            self.loadParticleConfig('special_effects/fountain/fountain.ptf', self.fountain_pos)
        
        
    def black_light(self):
        # Π’Ρ‹ΠΊΠ»ΡŽΡ‡Π΅Π½Ρ‹ΠΉ свСт
        ambientLight = AmbientLight("ambientLight")
        ambientLight.setColor((0, 0, 0, 1))
        directionalLight = DirectionalLight("directionalLight")
        directionalLight.setDirection((-5, -5, -5))
        directionalLight.setColor((1, 1, 1, 1))
        directionalLight.setSpecularColor((1, 1, 1, 1))
        render.setLight(render.attachNewNode(ambientLight))
        render.setLight(render.attachNewNode(directionalLight))

    def weapon_hide(self):
        # Π£Π±Ρ€Π°Ρ‚ΡŒ ΠΎΡ€ΡƒΠΆΠΈΠ΅
        self.hide_weapon = True
        self.weapon.hide()

    def toggleLights(self, lights):
        # Π‘ΠΏΠ΅Ρ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠ΅ освСщСниС
        if self.hide_weapon:
            for light in lights:
                if render.hasLight(light):
                    render.clearLight(light)
                else:
                    render.setLight(light)
            
            self.flash.setPos(self.weapon_pos)
        else:
            return


    def shot(self):
        dt = globalClock.getDt() + 0.5 # CΠΊΠΎΡ€ΠΎΡΡ‚ΡŒ двиТСния
        if not self.hide_weapon : # Ссли ΠΎΡ€ΡƒΠΆΠΈΠ΅ ΡƒΠ±Ρ€Π°Π½ΠΎ Ρ‚ΠΎ ΠΌΡ‹ Π½Π΅ ΠΌΠΎΠΆΠ΅ΠΌ ΡΡ‚Ρ€Π΅Π»ΡΡ‚ΡŒ
            self.shotSound.play() # ΠΈΠ³Ρ€Π°Π΅ΠΌ Π·Π²ΡƒΠΊ выстрСла
            self.bullet.setPos(self.weapon_pos) # ΠŸΡƒΠ»Ρ Π±ΡƒΠ΄Π΅Ρ‚ спавнится Π²Π½ΡƒΡ‚Ρ€ΠΈ ΠΏΡƒΡˆΠΊΠΈ
            self.bullet.setY(self.bullet, -11 * dt) # Π‘Π΄Π²ΠΈΠ³Π°Π΅ΠΌ ΠΏΡƒΠ»ΡŽ Π½Π° ΠΎΠ³Ρ€ΠΎΠΌΠ½ΠΎΠΉ скорости Π²ΠΏΠ΅Ρ€Ρ‘Π΄

    def check_loss(self):
        if self.state == 0: # Ссли ΠΆΠΈΠ·Π½Π΅ΠΉ Ρƒ корабля Π½Π΅ ΠΎΡΡ‚Π°Π»ΠΎΡΡŒ
            self.black_light() # Π²ΠΊΠ»ΡŽΡ‡ΠΈΠΌ Ρ‡Ρ‘Ρ€Π½Ρ‹ΠΉ свСт
            self.weapon_hide() # ΡƒΠ±Π΅Ρ€Ρ‘ΠΌ ΠΎΡ€ΡƒΠΆΠΈΠ΅
            self.info = OnscreenText(text='ΠΏΠΎΡ€Π°ΠΆΠ΅Π½ΠΈΠ΅', style=1, font=self.font,
                                     fg=(1,1,1,1),
                            pos=(-1.3, -0.5), align=TextNode.ALeft, scale=0.3) # напишСм ΠΎ ΠΏΠΎΡ€Π°ΠΆΠ΅Π½ΠΈΠΈ
            self.crackSound.play() # ΠΈΠ³Ρ€Π°Π΅ΠΌ Π·Π²ΡƒΠΊ Π²Π·Ρ€Ρ‹Π²Π°


    def setKey(self, key, value):
        self.keyMap[key] = value # Π”Π΅Π»Π°Π΅ΠΌ ΠΌΠ΅Ρ…aΠ½uΠ·ΠΌ наТатия клавиш.

    def move(self, task):

        ''' Π”Π΅Π»Π°Π΅ΠΌ Ρ„ΡƒΡ†Π½ΠΊΡ†ΠΈΡŽ двиТСния ΠΈΠ³Ρ€ΠΎΠΊΠ° '''

        dt = globalClock.getDt() - .005 # CΠΊΠΎΡ€ΠΎΡΡ‚ΡŒ двиТСния

        # ΠŸΠΎΠ²ΠΎΡ€ΠΎΡ‚ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ Π²Π»Π΅Π²ΠΎ ΠΈ Π²ΠΏΡ€Π°Π²ΠΎ

        if self.keyMap["cam-left"]:
            self.camera.setX(self.camera, -20 * dt) # МСняСм ΠΏΠΎΠ»ΠΎΠΆΠ΅Π½ΠΈΠΊΠ° ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ ΠΏΠΎ икс. Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ получаСтся илюзия ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚Π° ΡƒΠ³Π»Π° Π»ΡƒΡ‡Π°. Но Π½Π° самом Π΄Π΅Π»Π΅ ΠΊΠ°ΠΌΠ΅Ρ€Π° просто пСрСмСщаСтся.
        if self.keyMap["cam-right"]:
            self.camera.setX(self.camera, +20 * dt) # Π’ΠΎΠΆΠ΅ самоС, Ρ‡Ρ‚ΠΎ ΠΈ Π½Π°Π²Π΅Ρ€Ρ…Ρƒ.

        startpos = self.droid.getPos() # Π‘Π΄Π΅Π»Π°Π΅ΠΌ ΡƒΠ΄ΠΎΠ±Π½ΡƒΡŽ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ ΠΈΠ³Ρ€ΠΎΠΊΠ°

        if self.keyMap["left"]:
            self.droid.setH(self.droid.getH() + 300 * dt)
            self.enemy.setY(self.enemy, 1 * dt)
        if self.keyMap["right"]:
            self.droid.setH(self.droid.getH() - 300 * dt)
            self.enemy.setY(self.enemy, -1 * dt)
        if self.keyMap["forward"]:
            self.droid.setY(self.droid, -25 * dt)
            self.enemy.setX(self.enemy, 1 * dt)
            # Π‘Π΄Π΅Π»Π°Π΅ΠΌ ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½ΠΎΠ΅ условиС ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ ΡƒΠ±Ρ€Π°Π½ΠΎ ΠΎΡ€ΡƒΠΆΠΈΠ΅ ΠΈΠ»ΠΈ Π½Π΅Ρ‚
            if not self.hide_weapon:
                self.weapon_pos = self.droid.getX(), self.droid.getY() + 0.7, 3
                self.weapon.setPos(self.weapon_pos) # ОбновляСм ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΏΡƒΡˆΠΊΠΈ
            else:
                self.weapon_pos = self.droid.getX(), self.droid.getY() + 0.7, 3
                self.flash.setPos(self.weapon_pos)


        camvec = self.droid.getPos() - self.camera.getPos() # Π²Π΅ΠΊΡ‚ΠΎΡ€ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹
        camvec.setZ(0) # 0 высота Π²Π΅ΠΊΡ‚ΠΎΡ€Π°
        camdist = camvec.length() # дистанция ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ ΠΎΡ‚ Π΄Ρ€ΠΎΠΈΠ΄Π°
        camvec.normalize() # Π½ΠΎΡ€ΠΌΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ Π²Π΅ΠΊΡ‚ΠΎΡ€ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹
        if camdist > 10.0: # Ссли дистанция ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ большС 10, Ρ‚ΠΎ смСщаСм ΠΊΠ°ΠΌΠ΅Ρ€Ρƒ Π·Π° Π΄Ρ€ΠΎΠΎΠΈΠ΄ΠΎΠΌ
            self.camera.setPos(self.camera.getPos() + camvec * (camdist - 10))
            camdist = 10.0 # Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ дистанция Π±ΡƒΠ΄Π΅Ρ‚ снова 10
        if camdist < 5.0: # Ссли дистагцтя ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ мСньшС 5, Ρ‚ΠΎ...
            self.camera.setPos(self.camera.getPos() - camvec * (5 - camdist)) # сдвигаСм ΠΊΠ°ΠΌΠ΅Ρ€Ρƒ
            camdist = 5.0 # всё обновляСм
            
        self.camera.lookAt(self.floater) # Π²ΠΎΡ‚ ΠΈ пригодился наш floater


        return task.cont # Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌ Π·Π°Π΄Π°Ρ‡Ρƒ

    def addInstructions(self, pos, msg):
        return OnscreenText(text=msg, style=1, fg=(1,1,1,1), font=self.inst_font, pos=(-1.3, pos), align=TextNode.ALeft, scale = .04, shadow=(0,0,0,1)) # Ѐункция ΠΎ Ρ‚ΠΎΠΌ, ΠΊΠ°ΠΊ ΡƒΠΏΡ€Π°Π²Π»ΡΡ‚ΡŒ

    def addTitle(self, text):
        return OnscreenText(text=text, style=1, fg=(1, 1, 1, 1), scale=0.2,
                            parent=base.a2dBottomRight, align=TextNode.ARight,
                            pos=(-0.1, 0.09), shadow=(0, 0, 0, 1), font=self.font) # Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ тСкстового Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ° с ΡˆΡ€ΠΈΡ„Ρ‚ΠΎΠΌ ΠΈ ΠΏΠΎΠ·ΠΈΡ†ΠΈΠ΅ΠΉ
    

droid = DroidShooter() # Π‘ΠΎΠ·Π΄Π°Π΄ΠΈΠΌ экзСмпляр класса нашСй ΠΈΠ³Ρ€Ρ‹
droid.run() # 3апустим ΠΈΠ³Ρ€Ρƒ


# Ρ€Π°Π·Ρ€ΠΎΠ±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ :
# Π“Π»Π°Π²Π½Ρ‹ΠΉ Π°Π²Ρ‚ΠΎΡ€ : ma3rx
# ΠŸΠΎΠΌΠΎΡ‰Π½ΠΈΠΊ : panda3dmastercoder( присоСдСнился ΠΊ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Ρƒ 31 января, 12:??)

Wouldn’t it be easier to upload just a single zip file containing the code and all the folders, including the
panda3d art?

@rdb, Instruction to panda3d art :

  1. Download panda 3d art - https://www.panda3d.org/download/noversion/art-gallery.zip
  2. Select directory cat-enviroments
  3. Select bvw-f2004–milleniumfalcon
  4. Select all files and drop to world directory.

That doesn’t work. I have tried it as I am helping him make the game. They are saying that the file is too large.

If it’s too large, I recommend uploading it to either itch.io or GitHub instead. Both are free and have large limits.

I can’t, sorry :frowning:
You can do?

Hi! I create 3.0.4 updating!
New code :

#!/usr/bin/env python
# -*- coding: utf_8 -*-

# Π‘ΠΎΠ·Π΄Π°Π½ΠΎ : 22 число, ΡΠ½Π²Π°Ρ€ΡŒ, 2021 Π³ΠΎΠ΄

# Π˜ΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΡƒΠ΅ΠΌ всС Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹Π΅ инструмСнты
from direct.showbase.ShowBase import ShowBase
from panda3d.core import CollisionTraverser, CollisionNode
from panda3d.core import CollisionHandlerPusher, CollisionSphere, CollisionInvSphere
from panda3d.core import Filename, AmbientLight, DirectionalLight
from panda3d.core import PandaNode, NodePath, Camera, TextNode
from direct.particles.Particles import Particles
from direct.particles.ParticleEffect import ParticleEffect
from panda3d.core import PointLight, Spotlight
from panda3d.core import CollideMask
from panda3d.core import loadPrcFileData
from panda3d.core import *
from direct.gui.OnscreenText import OnscreenText
from direct.gui.OnscreenImage import OnscreenImage
from direct.gui.DirectButton import DirectButton
from direct.gui.DirectSlider import DirectSlider
from direct.actor.Actor import Actor
import random
import sys
import time
import os
import math


VERSION = '3.0.4'

settings = ['window-title Droid Game ' +  VERSION,
            'fullscreen 0']
            

loadPrcFileData('', settings[0]) # Π‘Π΄Π΅Π»Π°Π΅ΠΌ Π½Π΅ стандартный Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ (Π²ΠΎΠ·ΠΌΡ‘ΠΌ Π΅Π³ΠΎ ΠΈΠ· ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ settings)
loadPrcFileData('', settings[1]) # Π½Π΅ Π±ΡƒΠ΄Π΅ΠΌ Π΄Π΅Π»Π°Ρ‚ΡŒ полноэкранный Ρ€Π΅ΠΆΠΈΠΌ

# Π‘ΠΎΠ·Π΄Π°Π΄ΠΈΠΌ Π³Π»Π°Π²Π½Ρ‹ΠΉ класс нашСй ΠΈΠ³Ρ€Ρ‹
class DroidShooter(ShowBase):
    def __init__(self):
        ShowBase.__init__(self) # Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ всС сСлфы ΠΈΠ· direct
        self.speed = 1800 # ΡΠΊΠΎΡ€ΠΎΡΡ‚ΡŒ двигатСля
        self.menu() # звпуск мСню
        
    def menu(self):
        
        base.enableParticles() # ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ эффСкт Π΄Ρ‹ΠΌΠ°

        self.win.setClearColor((0, 0, 0, 1)) # Π—Π°ΠΊΡ€Π°ΡˆΠΈΠ²Π°Π΅ΠΌ ΠΏΠΎΠ²Π΅Ρ€Ρ…Π½ΠΎΡΡ‚ΡŒ Ρ‡Ρ‘Ρ€Π½Ρ‹ΠΌ. Π”Π΅Π»ΠΎ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ Π² этом ΠΈΠ³Ρ€ΠΎΠ²ΠΎΠΌ Π΄Π²ΠΈΠΆΠΊΠ΅ ΠΏΠΎΠ²Π΅Ρ€Ρ…Π½ΠΎΡΡ‚ΡŒ Π·Π°ΠΊΡ€Π°ΡˆΠΈΠ²Π°Π΅Ρ‚ΡΡ сСрым.
        self.font = loader.loadFont('./fonts/doom_font.ttf') # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ ΡˆΡ€ΠΈΡ„Ρ‚ ΠΈΠ· ΠΈΠ³Ρ€Ρ‹ doom
        self.inst_font = loader.loadFont('./fonts/arial.ttf') # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ ΡˆΡ€ΠΈΡ„Ρ‚ arial

        self.crackSound = loader.loadMusic('./sounds/crack.wav') # Π·Π²ΡƒΠΊ Π²Π·Ρ€Ρ‹Π²Π° корабля
        self.shotSound = loader.loadMusic('./sounds/shot.wav') # Π·Π²ΡƒΠΊ выстрСла
        self.startSound = loader.loadMusic('./sounds/started.wav') # Π·Π²ΡƒΠΊ запуска
        self.errorSound = loader.loadMusic('./sounds/error.wav') # Π·Π²ΡƒΠΊ запуска
        self.errorSound.setVolume(1) # полная Π³Ρ€ΠΎΠΌΠΊΠΎΡΡ‚ΡŒ Π·Π²ΡƒΠΊΠ°
        self.startSound.setVolume(1) # полная Π³Ρ€ΠΎΠΌΠΊΠΎΡΡ‚ΡŒ Π·Π²ΡƒΠΊΠ°
        self.crackSound.setVolume(1) # полная Π³Ρ€ΠΎΠΌΠΊΠΎΡΡ‚ΡŒ Π·Π²ΡƒΠΊΠ°
        self.shotSound.setVolume(1) # полная Π³Ρ€ΠΎΠΌΠΊΠΎΡΡ‚ΡŒ Π·Π²ΡƒΠΊΠ°
        self.startSound.play() # ΠΈΠ³Ρ€Π°Π΅ΠΌ Π·Π²ΡƒΠΊ запуска ΠΈΠ³Ρ€Ρ‹

        self.button_start = DirectButton(pos=(0.7, 0, 0), text="CTAPT",
                                   scale=.3, pad=(.2, .2),
                                   command=self.load_game) # ΠΊΠ½ΠΎΠΏΠΊΠ° запуска ΠΈΠ³Ρ€Ρ‹

        self.slider_sun = DirectSlider(pos=(0.1, 0, .75), scale=0.8, value=0.5,
                                    command=self.set_sun_interval)


        self.title = self.addTitle("Droid game " + VERSION)
        
        # НапСчатаСм ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅
        self.inst1 = self.addInstructions(0.95, u"[ESC]: Π’Ρ‹Ρ…ΠΎΠ΄")
        self.inst2 = self.addInstructions(0.90, u"[Left Arrow]: ΠŸΠΎΠ²ΠΎΡ€ΠΎΡ‚ Π΄Ρ€ΠΎΠΈΠ΄Π° Π² Π»Π΅Π²ΠΎ")
        self.inst3 = self.addInstructions(0.85, u"[Right Arrow]: ΠŸΠΎΠ²ΠΎΡ€ΠΎΡ‚ Π΄Ρ€ΠΎΠΈΠ΄Π° Π² ΠΏΡ€Π°Π²ΠΎ")
        self.inst4 = self.addInstructions(0.80, u"[Up Arrow]: Π’ΠΏΠ΅Ρ€Π΅Π΄")
        self.inst5 = self.addInstructions(0.75, u"[a]: ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ Π² ΠΏΡ€Π°Π²ΠΎ")
        self.inst6 = self.addInstructions(0.70, u"[d]: ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ Π² Π»Π΅Π²ΠΎ")
        self.inst7 = self.addInstructions(0.65, u"[Left Arrow + Up arrow]: ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚ Π΄Ρ€ΠΎΠΈΠ΄Π° Π² Π»Π΅Π²ΠΎ ΠΈ Π²ΠΏΠ΅Ρ€Ρ‘Π΄")
        self.inst8 = self.addInstructions(0.60, u"[Right Arrow + Up arrow]: ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚ Π΄Ρ€ΠΎΠΈΠ΄Π° Π² ΠΏΡ€Π°Π²ΠΎ ΠΈ Π²ΠΏΠ΅Ρ€Ρ‘Π΄")
        self.inst9 = self.addInstructions(0.55, u"[a + Up arrow]: ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ Π² ΠΏΡ€Π°Π²ΠΎ ΠΈ Π²ΠΏΠ΅Ρ€Ρ‘Π΄")
        self.inst10 = self.addInstructions(0.50, u"[d + Up arrow]: ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ Π² Π»Π΅Π²ΠΎ ΠΈ Π²ΠΏΠ΅Ρ€Ρ‘Π΄")
        self.inst11 = self.addInstructions(0.45, u"[space]: ΡΡ‚Ρ€Π΅Π»ΡŒΠ±Π°")
        self.inst12 = self.addInstructions(0.40, u"[s]: Π΄ΠΎΡΡ‚Π°Ρ‚ΡŒ Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊ")
        self.inst13 = self.addInstructions(0.35, u"[w]: ΡƒΠ±Ρ€Π°Ρ‚ΡŒ ΠΎΡ€ΡƒΠΆΠΈΠ΅")
        self.inst14 = self.addInstructions(0.30, u"[f]: ΠΏΠΎΠ»Π½Ρ‹ΠΉ Ρ€Π°Π·Π³ΠΎΠ½(ОПАБНО!)")
        self.inst15 = self.addInstructions(0.25, u"[0]: ΠΏΠΎΠΆΠ°Ρ€ΠΎΡ‚ΡƒΡˆΠΈΡ‚Π΅Π»ΡŒΠ½Π°Ρ систСма")

        self.accept("escape", sys.exit) # ΠŸΡ€ΠΈ Π½Π°ΠΆΠ°Ρ‚ΠΈΠΈ клавиши Esc Π²Ρ‹Ρ…ΠΎΠ΄ΠΈΠΌ.

    def set_sun_interval(self):
        self.sun_interval = self.slider_sun.guiItem.getValue() * 100 # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ слайдСрноС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΡƒΠΌΠ½ΠΎΠΆΠ΅Π½ΠΎΠ΅ Π½Π° 500, Π΄Π° Ρ‚Ρ€Π°Ρ‡Ρƒ ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΡŽ Π½ΠΎ ΠΌΠ½Π΅ каТСтся ΠΌΠ½ΠΎΠ³ΠΈΠΌ ΠΏΠ»Π΅Π²Π°Ρ‚ΡŒ Π½Π° ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΡŽ мСню, ΠΈΠ±ΠΎ Ρ‚Π°ΠΊΠΎΠ³ΠΎ понятия просто Π½Π΅Ρ‚Ρƒ :)
        

    def load_game(self):
        self.button_start.hide() # ΡƒΠ΄Π°Π»ΠΈΠΌ ΠΊΠ½ΠΎΠΏΠΊΡƒ старта
        self.title.hide() # ΡƒΠ΄Π°Π»ΠΈΠΌ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ ΠΈΠ³Ρ€Ρ‹
        # ΡƒΠ΄Π°Π»ΠΈΠΌ ΠΊΠ½ΠΎΠΏΠΊΠΈ управлСния
        self.inst1.hide()
        self.inst2.hide()
        self.inst3.hide()
        self.inst4.hide()
        self.inst5.hide()
        self.inst6.hide()
        self.inst7.hide()
        self.inst8.hide()
        self.inst9.hide()
        self.inst10.hide()
        self.inst11.hide()
        self.inst12.hide()
        self.inst13.hide()
        self.inst14.hide()
        self.inst15.hide()
        self.slider_sun.hide() # удаляСм слайдСр солнца
        
        self.keyMap = {
            "left": 0, "right": 0, "forward": 0, "cam-left": 0, "cam-right": 0} # Π‘ΠΎΠ·Π΄Π°Π΄ΠΈΠΌ ΡΠ»ΠΎΠ²Π°Ρ€ΡŒ ΠΊΠ½ΠΎΠΏΠΎΠΊ, ΠΏΠΎ ΠΈΡ… Π½Π°ΠΆΠ°Ρ‚ΠΈΡŽ        

        # РисуСм Π·Π²Ρ‘Π·Π΄Ρ‹

        self.sky = loader.loadModel("./models/sky/solar_sky_sphere") # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ модСль космоса(это сфСра)

        self.sky_tex = loader.loadTexture("./tex/stars_1k_tex.jpg") # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ тСкстуру
        self.sky.setTexture(self.sky_tex, 1) # Π·Π°Ρ€Π΅Π½Π΄Π΅Ρ€ΠΈΠΌ тСкстуру Π½Π° Π½Π΅Π±ΠΎ
        self.sky.reparentTo(render) # ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ Π½Π΅Π±ΠΎ
        self.sky.setScale(40000) # Ρ€Π°ΡΡˆΠΈΡ€ΠΈΠΌ Π½Π΅Π±ΠΎ Π΄ΠΎ максимальной Π²Π΅Π»ΠΈΡ‡ΠΈΠ½Ρ‹ panda3d

        self.environ = loader.loadModel("models/world/falcon.egg") # Π—Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ ΡƒΠΆΠ΅ созданный Π² blender ΠΌΠΈΡ€.
        self.environ.reparentTo(render) # Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ модСль ΠΌΠΈΡ€Π° Π² ΠΎΠΊΠ½ΠΎ

        droidStartPos = (-1, 0, 1.5 ) # Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ ΡΡ‚Π°Ρ€Ρ‚ΠΎΠ²ΡƒΡŽ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π² ΠΌΠΈΡ€Π΅.
        enemyStartPos = (-6, 1, 0.5) # Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ°-Π΄Ρ€ΠΎΠΈΠ΄Π°.
        self.droid = Actor("models/player/seeker.egg") # Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ модСль ΠΈΠ³Ρ€ΠΎΠΊΠ° (созданная Π² blender)
        self.enemy = Actor("models/enemies/r2d2/r2d2.egg") # Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ модСль ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ° (созданная Π² blender)
        self.droid.reparentTo(render) # ΠŸΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Π΅ΠΌ модСль ΠΈΠ³Ρ€ΠΎΠΊΠ° Π² наш ΠΌΠΈΡ€.
        self.enemy.reparentTo(render) # ΠŸΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Π΅ΠΌ модСль ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ° Π² наш ΠΌΠΈΡ€.
        self.droid.setScale(1) # Π”Π΅Π»Π°Π΅ΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ€ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π½Π° 1
        self.enemy.setScale(1) # Π”Π΅Π»Π°Π΅ΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ€ ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ° Π½Π° 1
        self.droid.setPos(droidStartPos) # Π‘Ρ‚Π°Π²ΠΈΠΌ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π½Π° Ρ€Π°Π½Π΅Π΅ ΡΠΎΠ·Π΄Π°Π½ΡƒΡŽ Π½Π°ΠΌΠΈ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ
        self.enemy.setPos(enemyStartPos) # Π‘Ρ‚Π°Π²ΠΈΠΌ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ° Π½Π° Ρ€Π°Π½Π΅Π΅ ΡΠΎΠ·Π΄Π°Π½ΡƒΡŽ Π½Π°ΠΌΠΈ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ

        self.weapon = Actor('models/weapon/lightsaber.egg') # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ ΠΎΡ€ΡƒΠΆΠΈΠ΅
        self.bullet = Actor('models/weapon/bullet/bullet.egg.pz') # Π—Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ ΠΏΡƒΠ»ΡŽ
        self.flash = Actor('models/whishlyflash/handlamp.egg') # Π—Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊ
               
        self.weapon.reparentTo(render) # пСрСмСстим ΠΎΡ€ΡƒΠΆΠΈΠ΅ Π² наш ΠΌΠΈΡ€
        self.bullet.reparentTo(render) # пСрСмСстим ΠΏΡƒΠ»ΡŽ Π² ΠΌΠΈΡ€ Π½ΠΎ появится ΠΎΠ½Π° сама Π½Π΅ скоро
        self.flash.reparentTo(render) # пСрСмСстим Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊ Π² наш ΠΌΠΈΡ€
        self.weapon.setScale(.5) # Π·Π°Π΄Π°Π΄ΠΈΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ€ ΠΏΡƒΡˆΠΊΠΈ
        self.bullet.setScale(.5) # Π·Π°Π΄Π°Π΄ΠΈΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ€ ΠΏΡƒΠ»ΠΈ
        self.flash.setScale(.5) # Π·Π°Π΄Π°Π΄ΠΈΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ€ Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊΠ°

        # враТСский ΠΈΡΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»ΡŒ
        self.fighter = Actor('models/fighter/fighter.egg') # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ ΠΌΠΎΠ΄Π΅Π»ΡŒΠΊΡƒ истрСбитСля
        self.fighter.reparentTo(render) # ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ ΠΈΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»ΡŒ
        self.fighter.setPos(0, 90, 0) # позиция истрСбитСля
                

        self.weapon_pos = self.droid.getX(), self.droid.getY() + 0.7, 1 # ΠŸΠΎΠ·ΠΈΡ†ΠΈΡ ΠΏΡƒΡˆΠΊΠΈ
        
        self.weapon.setPos(self.weapon_pos) # ΠŸΠΎΠΌΠ΅ΡΡ‚ΠΈΠΌ ΠΎΡ€ΡƒΠΆΠΈΠ΅ Ρ‡ΡƒΡ‚ΡŒ Π²Ρ‹ΡˆΠ΅ ΠΈΠ³Ρ€ΠΎΠΊΠ°
        
        
        self.spotlight = camera.attachNewNode(Spotlight("spotlight")) # ΠšΠΎΠ½Ρ„ΠΈΠ³ΠΈ Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊΠ°
        self.spotlight.node().setColor((.3, .3, .3, 1))
        self.spotlight.node().setSpecularColor((0, 0, 0, 1))

        self.floater = NodePath(PandaNode("floater")) 
        self.floater.reparentTo(self.droid)
        self.floater.setZ(2.0)

        self.accept("escape", sys.exit) # ΠŸΡ€ΠΈ Π½Π°ΠΆΠ°Ρ‚ΠΈΠΈ клавиши Esc Π²Ρ‹Ρ…ΠΎΠ΄ΠΈΠΌ.
        
        self.accept("arrow_left", self.setKey, ["left", True]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ Π²Π»Π΅Π²ΠΎ - ΠΏΠΎΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π²Π»Π΅Π²ΠΎ
        self.accept("arrow_right", self.setKey, ["right", True]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ Π²ΠΏΡ€Π°Π²ΠΎ - ΠΏΠΎΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π²ΠΏΡ€Π°Π²ΠΎ
        self.accept("arrow_up", self.setKey, ["forward", True]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ Π²ΠΏΠ΅Ρ€Ρ‘Π΄ - ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄
        self.accept("a", self.setKey, ["cam-left", True]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ a - Ρ€Π°Π·Π²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΊΠ°ΠΌΠ΅Ρ€Ρƒ Π²ΠΎΠΊΡ€ΡƒΠ³ нашСй модСльки
        self.accept("d", self.setKey, ["cam-right", True]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ s - Ρ€Π°Π·Π²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΊΠ°ΠΌΠ΅Ρ€Ρƒ Π²ΠΎΠΊΡ€ΡƒΠ³ нашСй модСльки
        self.accept("arrow_left-up", self.setKey, ["left", False]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ Π²Π²Π΅Ρ€Ρ…+Π²Π»Π΅Π²ΠΎ - ΠΏΠΎΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π²Π»Π΅Π²ΠΎ ΠΈ ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄
        self.accept("arrow_right-up", self.setKey, ["right", False]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ Π²Π²Π΅Ρ€Ρ…+ΠΏΡ€Π°Π²ΠΎ - ΠΏΠΎΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π²ΠΏΡ€Π°Π²ΠΎ ΠΈ ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄
        self.accept("arrow_up-up", self.setKey, ["forward", False]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ Π²Π²Π΅Ρ€Ρ…+Π²Π²Π΅Ρ€ΡŠ - ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄ ΠΈ ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄
        self.accept("a-up", self.setKey, ["cam-left", False]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ a+Π²ΠΏΠ΅Ρ€Ρ‘Π΄ - ΠΏΠΎΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΊΠ°ΠΌΠ΅Ρ€Ρƒ Π²Π»Π΅Π²ΠΎ ΠΈ ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄
        self.accept("d-up", self.setKey, ["cam-right", False]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ s+Π²ΠΏΠ΅Ρ€Ρ‘Π΄ - ΠΏΠΎΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΊΠ°ΠΌΠ΅Ρ€Ρƒ Π²ΠΏΡ€Π°Π²ΠΎ ΠΈ ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄

        self.accept("space", self.shot) # ΠΏΡ€ΠΈ ΠΏΡ€ΠΎΠ±Π΅Π»Π΅ стрСляСм
        self.accept("s", self.toggleLights, [[self.spotlight]]) # Π’ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊ
        self.accept("w", self.weapon_hide) # ΠΏΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ w - ΡƒΠ±Π΅Ρ€Ρ‘ΠΌ ΠΎΡ€ΡƒΠΆΠΈΠ΅.

        base.enableParticles() # Π’ΠΊΠ»ΡŽΡ‡Π°Π΅ΠΌ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ Π΄Ρ‹ΠΌΠ°
        self.t = loader.loadModel("models/weapon/lightsaber.egg") # Π—Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ Π΅Ρ‰Ρ‘ ΠΎΡ€ΡƒΠΆΠΈΠ΅
        self.t.reparentTo(render) # ΠŸΠ΅Ρ€Π΅ΠΌΠ΅ΡΡ‚ΠΈΠΌ ΠΎΡ€ΡƒΠΆΠΈΠ΅ Π² наш ΠΌΠΈΡ€
        self.p = ParticleEffect() # Π’ΠΊΠ»ΡŽΡ‡ΠΈΠΌ эффСкт Π΄Ρ‹ΠΌΠ°
        self.accept('f', self.particle_start) # ΠΏΡ€ΠΈ Π½Π°ΠΆΠ°Ρ‚ΠΈΠΈ f(ΠΎΡ‚ force) -  Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ Ρ„Π°ΠΉΠ» Π΄Ρ‹ΠΌΠ° ΠΈ пСрСмСстим Π² ΠΊΠΎΠ½Ρ„ΠΈΠ³ Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΈΠΌΠ΅Π½Π½ΠΎ эта анимация стала ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ΠΌ Π΄Ρ‹ΠΌΠ°
        self.accept('0', self.fountain) # ΠΏΡ€ΠΈ  Π½Π°ΠΆΠ°Ρ‚ΠΈΠΈ ΠΊΠ½ΠΎΠΏΠΎΠΊ f+o(fountain) Π²ΠΊΠ»ΡŽΡ‡ΠΈΠΌ ΠΏΠΎΠΆΠ°Ρ€ΠΎΡ‚ΡƒΡˆΠΈΡ‚Π΅Π»ΡŒΠ½ΡƒΡŽ систСму

        taskMgr.add(self.move, "moveTask") # ДобавляСм Π·Π°Π΄Π°Ρ‡Ρƒ Π² наш Π΄Π²ΠΈΠΆΠΎΠΊ

        self.isMoving = False # Π‘Ρ‚Π°Π²ΠΈΠΌ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ isMoving Π½Π° False(Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΌΠ΅Π½ΡΡ‚ΡŒ это Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅) Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΈΠ³Ρ€ΠΎΠΊ ΠΈΠ·Π½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎ стоял.
        # Π”Π΅Π»Π°Π΅ΠΌ Ρ‚Π°ΠΊ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ свСт Π±Ρ‹Π» ΠΈΠ·Π½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎ Π²Ρ‹ΠΊΠ»ΡŽΡ‡Π΅Π½.
        self.disableMouse() # ΠžΡ‚ΠΊΠ»ΡŽΡ‡Π°Π΅ΠΌ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π΅Π½ΠΈΠ΅ Ρ‡Π΅Ρ€Π΅Π· ΠΌΡ‹ΡˆΠΊΡƒ
        self.camera.setPos(self.droid.getX(), self.droid.getY() + 1, 3) # Π‘Ρ‚Π°Π²ΠΈΠΌ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ Ρ‡ΡƒΡ‚ΡŒ большС ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ ΠΈΠ³Ρ€ΠΎΠΊΠ°

        self.black_light() # Π‘Π΄Π΅Π»Π°Π΅ΠΌ Π²Ρ‹ΠΊΠ»ΡŽΡ‡Π΅Π½Π½Ρ‹ΠΉ свСт

        self.state = 100 # БостояниС корабля
        self.state_info = OnscreenText(text='ΠΊΠΎΡ€Π°Π±Π»ΡŒ :' + str(self.state), pos=(0.5, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля
                
        self.check_loss() # ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ ΠΏΠΎΡ€Π°ΠΆΠ΅Π½ΠΈΠ΅
        self.hide_weapon = False # ΠŸΠΎΡΡ‚Π°Π²ΠΈΠΌ, Ρ‡Ρ‚ΠΎ ΠΎΡ€ΡƒΠΆΠΈΠ΅ Π½Π΅ ΡƒΠ±Ρ€Π°Π½ΠΎ
        self.steam_pos = random.randrange(0, 5), random.randrange(0, 5), random.randrange(0, 5)
        self.fountain_pos = random.randrange(0, 5), random.randrange(0, 5), random.randrange(0, 1)

        self.motor_pos1 = 25.238849639892578, 8.962211608886719, 1.5 # позиция ΠΏΠ΅Ρ€Π²ΠΎΠ³ΠΎ ΠΌΠΎΡ‚ΠΎΡ€Π°
        self.motor_pos2 = -20.676218032836914, 10.55816650390625, 1.5 # позиция Π²Ρ‚ΠΎΡ€ΠΎΠ³ΠΎ ΠΌΠΎΡ‚ΠΎΡ€Π°

        self.motor1 = self.loadParticleConfig('special_effects/steam_critic+/fireish.ptf', self.motor_pos1) # ΠΌΠΎΡ‚ΠΎΡ€ 1
        self.motor2 = self.loadParticleConfig('special_effects/steam_critic+/fireish.ptf', self.motor_pos2) # ΠΌΠΎΡ‚ΠΎΡ€ 2

        self.state_info2 = OnscreenText(text='', pos=(-0.8, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля

        self.force = False # ΠŸΠΎΡΡ‚Π°Π²ΠΈΠΌ, Ρ‡Ρ‚ΠΎ Π½Π΅ Ρ€Π°Π·Π³ΠΎΠ½ΡΠ»ΠΈΡΡŒ

        # ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ ΠΊΠΎΠ»Π»ΠΈΠ·ΠΈΠΈ

        # Коллизия корабля(ΠΎΠ½ Ρƒ нас ΠΊΠ°ΠΊ главная ΠΊΠ°Ρ€Ρ‚Π°).
        self.cTrav = CollisionTraverser()
        pusher = CollisionHandlerPusher()
        
        environCenter = self.environ.getBounds().getCenter()
        environRad = self.environ.getBounds().getRadius()
        cNode = CollisionNode("environment")
        cNode.addSolid(CollisionInvSphere(environCenter, environRad))
        environC = self.environ.attachNewNode(cNode)

        # Коллизия Π΄Ρ€ΠΎΠΈΠ΄Π°.
        droidCenter = self.droid.getBounds().getCenter()
        droidRad = self.droid.getBounds().getRadius()
        cNode = CollisionNode("droid")
        cNode.addSolid(CollisionSphere(droidCenter, droidRad))
        droidC = self.droid.attachNewNode(cNode)
        
        pusher.addCollider(droidC, self.droid)
        self.cTrav.addCollider(droidC, pusher)

        # Коллизия ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ°.
        enemyCenter = self.enemy.getBounds().getCenter()
        enemyRad = self.enemy.getBounds().getRadius()
        cNode = CollisionNode("enemy")
        cNode.addSolid(CollisionSphere(enemyCenter, enemyRad))
        enemyC = self.enemy.attachNewNode(cNode)

        pusher.addCollider(enemyC, self.enemy)
        self.cTrav.addCollider(enemyC, pusher)

        # Коллизия враТСского истрСбитСля.
        fighterCenter = self.fighter.getBounds().getCenter()
        fighterRad = self.fighter.getBounds().getRadius()
        cNode = CollisionNode("fighter")
        cNode.addSolid(CollisionSphere(fighterCenter, fighterRad))
        fighterC = self.fighter.attachNewNode(cNode)

        pusher.addCollider(fighterC, self.fighter)
        self.cTrav.addCollider(fighterC, pusher)

        # Коллизия ΠΏΡƒΠ»ΠΈ.
        bulletCenter = self.bullet.getBounds().getCenter()
        bulletRad = self.bullet.getBounds().getRadius()
        cNode = CollisionNode("bullet")
        cNode.addSolid(CollisionSphere(bulletCenter, bulletRad))
        bulletC = self.bullet.attachNewNode(cNode)

        bulletCenter = self.bullet.getBounds().getCenter()
        bulletRad = self.bullet.getBounds().getRadius()
        cNode = CollisionNode("bullet")
        cNode.addSolid(CollisionSphere(bulletCenter, bulletRad))
        bulletC = self.bullet.attachNewNode(cNode)
        
        pusher.addCollider(bulletC, self.bullet)
        self.cTrav.addCollider(bulletC, pusher)

        # Коллизия ΠΏΡƒΡˆΠΊΠΈ. Π― Π±Ρ‹ Π½Π΅ сказал, Ρ‡Ρ‚ΠΎ это ΠΈΠΌΠ΅Π½Π½ΠΎ коллизия, скорСС это для рСалистичности
        weaponCenter = self.weapon.getBounds().getCenter()
        weaponRad = self.weapon.getBounds().getRadius()
        cNode = CollisionNode("weapon")
        cNode.addSolid(CollisionSphere(weaponCenter, weaponRad))
        weaponC = self.weapon.attachNewNode(cNode)
        
        pusher.addCollider(weaponC, self.weapon)
        self.cTrav.addCollider(weaponC, pusher)

        # солнцС(новая ΠΌΠ΅Ρ…Π°Π½ΠΈΠΊΠ° освСщСния)
        sun = DirectionalLight("sun")
        sun.set_color_temperature(6000)
        sun.color = sun.color * 4
        sun_path = render.attach_new_node(sun)
        sun_path.set_pos(10, -10, -10)
        sun_path.look_at(0, 0, 0)
        sun_path.hprInterval(self.sun_interval, (sun_path.get_h(), sun_path.get_p() - 360, sun_path.get_r()), bakeInStart=True).loop()
        render.set_light(sun_path)

    def fight_force(self):
        # сдвиТСниС истрСбитСля Π·Π° нашим ΠΊΠΎΡ€Π°Π±Π»Ρ‘ΠΌ(ΠΎΡ‡Π΅Π½ΡŒ простым способом я сдСлал Ρ‚Π°ΠΊ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΈΡΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»ΡŒ Π·Π°ΠΆΠΈΠΌΠ°Π» нас(Π»Π΅Ρ‚Π°Π» Π² нашСм ΠΊΠ²Π°Π΄Ρ€Π°Ρ‚Π΅)) ΠΈ Π·Π°ΠΆΠΈΠΌΠ°Π΅Ρ‚ ΠΎΠ½ Ρ€Π΅Π°Π»ΡŒΠ½ΠΎ, сблиТая ΠΊ Π½Π°ΠΌ свой ΠΊΠ²Π°Π΄Ρ€Π°Ρ‚
        self.fighter.setY(self.fighter.getY() - self.speed) 
        self.fighter.setX(self.fighter.getX() - 10)    

        print(self.fighter.getX())


    def loadParticleConfig(self, filename, pos):
        self.p.cleanup()
        self.p = ParticleEffect()
        self.p.loadConfig(Filename(filename))

        self.p.start(self.t)
        self.p.setPos(pos)

    def particle_start(self):
        self.force = True # ΠŸΠΎΡΡ‚Π°Π²ΠΈΠΌ, Ρ‡Ρ‚ΠΎ ΠΌΡ‹ ΡƒΠΆΠ΅ Ρ€Π°Π·Π³ΠΎΠ½ΡΠ»ΠΈΡΡŒ
        # ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Π΅ΠΌ всС ΠΎΠ±ΡŒΠ΅ΠΊΡ‚Ρ‹ Π·Π° ΠΊΠΎΡ€Π°Π±Π»Ρ‘ΠΌ
        self.environ.setY(self.environ.getY() - self.speed) # нСсёмся Π²ΠΏΡ€Π°Π²ΠΎ
        self.droid.setY(self.droid.getY() - self.speed) # сдвигаСм Π΄Ρ€ΠΎΠΈΠ΄Π° Π·Π° ΠΊΠΎΡ€Π°Π±Π»Ρ‘ΠΌ
        self.enemy.setY(self.enemy.getY() - self.speed) # сдфигаСм ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ° Π·Π° ΠΊΠΎΡ€Π°Π±Π»Ρ‘ΠΌ
        self.weapon.setY(self.weapon.getY() - self.speed) # ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Π΅ΠΌ ΠΎΡ€ΡƒΠΆΠΈΠ΅
        self.flash.setY(self.flash.getY() - self.speed) # ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Π΅ΠΌ Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊ
        self.fight_force()

        self.state -= 1 # сдСлаСм мСньшС ΠΎΡ‡ΠΊΠΎΠ²
        self.state_info.hide() # ΡƒΠ΄Π°Π»ΠΈΠΌ тСкстовыС ΠΎΡ‡ΠΊΠΈ
        
        if self.state != 10 and self.state > 10:
            self.state_info.hide() # ΡƒΠ±ΠΈΡ€Π°Π΅ΠΌ ΠΏΡ€Π΅Π΄Π΅Π΄ΡƒΡ‰Π΅Π΅ сообщСниС ΠΎ Тизнях корабля
            self.state_info = OnscreenText(text='ΠΊΠΎΡ€Π°Π±Π»ΡŒ :' + str(self.state), pos=(0.5, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля
            self.check_loss() # провСряСм ΠΏΠΎΡ€Π°ΠΆΠ΅Π½ΠΈΠ΅
            self.steam_pos = random.randrange(0, 5), random.randrange(0, 5) + 300, random.randrange(0, 5)
            self.loadParticleConfig('special_effects/steam/steam.ptf', self.steam_pos)
            self.errorSound.play() # ΠΈΠ³Ρ€Π°Π΅ΠΌ Π·Π²ΡƒΠΊ ошибки
            self.state_info2.hide() # ΡƒΠ±ΠΈΡ€Π°Π΅ΠΌ ΠΏΡ€Π΅Π΄Π΅Π΄ΡƒΡ‰Π΅Π΅ сообщСниС
            self.state_info2 = OnscreenText(text='Π΄Π²ΠΈΠ³Π°Ρ‚Π΅Π»ΡŒ нСисправСн', pos=(-0.8, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля
        else:
            self.state_info = OnscreenText(text='ΠΊΠΎΡ€Π°Π±Π»ΡŒ :' + str(self.state), pos=(0.5, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля
            self.check_loss() # провСряСм ΠΏΠΎΡ€Π°ΠΆΠ΅Π½ΠΈΠ΅
            self.steam_pos = random.randrange(0, 5), random.randrange(0, 5) + 300, random.randrange(0, 5)
            self.loadParticleConfig('special_effects/steam_critic/steam.ptf', self.steam_pos)
            self.errorSound.play() # ΠΈΠ³Ρ€Π°Π΅ΠΌ Π·Π²ΡƒΠΊ ошибки
            self.state_info2.hide()  # ΡƒΠ±ΠΈΡ€Π°Π΅ΠΌ ΠΏΡ€Π΅Π΄Π΅Π΄ΡƒΡ‰Π΅Π΅ сообщСниС
            self.state_info2 = OnscreenText(text='критичСскоС состояниС', pos=(-0.8, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля
    
        if self.state < 10:
            self.state_info.hide()
            self.state_info = OnscreenText(text='ΠΊΠΎΡ€Π°Π±Π»ΡŒ :' + str(self.state), pos=(0.5, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля
            self.check_loss() # провСряСм ΠΏΠΎΡ€Π°ΠΆΠ΅Π½ΠΈΠ΅
            self.steam_pos = random.randrange(0, 5), random.randrange(0, 5) + 300, random.randrange(0, 5)            
            self.loadParticleConfig('special_effects/steam_critic+/fireish.ptf', self.steam_pos)
            self.errorSound.play() # ΠΈΠ³Ρ€Π°Π΅ΠΌ Π·Π²ΡƒΠΊ ошибки
            self.state_info2.hide() # ΡƒΠ±ΠΈΡ€Π°Π΅ΠΌ ΠΏΡ€Π΅Π΄Π΅Π΄ΡƒΡ‰Π΅Π΅ сообщСниС
            self.state_info2 = OnscreenText(text='ΠΏΠ°Π΄Π°Π΅ΠΌ!', pos=(-0.8, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля


    def fountain(self):
        self.state_info2.hide() # ΡƒΠ±ΠΈΡ€Π°Π΅ΠΌ тСкст опасности
        if self.force:
            if self.state != 100:
                self.state += 1
                self.state_info.hide()
                self.state_info = OnscreenText(text='ΠΊΠΎΡ€Π°Π±Π»ΡŒ :' + str(self.state), pos=(0.5, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля

            self.fountain_pos = random.randrange(0, 5), random.randrange(0, 5) + 500, random.randrange(0, 1)    
            self.loadParticleConfig('special_effects/fountain/fountain.ptf', self.fountain_pos)

        else :
            if self.state != 100:
                self.state += 1
                self.state_info.hide()
                self.state_info = OnscreenText(text='ΠΊΠΎΡ€Π°Π±Π»ΡŒ :' + str(self.state), pos=(0.5, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля

            self.fountain_pos = random.randrange(0, 5), random.randrange(0, 5), random.randrange(0, 1)    
            self.loadParticleConfig('special_effects/fountain/fountain.ptf', self.fountain_pos)
        
        
    def black_light(self):
        # Π’Ρ‹ΠΊΠ»ΡŽΡ‡Π΅Π½Ρ‹ΠΉ свСт
        ambientLight = AmbientLight("ambientLight")
        ambientLight.setColor((0, 0, 0, 1))
        directionalLight = DirectionalLight("directionalLight")
        directionalLight.setDirection((-5, -5, -5))
        directionalLight.setColor((1, 1, 1, 1))
        directionalLight.setSpecularColor((1, 1, 1, 1))
        render.setLight(render.attachNewNode(ambientLight))
        render.setLight(render.attachNewNode(directionalLight))

    def weapon_hide(self):
        # Π£Π±Ρ€Π°Ρ‚ΡŒ ΠΎΡ€ΡƒΠΆΠΈΠ΅
        self.hide_weapon = True
        self.weapon.hide()

    def toggleLights(self, lights):
        # Π‘ΠΏΠ΅Ρ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠ΅ освСщСниС
        if self.hide_weapon:
            for light in lights:
                if render.hasLight(light):
                    render.clearLight(light)
                else:
                    render.setLight(light)
            
            self.flash.setPos(self.weapon_pos)
        else:
            return


    def shot(self):
        dt = globalClock.getDt() + 0.5 # CΠΊΠΎΡ€ΠΎΡΡ‚ΡŒ двиТСния
        if not self.hide_weapon : # Ссли ΠΎΡ€ΡƒΠΆΠΈΠ΅ ΡƒΠ±Ρ€Π°Π½ΠΎ Ρ‚ΠΎ ΠΌΡ‹ Π½Π΅ ΠΌΠΎΠΆΠ΅ΠΌ ΡΡ‚Ρ€Π΅Π»ΡΡ‚ΡŒ
            self.shotSound.play() # ΠΈΠ³Ρ€Π°Π΅ΠΌ Π·Π²ΡƒΠΊ выстрСла
            self.bullet.setPos(self.weapon_pos) # ΠŸΡƒΠ»Ρ Π±ΡƒΠ΄Π΅Ρ‚ спавнится Π²Π½ΡƒΡ‚Ρ€ΠΈ ΠΏΡƒΡˆΠΊΠΈ
            self.bullet.setY(self.bullet, -11 * dt) # Π‘Π΄Π²ΠΈΠ³Π°Π΅ΠΌ ΠΏΡƒΠ»ΡŽ Π½Π° ΠΎΠ³Ρ€ΠΎΠΌΠ½ΠΎΠΉ скорости Π²ΠΏΠ΅Ρ€Ρ‘Π΄

    def check_loss(self):
        if self.state == 0: # Ссли ΠΆΠΈΠ·Π½Π΅ΠΉ Ρƒ корабля Π½Π΅ ΠΎΡΡ‚Π°Π»ΠΎΡΡŒ
            self.black_light() # Π²ΠΊΠ»ΡŽΡ‡ΠΈΠΌ Ρ‡Ρ‘Ρ€Π½Ρ‹ΠΉ свСт
            self.weapon_hide() # ΡƒΠ±Π΅Ρ€Ρ‘ΠΌ ΠΎΡ€ΡƒΠΆΠΈΠ΅
            self.info = OnscreenText(text='ΠΏΠΎΡ€Π°ΠΆΠ΅Π½ΠΈΠ΅', style=1, font=self.font,
                                     fg=(1,1,1,1),
                            pos=(-1.3, -0.5), align=TextNode.ALeft, scale=0.3) # напишСм ΠΎ ΠΏΠΎΡ€Π°ΠΆΠ΅Π½ΠΈΠΈ
            self.crackSound.play() # ΠΈΠ³Ρ€Π°Π΅ΠΌ Π·Π²ΡƒΠΊ Π²Π·Ρ€Ρ‹Π²Π°


    def setKey(self, key, value):
        self.keyMap[key] = value # Π”Π΅Π»Π°Π΅ΠΌ ΠΌΠ΅Ρ…aΠ½uΠ·ΠΌ наТатия клавиш.

    def move(self, task):

        ''' Π”Π΅Π»Π°Π΅ΠΌ Ρ„ΡƒΡ†Π½ΠΊΡ†ΠΈΡŽ двиТСния ΠΈΠ³Ρ€ΠΎΠΊΠ° '''

        dt = globalClock.getDt() - .005 # CΠΊΠΎΡ€ΠΎΡΡ‚ΡŒ двиТСния

        # ΠŸΠΎΠ²ΠΎΡ€ΠΎΡ‚ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ Π²Π»Π΅Π²ΠΎ ΠΈ Π²ΠΏΡ€Π°Π²ΠΎ

        if self.keyMap["cam-left"]:
            self.camera.setX(self.camera, -20 * dt) # МСняСм ΠΏΠΎΠ»ΠΎΠΆΠ΅Π½ΠΈΠΊΠ° ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ ΠΏΠΎ икс. Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ получаСтся илюзия ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚Π° ΡƒΠ³Π»Π° Π»ΡƒΡ‡Π°. Но Π½Π° самом Π΄Π΅Π»Π΅ ΠΊΠ°ΠΌΠ΅Ρ€Π° просто пСрСмСщаСтся.
        if self.keyMap["cam-right"]:
            self.camera.setX(self.camera, +20 * dt) # Π’ΠΎΠΆΠ΅ самоС, Ρ‡Ρ‚ΠΎ ΠΈ Π½Π°Π²Π΅Ρ€Ρ…Ρƒ.

        startpos = self.droid.getPos() # Π‘Π΄Π΅Π»Π°Π΅ΠΌ ΡƒΠ΄ΠΎΠ±Π½ΡƒΡŽ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ ΠΈΠ³Ρ€ΠΎΠΊΠ°

        if self.keyMap["left"]:
            self.droid.setH(self.droid.getH() + 300 * dt)
            self.enemy.setY(self.enemy, 1 * dt)
        if self.keyMap["right"]:
            self.droid.setH(self.droid.getH() - 300 * dt)
            self.enemy.setY(self.enemy, -1 * dt)
        if self.keyMap["forward"]:
            self.droid.setY(self.droid, -25 * dt)
            self.enemy.setX(self.enemy, 1 * dt)
            # Π‘Π΄Π΅Π»Π°Π΅ΠΌ ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½ΠΎΠ΅ условиС ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ ΡƒΠ±Ρ€Π°Π½ΠΎ ΠΎΡ€ΡƒΠΆΠΈΠ΅ ΠΈΠ»ΠΈ Π½Π΅Ρ‚
            if not self.hide_weapon:
                self.weapon_pos = self.droid.getX(), self.droid.getY() + 0.7, 3
                self.weapon.setPos(self.weapon_pos) # ОбновляСм ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΏΡƒΡˆΠΊΠΈ
            else:
                self.weapon_pos = self.droid.getX(), self.droid.getY() + 0.7, 3
                self.flash.setPos(self.weapon_pos)


        camvec = self.droid.getPos() - self.camera.getPos() # Π²Π΅ΠΊΡ‚ΠΎΡ€ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹
        camvec.setZ(0) # 0 высота Π²Π΅ΠΊΡ‚ΠΎΡ€Π°
        camdist = camvec.length() # дистанция ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ ΠΎΡ‚ Π΄Ρ€ΠΎΠΈΠ΄Π°
        camvec.normalize() # Π½ΠΎΡ€ΠΌΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ Π²Π΅ΠΊΡ‚ΠΎΡ€ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹
        if camdist > 10.0: # Ссли дистанция ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ большС 10, Ρ‚ΠΎ смСщаСм ΠΊΠ°ΠΌΠ΅Ρ€Ρƒ Π·Π° Π΄Ρ€ΠΎΠΎΠΈΠ΄ΠΎΠΌ
            self.camera.setPos(self.camera.getPos() + camvec * (camdist - 10))
            camdist = 10.0 # Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ дистанция Π±ΡƒΠ΄Π΅Ρ‚ снова 10
        if camdist < 5.0: # Ссли дистагцтя ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ мСньшС 5, Ρ‚ΠΎ...
            self.camera.setPos(self.camera.getPos() - camvec * (5 - camdist)) # сдвигаСм ΠΊΠ°ΠΌΠ΅Ρ€Ρƒ
            camdist = 5.0 # всё обновляСм
            
        self.camera.lookAt(self.floater) # Π²ΠΎΡ‚ ΠΈ пригодился наш floater


        return task.cont # Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌ Π·Π°Π΄Π°Ρ‡Ρƒ

    def addInstructions(self, pos, msg):
        return OnscreenText(text=msg, style=1, fg=(1,1,1,1), font=self.inst_font, pos=(-1.3, pos), align=TextNode.ALeft, scale = .04, shadow=(0,0,0,1)) # Ѐункция ΠΎ Ρ‚ΠΎΠΌ, ΠΊΠ°ΠΊ ΡƒΠΏΡ€Π°Π²Π»ΡΡ‚ΡŒ

    def addTitle(self, text):
        return OnscreenText(text=text, style=1, fg=(1, 1, 1, 1), scale=0.2,
                            parent=base.a2dBottomRight, align=TextNode.ARight,
                            pos=(-0.1, 0.09), shadow=(0, 0, 0, 1), font=self.font) # Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ тСкстового Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ° с ΡˆΡ€ΠΈΡ„Ρ‚ΠΎΠΌ ΠΈ ΠΏΠΎΠ·ΠΈΡ†ΠΈΠ΅ΠΉ
    

droid = DroidShooter() # Π‘ΠΎΠ·Π΄Π°Π΄ΠΈΠΌ экзСмпляр класса нашСй ΠΈΠ³Ρ€Ρ‹
droid.run() # 3апустим ΠΈΠ³Ρ€Ρƒ


# Ρ€Π°Π·Ρ€ΠΎΠ±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ :
# Π“Π»Π°Π²Π½Ρ‹ΠΉ Π°Π²Ρ‚ΠΎΡ€ : ma3rx
# ΠŸΠΎΠΌΠΎΡ‰Π½ΠΈΠΊ : panda3dmastercoder( присоСдСнился ΠΊ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Ρƒ 31 января, 2021 Π³ΠΎΠ΄Π°, 12:??)
# Π Π΅ΠΊΠ»Π°ΠΌΡ‰ΠΈΠΊ : rdb (написал ΠΏΠ΅Ρ€Π²ΠΎΠ΅ сообщСниС Π½Π° Ρ„ΠΎΡ€ΡƒΠΌΠ΅ 6 фСвраля 2021 Π³ΠΎΠ΄Π°, 20:11)

Added collision for weapon, bug fixes fight and more!
Download now!

Hi! I create 3.0.5 update - add White-Black mode.
Delete directory ./shaders.
New code droid.py :

#!/usr/bin/env python
# -*- coding: utf_8 -*-

# Π‘ΠΎΠ·Π΄Π°Π½ΠΎ : 22 число, ΡΠ½Π²Π°Ρ€ΡŒ, 2021 Π³ΠΎΠ΄

# Π˜ΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΡƒΠ΅ΠΌ всС Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹Π΅ инструмСнты
from direct.showbase.ShowBase import ShowBase
from panda3d.core import CollisionTraverser, CollisionNode
from panda3d.core import CollisionHandlerPusher, CollisionSphere, CollisionInvSphere
from panda3d.core import Filename, AmbientLight, DirectionalLight
from panda3d.core import PandaNode, NodePath, Camera, TextNode
from direct.particles.Particles import Particles
from direct.particles.ParticleEffect import ParticleEffect
from panda3d.core import PointLight, Spotlight
from panda3d.core import CollideMask
from panda3d.core import loadPrcFileData
from panda3d.core import *
from direct.gui.OnscreenText import OnscreenText
from direct.gui.OnscreenImage import OnscreenImage
from direct.gui.DirectButton import DirectButton
from direct.gui.DirectSlider import DirectSlider
from direct.actor.Actor import Actor
import random
import sys
import time
import os
import math


VERSION = '3.0.5'

settings = ['window-title Droid Game ' +  VERSION,
            'fullscreen 0']
            

loadPrcFileData('', settings[0]) # Π‘Π΄Π΅Π»Π°Π΅ΠΌ Π½Π΅ стандартный Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ (Π²ΠΎΠ·ΠΌΡ‘ΠΌ Π΅Π³ΠΎ ΠΈΠ· ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ settings)
loadPrcFileData('', settings[1]) # Π½Π΅ Π±ΡƒΠ΄Π΅ΠΌ Π΄Π΅Π»Π°Ρ‚ΡŒ полноэкранный Ρ€Π΅ΠΆΠΈΠΌ

# Π‘ΠΎΠ·Π΄Π°Π΄ΠΈΠΌ Π³Π»Π°Π²Π½Ρ‹ΠΉ класс нашСй ΠΈΠ³Ρ€Ρ‹
class DroidShooter(ShowBase):
    def __init__(self):
        ShowBase.__init__(self) # Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ всС сСлфы ΠΈΠ· direct
        self.speed = 1800 # ΡΠΊΠΎΡ€ΠΎΡΡ‚ΡŒ двигатСля
        self.GB = False # НЕ Ρ‡Ρ‘Ρ€Π½ΠΎ-Π±Π΅Π»Ρ‹ΠΉ Ρ€Π΅ΠΆΠΈΠΌ
        self.menu() # звпуск мСню
        
    def menu(self):
        
        base.enableParticles() # ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ эффСкт Π΄Ρ‹ΠΌΠ°

        self.win.setClearColor((0, 0, 0, 1)) # Π—Π°ΠΊΡ€Π°ΡˆΠΈΠ²Π°Π΅ΠΌ ΠΏΠΎΠ²Π΅Ρ€Ρ…Π½ΠΎΡΡ‚ΡŒ Ρ‡Ρ‘Ρ€Π½Ρ‹ΠΌ. Π”Π΅Π»ΠΎ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ Π² этом ΠΈΠ³Ρ€ΠΎΠ²ΠΎΠΌ Π΄Π²ΠΈΠΆΠΊΠ΅ ΠΏΠΎΠ²Π΅Ρ€Ρ…Π½ΠΎΡΡ‚ΡŒ Π·Π°ΠΊΡ€Π°ΡˆΠΈΠ²Π°Π΅Ρ‚ΡΡ сСрым.
        self.font = loader.loadFont('./fonts/doom_font.ttf') # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ ΡˆΡ€ΠΈΡ„Ρ‚ ΠΈΠ· ΠΈΠ³Ρ€Ρ‹ doom
        self.inst_font = loader.loadFont('./fonts/arial.ttf') # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ ΡˆΡ€ΠΈΡ„Ρ‚ arial

        self.crackSound = loader.loadMusic('./sounds/crack.wav') # Π·Π²ΡƒΠΊ Π²Π·Ρ€Ρ‹Π²Π° корабля
        self.shotSound = loader.loadMusic('./sounds/shot.wav') # Π·Π²ΡƒΠΊ выстрСла
        self.startSound = loader.loadMusic('./sounds/started.wav') # Π·Π²ΡƒΠΊ запуска
        self.errorSound = loader.loadMusic('./sounds/error.wav') # Π·Π²ΡƒΠΊ запуска
        self.errorSound.setVolume(1) # полная Π³Ρ€ΠΎΠΌΠΊΠΎΡΡ‚ΡŒ Π·Π²ΡƒΠΊΠ°
        self.startSound.setVolume(1) # полная Π³Ρ€ΠΎΠΌΠΊΠΎΡΡ‚ΡŒ Π·Π²ΡƒΠΊΠ°
        self.crackSound.setVolume(1) # полная Π³Ρ€ΠΎΠΌΠΊΠΎΡΡ‚ΡŒ Π·Π²ΡƒΠΊΠ°
        self.shotSound.setVolume(1) # полная Π³Ρ€ΠΎΠΌΠΊΠΎΡΡ‚ΡŒ Π·Π²ΡƒΠΊΠ°
        self.startSound.play() # ΠΈΠ³Ρ€Π°Π΅ΠΌ Π·Π²ΡƒΠΊ запуска ΠΈΠ³Ρ€Ρ‹

        self.button_start = DirectButton(pos=(0.7, 0, 0.4), text="CTAPT",
                                   scale=.2, pad=(.2, .2),
                                   command=self.load_game) # ΠΊΠ½ΠΎΠΏΠΊΠ° запуска ΠΈΠ³Ρ€Ρ‹

        self.gb_start = DirectButton(pos=(0.7, 0, 0.1), text="GB",
                                   scale=.2, pad=(.2, .2),
                                   command=self.gb_mode) # ΠΊΠ½ΠΎΠΏΠΊΠ° запуска ΠΈΠ³Ρ€Ρ‹  Π² Ρ‡Ρ‘Ρ€Π½ΠΎ-Π±Π΅Π»ΠΎΠΌ Ρ€Π΅ΠΆΠΈΠΌΠ΅      

        self.slider_sun = DirectSlider(pos=(0.1, 0, .75), scale=0.8, value=0.5,
                                    command=self.set_sun_interval)


        self.title = self.addTitle("Droid game " + VERSION)
        
        # НапСчатаСм ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅
        self.inst1 = self.addInstructions(0.95, u"[ESC]: Π’Ρ‹Ρ…ΠΎΠ΄")
        self.inst2 = self.addInstructions(0.90, u"[Left Arrow]: ΠŸΠΎΠ²ΠΎΡ€ΠΎΡ‚ Π΄Ρ€ΠΎΠΈΠ΄Π° Π² Π»Π΅Π²ΠΎ")
        self.inst3 = self.addInstructions(0.85, u"[Right Arrow]: ΠŸΠΎΠ²ΠΎΡ€ΠΎΡ‚ Π΄Ρ€ΠΎΠΈΠ΄Π° Π² ΠΏΡ€Π°Π²ΠΎ")
        self.inst4 = self.addInstructions(0.80, u"[Up Arrow]: Π’ΠΏΠ΅Ρ€Π΅Π΄")
        self.inst5 = self.addInstructions(0.75, u"[a]: ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ Π² ΠΏΡ€Π°Π²ΠΎ")
        self.inst6 = self.addInstructions(0.70, u"[d]: ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ Π² Π»Π΅Π²ΠΎ")
        self.inst7 = self.addInstructions(0.65, u"[Left Arrow + Up arrow]: ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚ Π΄Ρ€ΠΎΠΈΠ΄Π° Π² Π»Π΅Π²ΠΎ ΠΈ Π²ΠΏΠ΅Ρ€Ρ‘Π΄")
        self.inst8 = self.addInstructions(0.60, u"[Right Arrow + Up arrow]: ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚ Π΄Ρ€ΠΎΠΈΠ΄Π° Π² ΠΏΡ€Π°Π²ΠΎ ΠΈ Π²ΠΏΠ΅Ρ€Ρ‘Π΄")
        self.inst9 = self.addInstructions(0.55, u"[a + Up arrow]: ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ Π² ΠΏΡ€Π°Π²ΠΎ ΠΈ Π²ΠΏΠ΅Ρ€Ρ‘Π΄")
        self.inst10 = self.addInstructions(0.50, u"[d + Up arrow]: ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ Π² Π»Π΅Π²ΠΎ ΠΈ Π²ΠΏΠ΅Ρ€Ρ‘Π΄")
        self.inst11 = self.addInstructions(0.45, u"[space]: ΡΡ‚Ρ€Π΅Π»ΡŒΠ±Π°")
        self.inst12 = self.addInstructions(0.40, u"[s]: Π΄ΠΎΡΡ‚Π°Ρ‚ΡŒ Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊ")
        self.inst13 = self.addInstructions(0.35, u"[w]: ΡƒΠ±Ρ€Π°Ρ‚ΡŒ ΠΎΡ€ΡƒΠΆΠΈΠ΅")
        self.inst14 = self.addInstructions(0.30, u"[f]: ΠΏΠΎΠ»Π½Ρ‹ΠΉ Ρ€Π°Π·Π³ΠΎΠ½(ОПАБНО!)")
        self.inst15 = self.addInstructions(0.25, u"[0]: ΠΏΠΎΠΆΠ°Ρ€ΠΎΡ‚ΡƒΡˆΠΈΡ‚Π΅Π»ΡŒΠ½Π°Ρ систСма")

        self.accept("escape", sys.exit) # ΠŸΡ€ΠΈ Π½Π°ΠΆΠ°Ρ‚ΠΈΠΈ клавиши Esc Π²Ρ‹Ρ…ΠΎΠ΄ΠΈΠΌ.

    def set_sun_interval(self):
        self.sun_interval = self.slider_sun.guiItem.getValue() * 100 # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ слайдСрноС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΡƒΠΌΠ½ΠΎΠΆΠ΅Π½ΠΎΠ΅ Π½Π° 500, Π΄Π° Ρ‚Ρ€Π°Ρ‡Ρƒ ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΡŽ Π½ΠΎ ΠΌΠ½Π΅ каТСтся ΠΌΠ½ΠΎΠ³ΠΈΠΌ ΠΏΠ»Π΅Π²Π°Ρ‚ΡŒ Π½Π° ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΡŽ мСню, ΠΈΠ±ΠΎ Ρ‚Π°ΠΊΠΎΠ³ΠΎ понятия просто Π½Π΅Ρ‚Ρƒ :)

    def gb_mode(self):
        '''Π²ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ Ρ‡Ρ‘Ρ€Π½ΠΎΠ±Π΅Π»ΠΎΠ³ΠΎ Ρ€Π΅ΠΆΠΈΠΌΠ°'''
        self.GB = True

    def load_game(self):
        self.button_start.hide() # ΡƒΠ΄Π°Π»ΠΈΠΌ ΠΊΠ½ΠΎΠΏΠΊΡƒ старта
        self.gb_start.hide() # ΡƒΠ΄Π°Π»ΠΈΠΌ ΠΊΠ½ΠΎΠΏΠΊΡƒ Ρ‡Ρ‘Ρ€Π½ΠΎ Π±Π΅Π»ΠΎΠ³ΠΎ Ρ€Π΅ΠΆΠΈΠΌΠ°.
        self.title.hide() # ΡƒΠ΄Π°Π»ΠΈΠΌ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ ΠΈΠ³Ρ€Ρ‹
        # ΡƒΠ΄Π°Π»ΠΈΠΌ ΠΊΠ½ΠΎΠΏΠΊΠΈ управлСния
        self.inst1.hide()
        self.inst2.hide()
        self.inst3.hide()
        self.inst4.hide()
        self.inst5.hide()
        self.inst6.hide()
        self.inst7.hide()
        self.inst8.hide()
        self.inst9.hide()
        self.inst10.hide()
        self.inst11.hide()
        self.inst12.hide()
        self.inst13.hide()
        self.inst14.hide()
        self.inst15.hide()
        self.slider_sun.hide() # удаляСм слайдСр солнца
        
        self.keyMap = {
            "left": 0, "right": 0, "forward": 0, "cam-left": 0, "cam-right": 0} # Π‘ΠΎΠ·Π΄Π°Π΄ΠΈΠΌ ΡΠ»ΠΎΠ²Π°Ρ€ΡŒ ΠΊΠ½ΠΎΠΏΠΎΠΊ, ΠΏΠΎ ΠΈΡ… Π½Π°ΠΆΠ°Ρ‚ΠΈΡŽ        

        # РисуСм Π·Π²Ρ‘Π·Π΄Ρ‹

        self.sky = loader.loadModel("./models/sky/solar_sky_sphere") # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ модСль космоса(это сфСра)

        self.sky_tex = loader.loadTexture("./tex/stars_1k_tex.jpg") # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ тСкстуру
        self.sky.setTexture(self.sky_tex, 1) # Π·Π°Ρ€Π΅Π½Π΄Π΅Ρ€ΠΈΠΌ тСкстуру Π½Π° Π½Π΅Π±ΠΎ
        self.sky.reparentTo(render) # ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ Π½Π΅Π±ΠΎ
        self.sky.setScale(40000) # Ρ€Π°ΡΡˆΠΈΡ€ΠΈΠΌ Π½Π΅Π±ΠΎ Π΄ΠΎ максимальной Π²Π΅Π»ΠΈΡ‡ΠΈΠ½Ρ‹ panda3d

        self.environ = loader.loadModel("models/world/falcon.egg") # Π—Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ ΡƒΠΆΠ΅ созданный Π² blender ΠΌΠΈΡ€.
        self.environ.reparentTo(render) # Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ модСль ΠΌΠΈΡ€Π° Π² ΠΎΠΊΠ½ΠΎ

        droidStartPos = (-1, 0, 1.5 ) # Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ ΡΡ‚Π°Ρ€Ρ‚ΠΎΠ²ΡƒΡŽ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π² ΠΌΠΈΡ€Π΅.
        enemyStartPos = (-6, 1, 0.5) # Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ°-Π΄Ρ€ΠΎΠΈΠ΄Π°.
        self.droid = Actor("models/player/seeker.egg") # Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ модСль ΠΈΠ³Ρ€ΠΎΠΊΠ° (созданная Π² blender)
        self.enemy = Actor("models/enemies/r2d2/r2d2.egg") # Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ модСль ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ° (созданная Π² blender)
        self.droid.reparentTo(render) # ΠŸΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Π΅ΠΌ модСль ΠΈΠ³Ρ€ΠΎΠΊΠ° Π² наш ΠΌΠΈΡ€.
        self.enemy.reparentTo(render) # ΠŸΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Π΅ΠΌ модСль ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ° Π² наш ΠΌΠΈΡ€.
        self.droid.setScale(1) # Π”Π΅Π»Π°Π΅ΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ€ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π½Π° 1
        self.enemy.setScale(1) # Π”Π΅Π»Π°Π΅ΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ€ ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ° Π½Π° 1
        self.droid.setPos(droidStartPos) # Π‘Ρ‚Π°Π²ΠΈΠΌ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π½Π° Ρ€Π°Π½Π΅Π΅ ΡΠΎΠ·Π΄Π°Π½ΡƒΡŽ Π½Π°ΠΌΠΈ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ
        self.enemy.setPos(enemyStartPos) # Π‘Ρ‚Π°Π²ΠΈΠΌ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ° Π½Π° Ρ€Π°Π½Π΅Π΅ ΡΠΎΠ·Π΄Π°Π½ΡƒΡŽ Π½Π°ΠΌΠΈ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ

        self.weapon = Actor('models/weapon/lightsaber.egg') # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ ΠΎΡ€ΡƒΠΆΠΈΠ΅
        self.bullet = Actor('models/weapon/bullet/bullet.egg.pz') # Π—Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ ΠΏΡƒΠ»ΡŽ
        self.flash = Actor('models/whishlyflash/handlamp.egg') # Π—Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊ
               
        self.weapon.reparentTo(render) # пСрСмСстим ΠΎΡ€ΡƒΠΆΠΈΠ΅ Π² наш ΠΌΠΈΡ€
        self.bullet.reparentTo(render) # пСрСмСстим ΠΏΡƒΠ»ΡŽ Π² ΠΌΠΈΡ€ Π½ΠΎ появится ΠΎΠ½Π° сама Π½Π΅ скоро
        self.flash.reparentTo(render) # пСрСмСстим Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊ Π² наш ΠΌΠΈΡ€
        self.weapon.setScale(.5) # Π·Π°Π΄Π°Π΄ΠΈΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ€ ΠΏΡƒΡˆΠΊΠΈ
        self.bullet.setScale(.5) # Π·Π°Π΄Π°Π΄ΠΈΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ€ ΠΏΡƒΠ»ΠΈ
        self.flash.setScale(.5) # Π·Π°Π΄Π°Π΄ΠΈΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ€ Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊΠ°

        # враТСский ΠΈΡΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»ΡŒ
        self.fighter = Actor('models/fighter/fighter.egg') # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ ΠΌΠΎΠ΄Π΅Π»ΡŒΠΊΡƒ истрСбитСля
        self.fighter.reparentTo(render) # ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ ΠΈΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»ΡŒ
        self.fighter.setPos(0, 90, 0) # позиция истрСбитСля
                

        self.weapon_pos = self.droid.getX(), self.droid.getY() + 0.7, 1 # ΠŸΠΎΠ·ΠΈΡ†ΠΈΡ ΠΏΡƒΡˆΠΊΠΈ
        
        self.weapon.setPos(self.weapon_pos) # ΠŸΠΎΠΌΠ΅ΡΡ‚ΠΈΠΌ ΠΎΡ€ΡƒΠΆΠΈΠ΅ Ρ‡ΡƒΡ‚ΡŒ Π²Ρ‹ΡˆΠ΅ ΠΈΠ³Ρ€ΠΎΠΊΠ°
        
        
        self.spotlight = camera.attachNewNode(Spotlight("spotlight")) # ΠšΠΎΠ½Ρ„ΠΈΠ³ΠΈ Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊΠ°
        self.spotlight.node().setColor((.3, .3, .3, 1))
        self.spotlight.node().setSpecularColor((0, 0, 0, 1))

        self.floater = NodePath(PandaNode("floater")) 
        self.floater.reparentTo(self.droid)
        self.floater.setZ(2.0)

        self.accept("escape", sys.exit) # ΠŸΡ€ΠΈ Π½Π°ΠΆΠ°Ρ‚ΠΈΠΈ клавиши Esc Π²Ρ‹Ρ…ΠΎΠ΄ΠΈΠΌ.
        
        self.accept("arrow_left", self.setKey, ["left", True]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ Π²Π»Π΅Π²ΠΎ - ΠΏΠΎΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π²Π»Π΅Π²ΠΎ
        self.accept("arrow_right", self.setKey, ["right", True]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ Π²ΠΏΡ€Π°Π²ΠΎ - ΠΏΠΎΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π²ΠΏΡ€Π°Π²ΠΎ
        self.accept("arrow_up", self.setKey, ["forward", True]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ Π²ΠΏΠ΅Ρ€Ρ‘Π΄ - ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄
        self.accept("a", self.setKey, ["cam-left", True]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ a - Ρ€Π°Π·Π²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΊΠ°ΠΌΠ΅Ρ€Ρƒ Π²ΠΎΠΊΡ€ΡƒΠ³ нашСй модСльки
        self.accept("d", self.setKey, ["cam-right", True]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ s - Ρ€Π°Π·Π²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΊΠ°ΠΌΠ΅Ρ€Ρƒ Π²ΠΎΠΊΡ€ΡƒΠ³ нашСй модСльки
        self.accept("arrow_left-up", self.setKey, ["left", False]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ Π²Π²Π΅Ρ€Ρ…+Π²Π»Π΅Π²ΠΎ - ΠΏΠΎΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π²Π»Π΅Π²ΠΎ ΠΈ ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄
        self.accept("arrow_right-up", self.setKey, ["right", False]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ Π²Π²Π΅Ρ€Ρ…+ΠΏΡ€Π°Π²ΠΎ - ΠΏΠΎΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π²ΠΏΡ€Π°Π²ΠΎ ΠΈ ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄
        self.accept("arrow_up-up", self.setKey, ["forward", False]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ Π²Π²Π΅Ρ€Ρ…+Π²Π²Π΅Ρ€ΡŠ - ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄ ΠΈ ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄
        self.accept("a-up", self.setKey, ["cam-left", False]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ a+Π²ΠΏΠ΅Ρ€Ρ‘Π΄ - ΠΏΠΎΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΊΠ°ΠΌΠ΅Ρ€Ρƒ Π²Π»Π΅Π²ΠΎ ΠΈ ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄
        self.accept("d-up", self.setKey, ["cam-right", False]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ s+Π²ΠΏΠ΅Ρ€Ρ‘Π΄ - ΠΏΠΎΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΊΠ°ΠΌΠ΅Ρ€Ρƒ Π²ΠΏΡ€Π°Π²ΠΎ ΠΈ ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄

        self.accept("space", self.shot) # ΠΏΡ€ΠΈ ΠΏΡ€ΠΎΠ±Π΅Π»Π΅ стрСляСм
        self.accept("s", self.toggleLights, [[self.spotlight]]) # Π’ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊ
        self.accept("w", self.weapon_hide) # ΠΏΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ w - ΡƒΠ±Π΅Ρ€Ρ‘ΠΌ ΠΎΡ€ΡƒΠΆΠΈΠ΅.

        base.enableParticles() # Π’ΠΊΠ»ΡŽΡ‡Π°Π΅ΠΌ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ Π΄Ρ‹ΠΌΠ°
        self.t = loader.loadModel("models/weapon/lightsaber.egg") # Π—Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ Π΅Ρ‰Ρ‘ ΠΎΡ€ΡƒΠΆΠΈΠ΅
        self.t.reparentTo(render) # ΠŸΠ΅Ρ€Π΅ΠΌΠ΅ΡΡ‚ΠΈΠΌ ΠΎΡ€ΡƒΠΆΠΈΠ΅ Π² наш ΠΌΠΈΡ€
        self.p = ParticleEffect() # Π’ΠΊΠ»ΡŽΡ‡ΠΈΠΌ эффСкт Π΄Ρ‹ΠΌΠ°
        self.accept('f', self.particle_start) # ΠΏΡ€ΠΈ Π½Π°ΠΆΠ°Ρ‚ΠΈΠΈ f(ΠΎΡ‚ force) -  Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ Ρ„Π°ΠΉΠ» Π΄Ρ‹ΠΌΠ° ΠΈ пСрСмСстим Π² ΠΊΠΎΠ½Ρ„ΠΈΠ³ Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΈΠΌΠ΅Π½Π½ΠΎ эта анимация стала ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ΠΌ Π΄Ρ‹ΠΌΠ°
        self.accept('0', self.fountain) # ΠΏΡ€ΠΈ  Π½Π°ΠΆΠ°Ρ‚ΠΈΠΈ ΠΊΠ½ΠΎΠΏΠΎΠΊ f+o(fountain) Π²ΠΊΠ»ΡŽΡ‡ΠΈΠΌ ΠΏΠΎΠΆΠ°Ρ€ΠΎΡ‚ΡƒΡˆΠΈΡ‚Π΅Π»ΡŒΠ½ΡƒΡŽ систСму

        taskMgr.add(self.move, "moveTask") # ДобавляСм Π·Π°Π΄Π°Ρ‡Ρƒ Π² наш Π΄Π²ΠΈΠΆΠΎΠΊ

        self.isMoving = False # Π‘Ρ‚Π°Π²ΠΈΠΌ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ isMoving Π½Π° False(Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΌΠ΅Π½ΡΡ‚ΡŒ это Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅) Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΈΠ³Ρ€ΠΎΠΊ ΠΈΠ·Π½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎ стоял.
        # Π”Π΅Π»Π°Π΅ΠΌ Ρ‚Π°ΠΊ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ свСт Π±Ρ‹Π» ΠΈΠ·Π½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎ Π²Ρ‹ΠΊΠ»ΡŽΡ‡Π΅Π½.
        self.disableMouse() # ΠžΡ‚ΠΊΠ»ΡŽΡ‡Π°Π΅ΠΌ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π΅Π½ΠΈΠ΅ Ρ‡Π΅Ρ€Π΅Π· ΠΌΡ‹ΡˆΠΊΡƒ
        self.camera.setPos(self.droid.getX(), self.droid.getY() + 1, 3) # Π‘Ρ‚Π°Π²ΠΈΠΌ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ Ρ‡ΡƒΡ‚ΡŒ большС ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ ΠΈΠ³Ρ€ΠΎΠΊΠ°

        self.black_light() # Π‘Π΄Π΅Π»Π°Π΅ΠΌ Π²Ρ‹ΠΊΠ»ΡŽΡ‡Π΅Π½Π½Ρ‹ΠΉ свСт

        self.state = 100 # БостояниС корабля
        self.state_info = OnscreenText(text='ΠΊΠΎΡ€Π°Π±Π»ΡŒ :' + str(self.state), pos=(0.5, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля
                
        self.check_loss() # ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ ΠΏΠΎΡ€Π°ΠΆΠ΅Π½ΠΈΠ΅
        self.hide_weapon = False # ΠŸΠΎΡΡ‚Π°Π²ΠΈΠΌ, Ρ‡Ρ‚ΠΎ ΠΎΡ€ΡƒΠΆΠΈΠ΅ Π½Π΅ ΡƒΠ±Ρ€Π°Π½ΠΎ
        self.steam_pos = random.randrange(0, 5), random.randrange(0, 5), random.randrange(0, 5)
        self.fountain_pos = random.randrange(0, 5), random.randrange(0, 5), random.randrange(0, 1)

        self.motor_pos1 = 25.238849639892578, 8.962211608886719, 1.5 # позиция ΠΏΠ΅Ρ€Π²ΠΎΠ³ΠΎ ΠΌΠΎΡ‚ΠΎΡ€Π°
        self.motor_pos2 = -20.676218032836914, 10.55816650390625, 1.5 # позиция Π²Ρ‚ΠΎΡ€ΠΎΠ³ΠΎ ΠΌΠΎΡ‚ΠΎΡ€Π°

        self.motor1 = self.loadParticleConfig('special_effects/steam_critic+/fireish.ptf', self.motor_pos1) # ΠΌΠΎΡ‚ΠΎΡ€ 1
        self.motor2 = self.loadParticleConfig('special_effects/steam_critic+/fireish.ptf', self.motor_pos2) # ΠΌΠΎΡ‚ΠΎΡ€ 2

        self.state_info2 = OnscreenText(text='', pos=(-0.8, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля

        self.force = False # ΠŸΠΎΡΡ‚Π°Π²ΠΈΠΌ, Ρ‡Ρ‚ΠΎ Π½Π΅ Ρ€Π°Π·Π³ΠΎΠ½ΡΠ»ΠΈΡΡŒ

        # ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ ΠΊΠΎΠ»Π»ΠΈΠ·ΠΈΠΈ

        # Коллизия корабля(ΠΎΠ½ Ρƒ нас ΠΊΠ°ΠΊ главная ΠΊΠ°Ρ€Ρ‚Π°).
        self.cTrav = CollisionTraverser()
        pusher = CollisionHandlerPusher()
        
        environCenter = self.environ.getBounds().getCenter()
        environRad = self.environ.getBounds().getRadius()
        cNode = CollisionNode("environment")
        cNode.addSolid(CollisionInvSphere(environCenter, environRad))
        environC = self.environ.attachNewNode(cNode)

        # Коллизия Π΄Ρ€ΠΎΠΈΠ΄Π°.
        droidCenter = self.droid.getBounds().getCenter()
        droidRad = self.droid.getBounds().getRadius()
        cNode = CollisionNode("droid")
        cNode.addSolid(CollisionSphere(droidCenter, droidRad))
        droidC = self.droid.attachNewNode(cNode)
        
        pusher.addCollider(droidC, self.droid)
        self.cTrav.addCollider(droidC, pusher)

        # Коллизия ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ°.
        enemyCenter = self.enemy.getBounds().getCenter()
        enemyRad = self.enemy.getBounds().getRadius()
        cNode = CollisionNode("enemy")
        cNode.addSolid(CollisionSphere(enemyCenter, enemyRad))
        enemyC = self.enemy.attachNewNode(cNode)

        pusher.addCollider(enemyC, self.enemy)
        self.cTrav.addCollider(enemyC, pusher)

        # Коллизия враТСского истрСбитСля.
        fighterCenter = self.fighter.getBounds().getCenter()
        fighterRad = self.fighter.getBounds().getRadius()
        cNode = CollisionNode("fighter")
        cNode.addSolid(CollisionSphere(fighterCenter, fighterRad))
        fighterC = self.fighter.attachNewNode(cNode)

        pusher.addCollider(fighterC, self.fighter)
        self.cTrav.addCollider(fighterC, pusher)

        # Коллизия ΠΏΡƒΠ»ΠΈ.
        bulletCenter = self.bullet.getBounds().getCenter()
        bulletRad = self.bullet.getBounds().getRadius()
        cNode = CollisionNode("bullet")
        cNode.addSolid(CollisionSphere(bulletCenter, bulletRad))
        bulletC = self.bullet.attachNewNode(cNode)

        bulletCenter = self.bullet.getBounds().getCenter()
        bulletRad = self.bullet.getBounds().getRadius()
        cNode = CollisionNode("bullet")
        cNode.addSolid(CollisionSphere(bulletCenter, bulletRad))
        bulletC = self.bullet.attachNewNode(cNode)
        
        pusher.addCollider(bulletC, self.bullet)
        self.cTrav.addCollider(bulletC, pusher)

        # Коллизия ΠΏΡƒΡˆΠΊΠΈ. Π― Π±Ρ‹ Π½Π΅ сказал, Ρ‡Ρ‚ΠΎ это ΠΈΠΌΠ΅Π½Π½ΠΎ коллизия, скорСС это для рСалистичности
        weaponCenter = self.weapon.getBounds().getCenter()
        weaponRad = self.weapon.getBounds().getRadius()
        cNode = CollisionNode("weapon")
        cNode.addSolid(CollisionSphere(weaponCenter, weaponRad))
        weaponC = self.weapon.attachNewNode(cNode)
        
        pusher.addCollider(weaponC, self.weapon)
        self.cTrav.addCollider(weaponC, pusher)

        # солнцС(новая ΠΌΠ΅Ρ…Π°Π½ΠΈΠΊΠ° освСщСния)
        sun = DirectionalLight("sun")
        sun.set_color_temperature(6000)
        sun.color = sun.color * 4
        sun_path = render.attach_new_node(sun)
        sun_path.set_pos(10, -10, -10)
        sun_path.look_at(0, 0, 0)
        sun_path.hprInterval(self.sun_interval, (sun_path.get_h(), sun_path.get_p() - 360, sun_path.get_r()), bakeInStart=True).loop()
        render.set_light(sun_path)

        # Если  ΠΈΠ³Ρ€ΠΎΠΊ Π·Π°Ρ…ΠΎΡ‚Π΅Π» ΠΏΠΎΠΈΠ³Ρ€Π°Ρ‚ΡŒ Π² Ρ‡Ρ‘Ρ€Π½ΠΎΠ±Π΅Π»ΡƒΡŽ ΠΈΠ³Ρ€Ρƒ, ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΠΌ это
        if self.GB :        
            render.set_shader(Shader.load(Shader.SL_GLSL, "lighting.vert", "lighting.frag")) # Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ ΡˆΠ΅ΠΉΠ΄Π΅Ρ€Ρ‹ Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‚!



    def fight_force(self):
        # сдвиТСниС истрСбитСля Π·Π° нашим ΠΊΠΎΡ€Π°Π±Π»Ρ‘ΠΌ(ΠΎΡ‡Π΅Π½ΡŒ простым способом я сдСлал Ρ‚Π°ΠΊ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΈΡΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»ΡŒ Π·Π°ΠΆΠΈΠΌΠ°Π» нас(Π»Π΅Ρ‚Π°Π» Π² нашСм ΠΊΠ²Π°Π΄Ρ€Π°Ρ‚Π΅)) ΠΈ Π·Π°ΠΆΠΈΠΌΠ°Π΅Ρ‚ ΠΎΠ½ Ρ€Π΅Π°Π»ΡŒΠ½ΠΎ, сблиТая ΠΊ Π½Π°ΠΌ свой ΠΊΠ²Π°Π΄Ρ€Π°Ρ‚
        self.fighter.setY(self.fighter.getY() - self.speed) 
        self.fighter.setX(self.fighter.getX() - 10)    

        print(self.fighter.getX())


    def loadParticleConfig(self, filename, pos):
        self.p.cleanup()
        self.p = ParticleEffect()
        self.p.loadConfig(Filename(filename))

        self.p.start(self.t)
        self.p.setPos(pos)

    def particle_start(self):
        self.force = True # ΠŸΠΎΡΡ‚Π°Π²ΠΈΠΌ, Ρ‡Ρ‚ΠΎ ΠΌΡ‹ ΡƒΠΆΠ΅ Ρ€Π°Π·Π³ΠΎΠ½ΡΠ»ΠΈΡΡŒ
        # ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Π΅ΠΌ всС ΠΎΠ±ΡŒΠ΅ΠΊΡ‚Ρ‹ Π·Π° ΠΊΠΎΡ€Π°Π±Π»Ρ‘ΠΌ
        self.environ.setY(self.environ.getY() - self.speed) # нСсёмся Π²ΠΏΡ€Π°Π²ΠΎ
        self.droid.setY(self.droid.getY() - self.speed) # сдвигаСм Π΄Ρ€ΠΎΠΈΠ΄Π° Π·Π° ΠΊΠΎΡ€Π°Π±Π»Ρ‘ΠΌ
        self.enemy.setY(self.enemy.getY() - self.speed) # сдфигаСм ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ° Π·Π° ΠΊΠΎΡ€Π°Π±Π»Ρ‘ΠΌ
        self.weapon.setY(self.weapon.getY() - self.speed) # ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Π΅ΠΌ ΠΎΡ€ΡƒΠΆΠΈΠ΅
        self.flash.setY(self.flash.getY() - self.speed) # ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Π΅ΠΌ Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊ
        self.fight_force()

        self.state -= 1 # сдСлаСм мСньшС ΠΎΡ‡ΠΊΠΎΠ²
        self.state_info.hide() # ΡƒΠ΄Π°Π»ΠΈΠΌ тСкстовыС ΠΎΡ‡ΠΊΠΈ
        
        if self.state != 10 and self.state > 10:
            self.state_info.hide() # ΡƒΠ±ΠΈΡ€Π°Π΅ΠΌ ΠΏΡ€Π΅Π΄Π΅Π΄ΡƒΡ‰Π΅Π΅ сообщСниС ΠΎ Тизнях корабля
            self.state_info = OnscreenText(text='ΠΊΠΎΡ€Π°Π±Π»ΡŒ :' + str(self.state), pos=(0.5, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля
            self.check_loss() # провСряСм ΠΏΠΎΡ€Π°ΠΆΠ΅Π½ΠΈΠ΅
            self.steam_pos = random.randrange(0, 5), random.randrange(0, 5) + 300, random.randrange(0, 5)
            self.loadParticleConfig('special_effects/steam/steam.ptf', self.steam_pos)
            self.errorSound.play() # ΠΈΠ³Ρ€Π°Π΅ΠΌ Π·Π²ΡƒΠΊ ошибки
            self.state_info2.hide() # ΡƒΠ±ΠΈΡ€Π°Π΅ΠΌ ΠΏΡ€Π΅Π΄Π΅Π΄ΡƒΡ‰Π΅Π΅ сообщСниС
            self.state_info2 = OnscreenText(text='Π΄Π²ΠΈΠ³Π°Ρ‚Π΅Π»ΡŒ нСисправСн', pos=(-0.8, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля
        else:
            self.state_info = OnscreenText(text='ΠΊΠΎΡ€Π°Π±Π»ΡŒ :' + str(self.state), pos=(0.5, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля
            self.check_loss() # провСряСм ΠΏΠΎΡ€Π°ΠΆΠ΅Π½ΠΈΠ΅
            self.steam_pos = random.randrange(0, 5), random.randrange(0, 5) + 300, random.randrange(0, 5)
            self.loadParticleConfig('special_effects/steam_critic/steam.ptf', self.steam_pos)
            self.errorSound.play() # ΠΈΠ³Ρ€Π°Π΅ΠΌ Π·Π²ΡƒΠΊ ошибки
            self.state_info2.hide()  # ΡƒΠ±ΠΈΡ€Π°Π΅ΠΌ ΠΏΡ€Π΅Π΄Π΅Π΄ΡƒΡ‰Π΅Π΅ сообщСниС
            self.state_info2 = OnscreenText(text='критичСскоС состояниС', pos=(-0.8, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля
    
        if self.state < 10:
            self.state_info.hide()
            self.state_info = OnscreenText(text='ΠΊΠΎΡ€Π°Π±Π»ΡŒ :' + str(self.state), pos=(0.5, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля
            self.check_loss() # провСряСм ΠΏΠΎΡ€Π°ΠΆΠ΅Π½ΠΈΠ΅
            self.steam_pos = random.randrange(0, 5), random.randrange(0, 5) + 300, random.randrange(0, 5)            
            self.loadParticleConfig('special_effects/steam_critic+/fireish.ptf', self.steam_pos)
            self.errorSound.play() # ΠΈΠ³Ρ€Π°Π΅ΠΌ Π·Π²ΡƒΠΊ ошибки
            self.state_info2.hide() # ΡƒΠ±ΠΈΡ€Π°Π΅ΠΌ ΠΏΡ€Π΅Π΄Π΅Π΄ΡƒΡ‰Π΅Π΅ сообщСниС
            self.state_info2 = OnscreenText(text='ΠΏΠ°Π΄Π°Π΅ΠΌ!', pos=(-0.8, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля


    def fountain(self):
        self.state_info2.hide() # ΡƒΠ±ΠΈΡ€Π°Π΅ΠΌ тСкст опасности
        if self.force:
            if self.state != 100:
                self.state += 1
                self.state_info.hide()
                self.state_info = OnscreenText(text='ΠΊΠΎΡ€Π°Π±Π»ΡŒ :' + str(self.state), pos=(0.5, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля

            self.fountain_pos = random.randrange(0, 5), random.randrange(0, 5) + 500, random.randrange(0, 1)    
            self.loadParticleConfig('special_effects/fountain/fountain.ptf', self.fountain_pos)

        else :
            if self.state != 100:
                self.state += 1
                self.state_info.hide()
                self.state_info = OnscreenText(text='ΠΊΠΎΡ€Π°Π±Π»ΡŒ :' + str(self.state), pos=(0.5, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля

            self.fountain_pos = random.randrange(0, 5), random.randrange(0, 5), random.randrange(0, 1)    
            self.loadParticleConfig('special_effects/fountain/fountain.ptf', self.fountain_pos)
        
        
    def black_light(self):
        # Π’Ρ‹ΠΊΠ»ΡŽΡ‡Π΅Π½Ρ‹ΠΉ свСт
        ambientLight = AmbientLight("ambientLight")
        ambientLight.setColor((0, 0, 0, 1))
        directionalLight = DirectionalLight("directionalLight")
        directionalLight.setDirection((-5, -5, -5))
        directionalLight.setColor((1, 1, 1, 1))
        directionalLight.setSpecularColor((1, 1, 1, 1))
        render.setLight(render.attachNewNode(ambientLight))
        render.setLight(render.attachNewNode(directionalLight))

    def weapon_hide(self):
        # Π£Π±Ρ€Π°Ρ‚ΡŒ ΠΎΡ€ΡƒΠΆΠΈΠ΅
        self.hide_weapon = True
        self.weapon.hide()

    def toggleLights(self, lights):
        # Π‘ΠΏΠ΅Ρ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠ΅ освСщСниС
        if self.hide_weapon:
            for light in lights:
                if render.hasLight(light):
                    render.clearLight(light)
                else:
                    render.setLight(light)
            
            self.flash.setPos(self.weapon_pos)
        else:
            return


    def shot(self):
        dt = globalClock.getDt() + 0.5 # CΠΊΠΎΡ€ΠΎΡΡ‚ΡŒ двиТСния
        if not self.hide_weapon : # Ссли ΠΎΡ€ΡƒΠΆΠΈΠ΅ ΡƒΠ±Ρ€Π°Π½ΠΎ Ρ‚ΠΎ ΠΌΡ‹ Π½Π΅ ΠΌΠΎΠΆΠ΅ΠΌ ΡΡ‚Ρ€Π΅Π»ΡΡ‚ΡŒ
            self.shotSound.play() # ΠΈΠ³Ρ€Π°Π΅ΠΌ Π·Π²ΡƒΠΊ выстрСла
            self.bullet.setPos(self.weapon_pos) # ΠŸΡƒΠ»Ρ Π±ΡƒΠ΄Π΅Ρ‚ спавнится Π²Π½ΡƒΡ‚Ρ€ΠΈ ΠΏΡƒΡˆΠΊΠΈ
            self.bullet.setY(self.bullet, -11 * dt) # Π‘Π΄Π²ΠΈΠ³Π°Π΅ΠΌ ΠΏΡƒΠ»ΡŽ Π½Π° ΠΎΠ³Ρ€ΠΎΠΌΠ½ΠΎΠΉ скорости Π²ΠΏΠ΅Ρ€Ρ‘Π΄

    def check_loss(self):
        if self.state == 0: # Ссли ΠΆΠΈΠ·Π½Π΅ΠΉ Ρƒ корабля Π½Π΅ ΠΎΡΡ‚Π°Π»ΠΎΡΡŒ
            self.black_light() # Π²ΠΊΠ»ΡŽΡ‡ΠΈΠΌ Ρ‡Ρ‘Ρ€Π½Ρ‹ΠΉ свСт
            self.weapon_hide() # ΡƒΠ±Π΅Ρ€Ρ‘ΠΌ ΠΎΡ€ΡƒΠΆΠΈΠ΅
            self.info = OnscreenText(text='ΠΏΠΎΡ€Π°ΠΆΠ΅Π½ΠΈΠ΅', style=1, font=self.font,
                                     fg=(1,1,1,1),
                            pos=(-1.3, -0.5), align=TextNode.ALeft, scale=0.3) # напишСм ΠΎ ΠΏΠΎΡ€Π°ΠΆΠ΅Π½ΠΈΠΈ
            self.crackSound.play() # ΠΈΠ³Ρ€Π°Π΅ΠΌ Π·Π²ΡƒΠΊ Π²Π·Ρ€Ρ‹Π²Π°


    def setKey(self, key, value):
        self.keyMap[key] = value # Π”Π΅Π»Π°Π΅ΠΌ ΠΌΠ΅Ρ…aΠ½uΠ·ΠΌ наТатия клавиш.

    def move(self, task):

        ''' Π”Π΅Π»Π°Π΅ΠΌ Ρ„ΡƒΡ†Π½ΠΊΡ†ΠΈΡŽ двиТСния ΠΈΠ³Ρ€ΠΎΠΊΠ° '''

        dt = globalClock.getDt() - .005 # CΠΊΠΎΡ€ΠΎΡΡ‚ΡŒ двиТСния

        # ΠŸΠΎΠ²ΠΎΡ€ΠΎΡ‚ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ Π²Π»Π΅Π²ΠΎ ΠΈ Π²ΠΏΡ€Π°Π²ΠΎ

        if self.keyMap["cam-left"]:
            self.camera.setX(self.camera, -20 * dt) # МСняСм ΠΏΠΎΠ»ΠΎΠΆΠ΅Π½ΠΈΠΊΠ° ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ ΠΏΠΎ икс. Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ получаСтся илюзия ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚Π° ΡƒΠ³Π»Π° Π»ΡƒΡ‡Π°. Но Π½Π° самом Π΄Π΅Π»Π΅ ΠΊΠ°ΠΌΠ΅Ρ€Π° просто пСрСмСщаСтся.
        if self.keyMap["cam-right"]:
            self.camera.setX(self.camera, +20 * dt) # Π’ΠΎΠΆΠ΅ самоС, Ρ‡Ρ‚ΠΎ ΠΈ Π½Π°Π²Π΅Ρ€Ρ…Ρƒ.

        startpos = self.droid.getPos() # Π‘Π΄Π΅Π»Π°Π΅ΠΌ ΡƒΠ΄ΠΎΠ±Π½ΡƒΡŽ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ ΠΈΠ³Ρ€ΠΎΠΊΠ°

        if self.keyMap["left"]:
            self.droid.setH(self.droid.getH() + 300 * dt)
            self.enemy.setY(self.enemy, 1 * dt)
        if self.keyMap["right"]:
            self.droid.setH(self.droid.getH() - 300 * dt)
            self.enemy.setY(self.enemy, -1 * dt)
        if self.keyMap["forward"]:
            self.droid.setY(self.droid, -25 * dt)
            self.enemy.setX(self.enemy, 1 * dt)
            # Π‘Π΄Π΅Π»Π°Π΅ΠΌ ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½ΠΎΠ΅ условиС ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ ΡƒΠ±Ρ€Π°Π½ΠΎ ΠΎΡ€ΡƒΠΆΠΈΠ΅ ΠΈΠ»ΠΈ Π½Π΅Ρ‚
            if not self.hide_weapon:
                self.weapon_pos = self.droid.getX(), self.droid.getY() + 0.7, 3
                self.weapon.setPos(self.weapon_pos) # ОбновляСм ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΏΡƒΡˆΠΊΠΈ
            else:
                self.weapon_pos = self.droid.getX(), self.droid.getY() + 0.7, 3
                self.flash.setPos(self.weapon_pos)


        camvec = self.droid.getPos() - self.camera.getPos() # Π²Π΅ΠΊΡ‚ΠΎΡ€ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹
        camvec.setZ(0) # 0 высота Π²Π΅ΠΊΡ‚ΠΎΡ€Π°
        camdist = camvec.length() # дистанция ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ ΠΎΡ‚ Π΄Ρ€ΠΎΠΈΠ΄Π°
        camvec.normalize() # Π½ΠΎΡ€ΠΌΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ Π²Π΅ΠΊΡ‚ΠΎΡ€ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹
        if camdist > 10.0: # Ссли дистанция ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ большС 10, Ρ‚ΠΎ смСщаСм ΠΊΠ°ΠΌΠ΅Ρ€Ρƒ Π·Π° Π΄Ρ€ΠΎΠΎΠΈΠ΄ΠΎΠΌ
            self.camera.setPos(self.camera.getPos() + camvec * (camdist - 10))
            camdist = 10.0 # Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ дистанция Π±ΡƒΠ΄Π΅Ρ‚ снова 10
        if camdist < 5.0: # Ссли дистагцтя ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ мСньшС 5, Ρ‚ΠΎ...
            self.camera.setPos(self.camera.getPos() - camvec * (5 - camdist)) # сдвигаСм ΠΊΠ°ΠΌΠ΅Ρ€Ρƒ
            camdist = 5.0 # всё обновляСм
            
        self.camera.lookAt(self.floater) # Π²ΠΎΡ‚ ΠΈ пригодился наш floater


        return task.cont # Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌ Π·Π°Π΄Π°Ρ‡Ρƒ

    def addInstructions(self, pos, msg):
        return OnscreenText(text=msg, style=1, fg=(1,1,1,1), font=self.inst_font, pos=(-1.3, pos), align=TextNode.ALeft, scale = .04, shadow=(0,0,0,1)) # Ѐункция ΠΎ Ρ‚ΠΎΠΌ, ΠΊΠ°ΠΊ ΡƒΠΏΡ€Π°Π²Π»ΡΡ‚ΡŒ

    def addTitle(self, text):
        return OnscreenText(text=text, style=1, fg=(1, 1, 1, 1), scale=0.2,
                            parent=base.a2dBottomRight, align=TextNode.ARight,
                            pos=(-0.1, 0.09), shadow=(0, 0, 0, 1), font=self.font) # Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ тСкстового Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ° с ΡˆΡ€ΠΈΡ„Ρ‚ΠΎΠΌ ΠΈ ΠΏΠΎΠ·ΠΈΡ†ΠΈΠ΅ΠΉ
    

droid = DroidShooter() # Π‘ΠΎΠ·Π΄Π°Π΄ΠΈΠΌ экзСмпляр класса нашСй ΠΈΠ³Ρ€Ρ‹
droid.run() # 3апустим ΠΈΠ³Ρ€Ρƒ


# Ρ€Π°Π·Ρ€ΠΎΠ±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ :
# Π“Π»Π°Π²Π½Ρ‹ΠΉ Π°Π²Ρ‚ΠΎΡ€ : ma3rx
# ΠŸΠΎΠΌΠΎΡ‰Π½ΠΈΠΊ : panda3dmastercoder( присоСдСнился ΠΊ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Ρƒ 31 января, 2021 Π³ΠΎΠ΄Π°, 12:??)
# Π Π΅ΠΊΠ»Π°ΠΌΡ‰ΠΈΠΊ : rdb (написал ΠΏΠ΅Ρ€Π²ΠΎΠ΅ сообщСниС Π½Π° Ρ„ΠΎΡ€ΡƒΠΌΠ΅ 6 фСвраля 2021 Π³ΠΎΠ΄Π°, 20:11)

Hi! I create 3.0.6 update.
Add too directory models :
./models/block : block.zip
New code :

#!/usr/bin/env python
# -*- coding: utf_8 -*-

# Π‘ΠΎΠ·Π΄Π°Π½ΠΎ : 22 число, ΡΠ½Π²Π°Ρ€ΡŒ, 2021 Π³ΠΎΠ΄

# Π˜ΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΡƒΠ΅ΠΌ всС Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹Π΅ инструмСнты
from direct.showbase.ShowBase import ShowBase
from panda3d.core import CollisionTraverser, CollisionNode
from panda3d.core import CollisionHandlerPusher, CollisionSphere, CollisionInvSphere
from panda3d.core import Filename, AmbientLight, DirectionalLight
from panda3d.core import PandaNode, NodePath, Camera, TextNode
from direct.particles.Particles import Particles
from direct.particles.ParticleEffect import ParticleEffect
from panda3d.core import PointLight, Spotlight
from panda3d.core import CollideMask
from panda3d.core import loadPrcFileData
from panda3d.core import *
from direct.gui.OnscreenText import OnscreenText
from direct.gui.OnscreenImage import OnscreenImage
from direct.gui.DirectButton import DirectButton
from direct.gui.DirectSlider import DirectSlider
from direct.actor.Actor import Actor
import random
import sys
import time
import os
import math


VERSION = '3.0.6'

settings = ['window-title Droid Game ' +  VERSION,
            'fullscreen 0']
            

loadPrcFileData('', settings[0]) # Π‘Π΄Π΅Π»Π°Π΅ΠΌ Π½Π΅ стандартный Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ (Π²ΠΎΠ·ΠΌΡ‘ΠΌ Π΅Π³ΠΎ ΠΈΠ· ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ settings)
loadPrcFileData('', settings[1]) # Π½Π΅ Π±ΡƒΠ΄Π΅ΠΌ Π΄Π΅Π»Π°Ρ‚ΡŒ полноэкранный Ρ€Π΅ΠΆΠΈΠΌ

# Π‘ΠΎΠ·Π΄Π°Π΄ΠΈΠΌ Π³Π»Π°Π²Π½Ρ‹ΠΉ класс нашСй ΠΈΠ³Ρ€Ρ‹
class DroidShooter(ShowBase):
    def __init__(self):
        ShowBase.__init__(self) # Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ всС сСлфы ΠΈΠ· direct
        self.speed = 1800 # ΡΠΊΠΎΡ€ΠΎΡΡ‚ΡŒ двигатСля
        self.GB = False # НЕ Ρ‡Ρ‘Ρ€Π½ΠΎ-Π±Π΅Π»Ρ‹ΠΉ Ρ€Π΅ΠΆΠΈΠΌ
        self.menu() # звпуск мСню
        
    def menu(self):
        
        base.enableParticles() # ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ эффСкт Π΄Ρ‹ΠΌΠ°

        self.win.setClearColor((0, 0, 0, 1)) # Π—Π°ΠΊΡ€Π°ΡˆΠΈΠ²Π°Π΅ΠΌ ΠΏΠΎΠ²Π΅Ρ€Ρ…Π½ΠΎΡΡ‚ΡŒ Ρ‡Ρ‘Ρ€Π½Ρ‹ΠΌ. Π”Π΅Π»ΠΎ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ Π² этом ΠΈΠ³Ρ€ΠΎΠ²ΠΎΠΌ Π΄Π²ΠΈΠΆΠΊΠ΅ ΠΏΠΎΠ²Π΅Ρ€Ρ…Π½ΠΎΡΡ‚ΡŒ Π·Π°ΠΊΡ€Π°ΡˆΠΈΠ²Π°Π΅Ρ‚ΡΡ сСрым.
        self.font = loader.loadFont('./fonts/doom_font.ttf') # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ ΡˆΡ€ΠΈΡ„Ρ‚ ΠΈΠ· ΠΈΠ³Ρ€Ρ‹ doom
        self.inst_font = loader.loadFont('./fonts/arial.ttf') # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ ΡˆΡ€ΠΈΡ„Ρ‚ arial

        self.crackSound = loader.loadMusic('./sounds/crack.wav') # Π·Π²ΡƒΠΊ Π²Π·Ρ€Ρ‹Π²Π° корабля
        self.shotSound = loader.loadMusic('./sounds/shot.wav') # Π·Π²ΡƒΠΊ выстрСла
        self.startSound = loader.loadMusic('./sounds/started.wav') # Π·Π²ΡƒΠΊ запуска
        self.errorSound = loader.loadMusic('./sounds/error.wav') # Π·Π²ΡƒΠΊ запуска
        self.errorSound.setVolume(1) # полная Π³Ρ€ΠΎΠΌΠΊΠΎΡΡ‚ΡŒ Π·Π²ΡƒΠΊΠ°
        self.startSound.setVolume(1) # полная Π³Ρ€ΠΎΠΌΠΊΠΎΡΡ‚ΡŒ Π·Π²ΡƒΠΊΠ°
        self.crackSound.setVolume(1) # полная Π³Ρ€ΠΎΠΌΠΊΠΎΡΡ‚ΡŒ Π·Π²ΡƒΠΊΠ°
        self.shotSound.setVolume(1) # полная Π³Ρ€ΠΎΠΌΠΊΠΎΡΡ‚ΡŒ Π·Π²ΡƒΠΊΠ°
        self.startSound.play() # ΠΈΠ³Ρ€Π°Π΅ΠΌ Π·Π²ΡƒΠΊ запуска ΠΈΠ³Ρ€Ρ‹

        self.button_start = DirectButton(pos=(0.7, 0, 0.4), text="CTAPT",
                                   scale=.2, pad=(.2, .2),
                                   command=self.load_game) # ΠΊΠ½ΠΎΠΏΠΊΠ° запуска ΠΈΠ³Ρ€Ρ‹

        self.gb_start = DirectButton(pos=(0.7, 0, 0.1), text="GB",
                                   scale=.2, pad=(.2, .2),
                                   command=self.gb_mode) # ΠΊΠ½ΠΎΠΏΠΊΠ° запуска ΠΈΠ³Ρ€Ρ‹  Π² Ρ‡Ρ‘Ρ€Π½ΠΎ-Π±Π΅Π»ΠΎΠΌ Ρ€Π΅ΠΆΠΈΠΌΠ΅      

        self.slider_sun = DirectSlider(pos=(0.1, 0, .75), scale=0.8, value=0.5,
                                    command=self.set_sun_interval)


        self.title = self.addTitle("Droid game " + VERSION)
        
        # НапСчатаСм ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅
        self.inst1 = self.addInstructions(0.95, u"[ESC]: Π’Ρ‹Ρ…ΠΎΠ΄")
        self.inst2 = self.addInstructions(0.90, u"[Left Arrow]: ΠŸΠΎΠ²ΠΎΡ€ΠΎΡ‚ Π΄Ρ€ΠΎΠΈΠ΄Π° Π² Π»Π΅Π²ΠΎ")
        self.inst3 = self.addInstructions(0.85, u"[Right Arrow]: ΠŸΠΎΠ²ΠΎΡ€ΠΎΡ‚ Π΄Ρ€ΠΎΠΈΠ΄Π° Π² ΠΏΡ€Π°Π²ΠΎ")
        self.inst4 = self.addInstructions(0.80, u"[Up Arrow]: Π’ΠΏΠ΅Ρ€Π΅Π΄")
        self.inst5 = self.addInstructions(0.75, u"[a]: ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ Π² ΠΏΡ€Π°Π²ΠΎ")
        self.inst6 = self.addInstructions(0.70, u"[d]: ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ Π² Π»Π΅Π²ΠΎ")
        self.inst7 = self.addInstructions(0.65, u"[Left Arrow + Up arrow]: ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚ Π΄Ρ€ΠΎΠΈΠ΄Π° Π² Π»Π΅Π²ΠΎ ΠΈ Π²ΠΏΠ΅Ρ€Ρ‘Π΄")
        self.inst8 = self.addInstructions(0.60, u"[Right Arrow + Up arrow]: ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚ Π΄Ρ€ΠΎΠΈΠ΄Π° Π² ΠΏΡ€Π°Π²ΠΎ ΠΈ Π²ΠΏΠ΅Ρ€Ρ‘Π΄")
        self.inst9 = self.addInstructions(0.55, u"[a + Up arrow]: ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ Π² ΠΏΡ€Π°Π²ΠΎ ΠΈ Π²ΠΏΠ΅Ρ€Ρ‘Π΄")
        self.inst10 = self.addInstructions(0.50, u"[d + Up arrow]: ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ Π² Π»Π΅Π²ΠΎ ΠΈ Π²ΠΏΠ΅Ρ€Ρ‘Π΄")
        self.inst11 = self.addInstructions(0.45, u"[space]: ΡΡ‚Ρ€Π΅Π»ΡŒΠ±Π°")
        self.inst12 = self.addInstructions(0.40, u"[s]: Π΄ΠΎΡΡ‚Π°Ρ‚ΡŒ Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊ")
        self.inst13 = self.addInstructions(0.35, u"[w]: ΡƒΠ±Ρ€Π°Ρ‚ΡŒ ΠΎΡ€ΡƒΠΆΠΈΠ΅")
        self.inst14 = self.addInstructions(0.30, u"[f]: ΠΏΠΎΠ»Π½Ρ‹ΠΉ Ρ€Π°Π·Π³ΠΎΠ½(ОПАБНО!)")
        self.inst15 = self.addInstructions(0.25, u"[0]: ΠΏΠΎΠΆΠ°Ρ€ΠΎΡ‚ΡƒΡˆΠΈΡ‚Π΅Π»ΡŒΠ½Π°Ρ систСма")

        self.accept("escape", sys.exit) # ΠŸΡ€ΠΈ Π½Π°ΠΆΠ°Ρ‚ΠΈΠΈ клавиши Esc Π²Ρ‹Ρ…ΠΎΠ΄ΠΈΠΌ.

    def set_sun_interval(self):
        self.sun_interval = self.slider_sun.guiItem.getValue() * 100 # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ слайдСрноС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΡƒΠΌΠ½ΠΎΠΆΠ΅Π½ΠΎΠ΅ Π½Π° 500, Π΄Π° Ρ‚Ρ€Π°Ρ‡Ρƒ ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΡŽ Π½ΠΎ ΠΌΠ½Π΅ каТСтся ΠΌΠ½ΠΎΠ³ΠΈΠΌ ΠΏΠ»Π΅Π²Π°Ρ‚ΡŒ Π½Π° ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΡŽ мСню, ΠΈΠ±ΠΎ Ρ‚Π°ΠΊΠΎΠ³ΠΎ понятия просто Π½Π΅Ρ‚Ρƒ :)

    def gb_mode(self):
        '''Π²ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ Ρ‡Ρ‘Ρ€Π½ΠΎΠ±Π΅Π»ΠΎΠ³ΠΎ Ρ€Π΅ΠΆΠΈΠΌΠ°'''
        self.GB = True

    def load_game(self):
        self.button_start.hide() # ΡƒΠ΄Π°Π»ΠΈΠΌ ΠΊΠ½ΠΎΠΏΠΊΡƒ старта
        self.gb_start.hide() # ΡƒΠ΄Π°Π»ΠΈΠΌ ΠΊΠ½ΠΎΠΏΠΊΡƒ Ρ‡Ρ‘Ρ€Π½ΠΎ Π±Π΅Π»ΠΎΠ³ΠΎ Ρ€Π΅ΠΆΠΈΠΌΠ°.
        self.title.hide() # ΡƒΠ΄Π°Π»ΠΈΠΌ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ ΠΈΠ³Ρ€Ρ‹
        # ΡƒΠ΄Π°Π»ΠΈΠΌ ΠΊΠ½ΠΎΠΏΠΊΠΈ управлСния
        self.inst1.hide()
        self.inst2.hide()
        self.inst3.hide()
        self.inst4.hide()
        self.inst5.hide()
        self.inst6.hide()
        self.inst7.hide()
        self.inst8.hide()
        self.inst9.hide()
        self.inst10.hide()
        self.inst11.hide()
        self.inst12.hide()
        self.inst13.hide()
        self.inst14.hide()
        self.inst15.hide()
        self.slider_sun.hide() # удаляСм слайдСр солнца
        
        self.keyMap = {
            "left": 0, "right": 0, "forward": 0, "cam-left": 0, "cam-right": 0} # Π‘ΠΎΠ·Π΄Π°Π΄ΠΈΠΌ ΡΠ»ΠΎΠ²Π°Ρ€ΡŒ ΠΊΠ½ΠΎΠΏΠΎΠΊ, ΠΏΠΎ ΠΈΡ… Π½Π°ΠΆΠ°Ρ‚ΠΈΡŽ        

        # РисуСм Π·Π²Ρ‘Π·Π΄Ρ‹

        self.sky = loader.loadModel("./models/sky/solar_sky_sphere") # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ модСль космоса(это сфСра)

        self.sky_tex = loader.loadTexture("./tex/stars_1k_tex.jpg") # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ тСкстуру
        self.sky.setTexture(self.sky_tex, 1) # Π·Π°Ρ€Π΅Π½Π΄Π΅Ρ€ΠΈΠΌ тСкстуру Π½Π° Π½Π΅Π±ΠΎ
        self.sky.reparentTo(render) # ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ Π½Π΅Π±ΠΎ
        self.sky.setScale(40000) # Ρ€Π°ΡΡˆΠΈΡ€ΠΈΠΌ Π½Π΅Π±ΠΎ Π΄ΠΎ максимальной Π²Π΅Π»ΠΈΡ‡ΠΈΠ½Ρ‹ panda3d

        self.environ = loader.loadModel("models/world/falcon.egg") # Π—Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ ΡƒΠΆΠ΅ созданный Π² blender ΠΌΠΈΡ€.
        self.environ.reparentTo(render) # Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ модСль ΠΌΠΈΡ€Π° Π² ΠΎΠΊΠ½ΠΎ

        droidStartPos = (-1, 0, 1.5 ) # Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ ΡΡ‚Π°Ρ€Ρ‚ΠΎΠ²ΡƒΡŽ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π² ΠΌΠΈΡ€Π΅.
        enemyStartPos = (-6, 1, 0.5) # Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ°-Π΄Ρ€ΠΎΠΈΠ΄Π°.
        self.droid = Actor("models/player/seeker.egg") # Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ модСль ΠΈΠ³Ρ€ΠΎΠΊΠ° (созданная Π² blender)
        self.enemy = Actor("models/enemies/r2d2/r2d2.egg") # Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ модСль ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ° (созданная Π² blender)
        self.droid.reparentTo(render) # ΠŸΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Π΅ΠΌ модСль ΠΈΠ³Ρ€ΠΎΠΊΠ° Π² наш ΠΌΠΈΡ€.
        self.enemy.reparentTo(render) # ΠŸΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Π΅ΠΌ модСль ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ° Π² наш ΠΌΠΈΡ€.
        self.droid.setScale(1) # Π”Π΅Π»Π°Π΅ΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ€ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π½Π° 1
        self.enemy.setScale(1) # Π”Π΅Π»Π°Π΅ΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ€ ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ° Π½Π° 1
        self.droid.setPos(droidStartPos) # Π‘Ρ‚Π°Π²ΠΈΠΌ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π½Π° Ρ€Π°Π½Π΅Π΅ ΡΠΎΠ·Π΄Π°Π½ΡƒΡŽ Π½Π°ΠΌΠΈ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ
        self.enemy.setPos(enemyStartPos) # Π‘Ρ‚Π°Π²ΠΈΠΌ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ° Π½Π° Ρ€Π°Π½Π΅Π΅ ΡΠΎΠ·Π΄Π°Π½ΡƒΡŽ Π½Π°ΠΌΠΈ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ

        self.weapon = Actor('models/weapon/lightsaber.egg') # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ ΠΎΡ€ΡƒΠΆΠΈΠ΅
        self.bullet = Actor('models/weapon/bullet/bullet.egg.pz') # Π—Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ ΠΏΡƒΠ»ΡŽ
        self.flash = Actor('models/whishlyflash/handlamp.egg') # Π—Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊ
               
        self.weapon.reparentTo(render) # пСрСмСстим ΠΎΡ€ΡƒΠΆΠΈΠ΅ Π² наш ΠΌΠΈΡ€
        self.bullet.reparentTo(render) # пСрСмСстим ΠΏΡƒΠ»ΡŽ Π² ΠΌΠΈΡ€ Π½ΠΎ появится ΠΎΠ½Π° сама Π½Π΅ скоро
        self.flash.reparentTo(render) # пСрСмСстим Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊ Π² наш ΠΌΠΈΡ€
        self.weapon.setScale(.5) # Π·Π°Π΄Π°Π΄ΠΈΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ€ ΠΏΡƒΡˆΠΊΠΈ
        self.bullet.setScale(.5) # Π·Π°Π΄Π°Π΄ΠΈΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ€ ΠΏΡƒΠ»ΠΈ
        self.flash.setScale(.5) # Π·Π°Π΄Π°Π΄ΠΈΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ€ Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊΠ°

        # враТСский ΠΈΡΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»ΡŒ
        self.fighter = Actor('models/fighter/fighter.egg') # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ ΠΌΠΎΠ΄Π΅Π»ΡŒΠΊΡƒ истрСбитСля
        self.fighter.reparentTo(render) # ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ ΠΈΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»ΡŒ
        self.fighter.setPos(0, 90, 0) # позиция истрСбитСля
                

        self.weapon_pos = self.droid.getX(), self.droid.getY() + 0.7, 1 # ΠŸΠΎΠ·ΠΈΡ†ΠΈΡ ΠΏΡƒΡˆΠΊΠΈ
        
        self.weapon.setPos(self.weapon_pos) # ΠŸΠΎΠΌΠ΅ΡΡ‚ΠΈΠΌ ΠΎΡ€ΡƒΠΆΠΈΠ΅ Ρ‡ΡƒΡ‚ΡŒ Π²Ρ‹ΡˆΠ΅ ΠΈΠ³Ρ€ΠΎΠΊΠ°

        self.cube = Actor('models/block/crate.egg') # Π·Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ Π±Π»ΠΎΠΊ
        self.cube.reparentTo(render)
        self.cube.setPos(0, -0, 0) # позиция ящика
        self.cube.setScale(0.7)
        self.cube.hprInterval(1.5, (0, 360, 360)).loop()

        self.Intervalcube = self.cube.posInterval(13,
                                                   Point3(0, -500, 0),
                                                   startPos=Point3(0, 10, 0))

        self.Intervalcube.loop()
        
        self.spotlight = camera.attachNewNode(Spotlight("spotlight")) # ΠšΠΎΠ½Ρ„ΠΈΠ³ΠΈ Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊΠ°
        self.spotlight.node().setColor((.3, .3, .3, 1))
        self.spotlight.node().setSpecularColor((0, 0, 0, 1))

        self.floater = NodePath(PandaNode("floater")) 
        self.floater.reparentTo(self.droid)
        self.floater.setZ(2.0)

        self.accept("escape", sys.exit) # ΠŸΡ€ΠΈ Π½Π°ΠΆΠ°Ρ‚ΠΈΠΈ клавиши Esc Π²Ρ‹Ρ…ΠΎΠ΄ΠΈΠΌ.
        
        self.accept("arrow_left", self.setKey, ["left", True]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ Π²Π»Π΅Π²ΠΎ - ΠΏΠΎΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π²Π»Π΅Π²ΠΎ
        self.accept("arrow_right", self.setKey, ["right", True]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ Π²ΠΏΡ€Π°Π²ΠΎ - ΠΏΠΎΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π²ΠΏΡ€Π°Π²ΠΎ
        self.accept("arrow_up", self.setKey, ["forward", True]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ Π²ΠΏΠ΅Ρ€Ρ‘Π΄ - ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄
        self.accept("a", self.setKey, ["cam-left", True]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ a - Ρ€Π°Π·Π²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΊΠ°ΠΌΠ΅Ρ€Ρƒ Π²ΠΎΠΊΡ€ΡƒΠ³ нашСй модСльки
        self.accept("d", self.setKey, ["cam-right", True]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ s - Ρ€Π°Π·Π²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΊΠ°ΠΌΠ΅Ρ€Ρƒ Π²ΠΎΠΊΡ€ΡƒΠ³ нашСй модСльки
        self.accept("arrow_left-up", self.setKey, ["left", False]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ Π²Π²Π΅Ρ€Ρ…+Π²Π»Π΅Π²ΠΎ - ΠΏΠΎΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π²Π»Π΅Π²ΠΎ ΠΈ ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄
        self.accept("arrow_right-up", self.setKey, ["right", False]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ Π²Π²Π΅Ρ€Ρ…+ΠΏΡ€Π°Π²ΠΎ - ΠΏΠΎΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π²ΠΏΡ€Π°Π²ΠΎ ΠΈ ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄
        self.accept("arrow_up-up", self.setKey, ["forward", False]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ Π²Π²Π΅Ρ€Ρ…+Π²Π²Π΅Ρ€ΡŠ - ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄ ΠΈ ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄
        self.accept("a-up", self.setKey, ["cam-left", False]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ a+Π²ΠΏΠ΅Ρ€Ρ‘Π΄ - ΠΏΠΎΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΊΠ°ΠΌΠ΅Ρ€Ρƒ Π²Π»Π΅Π²ΠΎ ΠΈ ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄
        self.accept("d-up", self.setKey, ["cam-right", False]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ s+Π²ΠΏΠ΅Ρ€Ρ‘Π΄ - ΠΏΠΎΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΊΠ°ΠΌΠ΅Ρ€Ρƒ Π²ΠΏΡ€Π°Π²ΠΎ ΠΈ ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄

        self.accept("space", self.shot) # ΠΏΡ€ΠΈ ΠΏΡ€ΠΎΠ±Π΅Π»Π΅ стрСляСм
        self.accept("s", self.toggleLights, [[self.spotlight]]) # Π’ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊ
        self.accept("w", self.weapon_hide) # ΠΏΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ w - ΡƒΠ±Π΅Ρ€Ρ‘ΠΌ ΠΎΡ€ΡƒΠΆΠΈΠ΅.

        base.enableParticles() # Π’ΠΊΠ»ΡŽΡ‡Π°Π΅ΠΌ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ Π΄Ρ‹ΠΌΠ°
        self.t = loader.loadModel("models/weapon/lightsaber.egg") # Π—Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ Π΅Ρ‰Ρ‘ ΠΎΡ€ΡƒΠΆΠΈΠ΅
        self.t.reparentTo(render) # ΠŸΠ΅Ρ€Π΅ΠΌΠ΅ΡΡ‚ΠΈΠΌ ΠΎΡ€ΡƒΠΆΠΈΠ΅ Π² наш ΠΌΠΈΡ€
        self.p = ParticleEffect() # Π’ΠΊΠ»ΡŽΡ‡ΠΈΠΌ эффСкт Π΄Ρ‹ΠΌΠ°
        self.accept('f', self.particle_start) # ΠΏΡ€ΠΈ Π½Π°ΠΆΠ°Ρ‚ΠΈΠΈ f(ΠΎΡ‚ force) -  Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ Ρ„Π°ΠΉΠ» Π΄Ρ‹ΠΌΠ° ΠΈ пСрСмСстим Π² ΠΊΠΎΠ½Ρ„ΠΈΠ³ Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΈΠΌΠ΅Π½Π½ΠΎ эта анимация стала ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ΠΌ Π΄Ρ‹ΠΌΠ°
        self.accept('0', self.fountain) # ΠΏΡ€ΠΈ  Π½Π°ΠΆΠ°Ρ‚ΠΈΠΈ ΠΊΠ½ΠΎΠΏΠΎΠΊ f+o(fountain) Π²ΠΊΠ»ΡŽΡ‡ΠΈΠΌ ΠΏΠΎΠΆΠ°Ρ€ΠΎΡ‚ΡƒΡˆΠΈΡ‚Π΅Π»ΡŒΠ½ΡƒΡŽ систСму

        taskMgr.add(self.move, "moveTask") # ДобавляСм Π·Π°Π΄Π°Ρ‡Ρƒ Π² наш Π΄Π²ΠΈΠΆΠΎΠΊ

        self.isMoving = False # Π‘Ρ‚Π°Π²ΠΈΠΌ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ isMoving Π½Π° False(Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΌΠ΅Π½ΡΡ‚ΡŒ это Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅) Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΈΠ³Ρ€ΠΎΠΊ ΠΈΠ·Π½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎ стоял.
        # Π”Π΅Π»Π°Π΅ΠΌ Ρ‚Π°ΠΊ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ свСт Π±Ρ‹Π» ΠΈΠ·Π½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎ Π²Ρ‹ΠΊΠ»ΡŽΡ‡Π΅Π½.
        self.disableMouse() # ΠžΡ‚ΠΊΠ»ΡŽΡ‡Π°Π΅ΠΌ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π΅Π½ΠΈΠ΅ Ρ‡Π΅Ρ€Π΅Π· ΠΌΡ‹ΡˆΠΊΡƒ
        self.camera.setPos(self.droid.getX(), self.droid.getY() + 1, 3) # Π‘Ρ‚Π°Π²ΠΈΠΌ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ Ρ‡ΡƒΡ‚ΡŒ большС ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ ΠΈΠ³Ρ€ΠΎΠΊΠ°

        self.black_light() # Π‘Π΄Π΅Π»Π°Π΅ΠΌ Π²Ρ‹ΠΊΠ»ΡŽΡ‡Π΅Π½Π½Ρ‹ΠΉ свСт

        self.state = 100 # БостояниС корабля
        self.state_info = OnscreenText(text='ΠΊΠΎΡ€Π°Π±Π»ΡŒ :' + str(self.state), pos=(0.5, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля
                
        self.check_loss() # ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ ΠΏΠΎΡ€Π°ΠΆΠ΅Π½ΠΈΠ΅
        self.hide_weapon = False # ΠŸΠΎΡΡ‚Π°Π²ΠΈΠΌ, Ρ‡Ρ‚ΠΎ ΠΎΡ€ΡƒΠΆΠΈΠ΅ Π½Π΅ ΡƒΠ±Ρ€Π°Π½ΠΎ
        self.steam_pos = random.randrange(0, 5), random.randrange(0, 5), random.randrange(0, 5)
        self.fountain_pos = random.randrange(0, 5), random.randrange(0, 5), random.randrange(0, 1)

        self.motor_pos1 = 25.238849639892578, 8.962211608886719, 1.5 # позиция ΠΏΠ΅Ρ€Π²ΠΎΠ³ΠΎ ΠΌΠΎΡ‚ΠΎΡ€Π°
        self.motor_pos2 = -20.676218032836914, 10.55816650390625, 1.5 # позиция Π²Ρ‚ΠΎΡ€ΠΎΠ³ΠΎ ΠΌΠΎΡ‚ΠΎΡ€Π°

        self.motor1 = self.loadParticleConfig('special_effects/steam_critic+/fireish.ptf', self.motor_pos1) # ΠΌΠΎΡ‚ΠΎΡ€ 1
        self.motor2 = self.loadParticleConfig('special_effects/steam_critic+/fireish.ptf', self.motor_pos2) # ΠΌΠΎΡ‚ΠΎΡ€ 2

        self.state_info2 = OnscreenText(text='', pos=(-0.8, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля

        self.force = False # ΠŸΠΎΡΡ‚Π°Π²ΠΈΠΌ, Ρ‡Ρ‚ΠΎ Π½Π΅ Ρ€Π°Π·Π³ΠΎΠ½ΡΠ»ΠΈΡΡŒ

        # ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ ΠΊΠΎΠ»Π»ΠΈΠ·ΠΈΠΈ

        # Коллизия корабля(ΠΎΠ½ Ρƒ нас ΠΊΠ°ΠΊ главная ΠΊΠ°Ρ€Ρ‚Π°).
        self.cTrav = CollisionTraverser()
        pusher = CollisionHandlerPusher()
        
        environCenter = self.environ.getBounds().getCenter()
        environRad = self.environ.getBounds().getRadius()
        cNode = CollisionNode("environment")
        cNode.addSolid(CollisionInvSphere(environCenter, environRad))
        environC = self.environ.attachNewNode(cNode)

        # Коллизия Π΄Ρ€ΠΎΠΈΠ΄Π°.
        droidCenter = self.droid.getBounds().getCenter()
        droidRad = self.droid.getBounds().getRadius()
        cNode = CollisionNode("droid")
        cNode.addSolid(CollisionSphere(droidCenter, droidRad))
        droidC = self.droid.attachNewNode(cNode)
        
        pusher.addCollider(droidC, self.droid)
        self.cTrav.addCollider(droidC, pusher)

        # Коллизия ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ°.
        enemyCenter = self.enemy.getBounds().getCenter()
        enemyRad = self.enemy.getBounds().getRadius()
        cNode = CollisionNode("enemy")
        cNode.addSolid(CollisionSphere(enemyCenter, enemyRad))
        enemyC = self.enemy.attachNewNode(cNode)

        pusher.addCollider(enemyC, self.enemy)
        self.cTrav.addCollider(enemyC, pusher)

        # Коллизия враТСского истрСбитСля.
        fighterCenter = self.fighter.getBounds().getCenter()
        fighterRad = self.fighter.getBounds().getRadius()
        cNode = CollisionNode("fighter")
        cNode.addSolid(CollisionSphere(fighterCenter, fighterRad))
        fighterC = self.fighter.attachNewNode(cNode)

        pusher.addCollider(fighterC, self.fighter)
        self.cTrav.addCollider(fighterC, pusher)

        # Коллизия ΠΏΡƒΠ»ΠΈ.
        bulletCenter = self.bullet.getBounds().getCenter()
        bulletRad = self.bullet.getBounds().getRadius()
        cNode = CollisionNode("bullet")
        cNode.addSolid(CollisionSphere(bulletCenter, bulletRad))
        bulletC = self.bullet.attachNewNode(cNode)

        bulletCenter = self.bullet.getBounds().getCenter()
        bulletRad = self.bullet.getBounds().getRadius()
        cNode = CollisionNode("bullet")
        cNode.addSolid(CollisionSphere(bulletCenter, bulletRad))
        bulletC = self.bullet.attachNewNode(cNode)
        
        pusher.addCollider(bulletC, self.bullet)
        self.cTrav.addCollider(bulletC, pusher)

        # Коллизия ΠΏΡƒΡˆΠΊΠΈ. Π― Π±Ρ‹ Π½Π΅ сказал, Ρ‡Ρ‚ΠΎ это ΠΈΠΌΠ΅Π½Π½ΠΎ коллизия, скорСС это для рСалистичности
        weaponCenter = self.weapon.getBounds().getCenter()
        weaponRad = self.weapon.getBounds().getRadius()
        cNode = CollisionNode("weapon")
        cNode.addSolid(CollisionSphere(weaponCenter, weaponRad))
        weaponC = self.weapon.attachNewNode(cNode)
        
        pusher.addCollider(weaponC, self.weapon)
        self.cTrav.addCollider(weaponC, pusher)

        # солнцС(новая ΠΌΠ΅Ρ…Π°Π½ΠΈΠΊΠ° освСщСния)
        sun = DirectionalLight("sun")
        sun.set_color_temperature(6000)
        sun.color = sun.color * 4
        sun_path = render.attach_new_node(sun)
        sun_path.set_pos(10, -10, -10)
        sun_path.look_at(0, 0, 0)
        sun_path.hprInterval(self.sun_interval, (sun_path.get_h(), sun_path.get_p() - 360, sun_path.get_r()), bakeInStart=True).loop()
        render.set_light(sun_path)

        # Если  ΠΈΠ³Ρ€ΠΎΠΊ Π·Π°Ρ…ΠΎΡ‚Π΅Π» ΠΏΠΎΠΈΠ³Ρ€Π°Ρ‚ΡŒ Π² Ρ‡Ρ‘Ρ€Π½ΠΎΠ±Π΅Π»ΡƒΡŽ ΠΈΠ³Ρ€Ρƒ, ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΠΌ это
        if self.GB :        
            render.set_shader(Shader.load(Shader.SL_GLSL, "lighting.vert", "lighting.frag")) # Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ ΡˆΠ΅ΠΉΠ΄Π΅Ρ€Ρ‹ Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‚!



    def fight_force(self):
        # сдвиТСниС истрСбитСля Π·Π° нашим ΠΊΠΎΡ€Π°Π±Π»Ρ‘ΠΌ(ΠΎΡ‡Π΅Π½ΡŒ простым способом я сдСлал Ρ‚Π°ΠΊ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΈΡΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»ΡŒ Π·Π°ΠΆΠΈΠΌΠ°Π» нас(Π»Π΅Ρ‚Π°Π» Π² нашСм ΠΊΠ²Π°Π΄Ρ€Π°Ρ‚Π΅)) ΠΈ Π·Π°ΠΆΠΈΠΌΠ°Π΅Ρ‚ ΠΎΠ½ Ρ€Π΅Π°Π»ΡŒΠ½ΠΎ, сблиТая ΠΊ Π½Π°ΠΌ свой ΠΊΠ²Π°Π΄Ρ€Π°Ρ‚
        self.fighter.setY(self.fighter.getY() - self.speed) 
        self.fighter.setX(self.fighter.getX() - 10)    

        print(self.fighter.getX())


    def loadParticleConfig(self, filename, pos):
        self.p.cleanup()
        self.p = ParticleEffect()
        self.p.loadConfig(Filename(filename))

        self.p.start(self.t)
        self.p.setPos(pos)

    def particle_start(self):
        self.force = True # ΠŸΠΎΡΡ‚Π°Π²ΠΈΠΌ, Ρ‡Ρ‚ΠΎ ΠΌΡ‹ ΡƒΠΆΠ΅ Ρ€Π°Π·Π³ΠΎΠ½ΡΠ»ΠΈΡΡŒ
        # ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Π΅ΠΌ всС ΠΎΠ±ΡŒΠ΅ΠΊΡ‚Ρ‹ Π·Π° ΠΊΠΎΡ€Π°Π±Π»Ρ‘ΠΌ
        self.environ.setY(self.environ.getY() - self.speed) # нСсёмся Π²ΠΏΡ€Π°Π²ΠΎ
        self.droid.setY(self.droid.getY() - self.speed) # сдвигаСм Π΄Ρ€ΠΎΠΈΠ΄Π° Π·Π° ΠΊΠΎΡ€Π°Π±Π»Ρ‘ΠΌ
        self.enemy.setY(self.enemy.getY() - self.speed) # сдфигаСм ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ° Π·Π° ΠΊΠΎΡ€Π°Π±Π»Ρ‘ΠΌ
        self.weapon.setY(self.weapon.getY() - self.speed) # ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Π΅ΠΌ ΠΎΡ€ΡƒΠΆΠΈΠ΅
        self.flash.setY(self.flash.getY() - self.speed) # ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Π΅ΠΌ Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊ
        self.cube.setY(self.cube.getY() - self.speed) # ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Π΅ΠΌ ящик
        self.fight_force()

        self.state -= 1 # сдСлаСм мСньшС ΠΎΡ‡ΠΊΠΎΠ²
        self.state_info.hide() # ΡƒΠ΄Π°Π»ΠΈΠΌ тСкстовыС ΠΎΡ‡ΠΊΠΈ
        
        if self.state != 10 and self.state > 10:
            self.state_info.hide() # ΡƒΠ±ΠΈΡ€Π°Π΅ΠΌ ΠΏΡ€Π΅Π΄Π΅Π΄ΡƒΡ‰Π΅Π΅ сообщСниС ΠΎ Тизнях корабля
            self.state_info = OnscreenText(text='ΠΊΠΎΡ€Π°Π±Π»ΡŒ :' + str(self.state), pos=(0.5, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля
            self.check_loss() # провСряСм ΠΏΠΎΡ€Π°ΠΆΠ΅Π½ΠΈΠ΅
            self.steam_pos = random.randrange(0, 5), random.randrange(0, 5) + 300, random.randrange(0, 5)
            self.loadParticleConfig('special_effects/steam/steam.ptf', self.steam_pos)
            self.errorSound.play() # ΠΈΠ³Ρ€Π°Π΅ΠΌ Π·Π²ΡƒΠΊ ошибки
            self.state_info2.hide() # ΡƒΠ±ΠΈΡ€Π°Π΅ΠΌ ΠΏΡ€Π΅Π΄Π΅Π΄ΡƒΡ‰Π΅Π΅ сообщСниС
            self.state_info2 = OnscreenText(text='Π΄Π²ΠΈΠ³Π°Ρ‚Π΅Π»ΡŒ нСисправСн', pos=(-0.8, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля
        else:
            self.state_info = OnscreenText(text='ΠΊΠΎΡ€Π°Π±Π»ΡŒ :' + str(self.state), pos=(0.5, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля
            self.check_loss() # провСряСм ΠΏΠΎΡ€Π°ΠΆΠ΅Π½ΠΈΠ΅
            self.steam_pos = random.randrange(0, 5), random.randrange(0, 5) + 300, random.randrange(0, 5)
            self.loadParticleConfig('special_effects/steam_critic/steam.ptf', self.steam_pos)
            self.errorSound.play() # ΠΈΠ³Ρ€Π°Π΅ΠΌ Π·Π²ΡƒΠΊ ошибки
            self.state_info2.hide()  # ΡƒΠ±ΠΈΡ€Π°Π΅ΠΌ ΠΏΡ€Π΅Π΄Π΅Π΄ΡƒΡ‰Π΅Π΅ сообщСниС
            self.state_info2 = OnscreenText(text='критичСскоС состояниС', pos=(-0.8, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля
    
        if self.state < 10:
            self.state_info.hide()
            self.state_info = OnscreenText(text='ΠΊΠΎΡ€Π°Π±Π»ΡŒ :' + str(self.state), pos=(0.5, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля
            self.check_loss() # провСряСм ΠΏΠΎΡ€Π°ΠΆΠ΅Π½ΠΈΠ΅
            self.steam_pos = random.randrange(0, 5), random.randrange(0, 5) + 300, random.randrange(0, 5)            
            self.loadParticleConfig('special_effects/steam_critic+/fireish.ptf', self.steam_pos)
            self.errorSound.play() # ΠΈΠ³Ρ€Π°Π΅ΠΌ Π·Π²ΡƒΠΊ ошибки
            self.state_info2.hide() # ΡƒΠ±ΠΈΡ€Π°Π΅ΠΌ ΠΏΡ€Π΅Π΄Π΅Π΄ΡƒΡ‰Π΅Π΅ сообщСниС
            self.state_info2 = OnscreenText(text='ΠΏΠ°Π΄Π°Π΅ΠΌ!', pos=(-0.8, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля


    def fountain(self):
        self.state_info2.hide() # ΡƒΠ±ΠΈΡ€Π°Π΅ΠΌ тСкст опасности
        if self.force:
            if self.state != 100:
                self.state += 1
                self.state_info.hide()
                self.state_info = OnscreenText(text='ΠΊΠΎΡ€Π°Π±Π»ΡŒ :' + str(self.state), pos=(0.5, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля

            self.fountain_pos = random.randrange(0, 5), random.randrange(0, 5) + 500, random.randrange(0, 1)    
            self.loadParticleConfig('special_effects/fountain/fountain.ptf', self.fountain_pos)

        else :
            if self.state != 100:
                self.state += 1
                self.state_info.hide()
                self.state_info = OnscreenText(text='ΠΊΠΎΡ€Π°Π±Π»ΡŒ :' + str(self.state), pos=(0.5, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля

            self.fountain_pos = random.randrange(0, 5), random.randrange(0, 5), random.randrange(0, 1)    
            self.loadParticleConfig('special_effects/fountain/fountain.ptf', self.fountain_pos)
        
        
    def black_light(self):
        # Π’Ρ‹ΠΊΠ»ΡŽΡ‡Π΅Π½Ρ‹ΠΉ свСт
        ambientLight = AmbientLight("ambientLight")
        ambientLight.setColor((0, 0, 0, 1))
        directionalLight = DirectionalLight("directionalLight")
        directionalLight.setDirection((-5, -5, -5))
        directionalLight.setColor((1, 1, 1, 1))
        directionalLight.setSpecularColor((1, 1, 1, 1))
        render.setLight(render.attachNewNode(ambientLight))
        render.setLight(render.attachNewNode(directionalLight))

    def weapon_hide(self):
        # Π£Π±Ρ€Π°Ρ‚ΡŒ ΠΎΡ€ΡƒΠΆΠΈΠ΅
        self.hide_weapon = True
        self.weapon.hide()

    def toggleLights(self, lights):
        # Π‘ΠΏΠ΅Ρ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠ΅ освСщСниС
        if self.hide_weapon:
            for light in lights:
                if render.hasLight(light):
                    render.clearLight(light)
                else:
                    render.setLight(light)
            
            self.flash.setPos(self.weapon_pos)
        else:
            return


    def shot(self):
        dt = globalClock.getDt() + 0.5 # CΠΊΠΎΡ€ΠΎΡΡ‚ΡŒ двиТСния
        if not self.hide_weapon : # Ссли ΠΎΡ€ΡƒΠΆΠΈΠ΅ ΡƒΠ±Ρ€Π°Π½ΠΎ Ρ‚ΠΎ ΠΌΡ‹ Π½Π΅ ΠΌΠΎΠΆΠ΅ΠΌ ΡΡ‚Ρ€Π΅Π»ΡΡ‚ΡŒ
            self.shotSound.play() # ΠΈΠ³Ρ€Π°Π΅ΠΌ Π·Π²ΡƒΠΊ выстрСла
            self.bullet.setPos(self.weapon_pos) # ΠŸΡƒΠ»Ρ Π±ΡƒΠ΄Π΅Ρ‚ спавнится Π²Π½ΡƒΡ‚Ρ€ΠΈ ΠΏΡƒΡˆΠΊΠΈ
            self.bullet.setY(self.bullet, -11 * dt) # Π‘Π΄Π²ΠΈΠ³Π°Π΅ΠΌ ΠΏΡƒΠ»ΡŽ Π½Π° ΠΎΠ³Ρ€ΠΎΠΌΠ½ΠΎΠΉ скорости Π²ΠΏΠ΅Ρ€Ρ‘Π΄

    def check_loss(self):
        if self.state == 0: # Ссли ΠΆΠΈΠ·Π½Π΅ΠΉ Ρƒ корабля Π½Π΅ ΠΎΡΡ‚Π°Π»ΠΎΡΡŒ
            self.black_light() # Π²ΠΊΠ»ΡŽΡ‡ΠΈΠΌ Ρ‡Ρ‘Ρ€Π½Ρ‹ΠΉ свСт
            self.weapon_hide() # ΡƒΠ±Π΅Ρ€Ρ‘ΠΌ ΠΎΡ€ΡƒΠΆΠΈΠ΅
            self.info = OnscreenText(text='ΠΏΠΎΡ€Π°ΠΆΠ΅Π½ΠΈΠ΅', style=1, font=self.font,
                                     fg=(1,1,1,1),
                            pos=(-1.3, -0.5), align=TextNode.ALeft, scale=0.3) # напишСм ΠΎ ΠΏΠΎΡ€Π°ΠΆΠ΅Π½ΠΈΠΈ
            self.crackSound.play() # ΠΈΠ³Ρ€Π°Π΅ΠΌ Π·Π²ΡƒΠΊ Π²Π·Ρ€Ρ‹Π²Π°


    def setKey(self, key, value):
        self.keyMap[key] = value # Π”Π΅Π»Π°Π΅ΠΌ ΠΌΠ΅Ρ…aΠ½uΠ·ΠΌ наТатия клавиш.

    def move(self, task):

        ''' Π”Π΅Π»Π°Π΅ΠΌ Ρ„ΡƒΡ†Π½ΠΊΡ†ΠΈΡŽ двиТСния ΠΈΠ³Ρ€ΠΎΠΊΠ° '''

        dt = globalClock.getDt() - .005 # CΠΊΠΎΡ€ΠΎΡΡ‚ΡŒ двиТСния

        # ΠŸΠΎΠ²ΠΎΡ€ΠΎΡ‚ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ Π²Π»Π΅Π²ΠΎ ΠΈ Π²ΠΏΡ€Π°Π²ΠΎ

        if self.keyMap["cam-left"]:
            self.camera.setX(self.camera, -20 * dt) # МСняСм ΠΏΠΎΠ»ΠΎΠΆΠ΅Π½ΠΈΠΊΠ° ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ ΠΏΠΎ икс. Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ получаСтся илюзия ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚Π° ΡƒΠ³Π»Π° Π»ΡƒΡ‡Π°. Но Π½Π° самом Π΄Π΅Π»Π΅ ΠΊΠ°ΠΌΠ΅Ρ€Π° просто пСрСмСщаСтся.
        if self.keyMap["cam-right"]:
            self.camera.setX(self.camera, +20 * dt) # Π’ΠΎΠΆΠ΅ самоС, Ρ‡Ρ‚ΠΎ ΠΈ Π½Π°Π²Π΅Ρ€Ρ…Ρƒ.

        startpos = self.droid.getPos() # Π‘Π΄Π΅Π»Π°Π΅ΠΌ ΡƒΠ΄ΠΎΠ±Π½ΡƒΡŽ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ ΠΈΠ³Ρ€ΠΎΠΊΠ°

        if self.keyMap["left"]:
            self.droid.setH(self.droid.getH() + 300 * dt)
            self.enemy.setY(self.enemy, 1 * dt)
        if self.keyMap["right"]:
            self.droid.setH(self.droid.getH() - 300 * dt)
            self.enemy.setY(self.enemy, -1 * dt)
        if self.keyMap["forward"]:
            self.droid.setY(self.droid, -25 * dt)
            self.enemy.setX(self.enemy, 1 * dt)
            # Π‘Π΄Π΅Π»Π°Π΅ΠΌ ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½ΠΎΠ΅ условиС ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ ΡƒΠ±Ρ€Π°Π½ΠΎ ΠΎΡ€ΡƒΠΆΠΈΠ΅ ΠΈΠ»ΠΈ Π½Π΅Ρ‚
            if not self.hide_weapon:
                self.weapon_pos = self.droid.getX(), self.droid.getY() + 0.7, 3
                self.weapon.setPos(self.weapon_pos) # ОбновляСм ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΏΡƒΡˆΠΊΠΈ
            else:
                self.weapon_pos = self.droid.getX(), self.droid.getY() + 0.7, 3
                self.flash.setPos(self.weapon_pos)


        camvec = self.droid.getPos() - self.camera.getPos() # Π²Π΅ΠΊΡ‚ΠΎΡ€ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹
        camvec.setZ(0) # 0 высота Π²Π΅ΠΊΡ‚ΠΎΡ€Π°
        camdist = camvec.length() # дистанция ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ ΠΎΡ‚ Π΄Ρ€ΠΎΠΈΠ΄Π°
        camvec.normalize() # Π½ΠΎΡ€ΠΌΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ Π²Π΅ΠΊΡ‚ΠΎΡ€ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹
        if camdist > 10.0: # Ссли дистанция ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ большС 10, Ρ‚ΠΎ смСщаСм ΠΊΠ°ΠΌΠ΅Ρ€Ρƒ Π·Π° Π΄Ρ€ΠΎΠΎΠΈΠ΄ΠΎΠΌ
            self.camera.setPos(self.camera.getPos() + camvec * (camdist - 10))
            camdist = 10.0 # Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ дистанция Π±ΡƒΠ΄Π΅Ρ‚ снова 10
        if camdist < 5.0: # Ссли дистагцтя ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ мСньшС 5, Ρ‚ΠΎ...
            self.camera.setPos(self.camera.getPos() - camvec * (5 - camdist)) # сдвигаСм ΠΊΠ°ΠΌΠ΅Ρ€Ρƒ
            camdist = 5.0 # всё обновляСм
            
        self.camera.lookAt(self.floater) # Π²ΠΎΡ‚ ΠΈ пригодился наш floater


        return task.cont # Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌ Π·Π°Π΄Π°Ρ‡Ρƒ

    def addInstructions(self, pos, msg):
        return OnscreenText(text=msg, style=1, fg=(1,1,1,1), font=self.inst_font, pos=(-1.3, pos), align=TextNode.ALeft, scale = .04, shadow=(0,0,0,1)) # Ѐункция ΠΎ Ρ‚ΠΎΠΌ, ΠΊΠ°ΠΊ ΡƒΠΏΡ€Π°Π²Π»ΡΡ‚ΡŒ

    def addTitle(self, text):
        return OnscreenText(text=text, style=1, fg=(1, 1, 1, 1), scale=0.2,
                            parent=base.a2dBottomRight, align=TextNode.ARight,
                            pos=(-0.1, 0.09), shadow=(0, 0, 0, 1), font=self.font) # Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ тСкстового Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ° с ΡˆΡ€ΠΈΡ„Ρ‚ΠΎΠΌ ΠΈ ΠΏΠΎΠ·ΠΈΡ†ΠΈΠ΅ΠΉ
    

droid = DroidShooter() # Π‘ΠΎΠ·Π΄Π°Π΄ΠΈΠΌ экзСмпляр класса нашСй ΠΈΠ³Ρ€Ρ‹
droid.run() # 3апустим ΠΈΠ³Ρ€Ρƒ


# Ρ€Π°Π·Ρ€ΠΎΠ±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ :
# Π“Π»Π°Π²Π½Ρ‹ΠΉ Π°Π²Ρ‚ΠΎΡ€ : ma3rx
# ΠŸΠΎΠΌΠΎΡ‰Π½ΠΈΠΊ : panda3dmastercoder( присоСдСнился ΠΊ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Ρƒ 31 января, 2021 Π³ΠΎΠ΄Π°, 12:??)
# Π Π΅ΠΊΠ»Π°ΠΌΡ‰ΠΈΠΊ : rdb (написал ΠΏΠ΅Ρ€Π²ΠΎΠ΅ сообщСниС Π½Π° Ρ„ΠΎΡ€ΡƒΠΌΠ΅ 6 фСвраля 2021 Π³ΠΎΠ΄Π°, 20:11)

New screenshot :

All Structure :
./models :
./models/world :frowning: Now, download panda3d art from https://www.panda3d.org/download/noversion/art-gallery.zip
Go to the cat-environment folder. In it you will see a millenium falcon folder. Take all the files from it and put it in the directory ./models/world)
./models/block : block.zip (269.6 KB)
./models/enemies : enemies.zip (381.4 KB)
./models/fighter : fighter.zip (36.9 KB)
./models/player : player.zip (644.6 KB)
./models/sky : sky.zip (12.5 KB)
./models/weapon : weapon.zip (234.3 KB)
./models/whishlyflash : whishlyflash.zip

./fonts : fonts.zip (192.5 KB)
./sounds : sounds.zip (1.8 MB)
./special_effects : special_effects.zip (19.3 KB)
./tex : tex.zip (95.1 KB)

droid.py source code :

#!/usr/bin/env python
# -*- coding: utf_8 -*-

# Π‘ΠΎΠ·Π΄Π°Π½ΠΎ : 22 число, ΡΠ½Π²Π°Ρ€ΡŒ, 2021 Π³ΠΎΠ΄

# Π˜ΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΡƒΠ΅ΠΌ всС Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹Π΅ инструмСнты
from direct.showbase.ShowBase import ShowBase
from panda3d.core import CollisionTraverser, CollisionNode
from panda3d.core import CollisionHandlerPusher, CollisionSphere, CollisionInvSphere
from panda3d.core import Filename, AmbientLight, DirectionalLight
from panda3d.core import PandaNode, NodePath, Camera, TextNode
from direct.particles.Particles import Particles
from direct.particles.ParticleEffect import ParticleEffect
from panda3d.core import PointLight, Spotlight
from panda3d.core import CollideMask
from panda3d.core import loadPrcFileData
from panda3d.core import *
from direct.gui.OnscreenText import OnscreenText
from direct.gui.OnscreenImage import OnscreenImage
from direct.gui.DirectButton import DirectButton
from direct.gui.DirectSlider import DirectSlider
from direct.actor.Actor import Actor
import random
import sys
import time
import os
import math


VERSION = '3.0.6'

settings = ['window-title Droid Game ' +  VERSION,
            'fullscreen 0']
            

loadPrcFileData('', settings[0]) # Π‘Π΄Π΅Π»Π°Π΅ΠΌ Π½Π΅ стандартный Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ (Π²ΠΎΠ·ΠΌΡ‘ΠΌ Π΅Π³ΠΎ ΠΈΠ· ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ settings)
loadPrcFileData('', settings[1]) # Π½Π΅ Π±ΡƒΠ΄Π΅ΠΌ Π΄Π΅Π»Π°Ρ‚ΡŒ полноэкранный Ρ€Π΅ΠΆΠΈΠΌ

# Π‘ΠΎΠ·Π΄Π°Π΄ΠΈΠΌ Π³Π»Π°Π²Π½Ρ‹ΠΉ класс нашСй ΠΈΠ³Ρ€Ρ‹
class DroidShooter(ShowBase):
    def __init__(self):
        ShowBase.__init__(self) # Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ всС сСлфы ΠΈΠ· direct
        self.speed = 1800 # ΡΠΊΠΎΡ€ΠΎΡΡ‚ΡŒ двигатСля
        self.GB = False # НЕ Ρ‡Ρ‘Ρ€Π½ΠΎ-Π±Π΅Π»Ρ‹ΠΉ Ρ€Π΅ΠΆΠΈΠΌ
        self.menu() # звпуск мСню
        
    def menu(self):
        
        base.enableParticles() # ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ эффСкт Π΄Ρ‹ΠΌΠ°

        self.win.setClearColor((0, 0, 0, 1)) # Π—Π°ΠΊΡ€Π°ΡˆΠΈΠ²Π°Π΅ΠΌ ΠΏΠΎΠ²Π΅Ρ€Ρ…Π½ΠΎΡΡ‚ΡŒ Ρ‡Ρ‘Ρ€Π½Ρ‹ΠΌ. Π”Π΅Π»ΠΎ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ Π² этом ΠΈΠ³Ρ€ΠΎΠ²ΠΎΠΌ Π΄Π²ΠΈΠΆΠΊΠ΅ ΠΏΠΎΠ²Π΅Ρ€Ρ…Π½ΠΎΡΡ‚ΡŒ Π·Π°ΠΊΡ€Π°ΡˆΠΈΠ²Π°Π΅Ρ‚ΡΡ сСрым.
        self.font = loader.loadFont('./fonts/doom_font.ttf') # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ ΡˆΡ€ΠΈΡ„Ρ‚ ΠΈΠ· ΠΈΠ³Ρ€Ρ‹ doom
        self.inst_font = loader.loadFont('./fonts/arial.ttf') # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ ΡˆΡ€ΠΈΡ„Ρ‚ arial

        self.crackSound = loader.loadMusic('./sounds/crack.wav') # Π·Π²ΡƒΠΊ Π²Π·Ρ€Ρ‹Π²Π° корабля
        self.shotSound = loader.loadMusic('./sounds/shot.wav') # Π·Π²ΡƒΠΊ выстрСла
        self.startSound = loader.loadMusic('./sounds/started.wav') # Π·Π²ΡƒΠΊ запуска
        self.errorSound = loader.loadMusic('./sounds/error.wav') # Π·Π²ΡƒΠΊ запуска
        self.errorSound.setVolume(1) # полная Π³Ρ€ΠΎΠΌΠΊΠΎΡΡ‚ΡŒ Π·Π²ΡƒΠΊΠ°
        self.startSound.setVolume(1) # полная Π³Ρ€ΠΎΠΌΠΊΠΎΡΡ‚ΡŒ Π·Π²ΡƒΠΊΠ°
        self.crackSound.setVolume(1) # полная Π³Ρ€ΠΎΠΌΠΊΠΎΡΡ‚ΡŒ Π·Π²ΡƒΠΊΠ°
        self.shotSound.setVolume(1) # полная Π³Ρ€ΠΎΠΌΠΊΠΎΡΡ‚ΡŒ Π·Π²ΡƒΠΊΠ°
        self.startSound.play() # ΠΈΠ³Ρ€Π°Π΅ΠΌ Π·Π²ΡƒΠΊ запуска ΠΈΠ³Ρ€Ρ‹

        self.button_start = DirectButton(pos=(0.7, 0, 0.4), text="CTAPT",
                                   scale=.2, pad=(.2, .2),
                                   command=self.load_game) # ΠΊΠ½ΠΎΠΏΠΊΠ° запуска ΠΈΠ³Ρ€Ρ‹

        self.gb_start = DirectButton(pos=(0.7, 0, 0.1), text="GB",
                                   scale=.2, pad=(.2, .2),
                                   command=self.gb_mode) # ΠΊΠ½ΠΎΠΏΠΊΠ° запуска ΠΈΠ³Ρ€Ρ‹  Π² Ρ‡Ρ‘Ρ€Π½ΠΎ-Π±Π΅Π»ΠΎΠΌ Ρ€Π΅ΠΆΠΈΠΌΠ΅      

        self.slider_sun = DirectSlider(pos=(0.1, 0, .75), scale=0.8, value=0.5,
                                    command=self.set_sun_interval)


        self.title = self.addTitle("Droid game " + VERSION)
        
        # НапСчатаСм ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅
        self.inst1 = self.addInstructions(0.95, u"[ESC]: Π’Ρ‹Ρ…ΠΎΠ΄")
        self.inst2 = self.addInstructions(0.90, u"[Left Arrow]: ΠŸΠΎΠ²ΠΎΡ€ΠΎΡ‚ Π΄Ρ€ΠΎΠΈΠ΄Π° Π² Π»Π΅Π²ΠΎ")
        self.inst3 = self.addInstructions(0.85, u"[Right Arrow]: ΠŸΠΎΠ²ΠΎΡ€ΠΎΡ‚ Π΄Ρ€ΠΎΠΈΠ΄Π° Π² ΠΏΡ€Π°Π²ΠΎ")
        self.inst4 = self.addInstructions(0.80, u"[Up Arrow]: Π’ΠΏΠ΅Ρ€Π΅Π΄")
        self.inst5 = self.addInstructions(0.75, u"[a]: ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ Π² ΠΏΡ€Π°Π²ΠΎ")
        self.inst6 = self.addInstructions(0.70, u"[d]: ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ Π² Π»Π΅Π²ΠΎ")
        self.inst7 = self.addInstructions(0.65, u"[Left Arrow + Up arrow]: ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚ Π΄Ρ€ΠΎΠΈΠ΄Π° Π² Π»Π΅Π²ΠΎ ΠΈ Π²ΠΏΠ΅Ρ€Ρ‘Π΄")
        self.inst8 = self.addInstructions(0.60, u"[Right Arrow + Up arrow]: ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚ Π΄Ρ€ΠΎΠΈΠ΄Π° Π² ΠΏΡ€Π°Π²ΠΎ ΠΈ Π²ΠΏΠ΅Ρ€Ρ‘Π΄")
        self.inst9 = self.addInstructions(0.55, u"[a + Up arrow]: ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ Π² ΠΏΡ€Π°Π²ΠΎ ΠΈ Π²ΠΏΠ΅Ρ€Ρ‘Π΄")
        self.inst10 = self.addInstructions(0.50, u"[d + Up arrow]: ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ Π² Π»Π΅Π²ΠΎ ΠΈ Π²ΠΏΠ΅Ρ€Ρ‘Π΄")
        self.inst11 = self.addInstructions(0.45, u"[space]: ΡΡ‚Ρ€Π΅Π»ΡŒΠ±Π°")
        self.inst12 = self.addInstructions(0.40, u"[s]: Π΄ΠΎΡΡ‚Π°Ρ‚ΡŒ Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊ")
        self.inst13 = self.addInstructions(0.35, u"[w]: ΡƒΠ±Ρ€Π°Ρ‚ΡŒ ΠΎΡ€ΡƒΠΆΠΈΠ΅")
        self.inst14 = self.addInstructions(0.30, u"[f]: ΠΏΠΎΠ»Π½Ρ‹ΠΉ Ρ€Π°Π·Π³ΠΎΠ½(ОПАБНО!)")
        self.inst15 = self.addInstructions(0.25, u"[0]: ΠΏΠΎΠΆΠ°Ρ€ΠΎΡ‚ΡƒΡˆΠΈΡ‚Π΅Π»ΡŒΠ½Π°Ρ систСма")

        self.accept("escape", sys.exit) # ΠŸΡ€ΠΈ Π½Π°ΠΆΠ°Ρ‚ΠΈΠΈ клавиши Esc Π²Ρ‹Ρ…ΠΎΠ΄ΠΈΠΌ.

    def set_sun_interval(self):
        self.sun_interval = self.slider_sun.guiItem.getValue() * 100 # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ слайдСрноС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΡƒΠΌΠ½ΠΎΠΆΠ΅Π½ΠΎΠ΅ Π½Π° 500, Π΄Π° Ρ‚Ρ€Π°Ρ‡Ρƒ ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΡŽ Π½ΠΎ ΠΌΠ½Π΅ каТСтся ΠΌΠ½ΠΎΠ³ΠΈΠΌ ΠΏΠ»Π΅Π²Π°Ρ‚ΡŒ Π½Π° ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΡŽ мСню, ΠΈΠ±ΠΎ Ρ‚Π°ΠΊΠΎΠ³ΠΎ понятия просто Π½Π΅Ρ‚Ρƒ :)

    def gb_mode(self):
        '''Π²ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ Ρ‡Ρ‘Ρ€Π½ΠΎΠ±Π΅Π»ΠΎΠ³ΠΎ Ρ€Π΅ΠΆΠΈΠΌΠ°'''
        self.GB = True

    def load_game(self):
        self.button_start.hide() # ΡƒΠ΄Π°Π»ΠΈΠΌ ΠΊΠ½ΠΎΠΏΠΊΡƒ старта
        self.gb_start.hide() # ΡƒΠ΄Π°Π»ΠΈΠΌ ΠΊΠ½ΠΎΠΏΠΊΡƒ Ρ‡Ρ‘Ρ€Π½ΠΎ Π±Π΅Π»ΠΎΠ³ΠΎ Ρ€Π΅ΠΆΠΈΠΌΠ°.
        self.title.hide() # ΡƒΠ΄Π°Π»ΠΈΠΌ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ ΠΈΠ³Ρ€Ρ‹
        # ΡƒΠ΄Π°Π»ΠΈΠΌ ΠΊΠ½ΠΎΠΏΠΊΠΈ управлСния
        self.inst1.hide()
        self.inst2.hide()
        self.inst3.hide()
        self.inst4.hide()
        self.inst5.hide()
        self.inst6.hide()
        self.inst7.hide()
        self.inst8.hide()
        self.inst9.hide()
        self.inst10.hide()
        self.inst11.hide()
        self.inst12.hide()
        self.inst13.hide()
        self.inst14.hide()
        self.inst15.hide()
        self.slider_sun.hide() # удаляСм слайдСр солнца
        
        self.keyMap = {
            "left": 0, "right": 0, "forward": 0, "cam-left": 0, "cam-right": 0} # Π‘ΠΎΠ·Π΄Π°Π΄ΠΈΠΌ ΡΠ»ΠΎΠ²Π°Ρ€ΡŒ ΠΊΠ½ΠΎΠΏΠΎΠΊ, ΠΏΠΎ ΠΈΡ… Π½Π°ΠΆΠ°Ρ‚ΠΈΡŽ        

        # РисуСм Π·Π²Ρ‘Π·Π΄Ρ‹

        self.sky = loader.loadModel("./models/sky/solar_sky_sphere") # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ модСль космоса(это сфСра)

        self.sky_tex = loader.loadTexture("./tex/stars_1k_tex.jpg") # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ тСкстуру
        self.sky.setTexture(self.sky_tex, 1) # Π·Π°Ρ€Π΅Π½Π΄Π΅Ρ€ΠΈΠΌ тСкстуру Π½Π° Π½Π΅Π±ΠΎ
        self.sky.reparentTo(render) # ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ Π½Π΅Π±ΠΎ
        self.sky.setScale(40000) # Ρ€Π°ΡΡˆΠΈΡ€ΠΈΠΌ Π½Π΅Π±ΠΎ Π΄ΠΎ максимальной Π²Π΅Π»ΠΈΡ‡ΠΈΠ½Ρ‹ panda3d

        self.environ = loader.loadModel("models/world/falcon.egg") # Π—Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ ΡƒΠΆΠ΅ созданный Π² blender ΠΌΠΈΡ€.
        self.environ.reparentTo(render) # Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ модСль ΠΌΠΈΡ€Π° Π² ΠΎΠΊΠ½ΠΎ

        droidStartPos = (-1, 0, 1.5 ) # Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ ΡΡ‚Π°Ρ€Ρ‚ΠΎΠ²ΡƒΡŽ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π² ΠΌΠΈΡ€Π΅.
        enemyStartPos = (-6, 1, 0.5) # Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ°-Π΄Ρ€ΠΎΠΈΠ΄Π°.
        self.droid = Actor("models/player/seeker.egg") # Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ модСль ΠΈΠ³Ρ€ΠΎΠΊΠ° (созданная Π² blender)
        self.enemy = Actor("models/enemies/r2d2/r2d2.egg") # Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ модСль ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ° (созданная Π² blender)
        self.droid.reparentTo(render) # ΠŸΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Π΅ΠΌ модСль ΠΈΠ³Ρ€ΠΎΠΊΠ° Π² наш ΠΌΠΈΡ€.
        self.enemy.reparentTo(render) # ΠŸΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Π΅ΠΌ модСль ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ° Π² наш ΠΌΠΈΡ€.
        self.droid.setScale(1) # Π”Π΅Π»Π°Π΅ΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ€ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π½Π° 1
        self.enemy.setScale(1) # Π”Π΅Π»Π°Π΅ΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ€ ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ° Π½Π° 1
        self.droid.setPos(droidStartPos) # Π‘Ρ‚Π°Π²ΠΈΠΌ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π½Π° Ρ€Π°Π½Π΅Π΅ ΡΠΎΠ·Π΄Π°Π½ΡƒΡŽ Π½Π°ΠΌΠΈ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ
        self.enemy.setPos(enemyStartPos) # Π‘Ρ‚Π°Π²ΠΈΠΌ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ° Π½Π° Ρ€Π°Π½Π΅Π΅ ΡΠΎΠ·Π΄Π°Π½ΡƒΡŽ Π½Π°ΠΌΠΈ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ

        self.weapon = Actor('models/weapon/lightsaber.egg') # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ ΠΎΡ€ΡƒΠΆΠΈΠ΅
        self.bullet = Actor('models/weapon/bullet/bullet.egg.pz') # Π—Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ ΠΏΡƒΠ»ΡŽ
        self.flash = Actor('models/whishlyflash/handlamp.egg') # Π—Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊ
               
        self.weapon.reparentTo(render) # пСрСмСстим ΠΎΡ€ΡƒΠΆΠΈΠ΅ Π² наш ΠΌΠΈΡ€
        self.bullet.reparentTo(render) # пСрСмСстим ΠΏΡƒΠ»ΡŽ Π² ΠΌΠΈΡ€ Π½ΠΎ появится ΠΎΠ½Π° сама Π½Π΅ скоро
        self.flash.reparentTo(render) # пСрСмСстим Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊ Π² наш ΠΌΠΈΡ€
        self.weapon.setScale(.5) # Π·Π°Π΄Π°Π΄ΠΈΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ€ ΠΏΡƒΡˆΠΊΠΈ
        self.bullet.setScale(.5) # Π·Π°Π΄Π°Π΄ΠΈΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ€ ΠΏΡƒΠ»ΠΈ
        self.flash.setScale(.5) # Π·Π°Π΄Π°Π΄ΠΈΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ€ Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊΠ°

        # враТСский ΠΈΡΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»ΡŒ
        self.fighter = Actor('models/fighter/fighter.egg') # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ ΠΌΠΎΠ΄Π΅Π»ΡŒΠΊΡƒ истрСбитСля
        self.fighter.reparentTo(render) # ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ ΠΈΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»ΡŒ
        self.fighter.setPos(0, 90, 0) # позиция истрСбитСля
                

        self.weapon_pos = self.droid.getX(), self.droid.getY() + 0.7, 1 # ΠŸΠΎΠ·ΠΈΡ†ΠΈΡ ΠΏΡƒΡˆΠΊΠΈ
        
        self.weapon.setPos(self.weapon_pos) # ΠŸΠΎΠΌΠ΅ΡΡ‚ΠΈΠΌ ΠΎΡ€ΡƒΠΆΠΈΠ΅ Ρ‡ΡƒΡ‚ΡŒ Π²Ρ‹ΡˆΠ΅ ΠΈΠ³Ρ€ΠΎΠΊΠ°

        self.cube = Actor('models/block/crate.egg') # Π·Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ Π±Π»ΠΎΠΊ
        self.cube.reparentTo(render)
        self.cube.setPos(0, -0, 0) # позиция ящика
        self.cube.setScale(0.7)
        self.cube.hprInterval(1.5, (0, 360, 360)).loop()

        self.Intervalcube = self.cube.posInterval(13,
                                                   Point3(0, -500, 0),
                                                   startPos=Point3(0, 10, 0))

        self.Intervalcube.loop()
        
        self.spotlight = camera.attachNewNode(Spotlight("spotlight")) # ΠšΠΎΠ½Ρ„ΠΈΠ³ΠΈ Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊΠ°
        self.spotlight.node().setColor((.3, .3, .3, 1))
        self.spotlight.node().setSpecularColor((0, 0, 0, 1))

        self.floater = NodePath(PandaNode("floater")) 
        self.floater.reparentTo(self.droid)
        self.floater.setZ(2.0)

        self.accept("escape", sys.exit) # ΠŸΡ€ΠΈ Π½Π°ΠΆΠ°Ρ‚ΠΈΠΈ клавиши Esc Π²Ρ‹Ρ…ΠΎΠ΄ΠΈΠΌ.
        
        self.accept("arrow_left", self.setKey, ["left", True]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ Π²Π»Π΅Π²ΠΎ - ΠΏΠΎΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π²Π»Π΅Π²ΠΎ
        self.accept("arrow_right", self.setKey, ["right", True]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ Π²ΠΏΡ€Π°Π²ΠΎ - ΠΏΠΎΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π²ΠΏΡ€Π°Π²ΠΎ
        self.accept("arrow_up", self.setKey, ["forward", True]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ Π²ΠΏΠ΅Ρ€Ρ‘Π΄ - ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄
        self.accept("a", self.setKey, ["cam-left", True]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ a - Ρ€Π°Π·Π²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΊΠ°ΠΌΠ΅Ρ€Ρƒ Π²ΠΎΠΊΡ€ΡƒΠ³ нашСй модСльки
        self.accept("d", self.setKey, ["cam-right", True]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ s - Ρ€Π°Π·Π²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΊΠ°ΠΌΠ΅Ρ€Ρƒ Π²ΠΎΠΊΡ€ΡƒΠ³ нашСй модСльки
        self.accept("arrow_left-up", self.setKey, ["left", False]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ Π²Π²Π΅Ρ€Ρ…+Π²Π»Π΅Π²ΠΎ - ΠΏΠΎΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π²Π»Π΅Π²ΠΎ ΠΈ ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄
        self.accept("arrow_right-up", self.setKey, ["right", False]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ Π²Π²Π΅Ρ€Ρ…+ΠΏΡ€Π°Π²ΠΎ - ΠΏΠΎΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π²ΠΏΡ€Π°Π²ΠΎ ΠΈ ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄
        self.accept("arrow_up-up", self.setKey, ["forward", False]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ Π²Π²Π΅Ρ€Ρ…+Π²Π²Π΅Ρ€ΡŠ - ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄ ΠΈ ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄
        self.accept("a-up", self.setKey, ["cam-left", False]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ a+Π²ΠΏΠ΅Ρ€Ρ‘Π΄ - ΠΏΠΎΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΊΠ°ΠΌΠ΅Ρ€Ρƒ Π²Π»Π΅Π²ΠΎ ΠΈ ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄
        self.accept("d-up", self.setKey, ["cam-right", False]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ s+Π²ΠΏΠ΅Ρ€Ρ‘Π΄ - ΠΏΠΎΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΊΠ°ΠΌΠ΅Ρ€Ρƒ Π²ΠΏΡ€Π°Π²ΠΎ ΠΈ ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄

        self.accept("space", self.shot) # ΠΏΡ€ΠΈ ΠΏΡ€ΠΎΠ±Π΅Π»Π΅ стрСляСм
        self.accept("s", self.toggleLights, [[self.spotlight]]) # Π’ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊ
        self.accept("w", self.weapon_hide) # ΠΏΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ w - ΡƒΠ±Π΅Ρ€Ρ‘ΠΌ ΠΎΡ€ΡƒΠΆΠΈΠ΅.

        base.enableParticles() # Π’ΠΊΠ»ΡŽΡ‡Π°Π΅ΠΌ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ Π΄Ρ‹ΠΌΠ°
        self.t = loader.loadModel("models/weapon/lightsaber.egg") # Π—Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ Π΅Ρ‰Ρ‘ ΠΎΡ€ΡƒΠΆΠΈΠ΅
        self.t.reparentTo(render) # ΠŸΠ΅Ρ€Π΅ΠΌΠ΅ΡΡ‚ΠΈΠΌ ΠΎΡ€ΡƒΠΆΠΈΠ΅ Π² наш ΠΌΠΈΡ€
        self.p = ParticleEffect() # Π’ΠΊΠ»ΡŽΡ‡ΠΈΠΌ эффСкт Π΄Ρ‹ΠΌΠ°
        self.accept('f', self.particle_start) # ΠΏΡ€ΠΈ Π½Π°ΠΆΠ°Ρ‚ΠΈΠΈ f(ΠΎΡ‚ force) -  Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ Ρ„Π°ΠΉΠ» Π΄Ρ‹ΠΌΠ° ΠΈ пСрСмСстим Π² ΠΊΠΎΠ½Ρ„ΠΈΠ³ Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΈΠΌΠ΅Π½Π½ΠΎ эта анимация стала ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ΠΌ Π΄Ρ‹ΠΌΠ°
        self.accept('0', self.fountain) # ΠΏΡ€ΠΈ  Π½Π°ΠΆΠ°Ρ‚ΠΈΠΈ ΠΊΠ½ΠΎΠΏΠΎΠΊ f+o(fountain) Π²ΠΊΠ»ΡŽΡ‡ΠΈΠΌ ΠΏΠΎΠΆΠ°Ρ€ΠΎΡ‚ΡƒΡˆΠΈΡ‚Π΅Π»ΡŒΠ½ΡƒΡŽ систСму

        taskMgr.add(self.move, "moveTask") # ДобавляСм Π·Π°Π΄Π°Ρ‡Ρƒ Π² наш Π΄Π²ΠΈΠΆΠΎΠΊ

        self.isMoving = False # Π‘Ρ‚Π°Π²ΠΈΠΌ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ isMoving Π½Π° False(Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΌΠ΅Π½ΡΡ‚ΡŒ это Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅) Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΈΠ³Ρ€ΠΎΠΊ ΠΈΠ·Π½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎ стоял.
        # Π”Π΅Π»Π°Π΅ΠΌ Ρ‚Π°ΠΊ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ свСт Π±Ρ‹Π» ΠΈΠ·Π½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎ Π²Ρ‹ΠΊΠ»ΡŽΡ‡Π΅Π½.
        self.disableMouse() # ΠžΡ‚ΠΊΠ»ΡŽΡ‡Π°Π΅ΠΌ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π΅Π½ΠΈΠ΅ Ρ‡Π΅Ρ€Π΅Π· ΠΌΡ‹ΡˆΠΊΡƒ
        self.camera.setPos(self.droid.getX(), self.droid.getY() + 1, 3) # Π‘Ρ‚Π°Π²ΠΈΠΌ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ Ρ‡ΡƒΡ‚ΡŒ большС ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ ΠΈΠ³Ρ€ΠΎΠΊΠ°

        self.black_light() # Π‘Π΄Π΅Π»Π°Π΅ΠΌ Π²Ρ‹ΠΊΠ»ΡŽΡ‡Π΅Π½Π½Ρ‹ΠΉ свСт

        self.state = 100 # БостояниС корабля
        self.state_info = OnscreenText(text='ΠΊΠΎΡ€Π°Π±Π»ΡŒ :' + str(self.state), pos=(0.5, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля
                
        self.check_loss() # ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ ΠΏΠΎΡ€Π°ΠΆΠ΅Π½ΠΈΠ΅
        self.hide_weapon = False # ΠŸΠΎΡΡ‚Π°Π²ΠΈΠΌ, Ρ‡Ρ‚ΠΎ ΠΎΡ€ΡƒΠΆΠΈΠ΅ Π½Π΅ ΡƒΠ±Ρ€Π°Π½ΠΎ
        self.steam_pos = random.randrange(0, 5), random.randrange(0, 5), random.randrange(0, 5)
        self.fountain_pos = random.randrange(0, 5), random.randrange(0, 5), random.randrange(0, 1)

        self.motor_pos1 = 25.238849639892578, 8.962211608886719, 1.5 # позиция ΠΏΠ΅Ρ€Π²ΠΎΠ³ΠΎ ΠΌΠΎΡ‚ΠΎΡ€Π°
        self.motor_pos2 = -20.676218032836914, 10.55816650390625, 1.5 # позиция Π²Ρ‚ΠΎΡ€ΠΎΠ³ΠΎ ΠΌΠΎΡ‚ΠΎΡ€Π°

        self.motor1 = self.loadParticleConfig('special_effects/steam_critic+/fireish.ptf', self.motor_pos1) # ΠΌΠΎΡ‚ΠΎΡ€ 1
        self.motor2 = self.loadParticleConfig('special_effects/steam_critic+/fireish.ptf', self.motor_pos2) # ΠΌΠΎΡ‚ΠΎΡ€ 2

        self.state_info2 = OnscreenText(text='', pos=(-0.8, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля

        self.force = False # ΠŸΠΎΡΡ‚Π°Π²ΠΈΠΌ, Ρ‡Ρ‚ΠΎ Π½Π΅ Ρ€Π°Π·Π³ΠΎΠ½ΡΠ»ΠΈΡΡŒ

        # ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ ΠΊΠΎΠ»Π»ΠΈΠ·ΠΈΠΈ

        # Коллизия корабля(ΠΎΠ½ Ρƒ нас ΠΊΠ°ΠΊ главная ΠΊΠ°Ρ€Ρ‚Π°).
        self.cTrav = CollisionTraverser()
        pusher = CollisionHandlerPusher()
        
        environCenter = self.environ.getBounds().getCenter()
        environRad = self.environ.getBounds().getRadius()
        cNode = CollisionNode("environment")
        cNode.addSolid(CollisionInvSphere(environCenter, environRad))
        environC = self.environ.attachNewNode(cNode)

        # Коллизия Π΄Ρ€ΠΎΠΈΠ΄Π°.
        droidCenter = self.droid.getBounds().getCenter()
        droidRad = self.droid.getBounds().getRadius()
        cNode = CollisionNode("droid")
        cNode.addSolid(CollisionSphere(droidCenter, droidRad))
        droidC = self.droid.attachNewNode(cNode)
        
        pusher.addCollider(droidC, self.droid)
        self.cTrav.addCollider(droidC, pusher)

        # Коллизия ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ°.
        enemyCenter = self.enemy.getBounds().getCenter()
        enemyRad = self.enemy.getBounds().getRadius()
        cNode = CollisionNode("enemy")
        cNode.addSolid(CollisionSphere(enemyCenter, enemyRad))
        enemyC = self.enemy.attachNewNode(cNode)

        pusher.addCollider(enemyC, self.enemy)
        self.cTrav.addCollider(enemyC, pusher)

        # Коллизия враТСского истрСбитСля.
        fighterCenter = self.fighter.getBounds().getCenter()
        fighterRad = self.fighter.getBounds().getRadius()
        cNode = CollisionNode("fighter")
        cNode.addSolid(CollisionSphere(fighterCenter, fighterRad))
        fighterC = self.fighter.attachNewNode(cNode)

        pusher.addCollider(fighterC, self.fighter)
        self.cTrav.addCollider(fighterC, pusher)

        # Коллизия ΠΏΡƒΠ»ΠΈ.
        bulletCenter = self.bullet.getBounds().getCenter()
        bulletRad = self.bullet.getBounds().getRadius()
        cNode = CollisionNode("bullet")
        cNode.addSolid(CollisionSphere(bulletCenter, bulletRad))
        bulletC = self.bullet.attachNewNode(cNode)

        bulletCenter = self.bullet.getBounds().getCenter()
        bulletRad = self.bullet.getBounds().getRadius()
        cNode = CollisionNode("bullet")
        cNode.addSolid(CollisionSphere(bulletCenter, bulletRad))
        bulletC = self.bullet.attachNewNode(cNode)
        
        pusher.addCollider(bulletC, self.bullet)
        self.cTrav.addCollider(bulletC, pusher)

        # Коллизия ΠΏΡƒΡˆΠΊΠΈ. Π― Π±Ρ‹ Π½Π΅ сказал, Ρ‡Ρ‚ΠΎ это ΠΈΠΌΠ΅Π½Π½ΠΎ коллизия, скорСС это для рСалистичности
        weaponCenter = self.weapon.getBounds().getCenter()
        weaponRad = self.weapon.getBounds().getRadius()
        cNode = CollisionNode("weapon")
        cNode.addSolid(CollisionSphere(weaponCenter, weaponRad))
        weaponC = self.weapon.attachNewNode(cNode)
        
        pusher.addCollider(weaponC, self.weapon)
        self.cTrav.addCollider(weaponC, pusher)

        # солнцС(новая ΠΌΠ΅Ρ…Π°Π½ΠΈΠΊΠ° освСщСния)
        sun = DirectionalLight("sun")
        sun.set_color_temperature(6000)
        sun.color = sun.color * 4
        sun_path = render.attach_new_node(sun)
        sun_path.set_pos(10, -10, -10)
        sun_path.look_at(0, 0, 0)
        sun_path.hprInterval(self.sun_interval, (sun_path.get_h(), sun_path.get_p() - 360, sun_path.get_r()), bakeInStart=True).loop()
        render.set_light(sun_path)

        # Если  ΠΈΠ³Ρ€ΠΎΠΊ Π·Π°Ρ…ΠΎΡ‚Π΅Π» ΠΏΠΎΠΈΠ³Ρ€Π°Ρ‚ΡŒ Π² Ρ‡Ρ‘Ρ€Π½ΠΎΠ±Π΅Π»ΡƒΡŽ ΠΈΠ³Ρ€Ρƒ, ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΠΌ это
        if self.GB :        
            render.set_shader(Shader.load(Shader.SL_GLSL, "lighting.vert", "lighting.frag")) # Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ ΡˆΠ΅ΠΉΠ΄Π΅Ρ€Ρ‹ Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‚!



    def fight_force(self):
        # сдвиТСниС истрСбитСля Π·Π° нашим ΠΊΠΎΡ€Π°Π±Π»Ρ‘ΠΌ(ΠΎΡ‡Π΅Π½ΡŒ простым способом я сдСлал Ρ‚Π°ΠΊ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΈΡΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»ΡŒ Π·Π°ΠΆΠΈΠΌΠ°Π» нас(Π»Π΅Ρ‚Π°Π» Π² нашСм ΠΊΠ²Π°Π΄Ρ€Π°Ρ‚Π΅)) ΠΈ Π·Π°ΠΆΠΈΠΌΠ°Π΅Ρ‚ ΠΎΠ½ Ρ€Π΅Π°Π»ΡŒΠ½ΠΎ, сблиТая ΠΊ Π½Π°ΠΌ свой ΠΊΠ²Π°Π΄Ρ€Π°Ρ‚
        self.fighter.setY(self.fighter.getY() - self.speed) 
        self.fighter.setX(self.fighter.getX() - 10)    

        print(self.fighter.getX())


    def loadParticleConfig(self, filename, pos):
        self.p.cleanup()
        self.p = ParticleEffect()
        self.p.loadConfig(Filename(filename))

        self.p.start(self.t)
        self.p.setPos(pos)

    def particle_start(self):
        self.force = True # ΠŸΠΎΡΡ‚Π°Π²ΠΈΠΌ, Ρ‡Ρ‚ΠΎ ΠΌΡ‹ ΡƒΠΆΠ΅ Ρ€Π°Π·Π³ΠΎΠ½ΡΠ»ΠΈΡΡŒ
        # ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Π΅ΠΌ всС ΠΎΠ±ΡŒΠ΅ΠΊΡ‚Ρ‹ Π·Π° ΠΊΠΎΡ€Π°Π±Π»Ρ‘ΠΌ
        self.environ.setY(self.environ.getY() - self.speed) # нСсёмся Π²ΠΏΡ€Π°Π²ΠΎ
        self.droid.setY(self.droid.getY() - self.speed) # сдвигаСм Π΄Ρ€ΠΎΠΈΠ΄Π° Π·Π° ΠΊΠΎΡ€Π°Π±Π»Ρ‘ΠΌ
        self.enemy.setY(self.enemy.getY() - self.speed) # сдфигаСм ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ° Π·Π° ΠΊΠΎΡ€Π°Π±Π»Ρ‘ΠΌ
        self.weapon.setY(self.weapon.getY() - self.speed) # ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Π΅ΠΌ ΠΎΡ€ΡƒΠΆΠΈΠ΅
        self.flash.setY(self.flash.getY() - self.speed) # ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Π΅ΠΌ Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊ
        self.cube.setY(self.cube.getY() - self.speed) # ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Π΅ΠΌ ящик
        self.fight_force()

        self.state -= 1 # сдСлаСм мСньшС ΠΎΡ‡ΠΊΠΎΠ²
        self.state_info.hide() # ΡƒΠ΄Π°Π»ΠΈΠΌ тСкстовыС ΠΎΡ‡ΠΊΠΈ
        
        if self.state != 10 and self.state > 10:
            self.state_info.hide() # ΡƒΠ±ΠΈΡ€Π°Π΅ΠΌ ΠΏΡ€Π΅Π΄Π΅Π΄ΡƒΡ‰Π΅Π΅ сообщСниС ΠΎ Тизнях корабля
            self.state_info = OnscreenText(text='ΠΊΠΎΡ€Π°Π±Π»ΡŒ :' + str(self.state), pos=(0.5, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля
            self.check_loss() # провСряСм ΠΏΠΎΡ€Π°ΠΆΠ΅Π½ΠΈΠ΅
            self.steam_pos = random.randrange(0, 5), random.randrange(0, 5) + 300, random.randrange(0, 5)
            self.loadParticleConfig('special_effects/steam/steam.ptf', self.steam_pos)
            self.errorSound.play() # ΠΈΠ³Ρ€Π°Π΅ΠΌ Π·Π²ΡƒΠΊ ошибки
            self.state_info2.hide() # ΡƒΠ±ΠΈΡ€Π°Π΅ΠΌ ΠΏΡ€Π΅Π΄Π΅Π΄ΡƒΡ‰Π΅Π΅ сообщСниС
            self.state_info2 = OnscreenText(text='Π΄Π²ΠΈΠ³Π°Ρ‚Π΅Π»ΡŒ нСисправСн', pos=(-0.8, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля
        else:
            self.state_info = OnscreenText(text='ΠΊΠΎΡ€Π°Π±Π»ΡŒ :' + str(self.state), pos=(0.5, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля
            self.check_loss() # провСряСм ΠΏΠΎΡ€Π°ΠΆΠ΅Π½ΠΈΠ΅
            self.steam_pos = random.randrange(0, 5), random.randrange(0, 5) + 300, random.randrange(0, 5)
            self.loadParticleConfig('special_effects/steam_critic/steam.ptf', self.steam_pos)
            self.errorSound.play() # ΠΈΠ³Ρ€Π°Π΅ΠΌ Π·Π²ΡƒΠΊ ошибки
            self.state_info2.hide()  # ΡƒΠ±ΠΈΡ€Π°Π΅ΠΌ ΠΏΡ€Π΅Π΄Π΅Π΄ΡƒΡ‰Π΅Π΅ сообщСниС
            self.state_info2 = OnscreenText(text='критичСскоС состояниС', pos=(-0.8, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля
    
        if self.state < 10:
            self.state_info.hide()
            self.state_info = OnscreenText(text='ΠΊΠΎΡ€Π°Π±Π»ΡŒ :' + str(self.state), pos=(0.5, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля
            self.check_loss() # провСряСм ΠΏΠΎΡ€Π°ΠΆΠ΅Π½ΠΈΠ΅
            self.steam_pos = random.randrange(0, 5), random.randrange(0, 5) + 300, random.randrange(0, 5)            
            self.loadParticleConfig('special_effects/steam_critic+/fireish.ptf', self.steam_pos)
            self.errorSound.play() # ΠΈΠ³Ρ€Π°Π΅ΠΌ Π·Π²ΡƒΠΊ ошибки
            self.state_info2.hide() # ΡƒΠ±ΠΈΡ€Π°Π΅ΠΌ ΠΏΡ€Π΅Π΄Π΅Π΄ΡƒΡ‰Π΅Π΅ сообщСниС
            self.state_info2 = OnscreenText(text='ΠΏΠ°Π΄Π°Π΅ΠΌ!', pos=(-0.8, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля


    def fountain(self):
        self.state_info2.hide() # ΡƒΠ±ΠΈΡ€Π°Π΅ΠΌ тСкст опасности
        if self.force:
            if self.state != 100:
                self.state += 1
                self.state_info.hide()
                self.state_info = OnscreenText(text='ΠΊΠΎΡ€Π°Π±Π»ΡŒ :' + str(self.state), pos=(0.5, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля

            self.fountain_pos = random.randrange(0, 5), random.randrange(0, 5) + 500, random.randrange(0, 1)    
            self.loadParticleConfig('special_effects/fountain/fountain.ptf', self.fountain_pos)

        else :
            if self.state != 100:
                self.state += 1
                self.state_info.hide()
                self.state_info = OnscreenText(text='ΠΊΠΎΡ€Π°Π±Π»ΡŒ :' + str(self.state), pos=(0.5, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля

            self.fountain_pos = random.randrange(0, 5), random.randrange(0, 5), random.randrange(0, 1)    
            self.loadParticleConfig('special_effects/fountain/fountain.ptf', self.fountain_pos)
        
        
    def black_light(self):
        # Π’Ρ‹ΠΊΠ»ΡŽΡ‡Π΅Π½Ρ‹ΠΉ свСт
        ambientLight = AmbientLight("ambientLight")
        ambientLight.setColor((0, 0, 0, 1))
        directionalLight = DirectionalLight("directionalLight")
        directionalLight.setDirection((-5, -5, -5))
        directionalLight.setColor((1, 1, 1, 1))
        directionalLight.setSpecularColor((1, 1, 1, 1))
        render.setLight(render.attachNewNode(ambientLight))
        render.setLight(render.attachNewNode(directionalLight))

    def weapon_hide(self):
        # Π£Π±Ρ€Π°Ρ‚ΡŒ ΠΎΡ€ΡƒΠΆΠΈΠ΅
        self.hide_weapon = True
        self.weapon.hide()

    def toggleLights(self, lights):
        # Π‘ΠΏΠ΅Ρ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠ΅ освСщСниС
        if self.hide_weapon:
            for light in lights:
                if render.hasLight(light):
                    render.clearLight(light)
                else:
                    render.setLight(light)
            
            self.flash.setPos(self.weapon_pos)
        else:
            return


    def shot(self):
        dt = globalClock.getDt() + 0.5 # CΠΊΠΎΡ€ΠΎΡΡ‚ΡŒ двиТСния
        if not self.hide_weapon : # Ссли ΠΎΡ€ΡƒΠΆΠΈΠ΅ ΡƒΠ±Ρ€Π°Π½ΠΎ Ρ‚ΠΎ ΠΌΡ‹ Π½Π΅ ΠΌΠΎΠΆΠ΅ΠΌ ΡΡ‚Ρ€Π΅Π»ΡΡ‚ΡŒ
            self.shotSound.play() # ΠΈΠ³Ρ€Π°Π΅ΠΌ Π·Π²ΡƒΠΊ выстрСла
            self.bullet.setPos(self.weapon_pos) # ΠŸΡƒΠ»Ρ Π±ΡƒΠ΄Π΅Ρ‚ спавнится Π²Π½ΡƒΡ‚Ρ€ΠΈ ΠΏΡƒΡˆΠΊΠΈ
            self.bullet.setY(self.bullet, -11 * dt) # Π‘Π΄Π²ΠΈΠ³Π°Π΅ΠΌ ΠΏΡƒΠ»ΡŽ Π½Π° ΠΎΠ³Ρ€ΠΎΠΌΠ½ΠΎΠΉ скорости Π²ΠΏΠ΅Ρ€Ρ‘Π΄

    def check_loss(self):
        if self.state == 0: # Ссли ΠΆΠΈΠ·Π½Π΅ΠΉ Ρƒ корабля Π½Π΅ ΠΎΡΡ‚Π°Π»ΠΎΡΡŒ
            self.black_light() # Π²ΠΊΠ»ΡŽΡ‡ΠΈΠΌ Ρ‡Ρ‘Ρ€Π½Ρ‹ΠΉ свСт
            self.weapon_hide() # ΡƒΠ±Π΅Ρ€Ρ‘ΠΌ ΠΎΡ€ΡƒΠΆΠΈΠ΅
            self.info = OnscreenText(text='ΠΏΠΎΡ€Π°ΠΆΠ΅Π½ΠΈΠ΅', style=1, font=self.font,
                                     fg=(1,1,1,1),
                            pos=(-1.3, -0.5), align=TextNode.ALeft, scale=0.3) # напишСм ΠΎ ΠΏΠΎΡ€Π°ΠΆΠ΅Π½ΠΈΠΈ
            self.crackSound.play() # ΠΈΠ³Ρ€Π°Π΅ΠΌ Π·Π²ΡƒΠΊ Π²Π·Ρ€Ρ‹Π²Π°


    def setKey(self, key, value):
        self.keyMap[key] = value # Π”Π΅Π»Π°Π΅ΠΌ ΠΌΠ΅Ρ…aΠ½uΠ·ΠΌ наТатия клавиш.

    def move(self, task):

        ''' Π”Π΅Π»Π°Π΅ΠΌ Ρ„ΡƒΡ†Π½ΠΊΡ†ΠΈΡŽ двиТСния ΠΈΠ³Ρ€ΠΎΠΊΠ° '''

        dt = globalClock.getDt() - .005 # CΠΊΠΎΡ€ΠΎΡΡ‚ΡŒ двиТСния

        # ΠŸΠΎΠ²ΠΎΡ€ΠΎΡ‚ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ Π²Π»Π΅Π²ΠΎ ΠΈ Π²ΠΏΡ€Π°Π²ΠΎ

        if self.keyMap["cam-left"]:
            self.camera.setX(self.camera, -20 * dt) # МСняСм ΠΏΠΎΠ»ΠΎΠΆΠ΅Π½ΠΈΠΊΠ° ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ ΠΏΠΎ икс. Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ получаСтся илюзия ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚Π° ΡƒΠ³Π»Π° Π»ΡƒΡ‡Π°. Но Π½Π° самом Π΄Π΅Π»Π΅ ΠΊΠ°ΠΌΠ΅Ρ€Π° просто пСрСмСщаСтся.
        if self.keyMap["cam-right"]:
            self.camera.setX(self.camera, +20 * dt) # Π’ΠΎΠΆΠ΅ самоС, Ρ‡Ρ‚ΠΎ ΠΈ Π½Π°Π²Π΅Ρ€Ρ…Ρƒ.

        startpos = self.droid.getPos() # Π‘Π΄Π΅Π»Π°Π΅ΠΌ ΡƒΠ΄ΠΎΠ±Π½ΡƒΡŽ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ ΠΈΠ³Ρ€ΠΎΠΊΠ°

        if self.keyMap["left"]:
            self.droid.setH(self.droid.getH() + 300 * dt)
            self.enemy.setY(self.enemy, 1 * dt)
        if self.keyMap["right"]:
            self.droid.setH(self.droid.getH() - 300 * dt)
            self.enemy.setY(self.enemy, -1 * dt)
        if self.keyMap["forward"]:
            self.droid.setY(self.droid, -25 * dt)
            self.enemy.setX(self.enemy, 1 * dt)
            # Π‘Π΄Π΅Π»Π°Π΅ΠΌ ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½ΠΎΠ΅ условиС ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ ΡƒΠ±Ρ€Π°Π½ΠΎ ΠΎΡ€ΡƒΠΆΠΈΠ΅ ΠΈΠ»ΠΈ Π½Π΅Ρ‚
            if not self.hide_weapon:
                self.weapon_pos = self.droid.getX(), self.droid.getY() + 0.7, 3
                self.weapon.setPos(self.weapon_pos) # ОбновляСм ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΏΡƒΡˆΠΊΠΈ
            else:
                self.weapon_pos = self.droid.getX(), self.droid.getY() + 0.7, 3
                self.flash.setPos(self.weapon_pos)


        camvec = self.droid.getPos() - self.camera.getPos() # Π²Π΅ΠΊΡ‚ΠΎΡ€ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹
        camvec.setZ(0) # 0 высота Π²Π΅ΠΊΡ‚ΠΎΡ€Π°
        camdist = camvec.length() # дистанция ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ ΠΎΡ‚ Π΄Ρ€ΠΎΠΈΠ΄Π°
        camvec.normalize() # Π½ΠΎΡ€ΠΌΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ Π²Π΅ΠΊΡ‚ΠΎΡ€ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹
        if camdist > 10.0: # Ссли дистанция ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ большС 10, Ρ‚ΠΎ смСщаСм ΠΊΠ°ΠΌΠ΅Ρ€Ρƒ Π·Π° Π΄Ρ€ΠΎΠΎΠΈΠ΄ΠΎΠΌ
            self.camera.setPos(self.camera.getPos() + camvec * (camdist - 10))
            camdist = 10.0 # Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ дистанция Π±ΡƒΠ΄Π΅Ρ‚ снова 10
        if camdist < 5.0: # Ссли дистагцтя ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ мСньшС 5, Ρ‚ΠΎ...
            self.camera.setPos(self.camera.getPos() - camvec * (5 - camdist)) # сдвигаСм ΠΊΠ°ΠΌΠ΅Ρ€Ρƒ
            camdist = 5.0 # всё обновляСм
            
        self.camera.lookAt(self.floater) # Π²ΠΎΡ‚ ΠΈ пригодился наш floater


        return task.cont # Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌ Π·Π°Π΄Π°Ρ‡Ρƒ

    def addInstructions(self, pos, msg):
        return OnscreenText(text=msg, style=1, fg=(1,1,1,1), font=self.inst_font, pos=(-1.3, pos), align=TextNode.ALeft, scale = .04, shadow=(0,0,0,1)) # Ѐункция ΠΎ Ρ‚ΠΎΠΌ, ΠΊΠ°ΠΊ ΡƒΠΏΡ€Π°Π²Π»ΡΡ‚ΡŒ

    def addTitle(self, text):
        return OnscreenText(text=text, style=1, fg=(1, 1, 1, 1), scale=0.2,
                            parent=base.a2dBottomRight, align=TextNode.ARight,
                            pos=(-0.1, 0.09), shadow=(0, 0, 0, 1), font=self.font) # Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ тСкстового Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ° с ΡˆΡ€ΠΈΡ„Ρ‚ΠΎΠΌ ΠΈ ΠΏΠΎΠ·ΠΈΡ†ΠΈΠ΅ΠΉ
    

droid = DroidShooter() # Π‘ΠΎΠ·Π΄Π°Π΄ΠΈΠΌ экзСмпляр класса нашСй ΠΈΠ³Ρ€Ρ‹
droid.run() # 3апустим ΠΈΠ³Ρ€Ρƒ


# Ρ€Π°Π·Ρ€ΠΎΠ±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ :
# Π“Π»Π°Π²Π½Ρ‹ΠΉ Π°Π²Ρ‚ΠΎΡ€ : ma3rx
# ΠŸΠΎΠΌΠΎΡ‰Π½ΠΈΠΊ : panda3dmastercoder( присоСдСнился ΠΊ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Ρƒ 31 января, 2021 Π³ΠΎΠ΄Π°, 12:??)
# Π Π΅ΠΊΠ»Π°ΠΌΡ‰ΠΈΠΊ : rdb (написал ΠΏΠ΅Ρ€Π²ΠΎΠ΅ сообщСниС Π½Π° Ρ„ΠΎΡ€ΡƒΠΌΠ΅ 6 фСвраля 2021 Π³ΠΎΠ΄Π°, 20:11)

Hi! I create 3.0.6.1 update - horizontal effect for droid.
New source code droid.py :

#!/usr/bin/env python
# -*- coding: utf_8 -*-

# Π‘ΠΎΠ·Π΄Π°Π½ΠΎ : 22 число, ΡΠ½Π²Π°Ρ€ΡŒ, 2021 Π³ΠΎΠ΄

# Π˜ΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΡƒΠ΅ΠΌ всС Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹Π΅ инструмСнты
from direct.showbase.ShowBase import ShowBase
from panda3d.core import CollisionTraverser, CollisionNode
from panda3d.core import CollisionHandlerPusher, CollisionSphere, CollisionInvSphere
from panda3d.core import Filename, AmbientLight, DirectionalLight
from panda3d.core import PandaNode, NodePath, Camera, TextNode
from direct.particles.Particles import Particles
from direct.particles.ParticleEffect import ParticleEffect
from panda3d.core import PointLight, Spotlight
from panda3d.core import CollideMask
from panda3d.core import loadPrcFileData
from panda3d.core import *
from direct.gui.OnscreenText import OnscreenText
from direct.gui.OnscreenImage import OnscreenImage
from direct.gui.DirectButton import DirectButton
from direct.gui.DirectSlider import DirectSlider
from direct.actor.Actor import Actor
from direct.interval.IntervalGlobal import Sequence
from direct.interval.IntervalGlobal import Wait
import random
import sys
import time
import os
import math


VERSION = '3.0.6.1'

settings = ['window-title Droid Game ' +  VERSION,
            'fullscreen 0']
            

loadPrcFileData('', settings[0]) # Π‘Π΄Π΅Π»Π°Π΅ΠΌ Π½Π΅ стандартный Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ (Π²ΠΎΠ·ΠΌΡ‘ΠΌ Π΅Π³ΠΎ ΠΈΠ· ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ settings)
loadPrcFileData('', settings[1]) # Π½Π΅ Π±ΡƒΠ΄Π΅ΠΌ Π΄Π΅Π»Π°Ρ‚ΡŒ полноэкранный Ρ€Π΅ΠΆΠΈΠΌ

# Π‘ΠΎΠ·Π΄Π°Π΄ΠΈΠΌ Π³Π»Π°Π²Π½Ρ‹ΠΉ класс нашСй ΠΈΠ³Ρ€Ρ‹
class DroidShooter(ShowBase):
    def __init__(self):
        ShowBase.__init__(self) # Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ всС сСлфы ΠΈΠ· direct
        self.speed = 1800 # ΡΠΊΠΎΡ€ΠΎΡΡ‚ΡŒ двигатСля
        self.GB = False # НЕ Ρ‡Ρ‘Ρ€Π½ΠΎ-Π±Π΅Π»Ρ‹ΠΉ Ρ€Π΅ΠΆΠΈΠΌ
        self.menu() # звпуск мСню
        
    def menu(self):
        
        base.enableParticles() # ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ эффСкт Π΄Ρ‹ΠΌΠ°

        self.win.setClearColor((0, 0, 0, 1)) # Π—Π°ΠΊΡ€Π°ΡˆΠΈΠ²Π°Π΅ΠΌ ΠΏΠΎΠ²Π΅Ρ€Ρ…Π½ΠΎΡΡ‚ΡŒ Ρ‡Ρ‘Ρ€Π½Ρ‹ΠΌ. Π”Π΅Π»ΠΎ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ Π² этом ΠΈΠ³Ρ€ΠΎΠ²ΠΎΠΌ Π΄Π²ΠΈΠΆΠΊΠ΅ ΠΏΠΎΠ²Π΅Ρ€Ρ…Π½ΠΎΡΡ‚ΡŒ Π·Π°ΠΊΡ€Π°ΡˆΠΈΠ²Π°Π΅Ρ‚ΡΡ сСрым.
        self.font = loader.loadFont('./fonts/doom_font.ttf') # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ ΡˆΡ€ΠΈΡ„Ρ‚ ΠΈΠ· ΠΈΠ³Ρ€Ρ‹ doom
        self.inst_font = loader.loadFont('./fonts/arial.ttf') # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ ΡˆΡ€ΠΈΡ„Ρ‚ arial

        self.crackSound = loader.loadMusic('./sounds/crack.wav') # Π·Π²ΡƒΠΊ Π²Π·Ρ€Ρ‹Π²Π° корабля
        self.shotSound = loader.loadMusic('./sounds/shot.wav') # Π·Π²ΡƒΠΊ выстрСла
        self.startSound = loader.loadMusic('./sounds/started.wav') # Π·Π²ΡƒΠΊ запуска
        self.errorSound = loader.loadMusic('./sounds/error.wav') # Π·Π²ΡƒΠΊ запуска
        self.errorSound.setVolume(1) # полная Π³Ρ€ΠΎΠΌΠΊΠΎΡΡ‚ΡŒ Π·Π²ΡƒΠΊΠ°
        self.startSound.setVolume(1) # полная Π³Ρ€ΠΎΠΌΠΊΠΎΡΡ‚ΡŒ Π·Π²ΡƒΠΊΠ°
        self.crackSound.setVolume(1) # полная Π³Ρ€ΠΎΠΌΠΊΠΎΡΡ‚ΡŒ Π·Π²ΡƒΠΊΠ°
        self.shotSound.setVolume(1) # полная Π³Ρ€ΠΎΠΌΠΊΠΎΡΡ‚ΡŒ Π·Π²ΡƒΠΊΠ°
        self.startSound.play() # ΠΈΠ³Ρ€Π°Π΅ΠΌ Π·Π²ΡƒΠΊ запуска ΠΈΠ³Ρ€Ρ‹

        self.button_start = DirectButton(pos=(0.7, 0, 0.4), text="CTAPT",
                                   scale=.2, pad=(.2, .2),
                                   command=self.load_game) # ΠΊΠ½ΠΎΠΏΠΊΠ° запуска ΠΈΠ³Ρ€Ρ‹

        self.gb_start = DirectButton(pos=(0.7, 0, 0.1), text="GB",
                                   scale=.2, pad=(.2, .2),
                                   command=self.gb_mode) # ΠΊΠ½ΠΎΠΏΠΊΠ° запуска ΠΈΠ³Ρ€Ρ‹  Π² Ρ‡Ρ‘Ρ€Π½ΠΎ-Π±Π΅Π»ΠΎΠΌ Ρ€Π΅ΠΆΠΈΠΌΠ΅      

        self.slider_sun = DirectSlider(pos=(0.1, 0, .75), scale=0.8, value=0.5,
                                    command=self.set_sun_interval)


        self.title = self.addTitle("Droid game " + VERSION)
        
        # НапСчатаСм ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅
        self.inst1 = self.addInstructions(0.95, u"[ESC]: Π’Ρ‹Ρ…ΠΎΠ΄")
        self.inst2 = self.addInstructions(0.90, u"[Left Arrow]: ΠŸΠΎΠ²ΠΎΡ€ΠΎΡ‚ Π΄Ρ€ΠΎΠΈΠ΄Π° Π² Π»Π΅Π²ΠΎ")
        self.inst3 = self.addInstructions(0.85, u"[Right Arrow]: ΠŸΠΎΠ²ΠΎΡ€ΠΎΡ‚ Π΄Ρ€ΠΎΠΈΠ΄Π° Π² ΠΏΡ€Π°Π²ΠΎ")
        self.inst4 = self.addInstructions(0.80, u"[Up Arrow]: Π’ΠΏΠ΅Ρ€Π΅Π΄")
        self.inst5 = self.addInstructions(0.75, u"[a]: ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ Π² ΠΏΡ€Π°Π²ΠΎ")
        self.inst6 = self.addInstructions(0.70, u"[d]: ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ Π² Π»Π΅Π²ΠΎ")
        self.inst7 = self.addInstructions(0.65, u"[Left Arrow + Up arrow]: ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚ Π΄Ρ€ΠΎΠΈΠ΄Π° Π² Π»Π΅Π²ΠΎ ΠΈ Π²ΠΏΠ΅Ρ€Ρ‘Π΄")
        self.inst8 = self.addInstructions(0.60, u"[Right Arrow + Up arrow]: ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚ Π΄Ρ€ΠΎΠΈΠ΄Π° Π² ΠΏΡ€Π°Π²ΠΎ ΠΈ Π²ΠΏΠ΅Ρ€Ρ‘Π΄")
        self.inst9 = self.addInstructions(0.55, u"[a + Up arrow]: ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ Π² ΠΏΡ€Π°Π²ΠΎ ΠΈ Π²ΠΏΠ΅Ρ€Ρ‘Π΄")
        self.inst10 = self.addInstructions(0.50, u"[d + Up arrow]: ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ Π² Π»Π΅Π²ΠΎ ΠΈ Π²ΠΏΠ΅Ρ€Ρ‘Π΄")
        self.inst11 = self.addInstructions(0.45, u"[space]: ΡΡ‚Ρ€Π΅Π»ΡŒΠ±Π°")
        self.inst12 = self.addInstructions(0.40, u"[s]: Π΄ΠΎΡΡ‚Π°Ρ‚ΡŒ Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊ")
        self.inst13 = self.addInstructions(0.35, u"[w]: ΡƒΠ±Ρ€Π°Ρ‚ΡŒ ΠΎΡ€ΡƒΠΆΠΈΠ΅")
        self.inst14 = self.addInstructions(0.30, u"[f]: ΠΏΠΎΠ»Π½Ρ‹ΠΉ Ρ€Π°Π·Π³ΠΎΠ½(ОПАБНО!)")
        self.inst15 = self.addInstructions(0.25, u"[0]: ΠΏΠΎΠΆΠ°Ρ€ΠΎΡ‚ΡƒΡˆΠΈΡ‚Π΅Π»ΡŒΠ½Π°Ρ систСма")

        self.accept("escape", sys.exit) # ΠŸΡ€ΠΈ Π½Π°ΠΆΠ°Ρ‚ΠΈΠΈ клавиши Esc Π²Ρ‹Ρ…ΠΎΠ΄ΠΈΠΌ.

    def set_sun_interval(self):
        self.sun_interval = self.slider_sun.guiItem.getValue() * 100 # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ слайдСрноС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΡƒΠΌΠ½ΠΎΠΆΠ΅Π½ΠΎΠ΅ Π½Π° 500, Π΄Π° Ρ‚Ρ€Π°Ρ‡Ρƒ ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΡŽ Π½ΠΎ ΠΌΠ½Π΅ каТСтся ΠΌΠ½ΠΎΠ³ΠΈΠΌ ΠΏΠ»Π΅Π²Π°Ρ‚ΡŒ Π½Π° ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΡŽ мСню, ΠΈΠ±ΠΎ Ρ‚Π°ΠΊΠΎΠ³ΠΎ понятия просто Π½Π΅Ρ‚Ρƒ :)

    def gb_mode(self):
        '''Π²ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ Ρ‡Ρ‘Ρ€Π½ΠΎΠ±Π΅Π»ΠΎΠ³ΠΎ Ρ€Π΅ΠΆΠΈΠΌΠ°'''
        self.GB = True

    def load_game(self):
        self.button_start.hide() # ΡƒΠ΄Π°Π»ΠΈΠΌ ΠΊΠ½ΠΎΠΏΠΊΡƒ старта
        self.gb_start.hide() # ΡƒΠ΄Π°Π»ΠΈΠΌ ΠΊΠ½ΠΎΠΏΠΊΡƒ Ρ‡Ρ‘Ρ€Π½ΠΎ Π±Π΅Π»ΠΎΠ³ΠΎ Ρ€Π΅ΠΆΠΈΠΌΠ°.
        self.title.hide() # ΡƒΠ΄Π°Π»ΠΈΠΌ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ ΠΈΠ³Ρ€Ρ‹
        # ΡƒΠ΄Π°Π»ΠΈΠΌ ΠΊΠ½ΠΎΠΏΠΊΠΈ управлСния
        self.inst1.hide()
        self.inst2.hide()
        self.inst3.hide()
        self.inst4.hide()
        self.inst5.hide()
        self.inst6.hide()
        self.inst7.hide()
        self.inst8.hide()
        self.inst9.hide()
        self.inst10.hide()
        self.inst11.hide()
        self.inst12.hide()
        self.inst13.hide()
        self.inst14.hide()
        self.inst15.hide()
        self.slider_sun.hide() # удаляСм слайдСр солнца
        
        self.keyMap = {
            "left": 0, "right": 0, "forward": 0, "cam-left": 0, "cam-right": 0} # Π‘ΠΎΠ·Π΄Π°Π΄ΠΈΠΌ ΡΠ»ΠΎΠ²Π°Ρ€ΡŒ ΠΊΠ½ΠΎΠΏΠΎΠΊ, ΠΏΠΎ ΠΈΡ… Π½Π°ΠΆΠ°Ρ‚ΠΈΡŽ        

        # РисуСм Π·Π²Ρ‘Π·Π΄Ρ‹

        self.sky = loader.loadModel("./models/sky/solar_sky_sphere") # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ модСль космоса(это сфСра)

        self.sky_tex = loader.loadTexture("./tex/stars_1k_tex.jpg") # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ тСкстуру
        self.sky.setTexture(self.sky_tex, 1) # Π·Π°Ρ€Π΅Π½Π΄Π΅Ρ€ΠΈΠΌ тСкстуру Π½Π° Π½Π΅Π±ΠΎ
        self.sky.reparentTo(render) # ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ Π½Π΅Π±ΠΎ
        self.sky.setScale(40000) # Ρ€Π°ΡΡˆΠΈΡ€ΠΈΠΌ Π½Π΅Π±ΠΎ Π΄ΠΎ максимальной Π²Π΅Π»ΠΈΡ‡ΠΈΠ½Ρ‹ panda3d

        self.environ = loader.loadModel("models/world/falcon.egg") # Π—Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ ΡƒΠΆΠ΅ созданный Π² blender ΠΌΠΈΡ€.
        self.environ.reparentTo(render) # Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ модСль ΠΌΠΈΡ€Π° Π² ΠΎΠΊΠ½ΠΎ

        droidStartPos = (-1, 0, 1.5 ) # Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ ΡΡ‚Π°Ρ€Ρ‚ΠΎΠ²ΡƒΡŽ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π² ΠΌΠΈΡ€Π΅.
        enemyStartPos = (-6, 1, 0.5) # Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ°-Π΄Ρ€ΠΎΠΈΠ΄Π°.
        self.droid = Actor("models/player/seeker.egg") # Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ модСль ΠΈΠ³Ρ€ΠΎΠΊΠ° (созданная Π² blender)
        self.enemy = Actor("models/enemies/r2d2/r2d2.egg") # Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ модСль ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ° (созданная Π² blender)
        self.droid.reparentTo(render) # ΠŸΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Π΅ΠΌ модСль ΠΈΠ³Ρ€ΠΎΠΊΠ° Π² наш ΠΌΠΈΡ€.
        self.enemy.reparentTo(render) # ΠŸΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Π΅ΠΌ модСль ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ° Π² наш ΠΌΠΈΡ€.
        self.droid.setScale(1) # Π”Π΅Π»Π°Π΅ΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ€ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π½Π° 1
        self.enemy.setScale(1) # Π”Π΅Π»Π°Π΅ΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ€ ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ° Π½Π° 1
        self.droid.setPos(droidStartPos) # Π‘Ρ‚Π°Π²ΠΈΠΌ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π½Π° Ρ€Π°Π½Π΅Π΅ ΡΠΎΠ·Π΄Π°Π½ΡƒΡŽ Π½Π°ΠΌΠΈ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ
        self.enemy.setPos(enemyStartPos) # Π‘Ρ‚Π°Π²ΠΈΠΌ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ° Π½Π° Ρ€Π°Π½Π΅Π΅ ΡΠΎΠ·Π΄Π°Π½ΡƒΡŽ Π½Π°ΠΌΠΈ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ

        self.weapon = Actor('models/weapon/lightsaber.egg') # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ ΠΎΡ€ΡƒΠΆΠΈΠ΅
        self.bullet = Actor('models/weapon/bullet/bullet.egg.pz') # Π—Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ ΠΏΡƒΠ»ΡŽ
        self.flash = Actor('models/whishlyflash/handlamp.egg') # Π—Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊ
               
        self.weapon.reparentTo(render) # пСрСмСстим ΠΎΡ€ΡƒΠΆΠΈΠ΅ Π² наш ΠΌΠΈΡ€
        self.bullet.reparentTo(render) # пСрСмСстим ΠΏΡƒΠ»ΡŽ Π² ΠΌΠΈΡ€ Π½ΠΎ появится ΠΎΠ½Π° сама Π½Π΅ скоро
        self.flash.reparentTo(render) # пСрСмСстим Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊ Π² наш ΠΌΠΈΡ€
        self.weapon.setScale(.5) # Π·Π°Π΄Π°Π΄ΠΈΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ€ ΠΏΡƒΡˆΠΊΠΈ
        self.bullet.setScale(.5) # Π·Π°Π΄Π°Π΄ΠΈΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ€ ΠΏΡƒΠ»ΠΈ
        self.flash.setScale(.5) # Π·Π°Π΄Π°Π΄ΠΈΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ€ Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊΠ°

        # враТСский ΠΈΡΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»ΡŒ
        self.fighter = Actor('models/fighter/fighter.egg') # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ ΠΌΠΎΠ΄Π΅Π»ΡŒΠΊΡƒ истрСбитСля
        self.fighter.reparentTo(render) # ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ ΠΈΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»ΡŒ
        self.fighter.setPos(0, 90, 0) # позиция истрСбитСля
                

        self.weapon_pos = self.droid.getX(), self.droid.getY() + 0.7, 1 # ΠŸΠΎΠ·ΠΈΡ†ΠΈΡ ΠΏΡƒΡˆΠΊΠΈ
        
        self.weapon.setPos(self.weapon_pos) # ΠŸΠΎΠΌΠ΅ΡΡ‚ΠΈΠΌ ΠΎΡ€ΡƒΠΆΠΈΠ΅ Ρ‡ΡƒΡ‚ΡŒ Π²Ρ‹ΡˆΠ΅ ΠΈΠ³Ρ€ΠΎΠΊΠ°

        self.cube = Actor('models/block/crate.egg') # Π·Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ Π±Π»ΠΎΠΊ
        self.cube.reparentTo(render)
        self.cube.setPos(0, -0, 0) # позиция ящика
        self.cube.setScale(0.7)
        self.cube.hprInterval(1.5, (0, 360, 360)).loop()

        self.Intervalcube = self.cube.posInterval(13,
                                                   Point3(0, -500, 0),
                                                   startPos=Point3(0, 10, 0))

        self.Intervalcube.loop()
        
        self.spotlight = camera.attachNewNode(Spotlight("spotlight")) # ΠšΠΎΠ½Ρ„ΠΈΠ³ΠΈ Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊΠ°
        self.spotlight.node().setColor((.3, .3, .3, 1))
        self.spotlight.node().setSpecularColor((0, 0, 0, 1))

        self.floater = NodePath(PandaNode("floater")) 
        self.floater.reparentTo(self.droid)
        self.floater.setZ(2.0)

        self.accept("escape", sys.exit) # ΠŸΡ€ΠΈ Π½Π°ΠΆΠ°Ρ‚ΠΈΠΈ клавиши Esc Π²Ρ‹Ρ…ΠΎΠ΄ΠΈΠΌ.
        
        self.accept("arrow_left", self.setKey, ["left", True]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ Π²Π»Π΅Π²ΠΎ - ΠΏΠΎΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π²Π»Π΅Π²ΠΎ
        self.accept("arrow_right", self.setKey, ["right", True]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ Π²ΠΏΡ€Π°Π²ΠΎ - ΠΏΠΎΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π²ΠΏΡ€Π°Π²ΠΎ
        self.accept("arrow_up", self.setKey, ["forward", True]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ Π²ΠΏΠ΅Ρ€Ρ‘Π΄ - ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄
        self.accept("a", self.setKey, ["cam-left", True]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ a - Ρ€Π°Π·Π²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΊΠ°ΠΌΠ΅Ρ€Ρƒ Π²ΠΎΠΊΡ€ΡƒΠ³ нашСй модСльки
        self.accept("d", self.setKey, ["cam-right", True]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ s - Ρ€Π°Π·Π²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΊΠ°ΠΌΠ΅Ρ€Ρƒ Π²ΠΎΠΊΡ€ΡƒΠ³ нашСй модСльки
        self.accept("arrow_left-up", self.setKey, ["left", False]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ Π²Π²Π΅Ρ€Ρ…+Π²Π»Π΅Π²ΠΎ - ΠΏΠΎΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π²Π»Π΅Π²ΠΎ ΠΈ ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄
        self.accept("arrow_right-up", self.setKey, ["right", False]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ Π²Π²Π΅Ρ€Ρ…+ΠΏΡ€Π°Π²ΠΎ - ΠΏΠΎΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π²ΠΏΡ€Π°Π²ΠΎ ΠΈ ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄
        self.accept("arrow_up-up", self.setKey, ["forward", False]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ Π²Π²Π΅Ρ€Ρ…+Π²Π²Π΅Ρ€ΡŠ - ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄ ΠΈ ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄
        self.accept("a-up", self.setKey, ["cam-left", False]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ a+Π²ΠΏΠ΅Ρ€Ρ‘Π΄ - ΠΏΠΎΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΊΠ°ΠΌΠ΅Ρ€Ρƒ Π²Π»Π΅Π²ΠΎ ΠΈ ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄
        self.accept("d-up", self.setKey, ["cam-right", False]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ s+Π²ΠΏΠ΅Ρ€Ρ‘Π΄ - ΠΏΠΎΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΊΠ°ΠΌΠ΅Ρ€Ρƒ Π²ΠΏΡ€Π°Π²ΠΎ ΠΈ ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄

        self.accept("space", self.shot) # ΠΏΡ€ΠΈ ΠΏΡ€ΠΎΠ±Π΅Π»Π΅ стрСляСм
        self.accept("s", self.toggleLights, [[self.spotlight]]) # Π’ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊ
        self.accept("w", self.weapon_hide) # ΠΏΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ w - ΡƒΠ±Π΅Ρ€Ρ‘ΠΌ ΠΎΡ€ΡƒΠΆΠΈΠ΅.

        base.enableParticles() # Π’ΠΊΠ»ΡŽΡ‡Π°Π΅ΠΌ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ Π΄Ρ‹ΠΌΠ°
        self.t = loader.loadModel("models/weapon/lightsaber.egg") # Π—Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ Π΅Ρ‰Ρ‘ ΠΎΡ€ΡƒΠΆΠΈΠ΅
        self.t.reparentTo(render) # ΠŸΠ΅Ρ€Π΅ΠΌΠ΅ΡΡ‚ΠΈΠΌ ΠΎΡ€ΡƒΠΆΠΈΠ΅ Π² наш ΠΌΠΈΡ€
        self.p = ParticleEffect() # Π’ΠΊΠ»ΡŽΡ‡ΠΈΠΌ эффСкт Π΄Ρ‹ΠΌΠ°
        self.accept('f', self.particle_start) # ΠΏΡ€ΠΈ Π½Π°ΠΆΠ°Ρ‚ΠΈΠΈ f(ΠΎΡ‚ force) -  Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ Ρ„Π°ΠΉΠ» Π΄Ρ‹ΠΌΠ° ΠΈ пСрСмСстим Π² ΠΊΠΎΠ½Ρ„ΠΈΠ³ Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΈΠΌΠ΅Π½Π½ΠΎ эта анимация стала ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ΠΌ Π΄Ρ‹ΠΌΠ°
        self.accept('0', self.fountain) # ΠΏΡ€ΠΈ  Π½Π°ΠΆΠ°Ρ‚ΠΈΠΈ ΠΊΠ½ΠΎΠΏΠΎΠΊ f+o(fountain) Π²ΠΊΠ»ΡŽΡ‡ΠΈΠΌ ΠΏΠΎΠΆΠ°Ρ€ΠΎΡ‚ΡƒΡˆΠΈΡ‚Π΅Π»ΡŒΠ½ΡƒΡŽ систСму

        taskMgr.add(self.move, "moveTask") # ДобавляСм Π·Π°Π΄Π°Ρ‡Ρƒ Π² наш Π΄Π²ΠΈΠΆΠΎΠΊ

        self.isMoving = False # Π‘Ρ‚Π°Π²ΠΈΠΌ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ isMoving Π½Π° False(Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΌΠ΅Π½ΡΡ‚ΡŒ это Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅) Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΈΠ³Ρ€ΠΎΠΊ ΠΈΠ·Π½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎ стоял.
        # Π”Π΅Π»Π°Π΅ΠΌ Ρ‚Π°ΠΊ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ свСт Π±Ρ‹Π» ΠΈΠ·Π½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎ Π²Ρ‹ΠΊΠ»ΡŽΡ‡Π΅Π½.
        self.disableMouse() # ΠžΡ‚ΠΊΠ»ΡŽΡ‡Π°Π΅ΠΌ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π΅Π½ΠΈΠ΅ Ρ‡Π΅Ρ€Π΅Π· ΠΌΡ‹ΡˆΠΊΡƒ
        self.camera.setPos(self.droid.getX(), self.droid.getY() + 1, 3) # Π‘Ρ‚Π°Π²ΠΈΠΌ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ Ρ‡ΡƒΡ‚ΡŒ большС ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ ΠΈΠ³Ρ€ΠΎΠΊΠ°

        self.black_light() # Π‘Π΄Π΅Π»Π°Π΅ΠΌ Π²Ρ‹ΠΊΠ»ΡŽΡ‡Π΅Π½Π½Ρ‹ΠΉ свСт

        self.state = 100 # БостояниС корабля
        self.state_info = OnscreenText(text='ΠΊΠΎΡ€Π°Π±Π»ΡŒ :' + str(self.state), pos=(0.5, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля
                
        self.check_loss() # ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ ΠΏΠΎΡ€Π°ΠΆΠ΅Π½ΠΈΠ΅
        self.hide_weapon = False # ΠŸΠΎΡΡ‚Π°Π²ΠΈΠΌ, Ρ‡Ρ‚ΠΎ ΠΎΡ€ΡƒΠΆΠΈΠ΅ Π½Π΅ ΡƒΠ±Ρ€Π°Π½ΠΎ
        self.steam_pos = random.randrange(0, 5), random.randrange(0, 5), random.randrange(0, 5)
        self.fountain_pos = random.randrange(0, 5), random.randrange(0, 5), random.randrange(0, 1)

        self.motor_pos1 = 25.238849639892578, 8.962211608886719, 1.5 # позиция ΠΏΠ΅Ρ€Π²ΠΎΠ³ΠΎ ΠΌΠΎΡ‚ΠΎΡ€Π°
        self.motor_pos2 = -20.676218032836914, 10.55816650390625, 1.5 # позиция Π²Ρ‚ΠΎΡ€ΠΎΠ³ΠΎ ΠΌΠΎΡ‚ΠΎΡ€Π°

        self.motor1 = self.loadParticleConfig('special_effects/steam_critic+/fireish.ptf', self.motor_pos1) # ΠΌΠΎΡ‚ΠΎΡ€ 1
        self.motor2 = self.loadParticleConfig('special_effects/steam_critic+/fireish.ptf', self.motor_pos2) # ΠΌΠΎΡ‚ΠΎΡ€ 2

        self.state_info2 = OnscreenText(text='', pos=(-0.8, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля

        self.force = False # ΠŸΠΎΡΡ‚Π°Π²ΠΈΠΌ, Ρ‡Ρ‚ΠΎ Π½Π΅ Ρ€Π°Π·Π³ΠΎΠ½ΡΠ»ΠΈΡΡŒ

        # ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ ΠΊΠΎΠ»Π»ΠΈΠ·ΠΈΠΈ

        # Коллизия корабля(ΠΎΠ½ Ρƒ нас ΠΊΠ°ΠΊ главная ΠΊΠ°Ρ€Ρ‚Π°).
        self.cTrav = CollisionTraverser()
        pusher = CollisionHandlerPusher()
        pusher.setHorizontal(True) 
        
        environCenter = self.environ.getBounds().getCenter()
        environRad = self.environ.getBounds().getRadius()
        cNode = CollisionNode("environment")
        cNode.addSolid(CollisionInvSphere(environCenter, environRad))
        environC = self.environ.attachNewNode(cNode)

        # Коллизия Π΄Ρ€ΠΎΠΈΠ΄Π°.
        droidCenter = self.droid.getBounds().getCenter()
        droidRad = self.droid.getBounds().getRadius()
        cNode = CollisionNode("droid")
        cNode.addSolid(CollisionSphere(droidCenter, droidRad))
        droidC = self.droid.attachNewNode(cNode)
        
        pusher.addCollider(droidC, self.droid)
        self.cTrav.addCollider(droidC, pusher)

        # Коллизия ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ°.
        enemyCenter = self.enemy.getBounds().getCenter()
        enemyRad = self.enemy.getBounds().getRadius()
        cNode = CollisionNode("enemy")
        cNode.addSolid(CollisionSphere(enemyCenter, enemyRad))
        enemyC = self.enemy.attachNewNode(cNode)

        pusher.addCollider(enemyC, self.enemy)
        self.cTrav.addCollider(enemyC, pusher)

        # Коллизия враТСского истрСбитСля.
        fighterCenter = self.fighter.getBounds().getCenter()
        fighterRad = self.fighter.getBounds().getRadius()
        cNode = CollisionNode("fighter")
        cNode.addSolid(CollisionSphere(fighterCenter, fighterRad))
        fighterC = self.fighter.attachNewNode(cNode)

        pusher.addCollider(fighterC, self.fighter)
        self.cTrav.addCollider(fighterC, pusher)

        # Коллизия ΠΏΡƒΠ»ΠΈ.
        bulletCenter = self.bullet.getBounds().getCenter()
        bulletRad = self.bullet.getBounds().getRadius()
        cNode = CollisionNode("bullet")
        cNode.addSolid(CollisionSphere(bulletCenter, bulletRad))
        bulletC = self.bullet.attachNewNode(cNode)

        bulletCenter = self.bullet.getBounds().getCenter()
        bulletRad = self.bullet.getBounds().getRadius()
        cNode = CollisionNode("bullet")
        cNode.addSolid(CollisionSphere(bulletCenter, bulletRad))
        bulletC = self.bullet.attachNewNode(cNode)
        
        pusher.addCollider(bulletC, self.bullet)
        self.cTrav.addCollider(bulletC, pusher)

        # Коллизия ΠΏΡƒΡˆΠΊΠΈ. Π― Π±Ρ‹ Π½Π΅ сказал, Ρ‡Ρ‚ΠΎ это ΠΈΠΌΠ΅Π½Π½ΠΎ коллизия, скорСС это для рСалистичности
        weaponCenter = self.weapon.getBounds().getCenter()
        weaponRad = self.weapon.getBounds().getRadius()
        cNode = CollisionNode("weapon")
        cNode.addSolid(CollisionSphere(weaponCenter, weaponRad))
        weaponC = self.weapon.attachNewNode(cNode)
        
        pusher.addCollider(weaponC, self.weapon)
        self.cTrav.addCollider(weaponC, pusher)

        # солнцС(новая ΠΌΠ΅Ρ…Π°Π½ΠΈΠΊΠ° освСщСния)
        sun = DirectionalLight("sun")
        sun.set_color_temperature(6000)
        sun.color = sun.color * 4
        sun_path = render.attach_new_node(sun)
        sun_path.set_pos(10, -10, -10)
        sun_path.look_at(0, 0, 0)
        sun_path.hprInterval(self.sun_interval, (sun_path.get_h(), sun_path.get_p() - 360, sun_path.get_r()), bakeInStart=True).loop()
        render.set_light(sun_path)

        # Если  ΠΈΠ³Ρ€ΠΎΠΊ Π·Π°Ρ…ΠΎΡ‚Π΅Π» ΠΏΠΎΠΈΠ³Ρ€Π°Ρ‚ΡŒ Π² Ρ‡Ρ‘Ρ€Π½ΠΎΠ±Π΅Π»ΡƒΡŽ ΠΈΠ³Ρ€Ρƒ, ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΠΌ это
        if self.GB :        
            render.set_shader(Shader.load(Shader.SL_GLSL, "lighting.vert", "lighting.frag")) # Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ ΡˆΠ΅ΠΉΠ΄Π΅Ρ€Ρ‹ Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‚!



    def fight_force(self):
        # сдвиТСниС истрСбитСля Π·Π° нашим ΠΊΠΎΡ€Π°Π±Π»Ρ‘ΠΌ(ΠΎΡ‡Π΅Π½ΡŒ простым способом я сдСлал Ρ‚Π°ΠΊ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΈΡΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»ΡŒ Π·Π°ΠΆΠΈΠΌΠ°Π» нас(Π»Π΅Ρ‚Π°Π» Π² нашСм ΠΊΠ²Π°Π΄Ρ€Π°Ρ‚Π΅)) ΠΈ Π·Π°ΠΆΠΈΠΌΠ°Π΅Ρ‚ ΠΎΠ½ Ρ€Π΅Π°Π»ΡŒΠ½ΠΎ, сблиТая ΠΊ Π½Π°ΠΌ свой ΠΊΠ²Π°Π΄Ρ€Π°Ρ‚
        self.fighter.setY(self.fighter.getY() - self.speed) 
        self.fighter.setX(self.fighter.getX() - 10)    

        print(self.fighter.getX())


    def loadParticleConfig(self, filename, pos):
        self.p.cleanup()
        self.p = ParticleEffect()
        self.p.loadConfig(Filename(filename))

        self.p.start(self.t)
        self.p.setPos(pos)

    def particle_start(self):
        self.force = True # ΠŸΠΎΡΡ‚Π°Π²ΠΈΠΌ, Ρ‡Ρ‚ΠΎ ΠΌΡ‹ ΡƒΠΆΠ΅ Ρ€Π°Π·Π³ΠΎΠ½ΡΠ»ΠΈΡΡŒ
        # ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Π΅ΠΌ всС ΠΎΠ±ΡŒΠ΅ΠΊΡ‚Ρ‹ Π·Π° ΠΊΠΎΡ€Π°Π±Π»Ρ‘ΠΌ
        self.environ.setY(self.environ.getY() - self.speed) # нСсёмся Π²ΠΏΡ€Π°Π²ΠΎ
        self.droid.setY(self.droid.getY() - self.speed) # сдвигаСм Π΄Ρ€ΠΎΠΈΠ΄Π° Π·Π° ΠΊΠΎΡ€Π°Π±Π»Ρ‘ΠΌ
        self.enemy.setY(self.enemy.getY() - self.speed) # сдфигаСм ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ° Π·Π° ΠΊΠΎΡ€Π°Π±Π»Ρ‘ΠΌ
        self.weapon.setY(self.weapon.getY() - self.speed) # ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Π΅ΠΌ ΠΎΡ€ΡƒΠΆΠΈΠ΅
        self.flash.setY(self.flash.getY() - self.speed) # ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Π΅ΠΌ Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊ
        self.cube.setY(self.cube.getY() - self.speed) # ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Π΅ΠΌ ящик
        self.fight_force()

        self.state -= 1 # сдСлаСм мСньшС ΠΎΡ‡ΠΊΠΎΠ²
        self.state_info.hide() # ΡƒΠ΄Π°Π»ΠΈΠΌ тСкстовыС ΠΎΡ‡ΠΊΠΈ
        
        if self.state != 10 and self.state > 10:
            self.state_info.hide() # ΡƒΠ±ΠΈΡ€Π°Π΅ΠΌ ΠΏΡ€Π΅Π΄Π΅Π΄ΡƒΡ‰Π΅Π΅ сообщСниС ΠΎ Тизнях корабля
            self.state_info = OnscreenText(text='ΠΊΠΎΡ€Π°Π±Π»ΡŒ :' + str(self.state), pos=(0.5, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля
            self.check_loss() # провСряСм ΠΏΠΎΡ€Π°ΠΆΠ΅Π½ΠΈΠ΅
            self.steam_pos = random.randrange(0, 5), random.randrange(0, 5) + 300, random.randrange(0, 5)
            self.loadParticleConfig('special_effects/steam/steam.ptf', self.steam_pos)
            self.errorSound.play() # ΠΈΠ³Ρ€Π°Π΅ΠΌ Π·Π²ΡƒΠΊ ошибки
            self.state_info2.hide() # ΡƒΠ±ΠΈΡ€Π°Π΅ΠΌ ΠΏΡ€Π΅Π΄Π΅Π΄ΡƒΡ‰Π΅Π΅ сообщСниС
            self.state_info2 = OnscreenText(text='Π΄Π²ΠΈΠ³Π°Ρ‚Π΅Π»ΡŒ нСисправСн', pos=(-0.8, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля
        else:
            self.state_info = OnscreenText(text='ΠΊΠΎΡ€Π°Π±Π»ΡŒ :' + str(self.state), pos=(0.5, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля
            self.check_loss() # провСряСм ΠΏΠΎΡ€Π°ΠΆΠ΅Π½ΠΈΠ΅
            self.steam_pos = random.randrange(0, 5), random.randrange(0, 5) + 300, random.randrange(0, 5)
            self.loadParticleConfig('special_effects/steam_critic/steam.ptf', self.steam_pos)
            self.errorSound.play() # ΠΈΠ³Ρ€Π°Π΅ΠΌ Π·Π²ΡƒΠΊ ошибки
            self.state_info2.hide()  # ΡƒΠ±ΠΈΡ€Π°Π΅ΠΌ ΠΏΡ€Π΅Π΄Π΅Π΄ΡƒΡ‰Π΅Π΅ сообщСниС
            self.state_info2 = OnscreenText(text='критичСскоС состояниС', pos=(-0.8, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля
    
        if self.state < 10:
            self.state_info.hide()
            self.state_info = OnscreenText(text='ΠΊΠΎΡ€Π°Π±Π»ΡŒ :' + str(self.state), pos=(0.5, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля
            self.check_loss() # провСряСм ΠΏΠΎΡ€Π°ΠΆΠ΅Π½ΠΈΠ΅
            self.steam_pos = random.randrange(0, 5), random.randrange(0, 5) + 300, random.randrange(0, 5)            
            self.loadParticleConfig('special_effects/steam_critic+/fireish.ptf', self.steam_pos)
            self.errorSound.play() # ΠΈΠ³Ρ€Π°Π΅ΠΌ Π·Π²ΡƒΠΊ ошибки
            self.state_info2.hide() # ΡƒΠ±ΠΈΡ€Π°Π΅ΠΌ ΠΏΡ€Π΅Π΄Π΅Π΄ΡƒΡ‰Π΅Π΅ сообщСниС
            self.state_info2 = OnscreenText(text='ΠΏΠ°Π΄Π°Π΅ΠΌ!', pos=(-0.8, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля


    def fountain(self):
        self.state_info2.hide() # ΡƒΠ±ΠΈΡ€Π°Π΅ΠΌ тСкст опасности
        if self.force:
            if self.state != 100:
                self.state += 1
                self.state_info.hide()
                self.state_info = OnscreenText(text='ΠΊΠΎΡ€Π°Π±Π»ΡŒ :' + str(self.state), pos=(0.5, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля

            self.fountain_pos = random.randrange(0, 5), random.randrange(0, 5) + 500, random.randrange(0, 1)    
            self.loadParticleConfig('special_effects/fountain/fountain.ptf', self.fountain_pos)

        else :
            if self.state != 100:
                self.state += 1
                self.state_info.hide()
                self.state_info = OnscreenText(text='ΠΊΠΎΡ€Π°Π±Π»ΡŒ :' + str(self.state), pos=(0.5, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля

            self.fountain_pos = random.randrange(0, 5), random.randrange(0, 5), random.randrange(0, 1)    
            self.loadParticleConfig('special_effects/fountain/fountain.ptf', self.fountain_pos)
        
        
    def black_light(self):
        # Π’Ρ‹ΠΊΠ»ΡŽΡ‡Π΅Π½Ρ‹ΠΉ свСт
        ambientLight = AmbientLight("ambientLight")
        ambientLight.setColor((0, 0, 0, 1))
        directionalLight = DirectionalLight("directionalLight")
        directionalLight.setDirection((-5, -5, -5))
        directionalLight.setColor((1, 1, 1, 1))
        directionalLight.setSpecularColor((1, 1, 1, 1))
        render.setLight(render.attachNewNode(ambientLight))
        render.setLight(render.attachNewNode(directionalLight))

    def weapon_hide(self):
        # Π£Π±Ρ€Π°Ρ‚ΡŒ ΠΎΡ€ΡƒΠΆΠΈΠ΅
        self.hide_weapon = True
        self.weapon.hide()

    def toggleLights(self, lights):
        # Π‘ΠΏΠ΅Ρ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠ΅ освСщСниС
        if self.hide_weapon:
            for light in lights:
                if render.hasLight(light):
                    render.clearLight(light)
                else:
                    render.setLight(light)
            
            self.flash.setPos(self.weapon_pos)
        else:
            return


    def shot(self):
        dt = globalClock.getDt() + 0.5 # CΠΊΠΎΡ€ΠΎΡΡ‚ΡŒ двиТСния
        if not self.hide_weapon : # Ссли ΠΎΡ€ΡƒΠΆΠΈΠ΅ ΡƒΠ±Ρ€Π°Π½ΠΎ Ρ‚ΠΎ ΠΌΡ‹ Π½Π΅ ΠΌΠΎΠΆΠ΅ΠΌ ΡΡ‚Ρ€Π΅Π»ΡΡ‚ΡŒ
            self.shotSound.play() # ΠΈΠ³Ρ€Π°Π΅ΠΌ Π·Π²ΡƒΠΊ выстрСла
            self.bullet.setPos(self.weapon_pos) # ΠŸΡƒΠ»Ρ Π±ΡƒΠ΄Π΅Ρ‚ спавнится Π²Π½ΡƒΡ‚Ρ€ΠΈ ΠΏΡƒΡˆΠΊΠΈ
            self.bullet.setY(self.bullet, -11 * dt) # Π‘Π΄Π²ΠΈΠ³Π°Π΅ΠΌ ΠΏΡƒΠ»ΡŽ Π½Π° ΠΎΠ³Ρ€ΠΎΠΌΠ½ΠΎΠΉ скорости Π²ΠΏΠ΅Ρ€Ρ‘Π΄

    def check_loss(self):
        if self.state == 0: # Ссли ΠΆΠΈΠ·Π½Π΅ΠΉ Ρƒ корабля Π½Π΅ ΠΎΡΡ‚Π°Π»ΠΎΡΡŒ
            self.black_light() # Π²ΠΊΠ»ΡŽΡ‡ΠΈΠΌ Ρ‡Ρ‘Ρ€Π½Ρ‹ΠΉ свСт
            self.weapon_hide() # ΡƒΠ±Π΅Ρ€Ρ‘ΠΌ ΠΎΡ€ΡƒΠΆΠΈΠ΅
            self.info = OnscreenText(text='ΠΏΠΎΡ€Π°ΠΆΠ΅Π½ΠΈΠ΅', style=1, font=self.font,
                                     fg=(1,1,1,1),
                            pos=(-1.3, -0.5), align=TextNode.ALeft, scale=0.3) # напишСм ΠΎ ΠΏΠΎΡ€Π°ΠΆΠ΅Π½ΠΈΠΈ
            self.crackSound.play() # ΠΈΠ³Ρ€Π°Π΅ΠΌ Π·Π²ΡƒΠΊ Π²Π·Ρ€Ρ‹Π²Π°


    def setKey(self, key, value):
        self.keyMap[key] = value # Π”Π΅Π»Π°Π΅ΠΌ ΠΌΠ΅Ρ…aΠ½uΠ·ΠΌ наТатия клавиш.



    def move(self, task):

        ''' Π”Π΅Π»Π°Π΅ΠΌ Ρ„ΡƒΡ†Π½ΠΊΡ†ΠΈΡŽ двиТСния ΠΈΠ³Ρ€ΠΎΠΊΠ° '''

        dt = globalClock.getDt() - .005 # CΠΊΠΎΡ€ΠΎΡΡ‚ΡŒ двиТСния

        # ΠŸΠΎΠ²ΠΎΡ€ΠΎΡ‚ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ Π²Π»Π΅Π²ΠΎ ΠΈ Π²ΠΏΡ€Π°Π²ΠΎ

        if self.keyMap["cam-left"]:
            self.camera.setX(self.camera, -20 * dt) # МСняСм ΠΏΠΎΠ»ΠΎΠΆΠ΅Π½ΠΈΠΊΠ° ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ ΠΏΠΎ икс. Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ получаСтся илюзия ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚Π° ΡƒΠ³Π»Π° Π»ΡƒΡ‡Π°. Но Π½Π° самом Π΄Π΅Π»Π΅ ΠΊΠ°ΠΌΠ΅Ρ€Π° просто пСрСмСщаСтся.
        if self.keyMap["cam-right"]:
            self.camera.setX(self.camera, +20 * dt) # Π’ΠΎΠΆΠ΅ самоС, Ρ‡Ρ‚ΠΎ ΠΈ Π½Π°Π²Π΅Ρ€Ρ…Ρƒ.

        startpos = self.droid.getPos() # Π‘Π΄Π΅Π»Π°Π΅ΠΌ ΡƒΠ΄ΠΎΠ±Π½ΡƒΡŽ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ ΠΈΠ³Ρ€ΠΎΠΊΠ°

        if self.keyMap["left"]:
            self.droid.setH(self.droid.getH() + 300 * dt)
            self.enemy.setY(self.enemy, 1 * dt)
        if self.keyMap["right"]:
            self.droid.setH(self.droid.getH() - 300 * dt)
            self.enemy.setY(self.enemy, -1 * dt)
        if self.keyMap["forward"]:
            self.droid.setY(self.droid, -25 * dt)
            self.enemy.setX(self.enemy, 1 * dt)
            # Π‘Π΄Π΅Π»Π°Π΅ΠΌ ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½ΠΎΠ΅ условиС ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ ΡƒΠ±Ρ€Π°Π½ΠΎ ΠΎΡ€ΡƒΠΆΠΈΠ΅ ΠΈΠ»ΠΈ Π½Π΅Ρ‚
            if not self.hide_weapon:
                self.weapon_pos = self.droid.getX(), self.droid.getY() + 0.7, 3
                self.weapon.setPos(self.weapon_pos) # ОбновляСм ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΏΡƒΡˆΠΊΠΈ
            else:
                self.weapon_pos = self.droid.getX(), self.droid.getY() + 0.7, 3
                self.flash.setPos(self.weapon_pos)


        camvec = self.droid.getPos() - self.camera.getPos() # Π²Π΅ΠΊΡ‚ΠΎΡ€ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹
        camvec.setZ(0) # 0 высота Π²Π΅ΠΊΡ‚ΠΎΡ€Π°
        camdist = camvec.length() # дистанция ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ ΠΎΡ‚ Π΄Ρ€ΠΎΠΈΠ΄Π°
        camvec.normalize() # Π½ΠΎΡ€ΠΌΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ Π²Π΅ΠΊΡ‚ΠΎΡ€ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹
        if camdist > 10.0: # Ссли дистанция ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ большС 10, Ρ‚ΠΎ смСщаСм ΠΊΠ°ΠΌΠ΅Ρ€Ρƒ Π·Π° Π΄Ρ€ΠΎΠΎΠΈΠ΄ΠΎΠΌ
            self.camera.setPos(self.camera.getPos() + camvec * (camdist - 10))
            camdist = 10.0 # Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ дистанция Π±ΡƒΠ΄Π΅Ρ‚ снова 10
        if camdist < 5.0: # Ссли дистагцтя ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ мСньшС 5, Ρ‚ΠΎ...
            self.camera.setPos(self.camera.getPos() - camvec * (5 - camdist)) # сдвигаСм ΠΊΠ°ΠΌΠ΅Ρ€Ρƒ
            camdist = 5.0 # всё обновляСм
            
        self.camera.lookAt(self.floater) # Π²ΠΎΡ‚ ΠΈ пригодился наш floater


        return task.cont # Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌ Π·Π°Π΄Π°Ρ‡Ρƒ

    def addInstructions(self, pos, msg):
        return OnscreenText(text=msg, style=1, fg=(1,1,1,1), font=self.inst_font, pos=(-1.3, pos), align=TextNode.ALeft, scale = .04, shadow=(0,0,0,1)) # Ѐункция ΠΎ Ρ‚ΠΎΠΌ, ΠΊΠ°ΠΊ ΡƒΠΏΡ€Π°Π²Π»ΡΡ‚ΡŒ

    def addTitle(self, text):
        return OnscreenText(text=text, style=1, fg=(1, 1, 1, 1), scale=0.2,
                            parent=base.a2dBottomRight, align=TextNode.ARight,
                            pos=(-0.1, 0.09), shadow=(0, 0, 0, 1), font=self.font) # Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ тСкстового Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ° с ΡˆΡ€ΠΈΡ„Ρ‚ΠΎΠΌ ΠΈ ΠΏΠΎΠ·ΠΈΡ†ΠΈΠ΅ΠΉ
    

droid = DroidShooter() # Π‘ΠΎΠ·Π΄Π°Π΄ΠΈΠΌ экзСмпляр класса нашСй ΠΈΠ³Ρ€Ρ‹
droid.run() # 3апустим ΠΈΠ³Ρ€Ρƒ


# Ρ€Π°Π·Ρ€ΠΎΠ±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ :
# Π“Π»Π°Π²Π½Ρ‹ΠΉ Π°Π²Ρ‚ΠΎΡ€ : ma3rx
# ΠŸΠΎΠΌΠΎΡ‰Π½ΠΈΠΊ : panda3dmastercoder( присоСдСнился ΠΊ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Ρƒ 31 января, 2021 Π³ΠΎΠ΄Π°, 12:??)
# Π Π΅ΠΊΠ»Π°ΠΌΡ‰ΠΈΠΊ : rdb (написал ΠΏΠ΅Ρ€Π²ΠΎΠ΅ сообщСниС Π½Π° Ρ„ΠΎΡ€ΡƒΠΌΠ΅ 6 фСвраля 2021 Π³ΠΎΠ΄Π°, 20:11)

3.0.6.2 update - bug fix shaders!
Add directory ./shaders : shaders.zip
New code :

#!/usr/bin/env python
# -*- coding: utf_8 -*-

# Π‘ΠΎΠ·Π΄Π°Π½ΠΎ : 22 число, ΡΠ½Π²Π°Ρ€ΡŒ, 2021 Π³ΠΎΠ΄

# Π˜ΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΡƒΠ΅ΠΌ всС Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹Π΅ инструмСнты
from direct.showbase.ShowBase import ShowBase
from panda3d.core import CollisionTraverser, CollisionNode
from panda3d.core import CollisionHandlerPusher, CollisionSphere, CollisionInvSphere
from panda3d.core import Filename, AmbientLight, DirectionalLight
from panda3d.core import PandaNode, NodePath, Camera, TextNode
from direct.particles.Particles import Particles
from direct.particles.ParticleEffect import ParticleEffect
from panda3d.core import PointLight, Spotlight
from panda3d.core import CollideMask
from panda3d.core import loadPrcFileData
from panda3d.core import *
from direct.gui.OnscreenText import OnscreenText
from direct.gui.OnscreenImage import OnscreenImage
from direct.gui.DirectButton import DirectButton
from direct.gui.DirectSlider import DirectSlider
from direct.actor.Actor import Actor
from direct.interval.IntervalGlobal import Sequence
from direct.interval.IntervalGlobal import Wait
import random
import sys
import time
import os
import math


VERSION = '3.0.6.2'

settings = ['window-title Droid Game ' +  VERSION,
            'fullscreen 0']
            

loadPrcFileData('', settings[0]) # Π‘Π΄Π΅Π»Π°Π΅ΠΌ Π½Π΅ стандартный Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ (Π²ΠΎΠ·ΠΌΡ‘ΠΌ Π΅Π³ΠΎ ΠΈΠ· ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ settings)
loadPrcFileData('', settings[1]) # Π½Π΅ Π±ΡƒΠ΄Π΅ΠΌ Π΄Π΅Π»Π°Ρ‚ΡŒ полноэкранный Ρ€Π΅ΠΆΠΈΠΌ

# Π‘ΠΎΠ·Π΄Π°Π΄ΠΈΠΌ Π³Π»Π°Π²Π½Ρ‹ΠΉ класс нашСй ΠΈΠ³Ρ€Ρ‹
class DroidShooter(ShowBase):
    def __init__(self):
        ShowBase.__init__(self) # Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ всС сСлфы ΠΈΠ· direct
        self.speed = 1800 # ΡΠΊΠΎΡ€ΠΎΡΡ‚ΡŒ двигатСля
        self.GB = False # НЕ Ρ‡Ρ‘Ρ€Π½ΠΎ-Π±Π΅Π»Ρ‹ΠΉ Ρ€Π΅ΠΆΠΈΠΌ
        self.menu() # звпуск мСню
        
    def menu(self):
        
        base.enableParticles() # ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ эффСкт Π΄Ρ‹ΠΌΠ°

        self.win.setClearColor((0, 0, 0, 1)) # Π—Π°ΠΊΡ€Π°ΡˆΠΈΠ²Π°Π΅ΠΌ ΠΏΠΎΠ²Π΅Ρ€Ρ…Π½ΠΎΡΡ‚ΡŒ Ρ‡Ρ‘Ρ€Π½Ρ‹ΠΌ. Π”Π΅Π»ΠΎ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ Π² этом ΠΈΠ³Ρ€ΠΎΠ²ΠΎΠΌ Π΄Π²ΠΈΠΆΠΊΠ΅ ΠΏΠΎΠ²Π΅Ρ€Ρ…Π½ΠΎΡΡ‚ΡŒ Π·Π°ΠΊΡ€Π°ΡˆΠΈΠ²Π°Π΅Ρ‚ΡΡ сСрым.
        self.font = loader.loadFont('./fonts/doom_font.ttf') # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ ΡˆΡ€ΠΈΡ„Ρ‚ ΠΈΠ· ΠΈΠ³Ρ€Ρ‹ doom
        self.inst_font = loader.loadFont('./fonts/arial.ttf') # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ ΡˆΡ€ΠΈΡ„Ρ‚ arial

        self.crackSound = loader.loadMusic('./sounds/crack.wav') # Π·Π²ΡƒΠΊ Π²Π·Ρ€Ρ‹Π²Π° корабля
        self.shotSound = loader.loadMusic('./sounds/shot.wav') # Π·Π²ΡƒΠΊ выстрСла
        self.startSound = loader.loadMusic('./sounds/started.wav') # Π·Π²ΡƒΠΊ запуска
        self.errorSound = loader.loadMusic('./sounds/error.wav') # Π·Π²ΡƒΠΊ запуска
        self.errorSound.setVolume(1) # полная Π³Ρ€ΠΎΠΌΠΊΠΎΡΡ‚ΡŒ Π·Π²ΡƒΠΊΠ°
        self.startSound.setVolume(1) # полная Π³Ρ€ΠΎΠΌΠΊΠΎΡΡ‚ΡŒ Π·Π²ΡƒΠΊΠ°
        self.crackSound.setVolume(1) # полная Π³Ρ€ΠΎΠΌΠΊΠΎΡΡ‚ΡŒ Π·Π²ΡƒΠΊΠ°
        self.shotSound.setVolume(1) # полная Π³Ρ€ΠΎΠΌΠΊΠΎΡΡ‚ΡŒ Π·Π²ΡƒΠΊΠ°
        self.startSound.play() # ΠΈΠ³Ρ€Π°Π΅ΠΌ Π·Π²ΡƒΠΊ запуска ΠΈΠ³Ρ€Ρ‹

        self.button_start = DirectButton(pos=(0.7, 0, 0.4), text="CTAPT",
                                   scale=.2, pad=(.2, .2),
                                   command=self.load_game) # ΠΊΠ½ΠΎΠΏΠΊΠ° запуска ΠΈΠ³Ρ€Ρ‹

        self.gb_start = DirectButton(pos=(0.7, 0, 0.1), text="GB",
                                   scale=.2, pad=(.2, .2),
                                   command=self.gb_mode) # ΠΊΠ½ΠΎΠΏΠΊΠ° запуска ΠΈΠ³Ρ€Ρ‹  Π² Ρ‡Ρ‘Ρ€Π½ΠΎ-Π±Π΅Π»ΠΎΠΌ Ρ€Π΅ΠΆΠΈΠΌΠ΅      

        self.slider_sun = DirectSlider(pos=(0.1, 0, .75), scale=0.8, value=0.5,
                                    command=self.set_sun_interval)


        self.title = self.addTitle("Droid game " + VERSION)
        
        # НапСчатаСм ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅
        self.inst1 = self.addInstructions(0.95, u"[ESC]: Π’Ρ‹Ρ…ΠΎΠ΄")
        self.inst2 = self.addInstructions(0.90, u"[Left Arrow]: ΠŸΠΎΠ²ΠΎΡ€ΠΎΡ‚ Π΄Ρ€ΠΎΠΈΠ΄Π° Π² Π»Π΅Π²ΠΎ")
        self.inst3 = self.addInstructions(0.85, u"[Right Arrow]: ΠŸΠΎΠ²ΠΎΡ€ΠΎΡ‚ Π΄Ρ€ΠΎΠΈΠ΄Π° Π² ΠΏΡ€Π°Π²ΠΎ")
        self.inst4 = self.addInstructions(0.80, u"[Up Arrow]: Π’ΠΏΠ΅Ρ€Π΅Π΄")
        self.inst5 = self.addInstructions(0.75, u"[a]: ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ Π² ΠΏΡ€Π°Π²ΠΎ")
        self.inst6 = self.addInstructions(0.70, u"[d]: ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ Π² Π»Π΅Π²ΠΎ")
        self.inst7 = self.addInstructions(0.65, u"[Left Arrow + Up arrow]: ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚ Π΄Ρ€ΠΎΠΈΠ΄Π° Π² Π»Π΅Π²ΠΎ ΠΈ Π²ΠΏΠ΅Ρ€Ρ‘Π΄")
        self.inst8 = self.addInstructions(0.60, u"[Right Arrow + Up arrow]: ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚ Π΄Ρ€ΠΎΠΈΠ΄Π° Π² ΠΏΡ€Π°Π²ΠΎ ΠΈ Π²ΠΏΠ΅Ρ€Ρ‘Π΄")
        self.inst9 = self.addInstructions(0.55, u"[a + Up arrow]: ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ Π² ΠΏΡ€Π°Π²ΠΎ ΠΈ Π²ΠΏΠ΅Ρ€Ρ‘Π΄")
        self.inst10 = self.addInstructions(0.50, u"[d + Up arrow]: ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ Π² Π»Π΅Π²ΠΎ ΠΈ Π²ΠΏΠ΅Ρ€Ρ‘Π΄")
        self.inst11 = self.addInstructions(0.45, u"[space]: ΡΡ‚Ρ€Π΅Π»ΡŒΠ±Π°")
        self.inst12 = self.addInstructions(0.40, u"[s]: Π΄ΠΎΡΡ‚Π°Ρ‚ΡŒ Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊ")
        self.inst13 = self.addInstructions(0.35, u"[w]: ΡƒΠ±Ρ€Π°Ρ‚ΡŒ ΠΎΡ€ΡƒΠΆΠΈΠ΅")
        self.inst14 = self.addInstructions(0.30, u"[f]: ΠΏΠΎΠ»Π½Ρ‹ΠΉ Ρ€Π°Π·Π³ΠΎΠ½(ОПАБНО!)")
        self.inst15 = self.addInstructions(0.25, u"[0]: ΠΏΠΎΠΆΠ°Ρ€ΠΎΡ‚ΡƒΡˆΠΈΡ‚Π΅Π»ΡŒΠ½Π°Ρ систСма")

        self.accept("escape", sys.exit) # ΠŸΡ€ΠΈ Π½Π°ΠΆΠ°Ρ‚ΠΈΠΈ клавиши Esc Π²Ρ‹Ρ…ΠΎΠ΄ΠΈΠΌ.

    def set_sun_interval(self):
        self.sun_interval = self.slider_sun.guiItem.getValue() * 100 # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ слайдСрноС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΡƒΠΌΠ½ΠΎΠΆΠ΅Π½ΠΎΠ΅ Π½Π° 500, Π΄Π° Ρ‚Ρ€Π°Ρ‡Ρƒ ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΡŽ Π½ΠΎ ΠΌΠ½Π΅ каТСтся ΠΌΠ½ΠΎΠ³ΠΈΠΌ ΠΏΠ»Π΅Π²Π°Ρ‚ΡŒ Π½Π° ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΡŽ мСню, ΠΈΠ±ΠΎ Ρ‚Π°ΠΊΠΎΠ³ΠΎ понятия просто Π½Π΅Ρ‚Ρƒ :)

    def gb_mode(self):
        '''Π²ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ Ρ‡Ρ‘Ρ€Π½ΠΎΠ±Π΅Π»ΠΎΠ³ΠΎ Ρ€Π΅ΠΆΠΈΠΌΠ°'''
        self.GB = True

    def load_game(self):
        self.button_start.hide() # ΡƒΠ΄Π°Π»ΠΈΠΌ ΠΊΠ½ΠΎΠΏΠΊΡƒ старта
        self.gb_start.hide() # ΡƒΠ΄Π°Π»ΠΈΠΌ ΠΊΠ½ΠΎΠΏΠΊΡƒ Ρ‡Ρ‘Ρ€Π½ΠΎ Π±Π΅Π»ΠΎΠ³ΠΎ Ρ€Π΅ΠΆΠΈΠΌΠ°.
        self.title.hide() # ΡƒΠ΄Π°Π»ΠΈΠΌ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ ΠΈΠ³Ρ€Ρ‹
        # ΡƒΠ΄Π°Π»ΠΈΠΌ ΠΊΠ½ΠΎΠΏΠΊΠΈ управлСния
        self.inst1.hide()
        self.inst2.hide()
        self.inst3.hide()
        self.inst4.hide()
        self.inst5.hide()
        self.inst6.hide()
        self.inst7.hide()
        self.inst8.hide()
        self.inst9.hide()
        self.inst10.hide()
        self.inst11.hide()
        self.inst12.hide()
        self.inst13.hide()
        self.inst14.hide()
        self.inst15.hide()
        self.slider_sun.hide() # удаляСм слайдСр солнца
        
        self.keyMap = {
            "left": 0, "right": 0, "forward": 0, "cam-left": 0, "cam-right": 0} # Π‘ΠΎΠ·Π΄Π°Π΄ΠΈΠΌ ΡΠ»ΠΎΠ²Π°Ρ€ΡŒ ΠΊΠ½ΠΎΠΏΠΎΠΊ, ΠΏΠΎ ΠΈΡ… Π½Π°ΠΆΠ°Ρ‚ΠΈΡŽ        

        # РисуСм Π·Π²Ρ‘Π·Π΄Ρ‹

        self.sky = loader.loadModel("./models/sky/solar_sky_sphere") # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ модСль космоса(это сфСра)

        self.sky_tex = loader.loadTexture("./tex/stars_1k_tex.jpg") # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ тСкстуру
        self.sky.setTexture(self.sky_tex, 1) # Π·Π°Ρ€Π΅Π½Π΄Π΅Ρ€ΠΈΠΌ тСкстуру Π½Π° Π½Π΅Π±ΠΎ
        self.sky.reparentTo(render) # ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ Π½Π΅Π±ΠΎ
        self.sky.setScale(40000) # Ρ€Π°ΡΡˆΠΈΡ€ΠΈΠΌ Π½Π΅Π±ΠΎ Π΄ΠΎ максимальной Π²Π΅Π»ΠΈΡ‡ΠΈΠ½Ρ‹ panda3d

        self.environ = loader.loadModel("models/world/falcon.egg") # Π—Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ ΡƒΠΆΠ΅ созданный Π² blender ΠΌΠΈΡ€.
        self.environ.reparentTo(render) # Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ модСль ΠΌΠΈΡ€Π° Π² ΠΎΠΊΠ½ΠΎ

        droidStartPos = (-1, 0, 1.5 ) # Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ ΡΡ‚Π°Ρ€Ρ‚ΠΎΠ²ΡƒΡŽ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π² ΠΌΠΈΡ€Π΅.
        enemyStartPos = (-6, 1, 0.5) # Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ°-Π΄Ρ€ΠΎΠΈΠ΄Π°.
        self.droid = Actor("models/player/seeker.egg") # Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ модСль ΠΈΠ³Ρ€ΠΎΠΊΠ° (созданная Π² blender)
        self.enemy = Actor("models/enemies/r2d2/r2d2.egg") # Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ модСль ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ° (созданная Π² blender)
        self.droid.reparentTo(render) # ΠŸΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Π΅ΠΌ модСль ΠΈΠ³Ρ€ΠΎΠΊΠ° Π² наш ΠΌΠΈΡ€.
        self.enemy.reparentTo(render) # ΠŸΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Π΅ΠΌ модСль ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ° Π² наш ΠΌΠΈΡ€.
        self.droid.setScale(1) # Π”Π΅Π»Π°Π΅ΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ€ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π½Π° 1
        self.enemy.setScale(1) # Π”Π΅Π»Π°Π΅ΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ€ ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ° Π½Π° 1
        self.droid.setPos(droidStartPos) # Π‘Ρ‚Π°Π²ΠΈΠΌ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π½Π° Ρ€Π°Π½Π΅Π΅ ΡΠΎΠ·Π΄Π°Π½ΡƒΡŽ Π½Π°ΠΌΠΈ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ
        self.enemy.setPos(enemyStartPos) # Π‘Ρ‚Π°Π²ΠΈΠΌ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ° Π½Π° Ρ€Π°Π½Π΅Π΅ ΡΠΎΠ·Π΄Π°Π½ΡƒΡŽ Π½Π°ΠΌΠΈ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ

        self.weapon = Actor('models/weapon/lightsaber.egg') # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ ΠΎΡ€ΡƒΠΆΠΈΠ΅
        self.bullet = Actor('models/weapon/bullet/bullet.egg.pz') # Π—Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ ΠΏΡƒΠ»ΡŽ
        self.flash = Actor('models/whishlyflash/handlamp.egg') # Π—Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊ
               
        self.weapon.reparentTo(render) # пСрСмСстим ΠΎΡ€ΡƒΠΆΠΈΠ΅ Π² наш ΠΌΠΈΡ€
        self.bullet.reparentTo(render) # пСрСмСстим ΠΏΡƒΠ»ΡŽ Π² ΠΌΠΈΡ€ Π½ΠΎ появится ΠΎΠ½Π° сама Π½Π΅ скоро
        self.flash.reparentTo(render) # пСрСмСстим Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊ Π² наш ΠΌΠΈΡ€
        self.weapon.setScale(.5) # Π·Π°Π΄Π°Π΄ΠΈΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ€ ΠΏΡƒΡˆΠΊΠΈ
        self.bullet.setScale(.5) # Π·Π°Π΄Π°Π΄ΠΈΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ€ ΠΏΡƒΠ»ΠΈ
        self.flash.setScale(.5) # Π·Π°Π΄Π°Π΄ΠΈΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ€ Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊΠ°

        # враТСский ΠΈΡΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»ΡŒ
        self.fighter = Actor('models/fighter/fighter.egg') # Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ ΠΌΠΎΠ΄Π΅Π»ΡŒΠΊΡƒ истрСбитСля
        self.fighter.reparentTo(render) # ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ ΠΈΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»ΡŒ
        self.fighter.setPos(0, 90, 0) # позиция истрСбитСля
                

        self.weapon_pos = self.droid.getX(), self.droid.getY() + 0.7, 1 # ΠŸΠΎΠ·ΠΈΡ†ΠΈΡ ΠΏΡƒΡˆΠΊΠΈ
        
        self.weapon.setPos(self.weapon_pos) # ΠŸΠΎΠΌΠ΅ΡΡ‚ΠΈΠΌ ΠΎΡ€ΡƒΠΆΠΈΠ΅ Ρ‡ΡƒΡ‚ΡŒ Π²Ρ‹ΡˆΠ΅ ΠΈΠ³Ρ€ΠΎΠΊΠ°

        self.cube = Actor('models/block/crate.egg') # Π·Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ Π±Π»ΠΎΠΊ
        self.cube.reparentTo(render)
        self.cube.setPos(0, -0, 0) # позиция ящика
        self.cube.setScale(0.7)
        self.cube.hprInterval(1.5, (0, 360, 360)).loop()

        self.Intervalcube = self.cube.posInterval(13,
                                                   Point3(0, -500, 0),
                                                   startPos=Point3(0, 10, 0))

        self.Intervalcube.loop()
        
        self.spotlight = camera.attachNewNode(Spotlight("spotlight")) # ΠšΠΎΠ½Ρ„ΠΈΠ³ΠΈ Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊΠ°
        self.spotlight.node().setColor((.3, .3, .3, 1))
        self.spotlight.node().setSpecularColor((0, 0, 0, 1))

        self.floater = NodePath(PandaNode("floater")) 
        self.floater.reparentTo(self.droid)
        self.floater.setZ(2.0)

        self.accept("escape", sys.exit) # ΠŸΡ€ΠΈ Π½Π°ΠΆΠ°Ρ‚ΠΈΠΈ клавиши Esc Π²Ρ‹Ρ…ΠΎΠ΄ΠΈΠΌ.
        
        self.accept("arrow_left", self.setKey, ["left", True]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ Π²Π»Π΅Π²ΠΎ - ΠΏΠΎΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π²Π»Π΅Π²ΠΎ
        self.accept("arrow_right", self.setKey, ["right", True]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ Π²ΠΏΡ€Π°Π²ΠΎ - ΠΏΠΎΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π²ΠΏΡ€Π°Π²ΠΎ
        self.accept("arrow_up", self.setKey, ["forward", True]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ Π²ΠΏΠ΅Ρ€Ρ‘Π΄ - ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄
        self.accept("a", self.setKey, ["cam-left", True]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ a - Ρ€Π°Π·Π²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΊΠ°ΠΌΠ΅Ρ€Ρƒ Π²ΠΎΠΊΡ€ΡƒΠ³ нашСй модСльки
        self.accept("d", self.setKey, ["cam-right", True]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ s - Ρ€Π°Π·Π²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΊΠ°ΠΌΠ΅Ρ€Ρƒ Π²ΠΎΠΊΡ€ΡƒΠ³ нашСй модСльки
        self.accept("arrow_left-up", self.setKey, ["left", False]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ Π²Π²Π΅Ρ€Ρ…+Π²Π»Π΅Π²ΠΎ - ΠΏΠΎΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π²Π»Π΅Π²ΠΎ ΠΈ ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄
        self.accept("arrow_right-up", self.setKey, ["right", False]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ Π²Π²Π΅Ρ€Ρ…+ΠΏΡ€Π°Π²ΠΎ - ΠΏΠΎΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π²ΠΏΡ€Π°Π²ΠΎ ΠΈ ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄
        self.accept("arrow_up-up", self.setKey, ["forward", False]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ Π²Π²Π΅Ρ€Ρ…+Π²Π²Π΅Ρ€ΡŠ - ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄ ΠΈ ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄
        self.accept("a-up", self.setKey, ["cam-left", False]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ a+Π²ΠΏΠ΅Ρ€Ρ‘Π΄ - ΠΏΠΎΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΊΠ°ΠΌΠ΅Ρ€Ρƒ Π²Π»Π΅Π²ΠΎ ΠΈ ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄
        self.accept("d-up", self.setKey, ["cam-right", False]) # ΠŸΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ s+Π²ΠΏΠ΅Ρ€Ρ‘Π΄ - ΠΏΠΎΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΊΠ°ΠΌΠ΅Ρ€Ρƒ Π²ΠΏΡ€Π°Π²ΠΎ ΠΈ ΠΈΠ΄Ρ‘ΠΌ Π²ΠΏΠ΅Ρ€Ρ‘Π΄

        self.accept("space", self.shot) # ΠΏΡ€ΠΈ ΠΏΡ€ΠΎΠ±Π΅Π»Π΅ стрСляСм
        self.accept("s", self.toggleLights, [[self.spotlight]]) # Π’ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊ
        self.accept("w", self.weapon_hide) # ΠΏΡ€ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ΅ w - ΡƒΠ±Π΅Ρ€Ρ‘ΠΌ ΠΎΡ€ΡƒΠΆΠΈΠ΅.

        base.enableParticles() # Π’ΠΊΠ»ΡŽΡ‡Π°Π΅ΠΌ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ Π΄Ρ‹ΠΌΠ°
        self.t = loader.loadModel("models/weapon/lightsaber.egg") # Π—Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ Π΅Ρ‰Ρ‘ ΠΎΡ€ΡƒΠΆΠΈΠ΅
        self.t.reparentTo(render) # ΠŸΠ΅Ρ€Π΅ΠΌΠ΅ΡΡ‚ΠΈΠΌ ΠΎΡ€ΡƒΠΆΠΈΠ΅ Π² наш ΠΌΠΈΡ€
        self.p = ParticleEffect() # Π’ΠΊΠ»ΡŽΡ‡ΠΈΠΌ эффСкт Π΄Ρ‹ΠΌΠ°
        self.accept('f', self.particle_start) # ΠΏΡ€ΠΈ Π½Π°ΠΆΠ°Ρ‚ΠΈΠΈ f(ΠΎΡ‚ force) -  Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠΌ Ρ„Π°ΠΉΠ» Π΄Ρ‹ΠΌΠ° ΠΈ пСрСмСстим Π² ΠΊΠΎΠ½Ρ„ΠΈΠ³ Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΈΠΌΠ΅Π½Π½ΠΎ эта анимация стала ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ΠΌ Π΄Ρ‹ΠΌΠ°
        self.accept('0', self.fountain) # ΠΏΡ€ΠΈ  Π½Π°ΠΆΠ°Ρ‚ΠΈΠΈ ΠΊΠ½ΠΎΠΏΠΎΠΊ f+o(fountain) Π²ΠΊΠ»ΡŽΡ‡ΠΈΠΌ ΠΏΠΎΠΆΠ°Ρ€ΠΎΡ‚ΡƒΡˆΠΈΡ‚Π΅Π»ΡŒΠ½ΡƒΡŽ систСму

        taskMgr.add(self.move, "moveTask") # ДобавляСм Π·Π°Π΄Π°Ρ‡Ρƒ Π² наш Π΄Π²ΠΈΠΆΠΎΠΊ

        self.isMoving = False # Π‘Ρ‚Π°Π²ΠΈΠΌ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ isMoving Π½Π° False(Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΌΠ΅Π½ΡΡ‚ΡŒ это Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅) Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΈΠ³Ρ€ΠΎΠΊ ΠΈΠ·Π½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎ стоял.
        # Π”Π΅Π»Π°Π΅ΠΌ Ρ‚Π°ΠΊ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ свСт Π±Ρ‹Π» ΠΈΠ·Π½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎ Π²Ρ‹ΠΊΠ»ΡŽΡ‡Π΅Π½.
        self.disableMouse() # ΠžΡ‚ΠΊΠ»ΡŽΡ‡Π°Π΅ΠΌ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π΅Π½ΠΈΠ΅ Ρ‡Π΅Ρ€Π΅Π· ΠΌΡ‹ΡˆΠΊΡƒ
        self.camera.setPos(self.droid.getX(), self.droid.getY() + 1, 3) # Π‘Ρ‚Π°Π²ΠΈΠΌ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ Ρ‡ΡƒΡ‚ΡŒ большС ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ ΠΈΠ³Ρ€ΠΎΠΊΠ°

        self.black_light() # Π‘Π΄Π΅Π»Π°Π΅ΠΌ Π²Ρ‹ΠΊΠ»ΡŽΡ‡Π΅Π½Π½Ρ‹ΠΉ свСт

        self.state = 100 # БостояниС корабля
        self.state_info = OnscreenText(text='ΠΊΠΎΡ€Π°Π±Π»ΡŒ :' + str(self.state), pos=(0.5, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля
                
        self.check_loss() # ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ ΠΏΠΎΡ€Π°ΠΆΠ΅Π½ΠΈΠ΅
        self.hide_weapon = False # ΠŸΠΎΡΡ‚Π°Π²ΠΈΠΌ, Ρ‡Ρ‚ΠΎ ΠΎΡ€ΡƒΠΆΠΈΠ΅ Π½Π΅ ΡƒΠ±Ρ€Π°Π½ΠΎ
        self.steam_pos = random.randrange(0, 5), random.randrange(0, 5), random.randrange(0, 5)
        self.fountain_pos = random.randrange(0, 5), random.randrange(0, 5), random.randrange(0, 1)

        self.motor_pos1 = 25.238849639892578, 8.962211608886719, 1.5 # позиция ΠΏΠ΅Ρ€Π²ΠΎΠ³ΠΎ ΠΌΠΎΡ‚ΠΎΡ€Π°
        self.motor_pos2 = -20.676218032836914, 10.55816650390625, 1.5 # позиция Π²Ρ‚ΠΎΡ€ΠΎΠ³ΠΎ ΠΌΠΎΡ‚ΠΎΡ€Π°

        self.motor1 = self.loadParticleConfig('special_effects/steam_critic+/fireish.ptf', self.motor_pos1) # ΠΌΠΎΡ‚ΠΎΡ€ 1
        self.motor2 = self.loadParticleConfig('special_effects/steam_critic+/fireish.ptf', self.motor_pos2) # ΠΌΠΎΡ‚ΠΎΡ€ 2

        self.state_info2 = OnscreenText(text='', pos=(-0.8, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля

        self.force = False # ΠŸΠΎΡΡ‚Π°Π²ΠΈΠΌ, Ρ‡Ρ‚ΠΎ Π½Π΅ Ρ€Π°Π·Π³ΠΎΠ½ΡΠ»ΠΈΡΡŒ

        # ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ ΠΊΠΎΠ»Π»ΠΈΠ·ΠΈΠΈ

        # Коллизия корабля(ΠΎΠ½ Ρƒ нас ΠΊΠ°ΠΊ главная ΠΊΠ°Ρ€Ρ‚Π°).
        self.cTrav = CollisionTraverser()
        pusher = CollisionHandlerPusher()
        pusher.setHorizontal(True) 
        
        environCenter = self.environ.getBounds().getCenter()
        environRad = self.environ.getBounds().getRadius()
        cNode = CollisionNode("environment")
        cNode.addSolid(CollisionInvSphere(environCenter, environRad))
        environC = self.environ.attachNewNode(cNode)

        # Коллизия Π΄Ρ€ΠΎΠΈΠ΄Π°.
        droidCenter = self.droid.getBounds().getCenter()
        droidRad = self.droid.getBounds().getRadius()
        cNode = CollisionNode("droid")
        cNode.addSolid(CollisionSphere(droidCenter, droidRad))
        droidC = self.droid.attachNewNode(cNode)
        
        pusher.addCollider(droidC, self.droid)
        self.cTrav.addCollider(droidC, pusher)

        # Коллизия ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ°.
        enemyCenter = self.enemy.getBounds().getCenter()
        enemyRad = self.enemy.getBounds().getRadius()
        cNode = CollisionNode("enemy")
        cNode.addSolid(CollisionSphere(enemyCenter, enemyRad))
        enemyC = self.enemy.attachNewNode(cNode)

        pusher.addCollider(enemyC, self.enemy)
        self.cTrav.addCollider(enemyC, pusher)

        # Коллизия враТСского истрСбитСля.
        fighterCenter = self.fighter.getBounds().getCenter()
        fighterRad = self.fighter.getBounds().getRadius()
        cNode = CollisionNode("fighter")
        cNode.addSolid(CollisionSphere(fighterCenter, fighterRad))
        fighterC = self.fighter.attachNewNode(cNode)

        pusher.addCollider(fighterC, self.fighter)
        self.cTrav.addCollider(fighterC, pusher)

        # Коллизия ΠΏΡƒΠ»ΠΈ.
        bulletCenter = self.bullet.getBounds().getCenter()
        bulletRad = self.bullet.getBounds().getRadius()
        cNode = CollisionNode("bullet")
        cNode.addSolid(CollisionSphere(bulletCenter, bulletRad))
        bulletC = self.bullet.attachNewNode(cNode)

        bulletCenter = self.bullet.getBounds().getCenter()
        bulletRad = self.bullet.getBounds().getRadius()
        cNode = CollisionNode("bullet")
        cNode.addSolid(CollisionSphere(bulletCenter, bulletRad))
        bulletC = self.bullet.attachNewNode(cNode)
        
        pusher.addCollider(bulletC, self.bullet)
        self.cTrav.addCollider(bulletC, pusher)

        # Коллизия ΠΏΡƒΡˆΠΊΠΈ. Π― Π±Ρ‹ Π½Π΅ сказал, Ρ‡Ρ‚ΠΎ это ΠΈΠΌΠ΅Π½Π½ΠΎ коллизия, скорСС это для рСалистичности
        weaponCenter = self.weapon.getBounds().getCenter()
        weaponRad = self.weapon.getBounds().getRadius()
        cNode = CollisionNode("weapon")
        cNode.addSolid(CollisionSphere(weaponCenter, weaponRad))
        weaponC = self.weapon.attachNewNode(cNode)
        
        pusher.addCollider(weaponC, self.weapon)
        self.cTrav.addCollider(weaponC, pusher)

        # солнцС(новая ΠΌΠ΅Ρ…Π°Π½ΠΈΠΊΠ° освСщСния)
        sun = DirectionalLight("sun")
        sun.set_color_temperature(6000)
        sun.color = sun.color * 4
        sun_path = render.attach_new_node(sun)
        sun_path.set_pos(10, -10, -10)
        sun_path.look_at(0, 0, 0)
        sun_path.hprInterval(self.sun_interval, (sun_path.get_h(), sun_path.get_p() - 360, sun_path.get_r()), bakeInStart=True).loop()
        render.set_light(sun_path)

        # Если  ΠΈΠ³Ρ€ΠΎΠΊ Π·Π°Ρ…ΠΎΡ‚Π΅Π» ΠΏΠΎΠΈΠ³Ρ€Π°Ρ‚ΡŒ Π² Ρ‡Ρ‘Ρ€Π½ΠΎΠ±Π΅Π»ΡƒΡŽ ΠΈΠ³Ρ€Ρƒ, ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΠΌ это
        if self.GB :        
            render.set_shader(Shader.load(Shader.SL_GLSL, "./shaders/lighting.vert", "./shaders/lighting.frag")) # Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ ΡˆΠ΅ΠΉΠ΄Π΅Ρ€Ρ‹ Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‚!



    def fight_force(self):
        # сдвиТСниС истрСбитСля Π·Π° нашим ΠΊΠΎΡ€Π°Π±Π»Ρ‘ΠΌ(ΠΎΡ‡Π΅Π½ΡŒ простым способом я сдСлал Ρ‚Π°ΠΊ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΈΡΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»ΡŒ Π·Π°ΠΆΠΈΠΌΠ°Π» нас(Π»Π΅Ρ‚Π°Π» Π² нашСм ΠΊΠ²Π°Π΄Ρ€Π°Ρ‚Π΅)) ΠΈ Π·Π°ΠΆΠΈΠΌΠ°Π΅Ρ‚ ΠΎΠ½ Ρ€Π΅Π°Π»ΡŒΠ½ΠΎ, сблиТая ΠΊ Π½Π°ΠΌ свой ΠΊΠ²Π°Π΄Ρ€Π°Ρ‚
        self.fighter.setY(self.fighter.getY() - self.speed) 
        self.fighter.setX(self.fighter.getX() - 10)    

        print(self.fighter.getX())


    def loadParticleConfig(self, filename, pos):
        self.p.cleanup()
        self.p = ParticleEffect()
        self.p.loadConfig(Filename(filename))

        self.p.start(self.t)
        self.p.setPos(pos)

    def particle_start(self):
        self.force = True # ΠŸΠΎΡΡ‚Π°Π²ΠΈΠΌ, Ρ‡Ρ‚ΠΎ ΠΌΡ‹ ΡƒΠΆΠ΅ Ρ€Π°Π·Π³ΠΎΠ½ΡΠ»ΠΈΡΡŒ
        # ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Π΅ΠΌ всС ΠΎΠ±ΡŒΠ΅ΠΊΡ‚Ρ‹ Π·Π° ΠΊΠΎΡ€Π°Π±Π»Ρ‘ΠΌ
        self.environ.setY(self.environ.getY() - self.speed) # нСсёмся Π²ΠΏΡ€Π°Π²ΠΎ
        self.droid.setY(self.droid.getY() - self.speed) # сдвигаСм Π΄Ρ€ΠΎΠΈΠ΄Π° Π·Π° ΠΊΠΎΡ€Π°Π±Π»Ρ‘ΠΌ
        self.enemy.setY(self.enemy.getY() - self.speed) # сдфигаСм ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ° Π·Π° ΠΊΠΎΡ€Π°Π±Π»Ρ‘ΠΌ
        self.weapon.setY(self.weapon.getY() - self.speed) # ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Π΅ΠΌ ΠΎΡ€ΡƒΠΆΠΈΠ΅
        self.flash.setY(self.flash.getY() - self.speed) # ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Π΅ΠΌ Ρ„ΠΎΠ½Π°Ρ€ΠΈΠΊ
        self.cube.setY(self.cube.getY() - self.speed) # ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Π΅ΠΌ ящик
        self.fight_force()

        self.state -= 1 # сдСлаСм мСньшС ΠΎΡ‡ΠΊΠΎΠ²
        self.state_info.hide() # ΡƒΠ΄Π°Π»ΠΈΠΌ тСкстовыС ΠΎΡ‡ΠΊΠΈ
        
        if self.state != 10 and self.state > 10:
            self.state_info.hide() # ΡƒΠ±ΠΈΡ€Π°Π΅ΠΌ ΠΏΡ€Π΅Π΄Π΅Π΄ΡƒΡ‰Π΅Π΅ сообщСниС ΠΎ Тизнях корабля
            self.state_info = OnscreenText(text='ΠΊΠΎΡ€Π°Π±Π»ΡŒ :' + str(self.state), pos=(0.5, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля
            self.check_loss() # провСряСм ΠΏΠΎΡ€Π°ΠΆΠ΅Π½ΠΈΠ΅
            self.steam_pos = random.randrange(0, 5), random.randrange(0, 5) + 300, random.randrange(0, 5)
            self.loadParticleConfig('special_effects/steam/steam.ptf', self.steam_pos)
            self.errorSound.play() # ΠΈΠ³Ρ€Π°Π΅ΠΌ Π·Π²ΡƒΠΊ ошибки
            self.state_info2.hide() # ΡƒΠ±ΠΈΡ€Π°Π΅ΠΌ ΠΏΡ€Π΅Π΄Π΅Π΄ΡƒΡ‰Π΅Π΅ сообщСниС
            self.state_info2 = OnscreenText(text='Π΄Π²ΠΈΠ³Π°Ρ‚Π΅Π»ΡŒ нСисправСн', pos=(-0.8, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля
        else:
            self.state_info = OnscreenText(text='ΠΊΠΎΡ€Π°Π±Π»ΡŒ :' + str(self.state), pos=(0.5, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля
            self.check_loss() # провСряСм ΠΏΠΎΡ€Π°ΠΆΠ΅Π½ΠΈΠ΅
            self.steam_pos = random.randrange(0, 5), random.randrange(0, 5) + 300, random.randrange(0, 5)
            self.loadParticleConfig('special_effects/steam_critic/steam.ptf', self.steam_pos)
            self.errorSound.play() # ΠΈΠ³Ρ€Π°Π΅ΠΌ Π·Π²ΡƒΠΊ ошибки
            self.state_info2.hide()  # ΡƒΠ±ΠΈΡ€Π°Π΅ΠΌ ΠΏΡ€Π΅Π΄Π΅Π΄ΡƒΡ‰Π΅Π΅ сообщСниС
            self.state_info2 = OnscreenText(text='критичСскоС состояниС', pos=(-0.8, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля
    
        if self.state < 10:
            self.state_info.hide()
            self.state_info = OnscreenText(text='ΠΊΠΎΡ€Π°Π±Π»ΡŒ :' + str(self.state), pos=(0.5, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля
            self.check_loss() # провСряСм ΠΏΠΎΡ€Π°ΠΆΠ΅Π½ΠΈΠ΅
            self.steam_pos = random.randrange(0, 5), random.randrange(0, 5) + 300, random.randrange(0, 5)            
            self.loadParticleConfig('special_effects/steam_critic+/fireish.ptf', self.steam_pos)
            self.errorSound.play() # ΠΈΠ³Ρ€Π°Π΅ΠΌ Π·Π²ΡƒΠΊ ошибки
            self.state_info2.hide() # ΡƒΠ±ΠΈΡ€Π°Π΅ΠΌ ΠΏΡ€Π΅Π΄Π΅Π΄ΡƒΡ‰Π΅Π΅ сообщСниС
            self.state_info2 = OnscreenText(text='ΠΏΠ°Π΄Π°Π΅ΠΌ!', pos=(-0.8, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля


    def fountain(self):
        self.state_info2.hide() # ΡƒΠ±ΠΈΡ€Π°Π΅ΠΌ тСкст опасности
        if self.force:
            if self.state != 100:
                self.state += 1
                self.state_info.hide()
                self.state_info = OnscreenText(text='ΠΊΠΎΡ€Π°Π±Π»ΡŒ :' + str(self.state), pos=(0.5, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля

            self.fountain_pos = random.randrange(0, 5), random.randrange(0, 5) + 500, random.randrange(0, 1)    
            self.loadParticleConfig('special_effects/fountain/fountain.ptf', self.fountain_pos)

        else :
            if self.state != 100:
                self.state += 1
                self.state_info.hide()
                self.state_info = OnscreenText(text='ΠΊΠΎΡ€Π°Π±Π»ΡŒ :' + str(self.state), pos=(0.5, 0.8), scale=0.1, fg=(1, 1, 1, 1), align=TextNode.ALeft, font=self.font) # НапишСм сообщСниС ΠΎ состоянии корабля

            self.fountain_pos = random.randrange(0, 5), random.randrange(0, 5), random.randrange(0, 1)    
            self.loadParticleConfig('special_effects/fountain/fountain.ptf', self.fountain_pos)
        
        
    def black_light(self):
        # Π’Ρ‹ΠΊΠ»ΡŽΡ‡Π΅Π½Ρ‹ΠΉ свСт
        ambientLight = AmbientLight("ambientLight")
        ambientLight.setColor((0, 0, 0, 1))
        directionalLight = DirectionalLight("directionalLight")
        directionalLight.setDirection((-5, -5, -5))
        directionalLight.setColor((1, 1, 1, 1))
        directionalLight.setSpecularColor((1, 1, 1, 1))
        render.setLight(render.attachNewNode(ambientLight))
        render.setLight(render.attachNewNode(directionalLight))

    def weapon_hide(self):
        # Π£Π±Ρ€Π°Ρ‚ΡŒ ΠΎΡ€ΡƒΠΆΠΈΠ΅
        self.hide_weapon = True
        self.weapon.hide()

    def toggleLights(self, lights):
        # Π‘ΠΏΠ΅Ρ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠ΅ освСщСниС
        if self.hide_weapon:
            for light in lights:
                if render.hasLight(light):
                    render.clearLight(light)
                else:
                    render.setLight(light)
            
            self.flash.setPos(self.weapon_pos)
        else:
            return


    def shot(self):
        dt = globalClock.getDt() + 0.5 # CΠΊΠΎΡ€ΠΎΡΡ‚ΡŒ двиТСния
        if not self.hide_weapon : # Ссли ΠΎΡ€ΡƒΠΆΠΈΠ΅ ΡƒΠ±Ρ€Π°Π½ΠΎ Ρ‚ΠΎ ΠΌΡ‹ Π½Π΅ ΠΌΠΎΠΆΠ΅ΠΌ ΡΡ‚Ρ€Π΅Π»ΡΡ‚ΡŒ
            self.shotSound.play() # ΠΈΠ³Ρ€Π°Π΅ΠΌ Π·Π²ΡƒΠΊ выстрСла
            self.bullet.setPos(self.weapon_pos) # ΠŸΡƒΠ»Ρ Π±ΡƒΠ΄Π΅Ρ‚ спавнится Π²Π½ΡƒΡ‚Ρ€ΠΈ ΠΏΡƒΡˆΠΊΠΈ
            self.bullet.setY(self.bullet, -11 * dt) # Π‘Π΄Π²ΠΈΠ³Π°Π΅ΠΌ ΠΏΡƒΠ»ΡŽ Π½Π° ΠΎΠ³Ρ€ΠΎΠΌΠ½ΠΎΠΉ скорости Π²ΠΏΠ΅Ρ€Ρ‘Π΄

    def check_loss(self):
        if self.state == 0: # Ссли ΠΆΠΈΠ·Π½Π΅ΠΉ Ρƒ корабля Π½Π΅ ΠΎΡΡ‚Π°Π»ΠΎΡΡŒ
            self.black_light() # Π²ΠΊΠ»ΡŽΡ‡ΠΈΠΌ Ρ‡Ρ‘Ρ€Π½Ρ‹ΠΉ свСт
            self.weapon_hide() # ΡƒΠ±Π΅Ρ€Ρ‘ΠΌ ΠΎΡ€ΡƒΠΆΠΈΠ΅
            self.info = OnscreenText(text='ΠΏΠΎΡ€Π°ΠΆΠ΅Π½ΠΈΠ΅', style=1, font=self.font,
                                     fg=(1,1,1,1),
                            pos=(-1.3, -0.5), align=TextNode.ALeft, scale=0.3) # напишСм ΠΎ ΠΏΠΎΡ€Π°ΠΆΠ΅Π½ΠΈΠΈ
            self.crackSound.play() # ΠΈΠ³Ρ€Π°Π΅ΠΌ Π·Π²ΡƒΠΊ Π²Π·Ρ€Ρ‹Π²Π°


    def setKey(self, key, value):
        self.keyMap[key] = value # Π”Π΅Π»Π°Π΅ΠΌ ΠΌΠ΅Ρ…aΠ½uΠ·ΠΌ наТатия клавиш.



    def move(self, task):

        ''' Π”Π΅Π»Π°Π΅ΠΌ Ρ„ΡƒΡ†Π½ΠΊΡ†ΠΈΡŽ двиТСния ΠΈΠ³Ρ€ΠΎΠΊΠ° '''

        dt = globalClock.getDt() - .005 # CΠΊΠΎΡ€ΠΎΡΡ‚ΡŒ двиТСния

        # ΠŸΠΎΠ²ΠΎΡ€ΠΎΡ‚ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ Π²Π»Π΅Π²ΠΎ ΠΈ Π²ΠΏΡ€Π°Π²ΠΎ

        if self.keyMap["cam-left"]:
            self.camera.setX(self.camera, -20 * dt) # МСняСм ΠΏΠΎΠ»ΠΎΠΆΠ΅Π½ΠΈΠΊΠ° ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ ΠΏΠΎ икс. Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ получаСтся илюзия ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚Π° ΡƒΠ³Π»Π° Π»ΡƒΡ‡Π°. Но Π½Π° самом Π΄Π΅Π»Π΅ ΠΊΠ°ΠΌΠ΅Ρ€Π° просто пСрСмСщаСтся.
        if self.keyMap["cam-right"]:
            self.camera.setX(self.camera, +20 * dt) # Π’ΠΎΠΆΠ΅ самоС, Ρ‡Ρ‚ΠΎ ΠΈ Π½Π°Π²Π΅Ρ€Ρ…Ρƒ.

        startpos = self.droid.getPos() # Π‘Π΄Π΅Π»Π°Π΅ΠΌ ΡƒΠ΄ΠΎΠ±Π½ΡƒΡŽ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ ΠΈΠ³Ρ€ΠΎΠΊΠ°

        if self.keyMap["left"]:
            self.droid.setH(self.droid.getH() + 300 * dt)
            self.enemy.setY(self.enemy, 1 * dt)
        if self.keyMap["right"]:
            self.droid.setH(self.droid.getH() - 300 * dt)
            self.enemy.setY(self.enemy, -1 * dt)
        if self.keyMap["forward"]:
            self.droid.setY(self.droid, -25 * dt)
            self.enemy.setX(self.enemy, 1 * dt)
            # Π‘Π΄Π΅Π»Π°Π΅ΠΌ ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½ΠΎΠ΅ условиС ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ ΡƒΠ±Ρ€Π°Π½ΠΎ ΠΎΡ€ΡƒΠΆΠΈΠ΅ ΠΈΠ»ΠΈ Π½Π΅Ρ‚
            if not self.hide_weapon:
                self.weapon_pos = self.droid.getX(), self.droid.getY() + 0.7, 3
                self.weapon.setPos(self.weapon_pos) # ОбновляСм ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΏΡƒΡˆΠΊΠΈ
            else:
                self.weapon_pos = self.droid.getX(), self.droid.getY() + 0.7, 3
                self.flash.setPos(self.weapon_pos)


        camvec = self.droid.getPos() - self.camera.getPos() # Π²Π΅ΠΊΡ‚ΠΎΡ€ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹
        camvec.setZ(0) # 0 высота Π²Π΅ΠΊΡ‚ΠΎΡ€Π°
        camdist = camvec.length() # дистанция ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ ΠΎΡ‚ Π΄Ρ€ΠΎΠΈΠ΄Π°
        camvec.normalize() # Π½ΠΎΡ€ΠΌΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ Π²Π΅ΠΊΡ‚ΠΎΡ€ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹
        if camdist > 10.0: # Ссли дистанция ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ большС 10, Ρ‚ΠΎ смСщаСм ΠΊΠ°ΠΌΠ΅Ρ€Ρƒ Π·Π° Π΄Ρ€ΠΎΠΎΠΈΠ΄ΠΎΠΌ
            self.camera.setPos(self.camera.getPos() + camvec * (camdist - 10))
            camdist = 10.0 # Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ дистанция Π±ΡƒΠ΄Π΅Ρ‚ снова 10
        if camdist < 5.0: # Ссли дистагцтя ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ мСньшС 5, Ρ‚ΠΎ...
            self.camera.setPos(self.camera.getPos() - camvec * (5 - camdist)) # сдвигаСм ΠΊΠ°ΠΌΠ΅Ρ€Ρƒ
            camdist = 5.0 # всё обновляСм
            
        self.camera.lookAt(self.floater) # Π²ΠΎΡ‚ ΠΈ пригодился наш floater


        return task.cont # Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌ Π·Π°Π΄Π°Ρ‡Ρƒ

    def addInstructions(self, pos, msg):
        return OnscreenText(text=msg, style=1, fg=(1,1,1,1), font=self.inst_font, pos=(-1.3, pos), align=TextNode.ALeft, scale = .04, shadow=(0,0,0,1)) # Ѐункция ΠΎ Ρ‚ΠΎΠΌ, ΠΊΠ°ΠΊ ΡƒΠΏΡ€Π°Π²Π»ΡΡ‚ΡŒ

    def addTitle(self, text):
        return OnscreenText(text=text, style=1, fg=(1, 1, 1, 1), scale=0.2,
                            parent=base.a2dBottomRight, align=TextNode.ARight,
                            pos=(-0.1, 0.09), shadow=(0, 0, 0, 1), font=self.font) # Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ тСкстового Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ° с ΡˆΡ€ΠΈΡ„Ρ‚ΠΎΠΌ ΠΈ ΠΏΠΎΠ·ΠΈΡ†ΠΈΠ΅ΠΉ
    

droid = DroidShooter() # Π‘ΠΎΠ·Π΄Π°Π΄ΠΈΠΌ экзСмпляр класса нашСй ΠΈΠ³Ρ€Ρ‹
droid.run() # 3апустим ΠΈΠ³Ρ€Ρƒ


# Ρ€Π°Π·Ρ€ΠΎΠ±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ :
# Π“Π»Π°Π²Π½Ρ‹ΠΉ Π°Π²Ρ‚ΠΎΡ€ : ma3rx
# ΠŸΠΎΠΌΠΎΡ‰Π½ΠΈΠΊ : panda3dmastercoder( присоСдСнился ΠΊ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Ρƒ 31 января, 2021 Π³ΠΎΠ΄Π°, 12:??)
# Π Π΅ΠΊΠ»Π°ΠΌΡ‰ΠΈΠΊ : rdb (написал ΠΏΠ΅Ρ€Π²ΠΎΠ΅ сообщСниС Π½Π° Ρ„ΠΎΡ€ΡƒΠΌΠ΅ 6 фСвраля 2021 Π³ΠΎΠ΄Π°, 20:11)

Hey, release of droid game coming soon!