Domanda

Ho questo script in un gioco che sto facendo. Questo verrà utilizzato nel motore di gioco di Blender. Blender esegue gli script più e più volte da cima a fondo in modo continuo, quindi se dichiaro una variabile all'inizio dello script, che continua ad essere inizializzato più e più volte.

#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])

In sostanza, il mio problema è che nel caso cicli, cambio la variabile dal suo valore originale per l'inverso del suo vecchio valore. Ma perché mi dichiaro il valore della variabile all'inizio dello script, le variabili di velocità non rimangono su quello che lo cambio a.

Ho bisogno di un modo per cambiare il valore della variabile in modo permanente o dichiarare una sola volta.

Grazie!

È stato utile?

Soluzione

Per gestire il loop continuo attraverso il codice di script è necessario un valore ist scritto al di fuori del codice. In caso contrario, non può funzionare. Come dovrebbe sapere il vostro script che è stato eseguito prima? In seguito esegue il codice con Blender 2.6 e 2.7 serie:

Possibilità 1:. Frullatori Dictionary globale aggiungere un Subdictionary (può essere vuoto troppo):

bge.logic.globalDict['mysubdictionaryName'] = { 'namestring' : False}

è possibile salvare i valori come questo: bge.globalDict['mysubdictionaryName'] = myValue.

Possibilità 2: OBJECTPROPERTY a) con Python:

myObject = bge.logic.getCurrentController().owner

myObject['myproperty_named_has_run_before'] = True

b) Uso Logicbricks e aggiungere proprietà all'interno della logica-editore

Nel tuo caso si dovrebbe usare ObjectProperties, perché il globalDict viene utilizzato, quando più gli oggetti comunicano o se è necessario prendere i dati ad un altro gamescene.

Altri suggerimenti

Mettere le dichiarazioni velocity_x e velocity_y prima del ciclo. Se stai usando le classi, renderle attributi dell'oggetto e li intialize solo una volta, all'interno del suo __init__().

EDIT: Non so come funziona il motore di Blender gioco, ma oltre ad avere lo script in un grande anello, ci dovrebbe essere un modo per inizializzare roba prima dell'inizio del ciclo. In realtà, questo è tutto quello che posso dire dato la mia limitata conoscenza della vostra situazione specifica.

Im che cerca la risposta alla stessa domanda. c'è un modo i coould find.u deve cliccare sul tasto "Aggiungi proprietà" e aggiungere una proprietà nel frullatore UI.for ad esempio, un tempo = False.

quindi nella scrittura di script:

se Onetime == false:      Do eventi.      OneTime = True

questo è l'unico modo che ho trovato.

Se l'ambiente di runtime di Python è lo stesso ogni volta che lo script viene eseguito provare a spostare la vostra inizializzazione per un gestore di eccezioni. In questo modo:

try:
    velocity_x = (velocity_x * -1)
except:
    velocity_x = 0.09

Si può anche provare l'imbottitura della variabile nel modulo __main__ se questo non funziona. In questo modo:

try:
    __main__.velocity_x = (velocity_x * -1)
except:
    __main__.velocity_x = 0.09

Se questo non dovesse funzionare sarà necessario qualcosa di leggero e costruito nel come il modulo sqlite3. Ho riscritto l'intero frammento di codice:

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()

Sì, potrebbe essere sintonizzato in funzioni o classi di fantasia, ma se questa è la portata di quello che state facendo non avete bisogno di molto di più.

Un esempio di utilizzo globale.

#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])

Modifica

ho visto un __init__ in qualche commento. Se sei in una classe non si dovrebbe scrivere qualcosa di simile:

self.loc_x += self.velocity_x

e così via, per fare riferimento all'istanza?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top