Egretia Engine Upgrade: Support Bytedance’s Mini Games

Image for post

Support Bytedance’s Mini Games

Image for post

Kind reminder:

To execute, developers shall use the latest version of Egretia engine and Egretia Launcher

Egretia Compiler

In this case, developers only need to install the latest version of Launcher and download Egretia Compiler in the [Tools] tab, which can be used more easily without executing the npm install command in each project.

Besides, here is an update on webpack:

• legacy mode

o Fix the decorator sorting problem;

o Fix the error of namespace;

o Fix the problem that the global enumeration cannot be accessed;

o Add sourcemap;

o Fix the compilation error caused by .d.ts in the src folder;

o Modify the .ts matching rules in legacy mode and adopt the configuration in tsconfig.json instead of hard-coded the src folder;

• Linux platform support;

• Fix the problem that Egretia.is returns incorrect results after compilation;

• Optimize the output volume which has been reduced about 20%

• Add typescript.tsconfigPath;

Egretia UI Editor

• Add right click to resource library -> copy resource name;

• Exml source code supports formatting;

• Support drag the skin by pressing the right button;

• The resource manager supports deleting files through the Delete key;

• The right-click menu item displays the corresponding shortcut keys;

• The interface can be zoomed by the mouse wheel in the preview state;

• Adjust the step length of the size & position part of the attribute item to 1, which is more user-friendly;

•To change the shortcut skin of Button by dragging and dropping resources to the input box

• The custom components are sorted alphabetically for easy search;

• The component frame is drawn by canvas, and the skin editing is smoother;

• Fix that clicking may cause the component level to be changed in some cases

• Fix that frequent changes to the component location may cause the editor to crash;

• Fix the issue that the list in the Ctrl+P shortcut to open the file is not updated synchronously after the file is changed

• Fix the problem that the interface is not updated in real time after changing the component skin;

Document

• Optimize the page loading speed from an average of 2 seconds to an average of 300 milliseconds

• Upload multiple documents and remove some outdated documents

  • All the sample codes in the document are written in ES2015 version, e.g. declare Variables with let and const

Stay tuned for updates from the Egretia official channels below so that you can be involved in all the exciting things to come!

Egretia Telegram: https://t.me/Egretia

Egretia Twitter: https://twitter.com/Egretia_io

Egretia Website: https://egretia.io/

Create A Space Shooter Game | Egretia Engine Tutorial For Beginners Part 7

This is the seventh part of Egretia Engine tutorial, showing how to build a space shooter game!

Part 1 https://bit.ly/32xy7r3

Part 2 https://bit.ly/2CV2CfC

Part 3 https://bit.ly/39uicLD

Part 4 https://bit.ly/3jJui8p

Part 5 https://bit.ly/31boR9Q

Part 6 https://bit.ly/31mFM9j

Demonstration

> Implementation of RES resources loading

Image for post

Main

Image for post

>Implementation of Resources loading

Image for post

Main

public menu:MainMenu;
public canvasIndex:number; // Interface index

Construct:

this.game= null;

this.addChild(this.menu);

this.canvasIndex=10; //10menu 20game 30over

Main

Add the following codes to touchdown,touchMove,touchup and update:

switch(this.canvasIndex)

{

case 10:

this.menu.touchDown(e);

break;

case 20:

this.game.touchDown(e);

break;

}

public loadingView;

private async loadResource() {

try {

this.loadingView = new LoadingUI();

this.stage.addChild(this.loadingView);

await RES.loadConfig(“resource/default.res.json”, “resource/”);

//menu belongs to the name of group and its background is saved in its group

await RES.loadGroup(“menu”, 0, this.loadingView); this.stage.removeChild(this.loadingView);

}

catch (e) {

console.error(e);

}

}

Mainmenu

public async touchDown(e:egret.TouchEvent)

{

//=null means there are no constructor or no resources loading. Then the interface starts to load

if(this.main.game == null){ // add the loading interface to the scene

this.stage.addChild(this.main.loadingView);

//read the resources

await RES.loadGroup(“game”, 0, this.main.loadingView);

//remove the interface

this.stage.removeChild(this.main.loadingView);

//construct the game interface after loading

this.main.game = new MainGame(this.main);

}

this.main.removeChild(this);

this.main.game.reset(0); // 0 is the game level

this.main.addChild(this.main.game);

this.main.canvasIndex = 20;

}

Loading

// add the loading interface to scene
this.stage.addChild(this.main.loadingView);
//read the resources
await RES.loadGroup(“game”, 0, this.main.loadingView);
//remove the interface
this.stage.removeChild(this.main.loadingView);

>Add the images in interfaces

Image for post

Create LoadingUI2

Image for post

Main

loadResource()

this.loadingView = new LoadingUI2();

Image for post

MainMenu

Image for post

> Singleton Pattern and Create JSON

An implementation of the singleton pattern must:

ensure that only one instance of the singleton class ever exists;

and provide global access to that instance.

JSON is an open standard file format, and data interchange format, that uses human-readable text to store and transmit data objects consisting of attribute–value pairs and array data types (or any other serializable value). It is a language-independent data format and a very common data format, with a diverse range of applications.

> Basic concepts of game design and game development:Separate data and logic

{
“playV”: 30, ”:”player’s speed”,
“zdV”: 10, ” :” Bullet rotational speed”
}

Create JSON file and import resources

Image for post

What are the coolest projects you saw from people using Egretia engine?

Stay tuned for updates from the Egretia official channels below so that you can be involved in all the exciting things to come!

Egretia Telegram: https://t.me/Egretia

Egretia Twitter: https://twitter.com/Egretia_io

Egretia Website: https://egretia.io/

Create A Space Shooter Game | Egretia Engine Tutorial For Beginners Part 6

This is the sixth part of Egretia Engine tutorial, showing how to build a space shooter game!

Part 1 https://bit.ly/32xy7r3

Part 2 https://bit.ly/2CV2CfC

Part 3 https://bit.ly/39uicLD

Part 4 https://bit.ly/3jJui8p

Part 5 https://bit.ly/31boR9Q

Demonstration

>Lasers

public dx:number;

public dy:number; // Offset value based on player coordinates

public static fi:number = 0 ; // animation frames of laser

//Type

case 10:

//build a picture frame

this.im=Main.createBitmapByName(“pzd4”+ZD.fi+”_png”);

/insert a picture after every shooting

ZD.fi++;

if(ZD.fi >= 10) ZD.fi = 0;

this.addChild(this.im);

//shoot once every pass of main loop, the distance is 80

this.vy = -80; //-80 upwards

this.vx = 0 ;

this.dx = this.dy = 0 ;

this.n = 0;

break;

update():

//the special one will be scheduled in advance and automatically executed. The “return” will show up when it finishes.

if(this.id == 10){

//the distances between planes and them

this.dx +=this.vx;

this.dy +=this.vy;

//offset value:base value+offset

// coordinates of laser is base coordinates and changes

this.x = this.game.player.x + this.dx;

this.y = this.game.player.y + this.dy;

// test whether it’s off-screen

if(this.y < -100 ){

this.vis = false;

}

return;

}

>Tracking bullet

Demonstration

Version:1.0 StartHTML:000000275 EndHTML:000053955 StartFragment:000021508 EndFragment:000053873 StartSelection:000021508 EndSelection:000053869 SourceURL:https://medium.com/egretia/create-a-space-shooter-game-egretia-engine-tutorial-for-beginners-part-6-a93d80fc08de Create A Space Shooter Game | Egretia Engine Tutorial For Beginners Part 6 | by Egretia Io | Egretia | Aug, 2020 | Medium

1)NPC:

NPCManager

//obtain NPC

public getNPC():NPC{

//length>0,NPC exists; if no, bounce off

if(this.nm.length > 0 ){

//if there is npc, choose one randomly

let npc = this.nm[Math.floor(Math.random()* this.nm.length)]

// decide whether NPC stays in the screen or not

if(npc.x > 0 && npc.x < 480 && npc.y > 0 && npc.y < 800){

return npc;

}

}

//no findings, null

return null;

}

2)calculate the angle to hit NPC
3)update the angle

Apply
public npc:NPC; //the target

/track the bullet

case 20:

this.im = Main.createBitmapByName(“pzd1_3_png”);

this.npc = null;

break;

update()

// the special one will be scheduled in advance and automatically executed. The “return” will show up when it finishes.

if(this.id == 20){

let bn = 0 ; //target angle: upward

if(this.npc == null){

this.npc = this.game.nm.getNPC();

}else{

bn = Math.atan2(this.npc.x -this.x,this.y-this.npc.y);

// This angle is in radians, which will be converted into angle values

bn = bn * 180/ Math.PI;

}

//N angle limit: -180°~180°

while(this.n <= -180)

this.n += 360;

while(this.n > 180)

this.n -= 360;

//if the angle difference is below 5, the two angles are approximately identical

if(Math.abs(this.n — bn) < ZD.VN){

this.n = bn;

}else{

//

if(this.n < bn){

if(this.n < bn — 180)

this.n -= ZD.VN;

else

this.n += ZD.VN;

}else{

if(this.n > bn + 180)

this.n += ZD.VN;

else

this.n -= ZD.VN;

}

}

// convert into angle values

// refresh the speed and angle

this.vx = this.v * Math.sin(this.n * Math.PI / 180);

this.vy= -this.v * Math.cos(this.n * Math.PI / 180);

this.im.rotation = this.n;

this.x +=this.vx;

this.y +=this.vy;

//test the border

if(this.x < -100 || this.x > 580 || this.y < -100 || this.y > 900){

this.vis = false;

}

return;

}

while(this.n <= -180)

this.n += 360;

while(this.n > 180)

this.n -=360;

//track the bullet

this.t++;

if(this.t >= 10){

this.game.zm.create(20,this.x,this.y,15,135,this.game);

this.game.zm.create(20,this.x,this.y,15,-135,this.game);

this.game.zm.create(20,this.x,this.y,15,45,this.game);

this.game.zm.create(20,this.x,this.y,15,-45,this.game);

this.t = 0 ;

}

> The cases of players

0 exit the game
1 playing the game
10 win the game and wait
11 win the game and exit

switch(this.m){

case 0 :

this.y -=this.v;

if(this.y <= 400){

this.m =1;

this.t = 0 ;

}

break;

case 1 :

this.fire();

this.movePlayer();

break;

case 10:

this.t++;

if(this.t >= 20){

this.t = 0;

this.m = 11;

}

break;

case 11:

this.y -=this.vy;

this.vy +=3;

if(this.y < -200){

// the switch of winning the game

}

break;

}

MovePlayer

public movePlayer(){

if(this.isDown == true ){

let a = this.ny — this.oy;

let b = this.nx — this.ox;

let c = Math.sqrt(a*a + b*b);

if( c > this.v){

this.vx = this.v*b/c;

this.vy = this.v*a/c;

this.ox += this.vx;

this.oy += this.vy;

}else{

this.vx = b;

this.vy = a;

this.ox = this.nx;

this.oy = this.ny;

}

// plane will set off at the speed

this.x +=this.vx ;

this.y +=this.vy ;

//test the border

if(this.x < 0)

this.x = 0;

else if(this.x > 480)

this.x = 480;

if(this.y < 0)

this.y = 0;

else if(this.y > 800)

this.y = 800;

}

else{

this.vx = 0;

}

if(this.vx < 0 ){

//fly towards the left side:

if(this.fi > -2)

this.fi — ;

}else if(this.vx > 0)

{

if(this.fi < 2)

this.fi++;

}

else{

this.fi = 0 ;

}

this.resetFI();

}

>public isHit(x:number , y:number):boolean{}

public isHit(x:number , y:number):boolean{

// this.x this.y is the center of a circle, 60 is radius

// Formula of the distance between two points

if(this.bhT > 0 ){

if((this.x -x )*(this.x -x ) + (this.y -y )*(this.y — y ) < 60*60){

return true;

}

return false;

}

if(this.m !=1)

return false;

if(Math.abs(this.x — x) < 20 && Math.abs(this.y -y )<20){

//death of players

return true;

}

return false;

}

add

public dead(){

for(let i = 0 ; i < 10 ; i++){ //ring

let dn =Math.random()*Math.PI * 2;

for(let j = 0 ; j < 15 ; j ++) //the bombs of each ring

{

this.game.tm.create(0,

this.x + (i+1)*30* Math.sin(dn+Math.PI*2*j/15),

this.y + (i+1)*30* Math.cos(dn+Math.PI*2*j/15),

i,Math.random() * 10 +5,this.game);

}

}

this.x = 240;

this.y = 1000;

this.m = 0 ;

this.t = 0;

}

> Players’ Shield

public bh:egret.Bitmap; // shield photo
public bhT:number; // shield timer: last 3 seconds
this.bh.anchorOffsetX = this.bh.width/2;
this.bh.anchorOffsetY =this.bh.height/2;
this.addChild(this.bh);
this.bh.scaleX = this.bh.scaleY = 0.5;
this.bhT = 60; // three seconds for 60 passes of main loop

Update;
//shield effective time>0. Visible = false when it comes to 0

if(this.bhT > 0 ){

this.bhT — ;

if(this.bhT <=0){

this.bh.visible = false;

}

}

NZDManager

if(this.game.player.isHit(one.x , one.y) ==true ){

one.vis = false;

if(this.game.player.m == 1 && this.game.player.bhT <= 0 ){

this.game.player.dead();

}

}

this.bhT = 60;
this.bh.visible = true;

> Win the game and Game level switch

BOSS0

public dead(){

for(let i = 0 ; i < 10 ; i++){ //ring

let dn =Math.random()*Math.PI * 2;

for(let j = 0 ; j < 15 ; j ++) //the number of bombs of each ring

{

this.nm.game.tm.create(0,

this.x + (i+1)*30* Math.sin(dn+Math.PI*2*j/15),

this.y + (i+1)*30* Math.cos(dn+Math.PI*2*j/15),

i,Math.random() * 10 +5,this.nm.game);

}

}

this.nm.game.player.win();

}

//pass

public win(){

this.t = 0 ;

this.m = 10; //Player will fly off the screen after victory

}

2)Level switch
Maingame:

apply public level:number; // to figure out the current level
construct:this.level = 0;

Maingame:

public reset(level:number)

{

this.level = level;

this.player.reset();

this.bg.reset();

this.nm.reset();

}

BG

public reset(){

switch(this.game.level){

case 0:

for(let i = 0 ; i < 2; i ++){

this.bg[i].texture = RES.getRes(“bg11_jpg”);

}

break;

case 1:

for(let i = 0 ; i < 2; i ++){

this.bg[i].texture = RES.getRes(“bg31_jpg”);

}

break;

}

}

NPCManager

//clean out

public reset(){

//the total length. To find out all the bullets by circulation

for(let i = 0 ; i < this.nm.length ; i++){

//find out every bullet

let one = this.nm[i];

this.removeChild(one);

this.nm.splice(i ,1);

i — ;

}

this.t =0;

this.cID = 0;

}

Player

public dead(){

for(let i = 0 ; i < 10 ; i++){ //rings

let dn =Math.random()*Math.PI * 2;

for(let j = 0 ; j < 15 ; j ++) //the number of bombs for each ring

{

this.game.tm.create(0,

this.x + (i+1)*30* Math.sin(dn+Math.PI*2*j/15),

this.y + (i+1)*30* Math.cos(dn+Math.PI*2*j/15),

i,Math.random() * 10 +5,this.game);

}

}

this.x = 240;

this.y = 700;

this.m = 0 ;

this.t = 0;

this.bhT = 60;

this.bh.visible = true;

}

public reset(){

this.isDown = false;

this.x = 240;this.y = 1000;

this.m = this.t = 0;

this.bhT = 60; //it will take 3 seconds for 60 passes of main loop

}

What are the coolest projects you saw from people using Egretia engine?

Stay tuned for updates from the Egretia official channels below so that you can be involved in all the exciting things to come!

Egretia Telegram: https://t.me/Egretia

Egretia Twitter: https://twitter.com/Egretia_io

Egretia Website: https://egretia.io/