Cocos中环形ScrollView的实现
大家好,今天是圣诞节,又是寒冷的一天。
在游戏开发中经常需要用到ScrollView去实现滚动的列表。
他通常包括垂直方向和水平方向两个选择。
本文将介绍一下ScrollView环形方向的实现。
本文源工程可在文末阅读原文获取,小伙伴们自行前往。
ScrollView(滚动视图组件)是一种用户界面元素,用于显示超过屏幕尺寸的内容,并允许用户在内容中进行滚动浏览。在游戏开发中,ScrollView通常用于处理大量的游戏界面元素,比如角色列表、道具列表等,这些内容可能超出屏幕可见区域。
我们接着来看看Cocos中的ScrollView
滚动视图组件。
我们仔细看下编辑器,ScrollView主要有以下可视选项:
Horizontal
和Vertical
,水平和垂直方向的支持,勾选后可开启该方向的滚动。
ScrollBar
,进度条,勾选了哪个方向的可以引用哪个方向的进度条。
Intertia
和Brake
,滚动惯性及系数,手停止滑动后,滚动列表继续滚动的惯性。
Elastic
和Duration
,回弹,触顶、触底后的回弹和系数。
Content
,可视内容的父节点。
CancelInnerEvents
,滚动过程阻断子节点的事件,防止误操作。
Events
,监听滚动相关的事件。
下面一起来看看环形ScrollView的原理
要实现环形滚动,即Item在圆周上运动,我们要先选择圆心和半径。
然后根据以下向量的模的计算公式,利用圆上的点到圆心的距离相等得出每个Item的x坐标。
设置的时机则是滚动事件的回调:
下面一起来实现环形ScrollView。
引擎版本:Cocos Creator 3.8.1
编程语言:TypeScript
为了有更好的节目效果,本期借用笔者游戏《填色之旅》中的资源(不吐槽节目组了)。
首先创建一个CircularScrollView
组件。
import { _decorator, CCFloat, Color, Component, Graphics, ScrollView, v3, Vec3 } from 'cc';
const { ccclass, property } = _decorator;
@ccclass('CircularScrollView')
export class CircularScrollView extends Component {
}
然后确定一下圆心和半径。
radius
,半径直接通过编辑器编辑,方便调整。centerPos
,圆心则是水平位移半径radius
的长度,往右为正,往左为负。@property({ type: CCFloat, tooltip: "环形半径" })
radius: number = 400;
scrollView: ScrollView;
centerPos: Vec3;
start() {
this.scrollView = this.getComponent(ScrollView);
if (this.scrollView) {
this.centerPos = v3(this.scrollView.node.worldPosition.x + this.radius, this.scrollView.node.worldPosition.y, 0);
}
}
根据监听ScrollView.EventType.SCROLLING
事件,遍历所有子Item,通过公式计算出他们对应的x坐标并设置:
this.scrollView.node.on(ScrollView.EventType.SCROLLING, this.updateItemPos, this);
updateItemPos() {
for (let i = 0; i < this.scrollView.content.children.length; i++) {
var child = this.scrollView.content.children[i];
var oldPos = child.worldPosition;
var newX = this.centerPos.x - Math.sign(this.radius) * Math.sqrt(Math.abs(this.radius * this.radius - (this.centerPos.y - oldPos.y) * (this.centerPos.y - oldPos.y)));
child.setWorldPosition(newX, oldPos.y, oldPos.z);
}
}
为了更好地展示效果,添加2个临时按钮去控制ScrollView环形的方向和辅助线的显示隐藏。
其中改变方向的核心代码,修改radius
,重新计算圆心,刷新:
changeDir() {
this.radius *= -1;
this.centerPos = v3(this.scrollView.node.worldPosition.x + this.radius, this.scrollView.node.worldPosition.y, 0);
this.updateItemPos();
this.onShowCircle(true);
}
其中辅助线通过Graphics
组件实现,包括圆心和圆周:
onShowCircle(onlyRefresh) {
var graphics = this.node.parent.getComponent(Graphics);
if (!graphics) {
graphics = this.node.parent.addComponent(Graphics);
graphics.enabled = false;
}
if (!onlyRefresh) {
graphics.enabled = !graphics.enabled;
}
graphics.clear();
graphics.lineWidth = 5;
graphics.strokeColor = Color.RED;
graphics.circle(this.centerPos.x - 640, this.centerPos.y - 360, Math.abs(this.radius));
graphics.stroke();
graphics.fillColor = Color.RED;
graphics.circle(this.centerPos.x - 640, this.centerPos.y - 360, 10);
graphics.fill();
}
向右环形滚动:
向左环形滚动:
辅助线:
整体效果:
本文源工程可通过私信CircularScrollView或者阅读原文付费获取。
在哪里可以看到如此清晰的思路,快跟上我的节奏!关注我,和我一起了解游戏行业最新动态,学习游戏开发技巧。
我是"亿元程序员",一位有着8年游戏行业经验的主程。在游戏开发中,希望能给到您帮助, 也希望通过您能帮助到大家。
AD:笔者线上的小游戏《贪吃蛇掌机经典》《重力迷宫球》《填色之旅》大家可以自行点击搜索体验。
实不相瞒,想要个赞和在看!请把该文章分享给你觉得有需要的其他小伙伴。谢谢!
推荐专栏: