目标
本小节我们制作一个屏幕环绕的效果,也就是当玩家走到屏幕的边界时,再继续走就从它的对面边界出来。这样,玩家始终走不出第一屏,这种效果在某些场景中或许会用到。
参考
本例参考自kidscancode的godot recipes中的screen wrap一节。地址我会放到置顶评论中。
https://kidscancode.org/godot_recipes/2d/screen_wrap/
场景结构
场景结构与之前的小节基本一致,还是我们的icon.png。 | |
---|---|
原理
我们通过键盘的上下左右键来控制玩家的移动,并且检测玩家的position属性,当它超出窗口可见部分的矩形范围时,我们就强制设置其position属性到对面边界的位置。
实现基础的移动
extends Sprite
var speed = 200
func _process(delta):
var dir = Input.get_vector(
"ui_left",
"ui_right",
"ui_up",
"ui_down"
)
position += dir * speed * delta
实现基础的环绕
extends Sprite
var speed = 200
onready var screen_size = get_viewport_rect().size 获取视口矩形的大小
func _process(delta):
var dir = Input.get_vector(
"ui_left",
"ui_right",
"ui_up",
"ui_down"
)
position += dir * speed * delta
if position.x > screen_size.x:
position.x = 0
if position.x < 0:
position.x = screen_size.x
if position.y > screen_size.y:
position.y = 0
if position.y < 0:
position.y = screen_size.y
代码分析
为了实现环绕,我们首先使用CanvasItem.get_viewport_rect()来获取窗口可视区域的矩形,将其保存到screen_size变量中。 然后使用四个if语句来进行Sprite位置的判断,当玩家的位置超越边界时就瞬间位移到对面边界。 上面的代码运行后我们已经可以获得正确的屏幕环绕效果。 |
|
---|---|
wrapf()函数
但是类似于之后我们将在《血量和经验、等级的设计策略》一节中讲到的钳制函数clamp(),这里我们可以使用wrapf()函数来进行值的循环,它可以让所赋值在给定的最小值和最大值之间循环,而不是钳制。 钳制函数clamp()和循环函数wrapf()都是 @GDScript 的成员方法,也就是GDScript中的全局函数,任何地方,任何时候都可以使用。 |
|
---|---|
改进的代码
| ```swift position.x = wrapf(position.x, 0, screen_size.x) position.y = wrapf(position.y, 0, screen_size.y)
| 通过使用循环函数wrapf(),我们可以将之前的四个if语句简化为两句。 |
| --- | --- |
<a name="e8XDT"></a>
## 最终代码
所以最终代码可以修改如下:
```swift
extends Sprite
var speed = 200
onready var screen_size = get_viewport_rect().size
func _process(delta):
var dir = Input.get_vector(
"ui_left",
"ui_right",
"ui_up",
"ui_down"
)
position += dir * speed * delta
position.x = wrapf(position.x, 0, screen_size.x)
position.y = wrapf(position.y, 0, screen_size.y)