在EDGE PROGRAM学习编程能开发游戏吗?

<!-- super cache不知道怎么开发VR游戏?【系列6】
招聘信息:
本文转自:,作者:王寒在本教程中我们将学习如何将产品在两个真机平台上进行测试-DK2和Gear VR。当然现在还有Oculus之外的其它VR设备平台,后续我们将会逐步支持更多推出消费版设备的VR硬件。配置到Oculus DK2上虽然我们可以在Unity中通过点击Play在DK2上测试项目,不过有时候我们还是希望可以在Unity之外测试项目,或者是发布产品。将项目配置到DK2上其实很简单。首先确保DK2可以正常工作,同时确保当前所选的平台是Standalone(参考本系列教程的第二篇文章)。接下来要检查游戏或应用的场景都在Scenes In Build中,然后点击Build and Run,Unity就会导出一个标准的windows.exe可执行文件,和一些支持文件夹。直接点击运行.exe文件,如果我们在项目中已经开启VR支持,就会在DK2上自动进入VR模式。如果运行.exe有问题,那么可能会需要手动强制运行VR模式。具体的方法是在命令行后面加上-vrmode在Unity指南的VR Overview部分有说明。我们可以考虑使用批处理文件,如下:BuildName.exe -vrmode oculus关于为DK2配置项目,Oculus有更详细的说明,将项目配置到Gear VR上如果想设置Gear VR的开发环境,我们需要同时设置Unity和手机。别忘了最新版的Gear VR只支持Samsung Galaxy S6,S6 Edge,S6 Edge+和Note 5。1.设置Unity用作Android开发[Unity – Manual: Android SDK Setup](Unity – Manual: Android SDK Setup)2.安装手机的USB驱动3.参考下面指南中的说明来启用手机上的developer settings,然后启用developer菜单的USB debugging最后,请参考Oculus 官方网站关于的详细说明。请注意,在Unity项目中需要创建一个Assets/Plugins/Android/assets/文件夹,以及提供相关的OSIG文件(),该文件将用作在Gear VR上发布内容。将应用发布到Oculus Store上为了将产品发布到Oculus Store上,可以查看Oculus 官网上的相关文件()。在Oculus Share上发布产品通过Oculus Share(Oculus Share),我们可以在社区内分享自己所开发的DK2 VR游戏和体验,并获取全世界用户的反馈。如果想把自己的作品发布到Oculus Share上,可以阅读相关的。此外,如果想讨论关于VR的任何话题,特别是VR开发相关的课题,不妨多去转转。
微信扫一扫
订阅每日移动开发及APP推广热点资讯公众号:CocoaChina
您还没有登录!请或
点击量18509点击量14681点击量13827点击量9781点击量8438点击量8037点击量7866点击量7575点击量6805
&2016 Chukong Technologies,Inc.
京公网安备892D多边形碰撞检测介绍这是一篇论证如何在2D动作游戏中执行碰撞检测的文章(Mario,宇宙入侵者等),为了保证它的高效性和精确性,碰撞检测是以多边形为基础的,而不是以sprite为基础。这是两种不同的设计途径。基于sprite的检测执行的是检测sprites的像素的交叉,以这种方式来检测碰撞。多边形是使用向量数学来精确的计算点,时间和碰撞的方向。当多边形只是一种近似sprite自身的时候,它就超越了sprite系统。表现出了更精确的物理现象,例如弹性,摩擦,在一个随机的形状中来处理斜坡。碰撞检测相对一个高速的sprite来讲是更加的精确的。在一个基于sprite的系统中,对象有可以在一个强力的跳跃中因为速度太快而相互穿越。这是一个基于向量数学的系统,所以可以扩展到3D,但是一个sprite碰撞系统被完全的限制到了2D中。特色:因为运算法则的限制,系统只能操作凸多边形,例如三角形,矩形,五边形,圆形。在一个非凸多边形中,你可以将这些多边形分成三角形来处理。无论是快速或者慢速的多边形,他的处理方式都是一样的。不管对象的移动有多快,碰撞也不会丢失的。他也可以来处理交叠,分开已经交叉的对象。里面的范例也有线段的交叉。这可以用来模拟子弹。它也提供了一些简单的物理系统,模拟弹力,一些基本的摩擦力和静摩擦力。在斜坡上的一些特性它也可以模拟。这里也有一个刚体系统的例子,引用的是Chrsi Hecker的物理文章。局限性:碰撞的种类,我的意思是它不能顺序的处理碰撞。在一个快速的对象中这可能会有问题。一旦一个碰撞被检测了,它便会直线的离开。你可以检测到第一个碰撞并处理它,然后再找到其他的碰撞。但是在一个2D的动作游戏中,这是很具有杀伤力的。必要条件:一些普通的原料,一个编译器,范例是基于GLUT(GL开发包)的框架,所以需要下载一个小的GLUT SDK和一个兼容opengl的显卡。你还需要对向量数学有一个基本的了解。这里的文章不准备对点乘进行讲解,但是它可以帮助你对向量的操作有更好的了解。对于刚体,你需要对Chris Hecker的文章仔细的阅读一下。它需要你付出更多,但是它是值得的,并不是多么的困难。内容列表:1:分离轴的方法2:扩展应用于碰撞反馈的分离轴的方法。分离轴的方法:这是碰撞检测的核心,原理是非常简单的,也非常的容易实现。它也是快速和稳定的,因为没有除法在运算中被使用。我将会带给大家一个简单的两个BOX碰撞测试的例子。
该运算法则试着来确定两个对象中的一个合适的面。如果有这样的一个面存在,如果有这样的面存在,说明对象是分离的,没有交叉。为了确定对象是否是分离的。只要将这个对象投影到这个平面的法线上,然后比较它们之间的间隔看他们是否交叉。所以,很明显有无数个边能够适合这两个分离的对象,但是已经证明你只要测试少数的几个面就可以了,对于上面图形中的两个BOX,你可以看到边的法线是形状B的边。从上面的这些形状中可以发现,那些即将被测试的分离面是两个BOX的边的法线。对于这两个BOX而言,你只需要测试4个分离的面。在这4个面中,一旦你发现一个分离面分隔了这两个BOX。你就可以知道了这两个BOX是分离的。然后返回一个没有碰撞的标记。如果这4个面没有分隔这两个BOX,那么这两个BOX肯定是交叉的,说明他们有一个碰撞。扩展到一般的多边形,该运算法则仍然是适用的。只不过是测试的边变化了。那些分离的面的法线是和每个多边形的边的垂直方向是平行的。在下面的图形中,你可以看到有两个分离面被测试。在红色的面被测试的时候,你可以看到那两个间隔是交叉的,但是在蓝色的被测试的时候,间隔并没有交叉。所有蓝色的面是分离面,对象因此是没有交叉的。
现在,我们有一个算法来检测两个多边形是否是相交的。代码可以分为三个部分:
a)&&&&&&&&&生成需要测试的分离轴
b)&&&&&&&&计算每一个多边形在分离轴法线上的投影
c)&&&&&&&&检测这些投影是否相交
bool Intersect(Polygon A, Polygon B){&&&&&for(I = 0; I & A.num_ I ++)&&&&&{&&&&&&&&&&&Vector N = Vector(-A.EdgeDir[I].y, A.EdgeDir[I].x);&&&&&&&&&&&if (AxisSeparatePolygons(N, A, B))&&&&&&&&&&&&&&&&&&&&&&&}&&&&&&&for(I = 0; I & B.num_ I ++)&&&&&&&{&&&&&&&&&&&&&Vector N = Vector(-B.EdgeDir[i].y, B.EdgeDir[I].x);&&&&&&&&&&&&&if (AxisSeparatePolygons (N, A, B))&&&&&&&&&&&&&&&&&&&&&&&&&&}&&&&&&&&}
void CalculateInterval(Vector Axis, Polygon P, float& min, float& max)&{&&&&&&&float d = Axis dot P.vertex[0];&&&&&&&min = max =&&&&&&&for(I = 0; I & P.num_ I ++)&&&&&&&{&&&&&&&&&&&&&float d = P.vertex[I] dot A&&&&&&&&&&&&&if (d & min)&&&&&&&&&&&&&&&&&&&min =&&&&&&&&&&&&&else&&&&&&&&&&&&&&&&&&&if(d & max)&&&&&&&&&&&&&&&&&&&&&&&&&max =&&&&&&&}&}
到这里,这个计算两个2D多边形碰撞的运算法则是非常快和稳定的。边的方向不一定是单位化的,所以你可以避免将边的方向都存储起来,你可以直接根据多边形的顶点来构建这些边的方向。
for(J = A.num_vertices-1, I = 0; I & A.num_ J = I, I ++)&{&&&&&&&Vector E = A.vertex[I] & A.vertex[J];&&&&&&&Vector N = Vector(-E.y, E.x);&&&&&&&if (AxisSeparatePolygons(N, A, B))&&&&&&&&&&&&&&}
扩展用于碰撞反馈的分离轴的方法:检测多边形是否碰撞是非常有用处的,但是我们可以做的更多。当多边形交叉后,我希望能够让多边形分离来制止他们交叉。分隔轴的方法还是要被用到的,通过作一个细微的额外工作。他能够返回他穿刺的深度和方向,并以此来分离它们。一个交叉的深度和方向的结合体也被称为MTD,或者是最小的转换距离。这个最小的向量需要让对象分离来制止他们交叉。我们可以借助于分离轴来计算MTD。当对象交叉的时候,我们知道了两个对象的交叉的每个分离轴的间隔距离。沿着这个轴的两个间隔的交叉的量提供了一个推进向量,你需要将其应用于这两个对象来让这些对象的投影来制止他们在这个轴上的交叉。
"推力向量"是一个向量,它的作用是你需要应用到A中以便制止他同B交叉。很明显,你不能让这个对象沿着一个随机的轴来分离。待选的这些轴中应该选择那个交叉的间隔最小的轴。这个推力向量提供了一个最小的转换的距离。
bool Intersect(Polygon A, Polygon B, Vector& MTD)&{&&&&&&&&// potential separation axes. they get converted into push&&&&&&&&vectors Vector Axis[32];&&&&&&&&// max of 16 vertices per polygon&&&&&&&&int iNumAxis = 0;&&&&&&&&for(J = A.num_vertices&1, I = 0; I & A. num_ J = I, I ++)&&&&&&&&{&&&&&&&&&&&&&&&Vector E = A.vertex[I] & A.vertex[J];&&&&&&&&&&&&&&&Axis[iNumAxis++] = Vector(-E.y, E.x);&&&&&&&&&&&&&&&if (AxisSeparatePolygons(N, A, B))&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&}&&&&&&&&for(J = B. num_vertices&1, I = 0; I & B.num_ J = I, I ++)&&&&&&&&{&&&&&&&&&&&&&&&Vector E = B.vertex[I] & B.vertex[J];&&&&&&&&&&&&&&&Axis[iNumAxis++] = Vector(-E.y, E.x);&&&&&&&&&&&&&&&&&&&&&&if (AxisSeparatePolygons (N, A, B))&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&}&&&&&&&&&&&&&&&// find the MTD among all the separation vectors&&&&&&&&MTD = FindMTD(Axis, iNumAxis);&&&&&&&&// makes sure the push vector is pushing A away from B&&&&&&&&Vector D = A.Position & B.P&&&&&&&&if (D dot MTD & 0.0f)&&&&&&&&&&&&&&&MTD = -MTD;&&&&&&&&&}
bool AxisSeparatePolygons(Vector& Axis, Polygon A, Polygon B)&{&&&&&&&&float mina,&&&&&&&&float minb,&&&&&&&&CalculateInterval(Axis, A, mina, maxa);&&&&&&&&CalculateInterval(Axis, B, minb, maxb);&&&&&&&&if (mina & maxb || minb & maxa)&&&&&&&&&&&&&&&&&&&&&&&// find the interval overlap&&&&&&&&float d0 = maxa -&&&&&&&&float d1 = maxb -&&&&&&&&float depth = (d0 & d1)? d0 : d1;&&&&&&&&// convert the separation axis into a push vector (re-normalise&&&&&&&&// the axis and multiply by interval overlap)&&&&&&&&float axis_length_squared = Axis dot A&&&&&&&&Axis *= depth / axis_length_&&&&&&&&&}
Vector FindMTD(Vector* PushVectors, int iNumVectors)&{&&&&&&&&Vector MTD = PushVector[0];&&&&&&&&float mind2 = PushVector[0] dot PushVector[0];&&&&&&&&for(int I = 1; I & iNumV I ++)&&&&&&&&{&&&&&&&&&&&&&&&float d2 = PushVector[I] * PushVector[I];&&&&&&&&&&&&&&&if (d2 & mind2)&&&&&&&&&&&&&&&{&&&&&&&&&&&&&&&&&&&&&&mind2 = d2;&&&&&&&&&&&&&&&&&&&&&&MTD = PushVector[I];&&&&&&&&&&&&&&&}&&&&&&&&}&&&&&&&&return MTD;&}
当对象交叉的情况下,你知道了MTD向量,分离他们就简单了。
A.Postion += MTD * 0.5f;B.Position -= MTD * 0.5f;
这只不过是一个投影数学。如果间隔是分离的,我们就需要计算一下这两个间隔接触的时间。比较一下那个"静态"的分离轴的计算方法,有一个额外的轴我们需要测试,这很明显是一个相对于位移向量(速度向量)的轴。所以对于每个分离轴,有三种选择。间隔重叠间隔分离,但是在未来的某个时间会重叠。间隔分离,但是在未来的某个时间不会重叠或者是碰撞的很晚。第3个选项的意思是对象不会在这帧上碰撞,分离轴真正的分离里这些对象。在这两个对象之间在这一帧上没有任何的碰撞。AxisSeparatePolygon()函数返回交叠的量或者碰撞的时间,为了区分这两种情况,当一个交叠被发现的时候,一个负数被返回,如果在将来一个碰撞被检测到了,一个整数被返回的,函数类似下列的函数:
bool AxisSeparatePolygons(Vector Axis, Polygon A, Polygon B, Vector Offset, Vector Vel, float& t, float tmax);
Offset是A和B的相对的位置,Vel是A和B的相对的速度。当找到碰撞面的时候,对于MTD是非常容易被找到的,但是对于在未来的某个时间的碰撞则优先于交叉的,如果碰撞在未来的某个时间被发现,最近一个会被选择。如果什么都没有发现,我只处理交叉,象以前那样,最小的交叠会被使用。碰撞计算的函数然后返回碰撞的法线,碰撞的深度(一个负数)或者碰撞的时间(一个正数)。最终的伪代码如下:
bool Collide(&&&&&const Vector* A, int Anum,&&&&&&&&&&&&&&&&&&&&&&&&&&&&&const Vector* B, int Bnum,&&&&&&&&&&&&&&&&&&&&&&&&&&&&&const Vector& xOffset, const Vector& xVel,&&&&&&&&&&&&&&&&&&&&&&&&&&&&&Vector& N, float& t)&{&&&&&&&&if (!A || !B)&&&&&&&&&&&&&&&&&&&&// All the separation axes&&&&&&&&// note : a maximum of 32 vertices per poly is supported&&&&&&&&Vector xAxis[64];&&&&&&&&float taxis[64];&&&&&&&&int iNumAxes=0;&&&&&&&&xAxis[iNumAxes] = Vector(-xVel.y, xVel.x);&&&&&&&&float fVel2 = xVel * xV&&&&&&&&if (fVel2 & 0.00001f)&&&&&&&&{&&&&&&&&&&&&&&&if (!IntervalIntersect( A, Anum, B, Bnum, xAxis[iNumAxes], xOffset, xVel, taxis[iNumAxes], t))&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&iNumAxes++;&&&&&&&&}&&&&&&&&// test separation axes of A&&&&&&&&for(int j = Anum-1, i = 0; i & A j = i, i ++)&&&&&&&&{&&&&&&&&&&&&&&&Vector E0 = A[j];&&&&&&&&&&&&&&&Vector E1 = A[i];&&&&&&&&&&&&&&&Vector E = E1 - E0;&&&&&&&&&&&&&&&xAxis[iNumAxes] = Vector(-E.y, E.x);&&&&&&&&&&&&&&&&&&&&&&&&&&&&&if (!IntervalIntersect( A, Anum, B, Bnum, xAxis[iNumAxes], xOffset, xVel, taxis[iNumAxes], t))&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&iNumAxes++;&&&&&&&&}&&&&&&&&// test separation axes of B&&&&&&&&for(int j = Bnum-1, i = 0; i & B j = i, i ++)&&&&&&&&{&&&&&&&&&&&&&&&Vector E0 = B[j];&&&&&&&&&&&&&&&Vector E1 = B[i];&&&&&&&&&&&&&&&Vector E = E1 - E0;&&&&&&&&&&&&&&&xAxis[iNumAxes] = Vector(-E.y, E.x);&&&&&&&&&&&&&&&if (!IntervalIntersect( A, Anum, B, Bnum, xAxis[iNumAxes], xOffset, xVel, taxis[iNumAxes], t))&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&iNumAxes++;&&&&&&&}&&&&&&&&&&&&&&if (!FindMTD(xAxis, taxis, iNumAxes, N, t))&&&&&&&&&&&&&&&&&&&&&&&// make sure the polygons gets pushed away from each other.&&&&&&&&if (N * xOffset & 0.0f)&&&&&&&&&&&&&&&N = -N;&&&&&&&&&}
bool AxisSeparatePolygons ( Vector N, Polygon A, Polygon B, Vector Offset, Vector Vel, float &t, float tmax)&{&&&&&&&&float min0, max0;&&&&&&&&float min1, max1;&&&&&&&&CalculateInterval(N, A, min0, max0);&&&&&&&&CalculateInterval(N, B, min1, max1);&&&&&&&&&&&&&&&float h = Offset dot N;&&&&&&&&min0 +=&&&&&&&&max0 +=&&&&&&&&float d0 = min0 - max1; // if overlapped, do & 0&&&&&&&&float d1 = min1 - max0; // if overlapped, d1 & 0&&&&&&&&// separated, test dynamic intervals&&&&&&&&if (d0 & 0.0f || d1 & 0.0f)&&&&&&&&{&&&&&&&&&&&&&&&float v = Vel dot N;&&&&&&&&&&&&&&&// small velocity, so only the overlap test will be relevant.&&&&&&&&&&&&&&&if (fabs(v) & 0.0000001f)&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&float t0 =-d0 / // time of impact to d0 reaches 0&&&&&&&&&&&&&&&float t1 = d1 / // time of impact to d0 reaches 1&&&&&&&&&&&&&&&// sort the times.&&&&&&&&&&&&&&&if (t0 & t1)&&&&&&&&&&&&&&&{&&&&&&&&&&&&&&&&&&&&&&float temp = t0;&&&&&&&&&&&&&&&&&&&&&&t0 = t1;&&&&&&&&&&&&&&&&&&&&&&t1 =&&&&&&&&&&&&&&&}&&&&&&&&&&&&&&&// take the minimum positive&&&&&&&&&&&&&&&taxis = (t0 & 0.0f)? t0 : t1;&&&&&&&&&&&&&&&// intersection time too late or back in time, no collision&&&&&&&&&&&&&&&if (taxis & 0.0f || taxis & tmax)&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&}&&&&&&&&else&&&&&&&&{&&&&&&&&&&&&&&&// overlap. get the interval, as a the smallest of |d0| and |d1|&&&&&&&&&&&&&&&// return negative number to mark it as an overlap&&&&&&&&&&&&&&&taxis = (d0 & d1)? d0 : d1;&&&&&&&&&&&&&&&&&&&&&&&}&}
bool FindCollisionPlane (Vector* Axis, float* taxis, int iNumAxes, Vector& Ncoll, float& tcoll)&{&&&&&&&&// find collision first&&&&&&&&int mini = -1;&&&&&&&&tcoll = 0.0f;&&&&&&&&for(int i = 0; i & iNumA i ++)&&&&&&&&{&&&&&&&&&&&&&&&if (taxis[i] & 0.0f)&&&&&&&&&&&&&&&{&&&&&&&&&&&&&&&&&&&&&&if (taxis[i] & tcoll)&&&&&&&&&&&&&&&&&&&&&&{&&&&&&&&&&&&&&&&&&&&&&&&&&&&&mini =&&&&&&&&&&&&&&&&&&&&&&&&&&&&&tcoll = taxis[i];&&&&&&&&&&&&&&&&&&&&&&&&&&&&&Ncoll = Axis[i];&&&&&&&&&&&&&&&&&&&&&&&&&&&&&Ncoll.Normalise(); // normalise axis&&&&&&&&&&&&&&&&&&&&&&}&&&&&&&&&&&&&&}&&&&&&&}&&&&&&&// found a collision&&&&&&&&if (mini != -1)&&&&&&&&&&&&&&&&&&&&&&&// nope, find overlaps&&&&&&&&mini = -1;&&&&&&&&for(int i = 0; i & iNumA i ++)&&&&&&&&{&&&&&&&&&&&&&&&float n = Axis[i].Normalise(); // axis length&&&&&&&&&&&&&&&taxis[i] /= // normalise interval overlap too&&&&&&&&&&&&&&&// remember, those numbers are negative, so take the closest to 0&&&&&&&&&&&&&&&if (mini == -1 || taxis[i] & tcoll)&&&&&&&&&&&&&&&{&&&&&&&&&&&&&&&&&&&&&&mini =&&&&&&&&&&&&&&&&&&&&&&tcoll = taxis[i];&&&&&&&&&&&&&&&&&&&&&&Ncoll = Axis[i];&&&&&&&&&&&&&&&}&&&&&&&&}&&&&&&&&&&&&&&&return (mini != -1);&}
这就是全部了,一个检测多边形的碰撞的系统返回一个未来的时间或者是当交叉的时候返回那个碰撞的面。
阅读(...) 评论()surface Pro4适合游戏开发吗_百度知道
surface Pro4适合游戏开发吗
我有更好的答案
适合的,它配备了性能强劲的第
6 代英特尔&#174;酷睿&#8482; i5 和酷睿&#8482; i7 处理器,可提供长达12小时的电池续航时间,其 13.5英寸光学显示屏,集合 PixelSense 技术,能够提供高达
267dpi的像素显示,改进画面延迟和视差,使其不但有着更清晰的显示效果,更能带来自然且流畅的书写体验。显示屏还可以与键盘分离,像纸质的笔记本一样单独使用,它可以用于素描和记录笔记,更可以在如 Microsoft
Edge这样的程序上直接使用。此外,还有独立的 GPU 可供选择,帮助充分利用硬件加速技术处理图像,更好地用于无缝视频编辑,快速图形渲染或体验身临其境的游戏。
它配备了性能强劲的第 6 代英特尔&#174;酷睿&#8482; i5 和酷睿&#8482; i7 处理器,可提供长达12小时的电池续航时间,其 13.5英寸光学显示屏,集合 PixelSense 技术,能够提供高达 267dpi的像素显示,改进画面延迟和视差,使其不但有着更清晰的显
为您推荐:
其他类似问题
您可能关注的内容
&#xe675;换一换
回答问题,赢新手礼包&#xe6b9;
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。& 使用VB.Net GDI+编程编写的3D魔方游戏程序
使用VB.Net GDI+编程编写的3D魔方游戏程序
最近学习了.net下的GDI+编程,下面小秀一下成果,使用GDI+编写的桌面魔方程序,今天把放上,欢迎大家下载,如果机器上有.net环境的话可以直接运行bin目录下的MagicCube.exe进行游戏。
下面方式几个重要的算法程序
1,魔方正面九宫格90度翻转,这个只要细心观察翻转前和翻转后的魔方,你就可以得到答案
左转90度:以(0,0)(2,2)为对称轴翻转后,再以(1,0)(1,2)为对称轴翻转
右转90度:以(0,2)(2,0)为对称轴翻转后,再以(1,0)(1,2)为对称轴翻转
算法如下:
'正方形数据交换
Private Sub RevertRectangleLeft(ByVal id As Integer)
'要实现左转90度
'先对角线转置
Dim i, j As Integer
For i = 1 To Me.DIMCOUNT - 1
For j = 0 To i - 1
Dim temp As Integer
temp = Me.Matrix3D(id)(i)(j)
Me.Matrix3D(id)(i)(j) = Me.Matrix3D(id)(j)(i)
Me.Matrix3D(id)(j)(i) = temp
''后水平翻转
For i = 0 To Me.DIMCOUNT - 1
Dim temp As Integer
temp = Me.Matrix3D(id)(0)(i)
Me.Matrix3D(id)(0)(i) = Me.Matrix3D(id)(Me.DIMCOUNT - 1)(i)
Me.Matrix3D(id)(Me.DIMCOUNT - 1)(i) = temp
'正方形数据交换
Private Sub RevertRectangleRight(ByVal id As Integer)
'要实现右转90度
'先对角线转置
Dim i, j As Integer
For i = 0 To Me.DIMCOUNT - 1
For j = 0 To Me.DIMCOUNT - 1 - i - 1
Dim temp As Integer
temp = Me.Matrix3D(id)(i)(j)
Me.Matrix3D(id)(i)(j) = Me.Matrix3D(id)(Me.DIMCOUNT - 1 - j)(Me.DIMCOUNT - 1 - i)
Me.Matrix3D(id)(Me.DIMCOUNT - 1 - j)(Me.DIMCOUNT - 1 - i) = temp
''后水平翻转
For i = 0 To Me.DIMCOUNT - 1
Dim temp As Integer
temp = Me.Matrix3D(id)(0)(i)
Me.Matrix3D(id)(0)(i) = Me.Matrix3D(id)(Me.DIMCOUNT - 1)(i)
Me.Matrix3D(id)(Me.DIMCOUNT - 1)(i) = temp
2,魔方正面的4个侧面的翻转,这个实现相对较难,方法也很多,CG这里使用了队列保存所有方块信息,然后再次存回数组的方式来实现,另外为了统一方向,CG使用了面相交边的参数来控制队列的进出,实现比较复杂,但是可以节省很多控件,如果大家有好的方法,欢迎分享
''' &summary&
''' 初始化各个面对应的边
''' &/summary&
''' &remarks&&/remarks&
Private Sub InitEdge()
'+/- 10 + 100 + 1000 + X 用于记录对应变的交换方式
'+/- 表示交换方式,顺序和逆序
'10 表示 x 的位置 x = 0 或 x = DIMCOUNT
'100 表示 y 的位置 y = 0 或 y = DIMCOUNT
'1000 表示 xy的方向 =0 y++ =1000 x++
Edge(0) = New Integer(3) {-12, 101, 1003, -1004}
Edge(1) = New Integer(3) {-1002, -1005, -1003, -1000}
Edge(2) = New Integer(3) {-15, 1, 0, 4}
Edge(3) = New Integer(3) {-10, -11, 5, -14}
Edge(4) = New Integer(3) {, }
Edge(5) = New Integer(3) {-13, -04}
''' &summary&
''' 边数据交换
''' &/summary&
''' &param name=&id&&&/param&
''' &remarks&&/remarks&
Private Sub RevertEdgeRight(ByVal id As Integer)
'获取边数据
Dim edges() As Integer
edges = Me.Edge(id)
Dim x, y, z, d As Integer
'临时队列数组
Dim queue() As Integer
queue = New Integer(4 * DIMCOUNT - 1) {}
Dim edge1 As Integer
Dim m, i, j As Integer
Dim count As Integer = 0
'存入临时数组
For m = 0 To 3
'需要交换边
edge1 = edges(m)
'获取交换行号与列号
If Math.Floor(Math.Abs(edge1 / 1000)) = 1 Then
edge1 = edge1 Mod 1000
If Math.Floor(Math.Abs(edge1 / 100)) = 1 Then
y = DIMCOUNT - 1
edge1 = edge1 Mod 100
If Math.Floor(Math.Abs(edge1 / 10)) = 1 Then
x = DIMCOUNT - 1
edge1 = edge1 Mod 10
Dim sg = Math.Sign(edge1)
If sg = 0 Then
If sg = 1 Then
'存入临时数组
For i = 0 To DIMCOUNT - 1
If z = 0 Then
queue(m * DIMCOUNT + i) = _
Me.Matrix3D(Math.Abs(edge1))(x)(d * (DIMCOUNT - 1) + sg * i)
queue(m * DIMCOUNT + i) = _
Me.Matrix3D(Math.Abs(edge1))(d * (DIMCOUNT - 1) + sg * i)(y)
'交换后存回
'存入临时数组
For m = 0 To 3
'需要交换边
edge1 = edges(m)
'获取交换行号与列号
If Math.Floor(Math.Abs(edge1 / 1000)) = 1 Then
edge1 = edge1 Mod 1000
If Math.Floor(Math.Abs(edge1 / 100)) = 1 Then
y = DIMCOUNT - 1
edge1 = edge1 Mod 100
If Math.Floor(Math.Abs(edge1 / 10)) = 1 Then
x = DIMCOUNT - 1
edge1 = edge1 Mod 10
Dim sg = Math.Sign(edge1)
If sg = 0 Then
Math.Sign(edge1) == 1 ? 0 : -1
If sg = 1 Then
For i = 0 To DIMCOUNT - 1
If z = 0 Then
Me.Matrix3D(Math.Abs(edge1))(x)(d * (DIMCOUNT - 1) + sg * i) = _
queue(((1 + m) Mod 4) * DIMCOUNT + i)
Me.Matrix3D(Math.Abs(edge1))(d * (DIMCOUNT - 1) + sg * i)(y) = _
queue(((1 + m) Mod 4) * DIMCOUNT + i)
3,绘制菱形,简单的点到点数组
''' &summary&
''' 增加菱形,用于魔方侧面
''' &/summary&
''' &remarks&&/remarks&
Private Sub AddPolygons()
'定义点阵数组
Dim pts() As PointF
'绘制上边矩形
Dim i, j As Integer
For i = 0 To DIMCOUNT - 1
For j = 0 To DIMCOUNT - 1
pts = AddPolygonPath1(New Point(POSTION.X + i * CUBEH + j * POLYH, _
POSTION.Y - j * POLYH))
'获取填充内容,并绘制
GR.FillPolygon(Me.GetColorById(2, DIMCOUNT - 1 - j, i), pts)
GR.DrawPolygon(OUTLINE, pts)
'绘制左边矩形
For i = 0 To DIMCOUNT - 1
For j = 0 To DIMCOUNT - 1
pts = AddPolygonPath2(New Point(POSTION.X + DIMCOUNT * CUBEH + i * POLYH, _
POSTION.Y + j * CUBEH - i * POLYH))
'获取填充内容,并绘制
GR.FillPolygon(Me.GetColorById(4, j, i), pts)
GR.DrawPolygon(OUTLINE, pts)
''' &summary&
''' 绘制横向菱形,通过起点参数,获取菱形四个定点坐标
''' &/summary&
''' &remarks&&/remarks&
Private Function AddPolygonPath1(ByVal pt As Point) As PointF()
Dim pts(3) As PointF
pts(0) = pt
pts(1) = New Point(pt.X + POLYH, pt.Y - POLYH)
pts(2) = New Point(pt.X + CUBEH + POLYH, pt.Y - POLYH)
pts(3) = New Point(pt.X + CUBEH, pt.Y)
Return pts
End Function
''' &summary&
''' 绘制在竖向菱形,通过起点参数,获取菱形四个定点坐标
''' &/summary&
''' &param name=&pt&&&/param&
''' &remarks&&/remarks&
Private Function AddPolygonPath2(ByVal pt As Point) As PointF()
Dim pts(3) As PointF
pts(0) = pt
pts(1) = New Point(pt.X + POLYH, pt.Y - POLYH)
pts(2) = New Point(pt.X + POLYH, pt.Y + CUBEH - POLYH)
pts(3) = New Point(pt.X, pt.Y + CUBEH)
Return pts
End Function
下面是演示效果
Categories:
推荐阅读:
Recent Posts
Random Post

我要回帖

 

随机推荐