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/