Frage

Ich habe dieses Skript in einem Spiel, das ich mache. Dies wird in dem Blender Game Engine verwendet werden. Blender läuft Skripte immer und immer von oben nach unten kontinuierlich, so dass, wenn ich eine Variable am Anfang des Skripts deklarieren, es initialisiert über und über immer wieder zu werden.

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

Im Grunde genommen mein Problem ist, dass die in, wenn Schleifen, ich die Variablen von ihrem ursprünglichen Wert auf das Inverse von seinem alten Wert ändern. Aber weil ich den Wert der Variablen am Anfang des Skripts deklarieren, die Geschwindigkeitsvariablen bleiben nicht auf das, was ich ändern es.

Ich brauche eine Art und Weise der Wert der Variablen dauerhaft zu verändern oder nur einmal erklären.

Danke!

War es hilfreich?

Lösung

Um die kontinuierliche Looping durch Ihren Skripte Code verarbeiten müssen Sie einen Wert, der ist außerhalb des Codes geschrieben. Sonst kann es nicht funktionieren. Wie Ihr Skript sollte wissen, dass es wurde vorher laufen? Folgender Code läuft mit Blender 2.6 und 2.7 Serie:

Möglichkeit 1:. Blender Globale Wörterbuch fügen Sie ein Subdictionary (kann auch leer sein):

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

Sie können Werte wie folgt speichern: bge.globalDict['mysubdictionaryName'] = myValue.

Möglichkeit 2: OBJECT a) mit Python:

myObject = bge.logic.getCurrentController().owner

myObject['myproperty_named_has_run_before'] = True

b) Verwenden Logicbricks und Eigenschaften Hinzufügen innerhalb des Logik-Editor

In Ihrem Fall sollten Sie Objekteigenschaften verwenden, da der globalDict verwendet wird, wenn mehrere Objekte kommunizieren oder wenn Sie Daten an einem anderen gamescene nehmen.

Andere Tipps

Setzen Sie die velocity_x und velocity_y Erklärungen vor der Schleife. Wenn Sie Klassen verwenden, machen sie von der Objektattribute und intialize sie nur ein einziges Mal, in seinem __init__().

EDIT: Ich weiß nicht, wie die Blender Game Engine funktioniert, aber neben das Skript mit in einer großen Schleife, soll es eine Möglichkeit geben, Sachen vor Beginn der Schleife zu initialisieren. Wirklich, das ist alles, kann ich mein begrenztes Wissen über Ihre spezifische Situation sagt gegeben.

Im Suche nach der Antwort von der gleichen Frage. gibt es eine Möglichkeit, i coould find.u auf „Add-Eigenschaft“ klicken muss und eine Eigenschaft im Mixer UI.for Beispiel hinzufügen, ONETIME = False.

dann im Skript schreiben:

Wenn ONETIME == False:      Haben Veranstaltungen.      ONETIME = True

Das ist der einzige Weg, wir finden können.

Wenn Sie Ihre Python-Laufzeitumgebung ist jedes Mal das gleiche der Skript Versuch ausgeführt wird Ihre Initialisierung zu einem Ausnahmehandler zu bewegen. Wie so:

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

Sie können auch versuchen, die Variable in die __main__ Modul Füllung, wenn das nicht funktioniert. Wie so:

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

Wenn das nicht funktioniert, werden Sie etwas leichtes müssen und in wie der sqlite3-Modul eingebaut. Ich schrieb den gesamten Code-Snippet:

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

Ja, es in Funktionen oder ausgefallene Klassen abgestimmt werden könnte, aber wenn es das ist das Ausmaß dessen, was Sie tun, Sie brauchen nicht viel mehr als das.

Ein Beispiel für die Verwendung 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])

Bearbeiten

ich sah einen __init__ in einigen Kommentar. Wenn Sie in einer Klasse sind, sollten Sie nicht schreiben etwas wie:

self.loc_x += self.velocity_x

und so weiter, um die Instanz zu verweisen?

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top