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!

Foi útil?

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?

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top