Egret(白鹭引擎) 入门
2023-01-05 本文已影响0人
brave_wu
入门首先看文档,然后是一些攻略,当然不可避免的还是碰到一些坑,我习惯首先自己想办法,实在不行请教大神,最后一步步学习开发第一个小游戏,以下是一些干货(代码)。
1.egret build 遇到http://localhost/打不开
我是按照文档一步步新建了个HelloWorld项目,但是就是build后在浏览器中打不开,此前不知道什么原因,但是看了新手入门文章知道了可以自己启动一个http服务,特别是Mac OS X自带了Apache,就按照web项目的方法启动了服务,并把egret build编译的东西放到
/资源库/WebServer/Documents/
目录下面,果然曲线救国了。
请教大神才知道实际上是端口和新编译模式的问题,解决办法:
第一步 动态端口号
//./launch.json 没有就新建
{
"configurations": [
{
"type": "Egret",
"request": "launch",
"name": "Egret Debugger",
"url": "http://localhost:${command:WebsitePort}",
"webRoot": "${workspaceFolder}",
"sourceMaps": true,
"userDataDir": "${tmpdir}",
"preLaunchTask": "egret: build"
}
],
"version": "0.2.0"
}
第二步 把新编译改为普通编译
// ./scripts/config.ts
if (command == 'build') {
const outputDir = 'bin-debug';
return {
outputDir,
commands: [
// new EmitResConfigFilePlugin({
// output: "resource/default.res.json",
// typeSelector: config.typeSelector,
// nameSelector: p => path.basename(p).replace(/\./gi, "_"),
// groupSelector: p => "preload"
// }),
new ExmlPlugin('debug'), // 非 EUI 项目关闭此设置
new IncrementCompilePlugin(),
]
}
}
2.显示对象和显示容器
了解添加显示对像,以及显示对象的坐标、锚点等
var shape: egret.Shape = new egret.Shape();
// shape.scaleX = 0.5;
// shape.scaleY = 0.5;
// shape.alpha = 0.5;
// shape.rotation = 30;
// shape.visible = true;
shape.graphics.beginFill(0x00ff00);
shape.graphics.drawRect(50, 0, 100, 100);
shape.graphics.endFill();
//锚点偏移
shape.anchorOffsetX = 100;
shape.x = 50;
shape.y = 175;
this.addChild(shape);
//文本
var txInfo: egret.TextField = new egret.TextField();
txInfo = new egret.TextField();
this.addChild(txInfo);
txInfo.text = "2222221";
txInfo.size = 28;
txInfo.x = 0;
txInfo.y = 150;
txInfo.textAlign = egret.HorizontalAlign.LEFT;
txInfo.textColor = 0x000000;
txInfo.type = egret.TextFieldType.DYNAMIC;
txInfo.lineSpacing = 6;
txInfo.multiline = true;
//自定义
const _mycell: MyCell = new MyCell();
this.addChild(_mycell);
//相对坐标
let offsetx: number;
let offsety: number;
const container: egret.DisplayObjectContainer =
new egret.DisplayObjectContainer();
container.x = 50;
container.y = 50;
this.addChild(container);
//画个圆
const circle: egret.Shape = new egret.Shape();
circle.graphics.beginFill(0xff0000);
circle.graphics.drawCircle(75, 75, 25);
circle.graphics.endFill();
container.addChild(circle);
显示对象可以添加事件
//添加点击事件
circle.touchEnabled = true;
circle.addEventListener(egret.TouchEvent.TOUCH_TAP, on_click, this);
circle.addEventListener(egret.TouchEvent.TOUCH_BEGIN, starMove, this);
circle.addEventListener(egret.TouchEvent.TOUCH_END, endMove, this);
function on_click(): void {
const targetPoint: egret.Point = container.globalToLocal(0, 0);
circle.x = targetPoint.x;
circle.y = targetPoint.y;
}
function starMove(e: egret.TouchEvent): void {
offsetx = e.stageX - circle.x;
offsety = e.stageY - circle.y;
//手指在屏幕上移动,会触发 onMove 方法
this.stage.addEventListener(egret.TouchEvent.TOUCH_MOVE, onMove, this);
}
function endMove(e: egret.TouchEvent): void {
//手指离开屏幕,移除手指移动的监听
this.stage.removeEventListener(egret.TouchEvent.TOUCH_MOVE, onMove, this);
}
function onMove(e: egret.TouchEvent): void {
//通过计算手指在屏幕上的位置,计算当前对象的坐标,达到跟随手指移动的效果
circle.x = e.stageX - offsetx;
circle.y = e.stageY - offsety;
}
可以把显示对象从显示列表里删除、更换层级,还可以获取显示对象
//删除显示
var mySprite: egret.Sprite = new egret.Sprite();
mySprite.graphics.beginFill(0x0000ff);
mySprite.graphics.drawRect(10, 200, 100, 100);
mySprite.graphics.endFill();
this.addChild(mySprite);
if (mySprite.parent) {
mySprite.parent.removeChild(mySprite);
}
//层级
this.addChildAt(mySprite, this.numChildren - 4);
this.removeChildAt(this.numChildren - 4);
this.removeChildren();
this.addChild(shape);
this.addChild(mySprite);
//层级互换
this.swapChildren(shape, mySprite);
//设置层级
this.setChildIndex(mySprite, this.numChildren);
//名字
mySprite.name = "my";
const spr: egret.DisplayObject = this.getChildByName("my");
spr.alpha = 0.6;
//推荐
this.addChild(_mycell);
const spr1: egret.DisplayObject = this.getChildAt(2);
spr1.alpha = 0.5;
this.removeChildren();
//zIndex
let superView = new egret.Sprite();
superView.sortableChildren = true; //注意,一定要设置为true
this.addChild(superView);
let b1 = new egret.Shape();
b1.graphics.beginFill(0x00ff00);
b1.graphics.drawRect(0, 0, 200, 100);
b1.graphics.endFill();
b1.x = 0;
superView.addChild(b1);
let b2 = new egret.Shape();
b2.graphics.beginFill(0xff0000);
b2.graphics.drawRect(0, 20, 200, 100);
b2.graphics.endFill();
b2.x = 70;
superView.addChild(b2);
let b3 = new egret.Shape();
b3.graphics.lineStyle(10, 0xff0000);
b3.graphics.beginFill(0x0000ff);
b3.graphics.drawRect(0, 40, 200, 100);
b3.graphics.endFill();
b3.x = 140;
superView.addChild(b3);
//设置到顶部
b1.zIndex = 3;
绘图、遮罩、富文本
//贝塞尔曲线
let b4 = new egret.Shape();
b4.graphics.lineStyle(2, 0xff0000);
b4.graphics.moveTo(50, 200);
b4.graphics.curveTo(100, 300, 300, 200);
b4.graphics.endFill();
superView.addChild(b4);
//圆弧
let b5 = new egret.Shape();
// b5.graphics.beginFill(0xff0000);
b5.graphics.lineStyle(3, 0xff0000);
b5.graphics.drawArc(100, 400, 100, 0, 1.5 * Math.PI, false);
b5.graphics.endFill();
superView.addChild(b5);
//遮罩
let b6 = new egret.Shape();
b6.graphics.beginFill(0xff0000);
b6.graphics.drawCircle(50, 50, 50);
b6.graphics.endFill();
b6.x = 0;
superView.addChild(b6);
b6.zIndex = 4;
const rect: egret.Rectangle = new egret.Rectangle(0, 0, 100, 100);
b1.mask = rect;
//文本
this.removeChildren();
this.addChild(txInfo);
// txInfo.type = egret.TextFieldType.INPUT;
// txInfo.inputType = egret.TextFieldInputType.PASSWORD;
txInfo.fontFamily = "Impact";
txInfo.strokeColor = 0xff0000;
txInfo.stroke = 2;
txInfo.text = "1 2 3 4 5";
txInfo.bold = true;
//斜体
txInfo.italic = true;
//富文本
txInfo.width = 400;
txInfo.height = 600;
txInfo.textFlow = <Array<egret.ITextElement>>[
{ text: "Text in ", style: { size: 20 } },
{
text: "Egret",
style: {
href: "event:ttttt",
textColor: 0x336699,
size: 60,
strokeColor: 0x6699cc,
stroke: 2,
},
},
{ text: " can ", style: { fontFamily: "Impact" } },
{ text: "be set ", style: { fontFamily: "Times New Roman" } },
{ text: "to a ", style: { textColor: 0xff0000 } },
{ text: "\n" },
{ text: "variety ", style: { textColor: 0x00ff00 } },
{ text: "of ", style: { textColor: 0xf000f0 } },
{ text: "styles ", style: { textColor: 0x00ffff } },
{ text: "with", style: { href: "https://www.egret.com/", size: 56 } },
{ text: "different ", style: { size: 16 } },
{ text: "colors, ", style: { size: 26 } },
{ text: "\n" },
{ text: "fonts ", style: { italic: true, textColor: 0x00ff00 } },
{
text: "and ",
style: { size: 26, textColor: 0xf000f0, fontfamily: "Quaver" },
},
{ text: "sizes", style: { italic: true, textColor: 0xf06f00 } },
];
txInfo.touchEnabled = true;
txInfo.addEventListener(
egret.TextEvent.LINK,
function (evt: egret.TextEvent) {
console.log(evt.text);
},
this
);
3.加载资源RES
本地资源放在./resource下,而且需要关注default.res.json文件,然后就可以在游戏中加载资源了
RES.addEventListener(
RES.ResourceEvent.GROUP_COMPLETE,
this.onGroupComplete,
this
);
await RES.loadConfig("resource/default.res.json", "resource/");
await RES.loadGroup("preload");
在onGroupComplete方法中使用加载好的资源
private onGroupComplete() {
//图片
let bgimg: egret.Bitmap = new egret.Bitmap();
bgimg.texture = RES.getRes("bg_jpg");
bgimg.y = 0;
this.addChild(bgimg);
}
4.滤镜效果
可以使用本身自带一些属性设置滤镜
//设置滤镜
let color: number = 0xff0000; /// 光晕的颜色,十六进制,不包含透明度
let alpha: number = 0.8; /// 光晕的颜色透明度,是对 color 参数的透明度设定。有效值为 0.0 到 1.0。例如,0.8 设置透明度值为 80%。
let blurX: number = 35; /// 水平模糊量。有效值为 0 到 255.0(浮点)
let blurY: number = 35; /// 垂直模糊量。有效值为 0 到 255.0(浮点)
let strength: number = 2; /// 压印的强度,值越大,压印的颜色越深,而且发光与背景之间的对比度也越强。有效值为 0 到 255。暂未实现
let quality: number = egret.BitmapFilterQuality.HIGH; /// 应用滤镜的次数,建议用 BitmapFilterQuality 类的常量来体现
let inner: boolean = false; /// 指定发光是否为内侧发光,暂未实现
let knockout: boolean = false; /// 指定对象是否具有挖空效果,暂未实现
const glowFilter: egret.GlowFilter = new egret.GlowFilter(
color,
alpha,
blurX,
blurY,
strength,
quality,
inner,
knockout
);
img.filters = [glowFilter];
也可以使用颜色矩阵
//灰化
let colorMatrix = [
0.3, 0.6, 0, 0, 0, 0.3, 0.6, 0, 0, 0, 0.3, 0.6, 0, 0, 0, 0, 0, 0, 1, 0,
];
let colorFlilter = new egret.ColorMatrixFilter(colorMatrix);
img.filters = [colorFlilter];
//红化
colorMatrix = [
1, 0, 0, 0, 100, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0,
];
colorFlilter = new egret.ColorMatrixFilter(colorMatrix);
img.filters = [colorFlilter];
//绿化
colorMatrix = [1, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0];
colorFlilter = new egret.ColorMatrixFilter(colorMatrix);
img.filters = [colorFlilter];
//蓝换红
colorMatrix = [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0];
colorFlilter = new egret.ColorMatrixFilter(colorMatrix);
img.filters = [colorFlilter];
//亮起来
colorMatrix = [
1, 0, 0, 0, 100, 0, 1, 0, 0, 100, 0, 0, 1, 0, 100, 0, 0, 0, 1, 0,
];
colorFlilter = new egret.ColorMatrixFilter(colorMatrix);
img.filters = [colorFlilter];
模糊和阴影效果
//模糊
const blurFliter = new egret.BlurFilter(9, 10);
img.filters = [blurFliter, colorFlilter];
//阴影
const distance: number = 20; /// 阴影的偏移距离,以像素为单位
const angle: number = 30; /// 阴影的角度,0 到 360 度
color = 0xff0000; /// 阴影的颜色,不包含透明度
alpha = 0.7; /// 光晕的颜色透明度,是对 color 参数的透明度设定
blurX = 16; /// 水平模糊量。有效值为 0 到 255.0(浮点)
blurY = 16; /// 垂直模糊量。有效值为 0 到 255.0(浮点)
strength = 0.65; /// 压印的强度,值越大,压印的颜色越深,而且阴影与背景之间的对比度也越强。有效值为 0 到 255。暂未实现
quality = egret.BitmapFilterQuality.LOW; /// 应用滤镜的次数,暂无实现
inner = false; /// 指定发光是否为内侧发光
knockout = false; /// 指定对象是否具有挖空效果
const dropShadowFilter: egret.DropShadowFilter = new egret.DropShadowFilter(
distance,
angle,
color,
alpha,
blurX,
blurY,
strength,
quality,
inner,
knockout
);
img.filters = [dropShadowFilter];
5.使用插件(比如p2物理引擎)
官方提供了一些第三方库,可以直接下载,下载之后把对应的文件放到./libs下
PS:不用放到modules中。
然后在egretProperties.json中添加,重新编译后即可使用
{
"engineVersion": "5.4.1",
"compilerVersion": "5.4.1",
"template": {},
"target": {
"current": "web"
},
"modules": [
{
"name": "egret"
},
{
"name": "game"
},
{
"name": "tween"
},
{
"name": "assetsmanager"
},
{
"name": "promise"
},
{
"name":"physics",
"path":"./libs/physics"
}
],
"vivo": {
"usePlugin": true
}
}
此时可以使用p2物理引擎开发一个点球小游戏了
//PlayBall.ts
/**
* @create 2023-01-05 16:25:46
*/
class PlayBall extends egret.Sprite {
private factor: number = 50;
private world: p2.World;
private boxBody: p2.Body;
private planeBody: p2.Body;
public constructor() {
super();
//图片
let bgimg: egret.Bitmap = new egret.Bitmap();
bgimg.texture = RES.getRes("bg_jpg");
bgimg.y = 0;
this.addChild(bgimg);
this.createGameScene();
}
/**
* 创建游戏场景
*/
private createGameScene(): void {
this.world = new p2.World();
this.world.sleepMode = p2.World.BODY_SLEEPING;
//创建plane
var planeShape: p2.Plane = new p2.Plane();
var planeBody: p2.Body = new p2.Body();
planeBody.addShape(planeShape);
planeBody.displays = [];
this.world.addBody(planeBody);
egret.Ticker.getInstance().register(function (dt) {
if (dt < 10) {
return;
}
if (dt > 1000) {
return;
}
this.world.step(dt / 1000);
var stageHeight: number = egret.MainContext.instance.stage.stageHeight;
var l = this.world.bodies.length;
for (var i: number = 0; i < l; i++) {
var boxBody: p2.Body = this.world.bodies[i];
var box: egret.DisplayObject = boxBody.displays[0];
if (box) {
box.x = boxBody.position[0] * this.factor;
box.y = stageHeight - boxBody.position[1] * this.factor;
box.rotation =
360 - ((boxBody.angle + boxBody.shapes[0].angle) * 180) / Math.PI;
if (boxBody.sleepState == p2.Body.SLEEPING) {
box.alpha = 0.5;
} else {
box.alpha = 1;
}
}
}
}, this);
this.touchEnabled = true;
//鼠标点击添加刚体
this.addEventListener(egret.TouchEvent.TOUCH_TAP, this.addOneBox, this);
}
private addOneBox(e: egret.TouchEvent): void {
var positionX: number = Math.floor(e.stageX / this.factor);
var positionY: number = Math.floor(
(egret.MainContext.instance.stage.stageHeight - e.stageY) / this.factor
);
var display: egret.DisplayObject;
if (Math.random() > 0.9) {
//添加方形刚体
var boxShape: p2.Shape = new p2.Box({ width: 2, height: 1 });
var boxBody: p2.Body = new p2.Body({
mass: 1,
position: [positionX, positionY],
angularVelocity: 1,
});
boxBody.addShape(boxShape);
this.world.addBody(boxBody);
display = this.createBitmapByName("rect");
display.width = (<p2.Box>boxShape).width * this.factor;
display.height = (<p2.Box>boxShape).height * this.factor;
} else {
//添加圆形刚体
var boxShape: p2.Shape = new p2.Circle({ radius: 1 });
var boxBody: p2.Body = new p2.Body({
mass: 1,
position: [positionX, positionY],
});
boxBody.addShape(boxShape);
this.world.addBody(boxBody);
display = this.createBitmapByName("circle");
display.width = (<p2.Circle>boxShape).radius * 2 * this.factor;
display.height = (<p2.Circle>boxShape).radius * 2 * this.factor;
}
display.anchorOffsetX = display.width / 2;
display.anchorOffsetY = display.height / 2;
boxBody.displays = [display];
this.addChild(display);
}
/**
* 根据name关键字创建一个Bitmap
*/
private createBitmapByName(name: string): egret.Bitmap {
var result: egret.Bitmap = new egret.Bitmap();
var texture: egret.Texture = RES.getRes(name);
result.texture = texture;
return result;
}
}
自此,第一个入门小游戏可以玩一会儿了。