This is the fifth 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
Demonstration



Programming
>Explosion
1)TX
public id:number; //Type
public vis:boolean; //vis is necessary in Factory pattern
public fi:number; //which animation frame it will play
public t:number; //timer, such as three passes of main loop
public m:number; //state
public l:number; //how long it will last
public tm:TXManager; // parent pointer
Constructor:
if(this.t > 0){
// it will be invisible in the storage system
//0 means “Get ready”, 1 means “Play”
this.visible = false;
this.m = 0;
}else{
this.visible = true;
this.m = 1 ;
}
TX
“`c
class TX extends egret.Sprite{
public im:egret.Bitmap;
public id:number; //Type
public vis:boolean; // vis is necessary in Factory pattern
public fi:number; // which animation frame it will play
public t:number; // timer, such as three passes of main loop
public m:number; //state
public l:number; // how long it will last
public tm:TXManager; // parent pointer
public constructor(id:number,x:number, y:number,
t:number,l:number,tm:TXManager) {
super();
this.id = id;
this.x = x ;
this.y = y;
this.t = t;
this.l = l;
this.m = 0;
this. fi = 0 ;
this.vis = true; // =false , the objects will disappear in the factory
this.tm = tm;
this.im = Main.createBitmapByName(“tx1_1_png”);
this.anchorOffsetX = this.im.width/2;
this.anchorOffsetY = this.im.height/2;
this.addChild(this.im);
if(this.t > 0){
//it will be invisible in the storage system
//0 means “Get ready”, 1 means “Play”
this.visible = false;
this.m = 0;
}else{
this.visible = true;
this.m = 1 ;
}
}
public update(){
switch(this.m ){
//
case 0:
//timer
this.t — ;
if(this.t <=0 ){
//explode
this.visible = true;
this.m = 1; //play
}
break;
case 1 :
//start the animation
this.fi++;
//
if(this.fi >= this.l){
this.vis =false; //object destruction
}else{ //if it’s not over, switch frame
//switch frame: fi from 0 to 9,
//10 is the number of photos, fi is the animation frame, 1 is the length
this.im.texture = RES.getRes(“tx1_”+Math.floor(this.fi*10/this.l + 1)+”_png”);
}
}
}
}
TXManager
class TXManager extends egret.Sprite{
public tm:Array<TX>; //Array: to add or remove objects
public game:MainGame;
public constructor(game:MainGame) {
super();
this.game = game;
this.tm = new Array();
}
//each create needs one new
public create(id:number,x:number,y:number,t:number,l:number,game:MainGame){
//create bullet
let one = new TX(id,x,y,t,l,this);
// add to the world
this.addChild(one);
//put it at the end of array
this.tm.push(one);
}
//find out and update all the bullets
public update(){
//the total length of storage system. Find out all of bullets by loop
for(let i = 0 ; i < this.tm.length ; i++){
// find out each bullet
let one = this.tm[i];
one.update();
//the extra bullets need to be removed
// bullets are out of screen ,vis == false.remove
if(one.vis == false){
//remove it from the scene firstly
this.removeChild(one);
//then remove it from storage system
this.tm.splice(i ,1);
//remove an object,length -1
i — ;
}
}
}
}
ZDManager
if(npc.hp <= 0 ){
for(let k = 0 ; k < 10 ; k ++){ //-50 to +50
this.game.tm.create( 0, npc.x + Math.random()*100 -50 ,
npc.y + Math.random()*100 -50 ,
Math.floor(Math.random() * 5), 10,this.game);
}
npc.vis = false;

>Effects of explosion
Add the following codes to NPC0,1
public dead(){
for(let k = 0 ; k < 10 ; k ++){
this.nm.game.tm.create( 0, this.x + Math.random()*100–50 ,
this.y + Math.random()*100–50 ,
Math.floor(Math.random() * 5), 10,this.nm.game);
}
}
then

>BOSS0
class BOSS0 extends NPC{
public im:egret.Bitmap;
public m:number;
public t:number;
public constructor(x:number,y:number,nm:NPCManager) {
super(nm);
this.x = x ;this.y = y;
this.im = Main.createBitmapByName(“boss50_png”);
this.im.anchorOffsetX = this.im.width/2;
this.im.anchorOffsetY = this.im.height/2;
this.addChild(this.im);
this.m = this.t = 0;
this.hp = 1000;
}
public update(){
}
public isHit(x:number,y:number):boolean{
return false;
}
public dead(){
}
}
Add BOSS
switch(this.m){
//where boss stops
case 0:
this.y+=10;
if(this.y >= 150){
this.t = 20 ;
this.m = 1;
}
break;
//break
case 1:
this.t — ;
if(this.t <=0){
this.m = 10;
this.t = 0 ;
}
break;
//set off the bullet
case 10:
this.t++;
// fire a single bullet every three passes of main loops
if(this.t % 3 == 0 ){
for(let i = 0 ; i < 5 ; i++){
//bullets in five rows
//160+i*10 fire a single bullet every angle of 10
this.nm.game.nzm.create(1, this.x, this.y, 10 ,160+i*10,this.nm.game );
}
}
if(this.t >= 20){
this.t = 10;
this.m = 1;
}
break;
}
Single bullet

Round-shaped bullet

//fire the bullet
case 10:
this.t++;
//fire a single bullet every three passes of main loop
if(this.t % 3 == 0 ){
for(let i = 0 ; i < 36 ; i++){
//bullets in five rows
//160+i*10 fire a single bullet every angle of 10
this.nm.game.nzm.create(1, this.x, this.y, 10 ,160+i*10,this.nm.game );
}
}
if(this.t >= 20){
this.t = Math.random()* 20 + 10;
this.m = 1;
}
break;
Swirl Bullet

case 11:
this.t++;
// the angle of bullets will change as t++ alters
this.nm.game.nzm.create(1, this.x, this.y, 10 ,180+this.t*10,this.nm.game ); //
Counterclockwise
this.nm.game.nzm.create(1, this.x, this.y, 10 ,180 — this.t*10,this.nm.game ); // clockwise
//fire the bullet every angle of 10
if(this.t >= 36){
this.t = Math.random()* 20 + 10;
this.m = 1;
}
break;
Matrix bullet



case 12:
this.t++;
//15,16,17,18,19 fire 5 bullets
if(this.t % 20 > 14){
for(let i = 0 ; i < 5 ; i++){
// fire a row every 20 degrees, 5 bullets from 130 degrees
//this.t/10,the result of top ten:10,11,12,13 when it comes to 1,the length = roundness*20
this.nm.game.nzm.create(1,this.x,this.y,10,Math.floor(this.t/20)*20 +130+i*5,this.nm.game );
// fire 5 bullets at 135 degree
}
}
if(this.t >= 100){
this.t = Math.random() * 20 + 10;
this.m =1 ;
}
break;
Whip-shaped bullets

// Whip bullet
case 13:
this.t++;
// the speed will increase as the time changes
this.nm.game.nzm.create( 1, this.x — 50, this.y, 6 + this.t *2 ,190 — this.t,this.nm.game );
this.nm.game.nzm.create( 1, this.x+50, this.y, 6 + this.t *2 ,170 + this.t,this.nm.game );
if(this.t >= 10){
this.t = Math.random() * 20 + 10;
this.m =1 ;
}
break;
Bullets Based on Orientation

Code:

// if n is null or empty, there is no value assigned
if(!n){
n = Math.atan2(this.game.player.x — x,y — this.game.player.y);
//note: convert the radians to degrees
n = n * 180/Math.PI;
}
BOSS0
//bullets based on orientation
case 14 :
this.t++;
// fire the bullets every ten passes of main loop
if(this.t % 10 > 4){
this.nm.game.nzm.create( 1, this.x — 50, this.y, 15);
}
if(this.t >= 50){
this.t = Math.random() * 20 + 10;
this.m =1 ;
}
break;
Random bullets
case1 this.m = Math.floor(Math.random() * 5 ) + 10; //random bullets
>Collision detection of irregular shapes

W 146 H166 73,83 pixels

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/