4 操作符和变量
让我们从一个简单的“画作”开始:
def setup():
size(800, 300)
def draw():
background(220)
ellipse(100, 200, 50, 50) # 左边轮子
ellipse(200, 200, 50, 50) # 右边轮子
rect(50, 160, 200, 20) # 车厢
查看现有效果,我对小车的位置并不完全满意。 我现在希望它再向右一点。
现在移动形状将意味着我们需要增加每个形状函数的x位置参数的值。
假设我们要向所有指定x位置的数字加150。 我们可以尝试在脑海中进行数学运算并在其中键入结果,但是幸运的是,我们可以使用python轻松进行数学运算。 不必键入加法的结果,我们只需键入所需的操作,python就会为我们进行计算(详见下面的程序)。
def setup():
size(800, 300)
def draw():
background(220)
ellipse(100 + 150, 200, 50, 50)
ellipse(200 + 150, 200, 50, 50)
rect(50 + 150, 160, 200, 20)
同样的事情也适用于其他运营商。 我们可以用类似的方式进行减法,乘法或除法。
我们需要牢记的一件事是操作符在程序中的运算顺序。 您可能已经从数学课中知道了这一点,但是某些运算符的优先级高于其他运算符。 例如,如果我们想将2加到一个数字上然后乘以4,我们可能会想写这样的东西:10 + 2 * 4。但是在此操作中,乘法将在加法之前发生。 2将与4乘以然后再加到10,因此上述操作将产生18而不是预期值48。
为了能够控制操作的顺序,我们可以使用括号。例如,我们可以这样写最上面的等式:(10 + 2)* 4括号内的任何内容都将在其他操作之前进行求值。
按照运算顺序,首先是括号,然后是乘法和除法,然后是加法和减法。
变量
能够像这样自动计算表达式的值,程序的这种特点非常有用。 但是我认为,在此示例中,真正的问题是需要在所有这三个不同的位置键入相同的数字,这种行为非常费力且容易出错。 在这种情况下,使用变量会很有用。
每当我们需要一个值,并且需要在多个地方使用该值时,我们都希望将该值存储在变量中。 使用变量的好处是,如果我们需要更新变量的值,则只需要在一个地方进行即可。 让我们更新此示例以使用变量。
记住如何创建变量。 Python中赋值语句对尚不存在的变量进行赋值的时候,就会自动创建该变量(如 a = 2)。然后,我们将为变量选择一个名称。 选择一个有意义的名称也很重要。 比如现在我们需要一个变量来表示使用它来将形状在x轴上偏移的长度的时候,像是x
或者offset
这样的名字将会。 使用明智的名称将有助于其他人甚至我们理解我们的代码。
现在我们有了一个指向值的变量,我们可以在操作中使用该变量而不是值本身。 这样做,我们只需要在某个位置更改此变量的值即可看到形状移动:
def setup():
size(800, 300)
def draw():
background(220)
offset = 150
ellipse(100 + 150, 200, 50, 50)
ellipse(200 + 150, 200, 50, 50)
rect(50 + 150, 160, 200, 20)
局部变量和全局变量
我想在另一个示例中说明变量的另一种行为。 让我们在屏幕中间画一个圆圈,在中间画一个矩形
def setup():
size(800, 300)
rectMode(CENTER)
def draw():
background(1, 186, 240)
# 画圆
fill(237, 34, 93)
noStroke()
ellipse(400, 150, 200, 200)
# 画方形
fill(255)
rect(400, 150, 150, 30)
您能想到我们可以对上述程序进行的一种优化吗? 注意我们如何重复形状的x和y位置值。 让我们改用变量:
def setup():
size(800, 300)
rectMode(CENTER)
def draw():
background(1, 186, 240)
# 创建变量
x = 400
y = 150
# 画圆
fill(237, 34, 93)
noStroke()
ellipse(x, y, 200, 200)
# 画方形
fill(255)
rect(x, y, 150, 30)
由于这些形状不是相对于画布大小定位的,因此,如果我们要更改画布的大小,则形状的相对位置也会发生变化。 对于方形画布,形状当前位于中心,但是对于较宽的画布,形状可能会开始向左倾斜。 要使任何给定画布尺寸的形状都靠近中心,我们可以使用变量来设置画布的宽度和高度值。 然后,我们可以利用相同的变量来控制形状的位置。
在setup
函数中,我们将创建两个新的变量,分别为canvasWidth
和canvasHeight
,其值分别为800
和300
。我们将把这些变量传递给createCanvas
函数,而不是使用以前的硬编码值。 计划是我们也可以在draw
函数中使用这些相同的变量,以便即使我们要更改画布的大小,形状的相对位置也将保持不变。
因此,让我们在draw
函数中使用这些变量(下面的程序)。 我们将它们除以2,以便获得画布的宽度和高度的一半。
def setup():
canvasWidth = 800
canvasHeight = 300
size(canvasWidth, canvasHeight)
rectMode(CENTER)
def draw():
background(1, 186, 240)
# 创建变量
x = canvasWidth / 2
t = canvasHeight / 2
# 画圆
fill(237, 34, 93)
noStroke()
ellipse(x, y, 200, 200)
# 画方形
fill(255)
rect(x, y, 150, 30)
在执行代码时,您会注意到我们收到一个错误。 如果我们要在控制台中查看错误消息,它会说明未定义变量名的内容:
因为我们在设置函数中明确声明了这些变量,所以这可能令人惊讶。 发生此错误的原因与变量的作用范围有关。 变量的范围(作用域)决定了在哪里可以访问该变量。 以默认方式创建变量时,它们具有函数作用域。
函数作用域 的工作方式是,从函数外部看不到在函数内部声明的任何变量。 它仅对它所驻留的功能以及可能嵌套在该功能内的其他功能可用。 同样,如果我们要在顶层使用一个变量,则该变量对于该级别以及嵌套在其中的级别的所有内容都是可见的,例如可能在其中定义的功能。
您也可以使用 global
关键字来声明变量。 如果非要在
我们现在面临的问题是在setup函数中定义的变量从draw函数中不可见。 因此,如果要在draw函数中声明变量,则它们在同一级别的其他函数中将不可见。
解决此问题的方法是,与其在setup函数中声明变量,不如在顶层声明它们,以便可以从在顶层声明的其他所有内容访问它们:
# 创建全局变量
canvasWidth = 800
canvasHeight = 300
def setup():
size(canvasWidth, canvasHeight)
rectMode(CENTER)
def draw():
background(1, 186, 240)
x = canvasWidth / 2
t = canvasHeight / 2
# 画圆
fill(237, 34, 93)
noStroke()
ellipse(x, y, 200, 200)
# 画方形
fill(255)
rect(x, y, 150, 30)
在顶层声明的变量称为全局变量,不要将滥用全局变量。
Processing中预定义的变量
Processing是一个非常有用的工具,它具有几个预定义的变量(也可以叫做“内置变量”),我们可以使用这些变量来获取某些值。 (例如width
和height
两个内置变量可以让我们获得画布的长度和高度)。 通过在setup
或draw
函数中使用width
和height
,我们可以获得当前的画布大小。
def setup():
size(800, 300)
rectMode(CENTER)
def draw():
background(1, 186, 240)
# 变量声明和赋值
x = width / 2
t = height / 2
# 画圆
fill(237, 34, 93)
noStroke()
ellipse(x, y, 200, 200)
# 画方形
fill(255)
rect(x, y, 150, 30)
应注意,width和height是p5.js变量,这意味着它们将无法在设置或绘图功能之外使用。
既然我们知道如何使用变量,就可以对形状进行动画处理了!
p5.js中动画的技巧是记住,p5.js不断为我们执行draw函数。 无论我们放入此函数的内容是什么,每次重新执行draw函数时都会被重绘。
执行此绘制功能的次数(可以认为是渲染到屏幕上)称为帧速率。 默认情况下,Processing默认帧速率为60。这意味着它尝试每秒重新绘制(或渲染)draw函数的内容60次。 如果我们有办法在每个绘制调用之间更改正在使用的变量的值,那么我们将能够创建动画。
这应该使您想起翻书动画。 每次调用draw函数都会生成一个静态图像,但是由于每幅图像稍有不同,它每秒都会发生60次,因此您会感觉到它是动画的。
为了能够创建动画,我们将在绘制函数外部初始化一个称为count的变量。 在draw函数内部,我们将使用此简单表达式,该表达式将在每次调用draw函数时将count变量加1。
count = 0 # 初始化作为计数器的变量
def setup():
size(800, 300)
rectMode(CENTER)
def draw():
background(1, 186, 240)
# 变量声明和赋值
x = width / 2
t = height / 2
size = 200 + count # 控制形状的尺寸大小
# 画圆
fill(237, 34, 93)
noStroke()
ellipse(x, y, size, size)
# 画方形
fill(255)
rect(x, y, size*0.75, size*0.15)
count = count + 1 # 将计数器变量更新(也就是将其加1)
这些变量也是全局变量,而且大部分都是只读变量。这些变量的作用都是为了能够实时准确地在程序运行的时候,告诉我们当前程序运行的状态信息。
当你有了某种更改这些变量的“需求”的时候,请压制住自己的冲动。比如当你想要重新调整