Como alterar permanentemente uma variável em um Python loop de jogo
Pergunta
Eu tenho esse script em um jogo que eu estou fazendo.Isso será usado no Blender game engine.O Blender executa scripts mais e mais a partir de cima para baixo continuamente, de forma que se eu declarar uma variável no início do script, ele continua sendo inicializado mais e mais.
#The current location of the object
loc_x = obj.getPosition()[0]
loc_y = obj.getPosition()[1]
#The velocity of the object
velocity_x = 0.09
velocity_y = 0.03
#If the location of the object is over 5, bounce off.
if loc_x > 5:
velocity_x = (velocity_x * -1)
if loc_y > 5:
velocity_y = (velocity_y * -1)
#Every frame set the object's position to the old position plus the velocity
obj.setPosition([(loc_x + velocity_x),(loc_y + velocity_y),0])
Basicamente, o meu problema é que no caso de loops, eu alterar a variável do seu valor original para o inverso do seu valor antigo.Mas porque eu declarar o valor da variável no início do script, a velocidade de variáveis não ficar sobre o que eu troco.
Eu preciso de uma maneira de alterar o valor da variável permanentemente ou declará-lo apenas uma vez.
Obrigado!
Solução
Para lidar com o ciclo contínuo através de seus scripts de código você precisa de um valor que o ist escrito fora do código.Caso contrário, ele não pode trabalhar.Como deve o seu script de saber que ele tem sido executado antes?Seguinte Código é executado com o Blender 2.6 e 2.7 da série:
Possibilidade 1:Liquidificadores Dicionário Global. adicionar um Subdictionary (pode ser vazia demais):
bge.logic.globalDict['mysubdictionaryName'] = { 'namestring' : False}
você pode salvar os valores como este:bge.globalDict['mysubdictionaryName'] = myValue
.
Possibilidade 2:Objectproperty a) com python:
myObject = bge.logic.getCurrentController().owner
myObject['myproperty_named_has_run_before'] = True
b) Utilizar Logicbricks e Adicionar Propriedades dentro da Lógica-editor
No seu caso, você deve usar objectproperties, porque o globalDict é usado, quando vários objetos se comunicam ou se você precisar de levar os dados para outro gamescene.
Outras dicas
Colocar o velocity_x
e velocity_y
declarações antes do loop.Se você estiver usando classes, torná-los atributos do objeto e inicializar-los apenas uma vez, dentro de suas __init__()
.
EDITAR:Eu não sei como o Blender game engine funciona, mas além de ter o script em um laço grande, deve haver uma maneira de inicializar coisas antes do loop inicia.Realmente, isso é tudo que posso dizer, dado o meu limitado conhecimento de sua situação específica.
estou procurando a resposta da mesma pergunta.existe uma maneira que eu coould encontrar.u deve clicar em "adicionar a propriedade" botão e adicione uma propriedade na INTERFACE do usuário do blender.por exemplo, oneTime=False.
em seguida, o script de gravação:
se oneTime==False:Fazer eventos.só=True
esta é a única maneira que eu poderia encontrar.
Se o seu python runtime environment é o mesmo cada vez que o script é executado tente mover seu inicialização para um manipulador de exceção.Assim:
try:
velocity_x = (velocity_x * -1)
except:
velocity_x = 0.09
Você também pode tentar enfiar a variável na __main__
módulo se que não funciona.Assim:
try:
__main__.velocity_x = (velocity_x * -1)
except:
__main__.velocity_x = 0.09
Se isso não funcionar, você vai precisar de algo leve e incorporado como o módulo sqlite3.Eu reescreveu todo o seu trecho de código:
import sqlite3
#The current location of the object
loc_x = obj.getPosition()[0]
loc_y = obj.getPosition()[1]
c = sqlite3.connect('/tmp/globals.db')
#c = sqlite3.connect('/dev/shm/globals.db')
# Using the commented connection line above instead will be
# faster on Linux. But it will not persist beyond a reboot.
# Both statements create the database if it doesn't exist.
# This will auto commit on exiting this context
with c:
# Creates table if it doesn't exist
c.execute('''create table if not exist vectors
(vector_name text primary key not null,
vector_value float not null,
unique (vector_name))''')
# Try to retrieve the value from the vectors table.
c.execute('''select * from vectors''')
vector_count = 0
for vector in c:
vector_count = vector_count + 1
# sqlite3 always returns unicode strings
if vector['vector_name'] == u'x':
vector_x = vector['vector_value']
elif vector['vector_name'] == u'y':
vector_y = vector['vector_value']
# This is a shortcut to avoid exception logic
# Change the count to match the number of vectors
if vector_count != 2:
vector_x = 0.09
vector_y = 0.03
# Insert default x vector. Should only have to do this once
with c:
c.executemany("""replace into stocks values
(?, ?)""", [('x', vector_x), ('y', vector_y)])
#If the location of the object is over 5, bounce off.
if loc_x > 5:
velocity_x = (velocity_x * -1)
if loc_y > 5:
velocity_y = (velocity_y * -1)
# Update stored vectors every time through the loop
with c:
c.executemany("""update or replace stocks set vector_name = ?,
vector_value = ?)""", [('x', vector_x), ('y', vector_y)])
#Every frame set the object's position to the old position plus the velocity
obj.setPosition([(loc_x + velocity_x),(loc_y + velocity_y),0])
# We can also close the connection if we are done with it
c.close()
Sim, pode ser ajustado em funções ou fantasia classes, mas se essa é a medida do que você está fazendo, você não precisa de muito mais do que isso.
Um exemplo de uso global.
#The velocity of the object
velocity_x = 0.09
velocity_y = 0.03
loc_x = 0
loc_y = 0
def update_velocity():
#If the location of the object is over 5, bounce off.
global velocity_x, velocity_y
if loc_x > 5:
velocity_x = (velocity_x * -1)
if loc_y > 5:
velocity_y = (velocity_y * -1)
def update_position():
global loc_x, loc_y # global allows you to write to global vars
# otherwise you're creating locals :)
loc_x += velocity_x
loc_y += velocity_y
#Every frame set the object's position to the old position plus the velocity
while True:
update_velocity()
update_position()
# undoubtedly you do more than this...
obj.setPosition([loc_x,loc_y,0])
EDITAR
Eu vi um __init__
em algum comentário.Se você está em uma classe não deveria escrever algo como:
self.loc_x += self.velocity_x
e assim por diante, a referência a instância?