![](/img/trans.png)
[英]Permanently change of the formula of a parameter inside a for loop in python
[英]How to permanently change a variable in a Python game loop
我正在制作的游戏中有此脚本。 这将在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循环中,我将变量从其原始值更改为其旧值的倒数。 但是因为我在脚本的开头声明了变量的值,所以速度变量不会停留在更改后的位置。
我需要一种永久更改变量值或仅声明一次的方法。
谢谢!
将velocity_x
和velocity_y
声明放在循环之前。 如果使用的是类,则使它们成为对象的属性,并在其__init__()
内部仅初始化一次。
编辑:我不知道Blender游戏引擎如何工作,但是除了使脚本处于较大的循环之外,还应该有一种在循环开始之前初始化内容的方法。 真的,鉴于我对您的具体情况的了解有限,我只能说这些。
我正在寻找相同问题的答案。 我有一种方法可以find.u必须单击“添加属性”按钮,然后在搅拌机UI中添加属性。例如,oneTime = False。
然后在脚本中编写:
如果oneTime == False:执行事件。 一次性=真
这是我唯一能找到的方法。
如果每次运行脚本时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()
是的,可以将其调整为函数或特殊类,但是如果这是您正在做的事情,那么您将不需要更多。
使用全局的示例。
#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
等等,以引用实例?
要处理脚本代码中的连续循环,您需要一个在代码外部编写的值。 否则它将无法正常工作。 您的脚本应该如何知道它已经运行过? 以下代码在Blender 2.6和2.7系列中运行:
可能性1:Blenders全球词典。 添加一个Subdictionary(也可以为空):
bge.logic.globalDict['mysubdictionaryName'] = { 'namestring' : False}
您可以这样保存值: bge.globalDict['mysubdictionaryName'] = myValue
。
可能性2:使用python的对象属性 a):
myObject = bge.logic.getCurrentController().owner
myObject['myproperty_named_has_run_before'] = True
b)在逻辑编辑器中使用Logicbricks和Add Properties
在您的情况下,应该使用objectproperties,因为使用了globalDict,当多个对象进行通信时,或者您需要将数据带到另一个游戏场景时。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.