2

我正在制作的游戏中有这个脚本。这将在 Blender 游戏引擎中使用。Blender 不断地从上到下不断地运行脚本,所以如果我在脚本的开头声明一个变量,它就会不断地被初始化。

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

基本上,我的问题是在 if 循环中,我将变量从其原始值更改为其旧值的倒数。但是因为我在脚本开头声明了变量的值,所以速度变量不会停留在我将其更改为的值上。

我需要一种方法来永久更改变量的值或只声明一次。

谢谢!

4

5 回答 5

2

velocity_xandvelocity_y声明放在循环之前。如果您正在使用类,请将它们设为对象的属性并在其__init__().

编辑:我不知道 Blender 游戏引擎是如何工作的,但除了让脚本在一个大循环中之外,应该有一种在循环开始之前初始化东西的方法。真的,鉴于我对您的具体情况的了解有限,我只能这么说。

于 2010-04-18T20:09:28.587 回答
1

我正在寻找同一个问题的答案。我可以找到一种方法。你必须单击“添加属性”按钮并在搅拌机 UI 中添加一个属性。例如,oneTime=False。

然后在脚本中写:

if oneTime==False:做事件。一次=真

这是我能找到的唯一方法。

于 2010-06-19T10:08:17.677 回答
1

如果每次运行脚本时您的 python 运行时环境都相同,请尝试将初始化移动到异常处理程序。像这样:

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

__main__如果这不起作用,您也可以尝试将变量填充到模块中。像这样:

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

如果这不起作用,您将需要一些轻量级的内置工具,例如 sqlite3 模块。我重写了你的整个代码片段:

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

是的,它可以调整为函数或花哨的类,但如果这是你正在做的事情的程度,那么你不需要更多。

于 2010-06-30T15:41:09.010 回答
0

一个使用全局的例子。

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

编辑

__init__在一些评论中看到了一个。如果你在上课,你不应该写这样的东西:

self.loc_x += self.velocity_x

等等,引用实例?

于 2010-04-18T20:18:05.757 回答
0

要处理脚本代码的连续循环,您需要一个写在代码之外的值。否则无法正常工作。你的脚本应该如何知道它之前已经运行过?以下代码使用 Blender 2.6 和 2.7 系列运行:

可能性一:Blenders 全球词典。 添加一个子字典(也可以为空):

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

您可以像这样保存值: bge.globalDict['mysubdictionaryName'] = myValue.

可能性 2:Objectproperty a) 使用 python:

myObject = bge.logic.getCurrentController().owner

myObject['myproperty_named_has_run_before'] = True

b) 使用 Logicbricks 并在 Logic-editor 中添加属性

在您的情况下,您应该使用 objectproperties,因为使用 globalDict,当多个对象进行通信或您需要将数据带到另一个游戏场景时。

于 2015-01-16T21:35:41.657 回答