我报名参加金石计划1期挑战——瓜分10万奖池,这是我的第1篇文章,点击查看活动详情
下面是Phaser知识点大致结构,后面会针对每个知识点出一些相关的教程。
由于phaser的官方文档并没有中文,准备开始更新一系列Phaser的教程,每篇文章都会涉及一个大的知识点,本篇主要是介绍了phaser的图形学,比如说绘制一些图形,路径,包括物体沿着路径或者图形运动。本篇会尽量介绍相关api,英文好的同学可以直接看官方文档。
Phaser绘制图形Graphics
线段
phaser绘制图形第一步都是先创建画笔(后面不在声明):
const graphics = this.add.graphics();
基础方法
绘制线段一般常用两个个方法:
- moveTo(x,y):抬起画笔放在x,y点
- moveTo(x, y):移动画笔绘制至x,y点
drawLine() {
const graphics = this.add.graphics();
graphics.lineStyle(2, 0xFF00FF, 1.0);
graphics.moveTo(100, 100);
graphics.lineTo(200, 200);
graphics.moveTo(200, 100);
graphics.lineTo(300, 200);
graphics.strokePath();
}
- lineStyle(width, color, alpha):设置线段样式
- strokePath():绘制路径,要先设置线段样式
- fill():填充绘制的路径,前提是绘制所有的线段可以闭合成一个封闭图形
- fillStyle(coor, alpha):设置填充样式,和fill()一起使用
graphics.fillStyle(0xffccee, 1);
graphics.moveTo(400, 300);
graphics.lineTo(500, 300);
graphics.lineTo(500, 400);
graphics.lineTo(400, 400);
graphics.fill();
如果需要你绘制的线段闭合,则需要使用下面两个方法:
- beginPath():开始一个新的路径
- closePath():闭合一个路径,前提是绘制的线段可以闭合一个封闭图形,需要闭合多个路径则需要调用多次
不使用:
使用:
const graphics = this.add.graphics();
graphics.beginPath();
graphics.lineStyle(2, 0xFF00FF, 1.0);
graphics.moveTo(100, 100);
graphics.lineTo(200, 200);
graphics.moveTo(200, 100);
graphics.lineTo(300, 200);
graphics.lineTo(300, 300);
graphics.closePath();
graphics.strokePath();
根据点集合绘制线段
strokePoints([points], closeShape, closePath, endPointIndex)
- points: 一系列点的数组
- closeShape:是否链接最后一个点和第一个点
- closePath:是否关闭路径
- endPointIndex:结束点的的索引,注意是从1开始
const graphics = this.add.graphics();
graphics.lineStyle(2, 0xFF00FF, 1.0);
const p1 = new Phaser.Geom.Point(100, 10)
const p2 = new Phaser.Geom.Point(200, 10)
const p3 = new Phaser.Geom.Point(200, 100)
const p4 = new Phaser.Geom.Point(100, 200)
// 从第三个点结束并关闭路径
graphics.strokePoints([p1, p2, p3, p4], true, true, 3);
- new Phaser.Geom.Point(x, y) :创建一个点
两点绘制线段
- graphics.lineBetween(x1, y1, x2, y2):在x1,y1 和x2,y2两个点绘制一条线段
根据已有的线段绘制
- new Phaser.Geom.Line(x1, y1, x2, y2):生成一条线段
- graphics.strokeLineShape(line):绘制出这条线段
注意:Geom提供的方法只是简单生成一个图形对象,并不会显示出来
绘制基本图形
矩形
- graphics.strokeRect(x, y, width, height):绘制一个矩形
- graphics.fillRect(x, y, width, height):填充一个矩形
graphics.strokeRect(100, 100, 200, 100)
graphics.fillRect(320, 100, 200, 100);
- graphics.strokeRectShape(rect1): 根据已有的矩形对象绘制
- graphics.fillRectShape(rect2): 根据已有的矩形对象填充绘制
- new Phaser.Geom.Rectangle(x, y, width, height):创建一个矩形对象
const rect1 = new Phaser.Geom.Rectangle(100, 100, 200, 100);
const rect2 = new Phaser.Geom.Rectangle(320, 100, 200, 100);
graphics.strokeRectShape(rect1)
graphics.fillRectShape(rect2)
圆形
- graphics.strokeCircle(x, y, radius):绘制一个圆形
- graphics.fillCircle(x, y, radius):填充一个圆形
- graphics.strokeCircleShape(c1): 根据已有的圆形对象绘制
- graphics.fillCircleShape(c2): 根据已有的圆形对象填充绘制
- new Phaser.Geom.Circle(x, y, radius):创建一个圆形对象
const c1 = new Phaser.Geom.Circle(100, 100, 50);
const c2 = new Phaser.Geom.Circle(200, 100, 50);
graphics.strokeCircleShape(c1)
graphics.fillCircleShape(c2)
椭圆
graphics.strokeEllipse(x, y, width, height, smooth):绘制一个椭圆
graphics.fillEllipse(x, y, width, height, smooth):填充一个椭圆
- x,y:椭圆中心点坐标
- width、height:椭圆宽高
- smooth:椭圆平滑程度,越大越平滑
graphics.strokeEllipse(200, 200, 200, 100, 50);
graphics.fillEllipse(400, 200, 200, 100, 50);
- graphics.strokeEllipseShape(el1, smooth):根据已有的椭圆对象绘制
- graphics.fillEllipseShape(el2, smooth): 根据已有的椭圆对象填充绘制
- new Phaser.Geom.Ellipse(x, y, width, height):创建一个椭圆对象
const el1 = new Phaser.Geom.Ellipse(200, 200, 200, 100);
const el2 = new Phaser.Geom.Ellipse(400, 200, 200, 100);
graphics.strokeEllipseShape(el1, 50);
graphics.fillEllipseShape(el2, 50);
三角形
- graphics.strokeTriangle(x1, y1, x2, y2, x3, y3):绘制一个三角形
- graphics.fillTriangle(x1, y1, x2, y2, x3, y3):填充一个三角形
- graphics.strokeTriangleShape(el1, smooth):根据已有的三角形对象绘制
- graphics.fillTriangleShape(el2, smooth): 根据已有的三角形对象填充绘制
- new Phaser.Geom.Triangle(x, y, width, height):创建一个三角形对象
const t1 = new Phaser.Geom.Triangle(100, 100, 100, 200, 250, 200);
const t2 = new Phaser.Geom.Triangle(300, 100, 300, 200, 450, 200);
graphics.strokeTriangleShape(t1)
graphics.fillTriangleShape(t2)
Phaser生成图形Geom
Geom和Graphics区别是,Graphics在场景绘制出来一个图形,Geom是生成一个图形对象,但是并不会在场景显示出来,通过调用Graphics相关方法,才会绘制出来。
线段
Phaser.Geom.Line(x1, y1, x2, y2)
以x1,y1为起点,x2,y2为终点绘制一条直线
const l1 = new Phaser.Geom.Line(100, 100, 300, 100);
graphics.strokeLineShape(l1);
getPoint(percent, point)
返回一条直线上面的一个点
- percent(0-1):线段上面这个点的位置,占线段的百分比
- point:可选填,Phaser.Geom.Point类型,point就是这个点的详细信息
const l1 = new Phaser.Geom.Line(100, 100, 300, 100);
const p = new Phaser.Geom.Point();
l1.getPoint(0.5, p)
console.log(p) // Point {type: 3, x: 200, y: 100}
console.log( l1.getPoint(0.5)); // Point {type: 3, x: 200, y: 100}
getRandomPoint(point)
返回一条直线上面随机的一个点
- point:可选填,Phaser.Geom.Point类型,point就是这个点的详细信息(后面就不继续介绍这个方法,用的很少,一般都是通过方法返回值获取,文档上面的output<Point>,就是这种方法。)
const l1 = new Phaser.Geom.Line(100, 100, 300, 100);
const p = new Phaser.Geom.Point();
console.log(l1.getRandomPoint()); // Point {type: 3, x: 289.67964897625933, y: 100}
l1.getRandomPoint(p)
console.log(p); // Point {type: 3, x: 269.25010800121356, y: 100}
getPoints(quantity, stepRate)
返回构成这条线段的点数组
- quantity:返回多少个点,值越大,获取的点越多
- stepRate:每个点之间的间距,需要设置quantity为0
const l1 = new Phaser.Geom.Line(100, 100, 300, 100);
console.log(l1.getPoints(2)) // [Point, Point]
console.log(l1.getPoints(0, 50)) // [Point, Point, Point, Point]
getPointA()、getPointB()
返回这条线段起始点和结束点的向量
const l1 = new Phaser.Geom.Line(100, 100, 300, 100);
console.log(l1.getPointA()); // Vector2 {x: 100, y: 100}
console.log(l1.getPointB()); // Vector2 {x: 300, y: 100}
注意:向量和点坐标是不同的类型,向量有方向
setTo(x1, y1, x2, y2);
生成一个新的线段
const l1 = new Phaser.Geom.Line(100, 100, 300, 100);
graphics.strokeLineShape(l1);
setTimeout(() => {
l1.setTo(100, 200, 400, 200);
graphics.strokeLineShape(l1)
}, 2000)
下面的方法都是静态方法
CenterOn(line, x, y)
以为x,y为中心点生成一个新的线段,线段的长度是line的长度,这个新的线段平行line
const l1 = new Phaser.Geom.Line(100, 100, 300, 100);
graphics.strokeLineShape(l1);
const l2 = Phaser.Geom.Line.CenterOn(l1, 300, 150)
console.log(l2);
graphics.strokeLineShape(l2)
Clone(line)
克隆一条线段
Equals(l1, l2)
判断l1是否等于l2
Extend(line, left, right)
向左或者向右延长线段,返回延长后的线段
- left和right是number类型
GetMidPoint(line)
获取给定直线的中点
GetNearestPoint(line, point)
返回line上一个点,这个点和point连线垂直于line
const l1 = new Phaser.Geom.Line(100, 100, 300, 120);
graphics.strokeLineShape(l1);
const p = new Phaser.Geom.Point(120, 150)
graphics.fillPointShape(p, 10)
const p2 = Phaser.Geom.Line.GetNearestPoint(l1, p)
graphics.fillPointShape(p2, 10)
graphics.strokeLineShape(new Phaser.Geom.Line(p.x, p.y, p2.x, p2.y))
GetShortestDistance(line, point)
返回这个point到line的最短距离
const p = new Phaser.Geom.Point(120, 150)
console.log(Phaser.Geom.Line.GetShortestDistance(l1, p)); // 50
Length(line)、Height(line)
获取这个线段的长度和高度
console.log(Phaser.Geom.Line.Length(l1)); // 200
console.log(Phaser.Geom.Line.Height(l1)); // 0
NormalAngle(line)
获取这个线段的弧度
Slope(line)
获取这个线段的斜率
ReflectAngle(lineA, lineB)
返回两个线段之间的角度
RotateAroundPoint(line, point, angle)
line围绕point点旋转angle弧度,返回一条新的线段,不影响旧的
const p = new Phaser.Geom.Point(200, 150);
graphics.fillPointShape(p, 10)
const l2 = Phaser.Geom.Line.RotateAroundPoint(l1, p, Math.PI / 2);
graphics.strokeLineShape(l2);
RotateAroundXY(line, x, y, angle)
line围绕x,y点旋转angle弧度,返回一条新的线段,不影响旧的
Line所有api地址
点
Phaser.Geom.Point(x, y)
创建一个点对象
p.setTo(x, y);
根据p创建一个点新的对象
Ceil(point)、Floor(point)
对point的x,y向上、下取整,并且返回一个新的点
Clone(point)、Equals(p1, p2)
同上面线段方法
GetCentroid(points)
返回由points集合创建图形的几何中心
const p = new Phaser.Geom.Point(200, 150);
const p2 = new Phaser.Geom.Point(280, 190);
const p3 = new Phaser.Geom.Point(130, 160);
const p4 = new Phaser.Geom.Point(220, 90);
graphics.fillPointShape(p, 5)
graphics.fillPointShape(p2, 5)
graphics.fillPointShape(p3, 5)
graphics.fillPointShape(p4, 5)
const sp = Phaser.Geom.Point.GetCentroid([p, p2, p3, p4]);
graphics.fillStyle(0xff0000);
graphics.fillPointShape(sp, 5)
GetMagnitude(point)、GetMagnitudeSq(point)
获取点到原点的距离、距离平方
GetRectangleFromPoints(points)
创建一个矩形,将这些点包含进来
Interpolate(pointA, pointB, t)
在A、B之间插入一个点,点的位置和插值t(0<t<1)有关,返回这个点
Invert(point)
交换point的x、y的值,返回一个新的点
Negative(point)
反转point的x、y的值,返回一个新的点
矩形、三角形、圆形、椭圆
矩形 Phaser.Geom.Rectangle(x, y, width, height)
三角形 Phaser.Geom.Triangle(x, y, x1, y1, x2, y2)
圆形 Phaser.Geom.Circle(x, y, x1, r)
椭圆 Phaser.Geom.Ellipse(x, y, width, height)
contains(x, y)
判断图形是否包含x,y点
getLineA()、getLineB()、getLineC()、getLineD()
获取矩形四个边、三角形三个边
getPoints(quantity, stepRate)
获取构建图形的所有点
- quantity:返回多少个点,值越大,获取的点越多
- stepRate:每个点之间的间距,需要设置quantity为0
getRandomPoint()
获取图形内随机一个点
isEmpty()
矩形宽高有一个小于等于0返回true
setEmpty()
将宽高位置重置为0
Area()
计算面积
Contains(rect、triangle,x,y)
判断矩形或者三角形的边界是否包含x,y点
GetCenter(rect)
获取矩形中心点
封闭图形api基本都差不多,基本常用的就这几个,后面用到新的在介绍。
多边形 Polygon
Phaser.Geom.Polygon([x1,y1,x2,y2,x3,y3....]);
Phaser.Geom.Polygon([point1, point2....]);
绘制多边形
const plo = new Phaser.Geom.Polygon([100, 20, 150, 80, 350, 50, 80, 120]);
const p1 = new Phaser.Geom.Point(100, 120);
const p2 = new Phaser.Geom.Point(150, 180);
const p3 = new Phaser.Geom.Point(350, 150);
const p4 = new Phaser.Geom.Point(80, 220);
const plo2 = new Phaser.Geom.Polygon([p1, p2, p3, p4]);
graphics.fillPoints(plo.points, true);
graphics.strokePoints(plo2.points, true);
points()
返回构成多边形的顶点集合
area()
返回多边形的面积
contains(x, y)
判断多边形是否包含点x,y
getPoints(quantity, stepRate)
返回构成多边形的点的集合,参数意义同上其它简单几何图形
GetAABB(plo)
返回一个矩形,将这个多边形包住
GetNumberArray(plo)
返回扁平化后的顶点坐标
Perimeter(plo)
返回周长
Smooth(plo)
返回更平滑的多边形
phaser的图形绘制就介绍到这里了,更全的文档可以去查看官方文档提供的api,后面文章会陆续介绍如何制作动画,摄像机相关,物理引擎相关等。