主要内容
交互场景
现在我们会做精美的动画情景,我们要保证可以处理另外那种非静态的场景:对用户的互动进行反应。例如,我们要绘制小黄鸭生宝宝的情景(当然,这是在他的摇滚明星阶段以后)-- 但我们还要让用户点击而给小黄鸭更多宝宝。因为我们这世界上总可以用更多黄鸭宝宝,对吧?
以下是这个情景作为独立的程序会是什么样子的。程序绘制情景静态的部分,然后在
mouseClicked
(鼠标点击事件) 中,它在鼠标点击的位置绘制黄鸭宝宝的图像,把它们放在该处原已有的任何东西上面。我们会怎样将这个整合到我们多场景的程序中呢?好吧,我们会先把所有静态绘制的代码都放进一个绘制场景的函数
drawScene5()
并为 mouseClicked
加上换场景的逻辑:var drawScene5 = function() {
currentScene = 5;
background(173, 239, 255);
fill(7, 14, 145);
textSize(39);
text("Winston has babies!", 10, 47);
...
};
mouseClicked = function() {
if (currentScene === 1) {
drawScene2();
} else if (currentScene === 2) {
drawScene3();
} else if (currentScene === 3) {
drawScene4();
} else if (currentScene === 4) {
drawScene5();
} else if (currentScene === 5) {
drawScene1();
}
};
如下所示:
但我们如何整合
mouseClicked
的功能呢?我们已经在代码中定义了 mouseClicked
,我们不能再次定义它。在 Javascript 中,最后的函数定义 “赢”,它会覆盖之前的任何定义。也就是说,我们要在现有的 mouseClicked
中找个好地方来放那行画宝宝的代码。让我们谈谈几种选择:1. 我们可以把这行放在函数的上面:
mouseClicked = function() {
image(getImage("creatures/BabyWinston"), mouseX-20, mouseY-20);
...
};
这样,每次用户点击鼠标它都会被调用,即使不是绘制宝宝的场景 (如果黄鸭宝宝有了宝宝就怪了)。这样是不对的。
2. 我们可以把这行放在
currentScene === 4
的 if 语句中:mouseClicked = function() {
if (currentScene === 1) {
drawScene2();
} else if (currentScene === 2) {
drawScene3();
} else if (currentScene === 3) {
drawScene4();
} else if (currentScene === 4) {
drawScene5();
image(getImage("creatures/BabyWinston"), mouseX-20, mouseY-20);
} else if (currentScene === 5) {
drawScene1();
}
};
归根到底,我们就在哪儿调用
drawScene5()
,而宝宝应该在哪被加到第 5 个场景。但想想:这就意味着我们 每次 画这个场景时都会多画一个宝宝。这也意味着我们永远不再画 更多 宝宝了,因为 currentScene
会被改成 5,而 if 语句中的代码不再会被执行。3. 我们可以把这行放在
currentScene === 5
的 if 语句中:mouseClicked = function() {
if (currentScene === 1) {
drawScene2();
} else if (currentScene === 2) {
drawScene3();
} else if (currentScene === 3) {
drawScene4();
} else if (currentScene === 4) {
drawScene5();
} else if (currentScene === 5) {
image(getImage("creatures/BabyWinston"), mouseX-20, mouseY-20);
drawScene1();
}
};
也就是说,我们直到初次绘制这个场景后的第一次点击前都不会画宝宝。但是,正如你在之后这一行可见,宝宝会立刻被第 1 个场景代替。
在此我们发现了整合宝宝点击场景这个主意的致命缺点:我们在用完全相同的互动 -- 屏幕上任何位置的鼠标点击 -- 来切换场景并且进行场景内的互动。现在我们真的有了个难题,我们要考虑更彻底的方法来整合这个场景。
4. 我们可以在最后停止重画场景 1,并在此时告诉用户重启。 当然,那会有效,但是前提是我们的点击控制的场景必须是最后一个。那如果我们想要一个早一些的点击控制的场景呢?这个方法就会失败。
5. 我们可以用另外一种互动 - 例如
mouseDragged。
那会有效,因为拖动鼠标不会引起点击的事件发生。我们还要确认 currentScene === 5
,以保证拖动在其它场景中不会画宝宝。mouseDragged = function() {
if (currentScene === 5) {
image(getImage("creatures/BabyWinston"), mouseX-20, mouseY-20);
}
};
下面来试试,确保你在最后一个场景拖动:
这样,这似乎有效,但我有点担心小黄鸭最后会有多少宝宝。总而言之,这不是理想的方法,因为这意味着我们必须避免设计对点击鼠标有反应的场景。我们不想有这样的限制,一定还有更好的方法。
如果我们把点击鼠标根据位置区别,使一个位置的点击表示切换场景,而其它位置的点击为场景内的互动,会怎么样?如你所知,就像一个按钮!其实,大部分多场景的程序都是这样处理这个问题的,我们接下来会谈这个问题。