} Скрыть} Скрыть
На сайте:
118 человека: Дима и 117 гостей
Обсуждаем:

Владас

Блог-свалка :)

Давно я обратил внимание на кнопочку "Блог"... Ну блог так блог, не зря же тут эта кнопочка :)
Буду тут выкладывать свои задумки, наработки, куски кода, заброшенные проекты, WIP'ы и прочий мусор :) (надеюсь никто не против)
Может быть что то из всего этого даже кому то поможет...

!!! ВНИМАНИЕ! ЛЮБОЙ КОНТЕНТ, РАЗМЕЩЕННЫЙ ДАЛЕЕ (В ПРЕДЕЛАХ МОЕГО БЛОГА, НЕ ОГРАНИЧИВАЯСЬ ЭТИМ ПОСТОМ, ВКЛЮЧАЯ, ТАКЖЕ, ВСЕ КОММЕНТАРИИ), РАСПРОСТРАНЯЕТСЯ ПО ЛИЦЕНЗИИ MIT (ЕСЛИ НЕ УКАЗАНО ИНОЕ) !!!


И для начала выложу несколько скриптов (не все написано оптимально, я ж не крутой кодер, главное что кое как да работают :) ), точнее это один скрипт состоящий из кучи функций, которые можно вызывать актуатором Python (такой подход порой эффективнее и компактнее чем куча отдельных маленьких скриптов).
####################################################
#Copyright © 2016-2017 Владас. All rights reserved.#
#License: http://opensource.org/licenses/MIT       #
####################################################
  
from bge import logic as G, events as E
from mathutils import *
from random import *
  
G.loadGlobalDict()
  
#меняет разрешение (качество) текста и сам текст (полезно чтобы не делать
#несколько разных текстовых объектов, а сделать клоны с другими значениями TEXT),
#требуется проперти Res с целым числом, и TEXT с текстом на который поменять.
def Res(cont):
    own = cont.owner
    own.resolution = own.get("Res", 3)
    
    own["Text"] = own.get("TEXT", own["Text"])
  
#нужная функция, используется для функций FadeColor и FadeScale, без нее они не работают.
def Change(id, start, end, cycles = 600, rem = G.getCurrentScene()):
    id = str(id)
  
    if not id in rem:
        rem[id] = {
        "Cycle" : 0,
        "ResultBackup" : start,
        "AddBackup" : (end - start) / cycles}
        
        return start
                                
    if id in rem and rem[id]["Cycle"] < cycles:
        rem[id]["Cycle"] += 1
        
        rem[id]["ResultBackup"] += rem[id]["AddBackup"]
                                
        if rem[id]["Cycle"] >= cycles:
            del rem[id]
            
            return end
                                                                
        return rem[id]["ResultBackup"]
  
#плавное изменение цвета объекта по сообщению (уже не помню почему так сделал),
#требует сенсор "сообщение" в импульсном режиме (оба уровня), тело получаемого
#сообщения должно состоять из: красный/зеленый/синий/количество_логических_тиков.
#Тоесть "1/1/1/60" для изменения цаета на белый за 60 тиков
def FadeColor(cont):
    sce = G.getCurrentScene()
    own = cont.owner
    
    if "FadeColor" in cont.sensors:
        fs = cont.sensors["FadeColor"]
        
        if fs.positive:
            own["FColor"] = fs.bodies[0].split("/")[0]
            own["TColor"] = fs.bodies[0].split("/")[1]
            
            if len(fs.bodies[0].split("/")) > 2: own["CCycles"] = int(fs.bodies[0].split("/")[2])
                                                                
    if own.get("FColor"):
        FC = Vector([float(n) for n in own.get("FColor", "1,1,1,1").split(",")])
        TC = Vector([float(n) for n in own.get("TColor", "0,0,0,0").split(",")])
        
        own.color = Change(id(own), FC, TC, own.get("CCycles", 600), own)
        
        if own.color == TC:
            del own["FColor"]
            del own["TColor"]
            del own["CCycles"]
                                                                                                
            for act in cont.actuators:
                cont.activate(act)
  
#аналогично предыдущему, только изменяет размер объекта.
def FadeScale(cont):
    sce = G.getCurrentScene()
    own = cont.owner
    
    if "FadeScale" in cont.sensors:
        fs = cont.sensors["FadeScale"]
        
        if fs.positive:
            own["FScale"] = fs.bodies[0].split("/")[0]
            own["TScale"] = fs.bodies[0].split("/")[1]
            
            if len(fs.bodies[0].split("/")) > 2: own["SCycles"] = int(fs.bodies[0].split("/")[2])
    
    if own.get("FScale"):
        FS = Vector([float(n) for n in own.get("FScale", "1,1,1").split(",")])
        TS = Vector([float(n) for n in own.get("TScale", "0,0,0").split(",")])
        
        own.localScale = Change(id(own), FS, TS, own.get("SCycles", 600), own)
        
        if own.localScale == TS:
            del own["FScale"]
            del own["TScale"]
            del own["SCycles"]
  
            for act in cont.actuators:
                cont.activate(act)
  
#для создания курсора в меню игры, требует сенсор Mouse (курсор над любым)
#в импульсном режиме истины и поверхность на весь экран столкновения с которой
#и будут копироваться для объекта (копируются положение по X и Y).
def Cursor(cont):
    own = cont.owner
    mouse = cont.sensors["Mouse"]
    
    own.worldPosition.x = mouse.hitPosition.x
    own.worldPosition.y = mouse.hitPosition.y
    
    for act in cont.actuators:
        cont.activate(act)
  
#сохраняет все свойства объекта в globalDict, если есть свойство SaveName
#сохранит под указанным там названием, иначе сохранит под именем объекта.
def SaveProps(cont):
    own = cont.owner
    
    G.globalDict[own.get("SaveName", own.name)] = {x:own[x] for x in own.getPropertyNames() if x != "SaveName"}
    
    G.saveGlobalDict()
    
    for act in cont.actuators:
        cont.activate(act)
  
#загружает сохраненные свойства.
def LoadProps(cont):
    own = cont.owner
    prop = G.globalDict.get(own.get("SaveName", own.name))
    
    if prop:
        for x in prop:
            own[x] = prop[x]
            
    for act in cont.actuators:
        cont.activate(act)
  
#удаляет все сохранения если нет свойства DelSaves, иначе удаляет только те,
#что указаны в DelSaves через запятую (без пробела).
def DelSaves(cont):
    own = cont.owner
    
    if "DelSaves" in own: own["DelSaves"] = [G.globalDict[sav] for sav in own["DelSaves"].split(",")]
    else: own["DelSaves"] = [sav for sav in G.globalDict]
    
    for save in own["DelSaves"]: del save
    
    G.saveGlobalDict()
    
    for act in cont.actuators:
        cont.activate(act)
  
#поворачивает объект в сторону его движения.
def Ballist(cont):
    cont.owner.alignAxisToVect(-cont.owner.getLinearVelocity())
  
#требует сенсор Collision, вычитает урон (свойство Damage) из жизней столкнувшегося
#с ним объета (свойство Health). Если есть свойство Force, тогда еще и толкает объект.
#Если есть свойство HitAll, то выбивает жизни у всех столкнувшихся, иначе только у первого.
def HitOnColl(cont):
    own = cont.owner
    sce = G.getCurrentScene()
    objs = cont.sensors["Collision"].hitObjectList
    
    if objs:
        if "HitAll" in own: klvo = len(objs)
        else: klvo = 1
        
        for i in range(0, klvo):
            if "Damage" in own and "Health" in objs[i]:
                objs[i]["Health"] -= own["Damage"]
                              
            if "Force" in own and objs[i].getPhysicsId() != 0:
                norm = (objs[i].worldPosition - own.worldPosition).normalized() * own["Force"]
                
                objs[i].applyImpulse(objs[i].worldPosition, norm)
            
        for act in cont.actuators:
            cont.activate(act)
  
#аналогично, требует свойства Rad с радиусом поражения, Damage с уроном и Force с силой отбрасывания.
def Explosion(cont):
    own = cont.owner
    sce = G.getCurrentScene()
    
    if cont.sensors["Collision"].positive:
        objs = [obj for obj in sce.objects if obj.getDistanceTo(own) <= own["Rad"] and obj != own]
        
        if len(objs) > 0:
            for obj in objs:
                if "Health" in obj:
                    dam = (own["Damage"] / own["Rad"]) * (own["Rad"] - obj.getDistanceTo(own))
                    
                    obj["Health"] -= dam
                    
                if obj.getPhysicsId() != 0:
                    norm = (obj.worldPosition - own.worldPosition).normalized()
                    norm *= (own["Force"] / own["Rad"]) * (own["Rad"] - obj.getDistanceTo(own))
                    
                    obj.applyImpulse(obj.worldPosition, norm)
            
        for act in cont.actuators:
            cont.activate(act)
  
#прокрутка UV, хорошо для водопадов например :)
#Требует сенсор Always в импульсном режиме и свойства SpeedX и SpeedY
#со скоростью прокрутки, index и array (уже не помню зачем эти два).
def UVscroll(cont):
    own = cont.owner
    mesh = own.meshes[0]
    
    array = mesh.getVertexArrayLength(own.get('array', 0))
    
    for v in range(0,array):
        vertex = mesh.getVertex(own.get('index', 0) ,v)
        
        UV = vertex.getUV()
        UV[0] += own.get('SpeedX', 0.001)
        UV[1] += own.get('SpeedY', 0.001)
        
        vertex.setUV(UV)
1501769470
Последнее время я потихоньку изучал фильтры (методом проб и ошибок и ковырянием чужих фильтров), зянятная это штука :)
И вот наконец что-то получилось, и я подумал почему бы не выложить это тут?
(Немного коряво, конечно, но, думаю задумку свою я осуществил :) )

Фильтр на красный цвет
Фильтр пропускает только красный цвет, оставляя остальное черно-белым. С помощю параметра strenght в фильтре, можно регулировать силу фильтра, ну как бы чувствительность к красному (высокие значения позволяют фильтру пропускать только "самый красный" :) ). Звук работающего проектора и дрожжание частично логикой (если это не нужно - можно просто убрать, оставив только фильтр).


Blend:
Filter_R.blend
Управление:
•WS - вперед/назад;
•AD - впаво/влево;
•Space/Ctrl - вверх/вниз;
•F - включить/выключить фильтр;
1501201774
Скрипт сохранения/загрузки
Сохраняет отмеченные свойством объекты в файл (по умолчанию Save.sav) в папку Saves.
Скрипт, наверное, немного корявый, сохранения в итоге весят многовато, но зато нету проблем с кириллицей (во всяком случае у меня из папки с русским названием скрипт работал, в отличии от варианта с globalDict) :) тут еще есть над чем поработать, если кому-то это оказалось полезным - буду дорабатывать, шлифовать и полировать :)

Свойства:
Для объекта, на котором весит скрипт, требуется свойство SaveName с именем сохранения;
Для сохраняемых объектов требуется свойство SaveObj, в нем через запятую перечислить что нужно сохранять:

•T - положение/вращение/размер (.worldTransform);
•Ph - сохранение физики (ну там линейная скорость, скорость вращения...);
•Ms - сохранение веса;
•P - свойства;
•C - цвет;
•M - меш (сохраняется только имя. При загрузке скрипт попытается сменить меш с помощю .replaceMesh(сохраненное_имя) );
•V - видимость;
•S - состояние (.state).

Сенсоры:
Любые (все подключенные сенсоры должны быть активированы).

Актуаторы:
Нету.

Как пользоваться:
Вызывать одну из фкнкций (Save/Load/Del) с помощю контроллера 'Python' в режиме модуля.

Скрипт:
Скрипт был длинноватым, и я решил что бленд-файла будет достаточно :)

.blend:
save.blend
Управление:
•Пробел - добавить кубик;
•1 - сохранить;
•2 - загрузить;
•3 - удалить сохранение.
1496612599
Скрипт движения платформы

Свойства:
•Range (строка, скрипт конвертирует в вектор) - Диапазон движения. 3 числа через запятую с пробелом.
•Time (целое число) - Время прохождения диапазона (в логических тиках).
•Pause (целое число) - Время ожидания перед возвратом (в логических тиках).

Сенсоры:
•Always (импульсный режим)
•Collision (назвать Coll) - если подключить этот сенсор, включается костыль для удержания объектов на платформе. (На Character не действует!)

Актуаторы:
Любые. Для активации во время движения, перед именем актуатора дописать "Move", для разовой активации при остановке - "Stop" (Например "Move_Sound" или "StopSound").

Скрипт:
###############################################
#Copyright © 2017 Владас. All rights reserved.#
#License: http://opensource.org/licenses/MIT  #
###############################################
  
from bge import logic as G
from mathutils import Vector as vec
    
cont = G.getCurrentController()
own = cont.owner
spd = own.get('Time', 60)
paus = own.get('Pause', 30)
  
active = [sens.positive for sens in cont.sensors if sens.name != 'Coll']
  
if not False in active:
    
    if own.get('cyc', -paus) <= -paus:
        own['cyc'] = spd
        own['clist'] = []
        
        if not 'shag' in own:
            rang = vec([float(i) for i in own.get('Range', "1, 1, 1").split(', ')])
            own['shag'] = rang / spd
        
        else: own['shag'] *= -1
      
    if own['cyc'] > 0:
        own.worldPosition += own['shag']
        
        for act in cont.actuators:
            if act.name[0:4] == 'Move':
                cont.activate(act)
                
            elif act.name[0:4] == 'Stop':
                cont.deactivate(act)
        
    elif own['cyc'] == 0:
        for act in cont.actuators:
            if act.name[0:4] == 'Move':
                cont.deactivate(act)
       
            elif act.name[0:4] == 'Stop':
                cont.activate(act)
    
    if 'Coll' in cont.sensors and own['cyc'] >= 0:
        coll = cont.sensors['Coll']
        znk = (own['cyc'] > 0) * 2 - 1
        
        for obj in coll.hitObjectList:
            
            if (znk > 0 and obj not in own['clist']) or (znk < 0 and obj in own['clist']):
                vel = obj.getLinearVelocity(False) + (own['shag'] * 60 * znk)
                obj.setLinearVelocity(vel, False)
                
                own['clist'].append(obj)
      
    own['cyc'] -= 1
Blend:
platform.blend
Николай: Платформа ездит, а игрок стоит... вот то беда  ! А потом упадет - и еще больше беда  И если бы в свойстве Range прописывалось направление только в одну сторону, а не от центра + -, еще бы лучше было бы. А если прописать звук цикличный, и паузу при остановке - ну просто Портал, и ...
Владас: Про игрока - это беда физики, сам вчера в очередной раз разочаровался (скрипт то для игры с платформами делал), сейчас думаю как это править (тут без костылей для игрока не обойтись ).И если бы в свойстве Range прописывалось направление только в одну сторону, а не от центра + -Незнаю ...   k 1
... k +3
Дима: Круто, я ЗА такие блоги - побольше бы   k 1
IdeaGen: о, так дима, оказывается, - бот )))   k 1
Весь блендер на карте инфографики. Изучение блендер на одном постере. Горячие клавиши. Скачай и распечатай постер --> Горячие клавиши Блендер