B4J Tutorial [ABMaterial] 2.0 introducing B4JS

This post is no longer valid! B4JS has been rewritten from the ground up and will first introduced in In ABM 4.25. Stay tuned...
------------------------------------------------------------------------------
Old post:

As Erel pointed out, the biggest challenge for ABMXPlay component would be how to handle what happens on the server and what on the client side.
I've poundered a lot on this, and finaly came up with B4JS, a B4J to JavaScript translator that will be first used in the ABMXPlay component. In the following months, other ABM Components will get a similar functionality.

1. Variables, synced on both sides:

Declared in Class_Global, and with the prefix B4JS. Currently support for Int, Double, Boolean, String, List, Map and Array

Examples:

Dim B4JSCharFilterStates(3) As Int
Dim B4JSFilterState As Int
Dim B4JSFlowDirection As Int = 1
Dim B4JSTestMap As Map
Dim B4JSTestList As List

2. Events

The object will get two kind of events, SERVER and B4JS events:

2.1. SERVER events

SERVERInitialized(GraphicsType as String)
SERVERStartDrag(Params as Map)
SERVERStopDrag(Params as Map)
SERVERTouchDown(Params as Map)
SERVERTouchUp(Params as Map)
SERVERPreloadComplete()
SERVERKeyDown(KeyCodes as Object)
SERVERKeyUp(KeyCodes as Object)
SERVERObjectRemoved(objectName as String)

These events are like the ones you're used to in ABMaterial. They must be ended with an ABMXPlay.Update command to sync everything with the client.

PRO:
You can use any B4J command in them
Debuggable in B4J
CON:
Traffic

To use a Global B4JS variable in a SERVER event, you need to 'sync' it before using/changing.

Example:

B4X:
   B4JSFlowDirection = xplay.GetB4JSVariable("B4JSFlowDirection")
   Log("B4JSFlowDirection: " & B4JSFlowDirection)
   If (B4JSFlowDirection=1) Then
     B4JSFlowDirection = -1
   Else
     B4JSFlowDirection = 1  
   End If
 
   xplay.SetB4JSVariable("B4JSFlowDirection", B4JSFlowDirection)

You can also work with ABMXP components, even if they are created on the Client side!

Example:

B4X:
   Select Case objectName
   Case "xplay" ' self
     ' although stan was created in javascript, we can still access him in the SERVER events if needed!
     ' the object is only 'mapped' to the server with futures the first time you try to access it (e.g. by using GetSprite).
     Dim stan As ABMXPSprite = xplay.GetSprite("stan")
     stan.X = Rnd(100,540)
     stan.Y = Rnd(100,380)
     xplay.Update
   End Select

2.2. B4JS events

This is new! B4J code in a B4JS event will be translated to Javascript.

B4JSRender(xPlay as ABMXPlay)
B4JSStartDrag(xPlay As ABMXPlay, objectName As String, x As Int, y As Int) As Boolean
B4JSStopDrag(xPlay As ABMXPlay, objectName As String, x As Int, y As Int) As Boolean
B4JSMoveDrag(xPlay As ABMXPlay, objectName As String, x As Int, y As Int)
B4JSTouchDown(xPlay As ABMXPlay, objectName As String, x As Int, y As Int) As Boolean
B4JSTouchMove(xPlay As ABMXPlay, objectName As String, x As Int, y As Int)
B4JSTouchUp(xPlay As ABMXPlay, objectName As String, x As Int, y As Int) As Boolean
B4JSPreloadComplete(xPlay As ABMXPlay) As Boolean
B4JSKeyDown(xPlay As ABMXPlay, KeyCodes as Object) As Boolean
B4JSKeyUp(xPlay As ABMXPlay, KeyCodes as Object) As Boolean
B4JSObjectRemoved(xPlay As ABMXPlay, objectName as String) As Boolean

These events do not need xplay.update, but you have to return a boolean value for some methods. With this boolean, you can block a SERVER event.
e.g. In B4JSTouchUp you do some stuff and nothing is needed to be done on the server (e.g. moving some objects around). Return false and the SERVERTouchUp() event will not be raised.

So in short, B4JS methods will NOT go back and forth to the server, as they pure Javascript.

PRO:
Speed and less traffic
CON:
Limited B4J syntax set. No B4J external library can be used. Currently support for Int, Double, Boolean, String, List, Map, Array, all ABMXPlay components, If then else, For loops, While loops, Select case
Can not be debugged in B4J

But, as these B4JS events are mostly used to do 'logic' stuff, the limited syntax is extremely useful for games. In the future, in the other ABMComponents, this could be used to check e.g. if a user has filled in all input fields.

You can use Global B4JS variables just as you use any other B4J variable. No need for the GetB4JSVariable methods.

Example:

B4X:
Sub xplay_B4JSPreloadComplete(xPlay As ABMXPlay) As Boolean
   Log("preload complete")
 
   ' create a sprite
     Dim bg As ABMXPSprite
   bg.Initialize(xPlay,"background", "background", 0,0, 1, 0, 1,1)
   xPlay.AddDisplayObject(bg)

     ' add a displacement filter
   Dim displacementmapSprite As ABMXPSprite
     displacementmapSprite.initialize(xPlay,"displacementmapSprite", "displacementmap", 0,0,1, 0, 1,1)
     xPlay.AddDisplayObject(displacementmapSprite)
 
   Dim filter As ABMXPFilterDisplacement
   filter.initialize(xPlay, "displacementmapSprite", 50,50)
     xPlay.AddFilter(filter)
 
   ' place some transparent ghost Kennys randomly (Kenny dies in every epsode)
   For i = 0 To 100
         ' make a new kenny and place it randomly somewhere
         Dim scale As Double = 0.2 * ABM.Util.Rnd(0,1) + 0.2
         Dim kn As ABMXPSprite
         kn.Initialize(xPlay,"kenny" & i, "kenny", 630*ABM.Util.Rnd(0,1),300*ABM.Util.Rnd(0,1), 0.33,0,scale, scale)
         xPlay.AddDisplayObject(kn)
         ' tween rotate at random speed
         kn.TweenStartRotation("rotatekenny" & i, ABM.XP.TWEEN_EASINGTYPE_LINEAR, ABM.XP.TWEEN_REPEATTYPE_RESTARTCONTINIOUS, ABM.Util.Rnd(3000,10000), 0,360)
   Next
 
   ' add the other draggable chars
     ' create a sprite we can move and click
     Dim St As ABMXPSprite
   St.Initialize(xPlay, "stan", "stan", 100,100, 1, 0, 1,1)
   St.IsClickable = True
   St.IsDraggable = True
   xPlay.AddDisplayObject(St)
 
   Dim ky As ABMXPSprite
   ky.Initialize(xPlay, "kyle", "kyle", 250,200, 1, 0, 1,1)
   ky.IsClickable = True
     ky.IsDraggable = True
   xPlay.AddDisplayObject(ky)
 
   Dim er As ABMXPSprite
   er.Initialize(xPlay, "eric", "eric", 400,150, 1, 0, 1,1)
   er.IsClickable = True
     er.IsDraggable = True
   xPlay.AddDisplayObject(er)
 
   ' create a tiled sprite with waves
     Dim overlay As ABMXPSprite
   overlay.InitializeTiling(xPlay,"overlaySprite", "zeldaWaves", 0,0, 0.09, 0, 1,1,0,0,1,1)
   ' we want the overlay to stay on top if we click on the characters
   overlay.StayOnTop = True
   xPlay.AddDisplayObject(overlay)

   ' IMPORTANT! We do not need the SERVERTouchUp event to be raised.
   Return False
End Sub

Will be translated to JavaScript as:

B4X:
this.b4jspreloadcomplete = function (_xplay){
   try {
     var _bg;
     var tmpTexture_bg=_xplay.getasset("background");
     _bg=new PIXI.Sprite(tmpTexture_bg);
     _bg.position.x = 0 + tmpTexture_bg.ABXPWidth / 2;
     _bg.position.y = 0 + tmpTexture_bg.ABXPHeight / 2;
     _bg.ABXPWidth = tmpTexture_bg.ABXPWidth;
     _bg.ABXPHeight = tmpTexture_bg.ABXPHeight;
     _bg.ABXPParentName='';
     var tmpPivotX = tmpTexture_bg.ABXPWidth / 2;
     var tmpPivotY = tmpTexture_bg.ABXPWidth / 2;
     _bg.anchor.x = 0.5;
     _bg.anchor.y = 0.5;
     _bg.interactive=false;
     _bg.alpha=1;
     _bg.rotation=0;
     _bg.scale.x=1;
     _bg.scale.y=1;
     _bg.tilePosition={x: 0, y:0};
     _bg.tileScale={x: 0, y:0};
     _bg.ApplyFilters=[];
     _bg.emitters={};
     _bg.ABXPName="background";
     _bg.isTweening=false;
     _bg.hasMask=false;
     if (_bg.interactive) {
       _xplay.DoInteractive(_bg,[0,0,0,0,0], false, false, "sprite");
     }
     if (_bg.ABXPParentName == '') {
       _xplay.getscene().addChild(_bg);
     } else {
       _xplay.setobject(_bg.ABXPParentName,_bg);
     }
     _xplay.setobject(_bg.ABXPName,_bg);
     var _displacementmapsprite;
     var tmpTexture_displacementmapsprite=_xplay.getasset("displacementmap");
     _displacementmapsprite=new PIXI.Sprite(tmpTexture_displacementmapsprite);
     _displacementmapsprite.position.x = 0 + tmpTexture_displacementmapsprite.ABXPWidth / 2;
     _displacementmapsprite.position.y = 0 + tmpTexture_displacementmapsprite.ABXPHeight / 2;
     _displacementmapsprite.ABXPWidth = tmpTexture_displacementmapsprite.ABXPWidth;
     _displacementmapsprite.ABXPHeight = tmpTexture_displacementmapsprite.ABXPHeight;
     _displacementmapsprite.ABXPParentName='';
     var tmpPivotX = tmpTexture_displacementmapsprite.ABXPWidth / 2;
     var tmpPivotY = tmpTexture_displacementmapsprite.ABXPWidth / 2;
     _displacementmapsprite.anchor.x = 0.5;
     _displacementmapsprite.anchor.y = 0.5;
     _displacementmapsprite.interactive=false;
     _displacementmapsprite.alpha=1;
     _displacementmapsprite.rotation=0;
     _displacementmapsprite.scale.x=1;
     _displacementmapsprite.scale.y=1;
     _displacementmapsprite.tilePosition={x: 0, y:0};
     _displacementmapsprite.tileScale={x: 0, y:0};
     _displacementmapsprite.ApplyFilters=[];
     _displacementmapsprite.emitters={};
     _displacementmapsprite.ABXPName="displacementmapsprite";
     _displacementmapsprite.isTweening=false;
     _displacementmapsprite.hasMask=false;
     if (_displacementmapsprite.interactive) {
       _xplay.DoInteractive(_displacementmapsprite,[0,0,0,0,0], false, false, "sprite");
     }
     if (_displacementmapsprite.ABXPParentName == '') {
       _xplay.getscene().addChild(_displacementmapsprite);
     } else {
       _xplay.setobject(_displacementmapsprite.ABXPParentName,_displacementmapsprite);
     }
     _xplay.setobject(_displacementmapsprite.ABXPName,_displacementmapsprite);
     var _filter;
     var _tmpSpriteTexture_filter=_xplay.getobject("displacementmapsprite");
     _filter=new PIXI.filters.DisplacementFilter(_tmpSpriteTexture_filter);
     _filter.scale.x=50;
     _filter.scale.y=50;
     _filter.ABXPType=1;
     _xplay.getscene().ApplyFilters.push(_filter);
     _xplay.getscene().filters = _xplay.getscene().ApplyFilters;
     for (var _i=0;_i<=100;_i++) {
       var _scale=0.2*(Math.random() * (1 - 0) + 0) +0.2;
       var _kn;
       var tmpTexture_kn=_xplay.getasset("kenny");
       _kn=new PIXI.Sprite(tmpTexture_kn);
       _kn.position.x = 630*(Math.random() * (1 - 0) + 0)  + tmpTexture_kn.ABXPWidth / 2;
       _kn.position.y = 300*(Math.random() * (1 - 0) + 0)  + tmpTexture_kn.ABXPHeight / 2;
       _kn.ABXPWidth = tmpTexture_kn.ABXPWidth;
       _kn.ABXPHeight = tmpTexture_kn.ABXPHeight;
       _kn.ABXPParentName='';
       var tmpPivotX = tmpTexture_kn.ABXPWidth / 2;
       var tmpPivotY = tmpTexture_kn.ABXPWidth / 2;
       _kn.anchor.x = 0.5;
       _kn.anchor.y = 0.5;
       _kn.interactive=false;
       _kn.alpha=0.33;
       _kn.rotation=0;
       _kn.scale.x=_scale;
       _kn.scale.y=_scale;
       _kn.tilePosition={x: 0, y:0};
       _kn.tileScale={x: 0, y:0};
       _kn.ApplyFilters=[];
       _kn.emitters={};
       _kn.ABXPName="kenny"+i;
       _kn.isTweening=false;
       _kn.hasMask=false;
       if (_kn.interactive) {
         _xplay.DoInteractive(_kn,[0,0,0,0,0], false, false, "sprite");
       }
       if (_kn.ABXPParentName == '') {
         _xplay.getscene().addChild(_kn);
       } else {
         _xplay.setobject(_kn.ABXPParentName,_kn);
       }
       _xplay.setobject(_kn.ABXPName,_kn);
     }
     var _st;
     var tmpTexture_st=_xplay.getasset("stan");
     _st=new PIXI.Sprite(tmpTexture_st);
     _st.position.x = 100 + tmpTexture_st.ABXPWidth / 2;
     _st.position.y = 100 + tmpTexture_st.ABXPHeight / 2;
     _st.ABXPWidth = tmpTexture_st.ABXPWidth;
     _st.ABXPHeight = tmpTexture_st.ABXPHeight;
     _st.ABXPParentName='';
     var tmpPivotX = tmpTexture_st.ABXPWidth / 2;
     var tmpPivotY = tmpTexture_st.ABXPWidth / 2;
     _st.anchor.x = 0.5;
     _st.anchor.y = 0.5;
     _st.interactive=true;
     _st.alpha=1;
     _st.rotation=0;
     _st.scale.x=1;
     _st.scale.y=1;
     _st.tilePosition={x: 0, y:0};
     _st.tileScale={x: 0, y:0};
     _st.ApplyFilters=[];
     _st.emitters={};
     _st.ABXPName="stan";
     _st.isTweening=false;
     _st.hasMask=false;
     if (_st.interactive) {
       _xplay.DoInteractive(_st,[0,0,0,0,0], true, true, "sprite");
     }
     if (_st.ABXPParentName == '') {
       _xplay.getscene().addChild(_st);
     } else {
       _xplay.setobject(_st.ABXPParentName,_st);
     }
     _xplay.setobject(_st.ABXPName,_st);
     var _ky;
     var tmpTexture_ky=_xplay.getasset("kyle");
     _ky=new PIXI.Sprite(tmpTexture_ky);
     _ky.position.x = 250 + tmpTexture_ky.ABXPWidth / 2;
     _ky.position.y = 200 + tmpTexture_ky.ABXPHeight / 2;
     _ky.ABXPWidth = tmpTexture_ky.ABXPWidth;
     _ky.ABXPHeight = tmpTexture_ky.ABXPHeight;
     _ky.ABXPParentName='';
     var tmpPivotX = tmpTexture_ky.ABXPWidth / 2;
     var tmpPivotY = tmpTexture_ky.ABXPWidth / 2;
     _ky.anchor.x = 0.5;
     _ky.anchor.y = 0.5;
     _ky.interactive=true;
     _ky.alpha=1;
     _ky.rotation=0;
     _ky.scale.x=1;
     _ky.scale.y=1;
     _ky.tilePosition={x: 0, y:0};
     _ky.tileScale={x: 0, y:0};
     _ky.ApplyFilters=[];
     _ky.emitters={};
     _ky.ABXPName="kyle";
     _ky.isTweening=false;
     _ky.hasMask=false;
     if (_ky.interactive) {
       _xplay.DoInteractive(_ky,[0,0,0,0,0], true, true, "sprite");
     }
     if (_ky.ABXPParentName == '') {
       _xplay.getscene().addChild(_ky);
     } else {
       _xplay.setobject(_ky.ABXPParentName,_ky);
     }
     _xplay.setobject(_ky.ABXPName,_ky);
     var _er;
     var tmpTexture_er=_xplay.getasset("eric");
     _er=new PIXI.Sprite(tmpTexture_er);
     _er.position.x = 400 + tmpTexture_er.ABXPWidth / 2;
     _er.position.y = 150 + tmpTexture_er.ABXPHeight / 2;
     _er.ABXPWidth = tmpTexture_er.ABXPWidth;
     _er.ABXPHeight = tmpTexture_er.ABXPHeight;
     _er.ABXPParentName='';
     var tmpPivotX = tmpTexture_er.ABXPWidth / 2;
     var tmpPivotY = tmpTexture_er.ABXPWidth / 2;
     _er.anchor.x = 0.5;
     _er.anchor.y = 0.5;
     _er.interactive=true;
     _er.alpha=1;
     _er.rotation=0;
     _er.scale.x=1;
     _er.scale.y=1;
     _er.tilePosition={x: 0, y:0};
     _er.tileScale={x: 0, y:0};
     _er.ApplyFilters=[];
     _er.emitters={};
     _er.ABXPName="eric";
     _er.isTweening=false;
     _er.hasMask=false;
     if (_er.interactive) {
       _xplay.DoInteractive(_er,[0,0,0,0,0], true, true, "sprite");
     }
     if (_er.ABXPParentName == '') {
       _xplay.getscene().addChild(_er);
     } else {
       _xplay.setobject(_er.ABXPParentName,_er);
     }
     _xplay.setobject(_er.ABXPName,_er);
     var _overlay;
     var tmpTexture_overlay=_xplay.getasset("zeldawaves");
     _overlay=new PIXI.extras.TilingSprite(tmpTexture_overlay, tmpTexture_overlay.ABXPWidth, tmpTexture_overlay.ABXPHeight);
     _overlay.position.x = 0 + tmpTexture_overlay.ABXPWidth / 2;
     _overlay.position.y = 0 + tmpTexture_overlay.ABXPHeight / 2;
     _overlay.ABXPWidth = tmpTexture_overlay.ABXPWidth;
     _overlay.ABXPHeight = tmpTexture_overlay.ABXPHeight;
     _overlay.ABXPParentName='';
     var tmpPivotX = tmpTexture_overlay.ABXPWidth / 2;
     var tmpPivotY = tmpTexture_overlay.ABXPWidth / 2;
     _overlay.anchor.x = 0.5;
     _overlay.anchor.y = 0.5;
     _overlay.interactive=false;
     _overlay.alpha=0.09;
     _overlay.rotation=0;
     _overlay.scale.x=1;
     _overlay.scale.y=1;
     _overlay.tilePosition.x=0;
     _overlay.tilePosition.y=0;
     _overlay.tileScale.x=1;
     _overlay.tileScale.y=1;
     _overlay.ApplyFilters=[];
     _overlay.emitters={};
     _overlay.ABXPName="overlaysprite";
     _overlay.isTweening=false;
     _overlay.hasMask=false;
     _overlay.StayOnTop=true;
     if (_overlay.interactive) {
       _xplay.DoInteractive(_overlay,[0,0,0,0,0], false, false, "sprite");
     }
     if (_overlay.ABXPParentName == '') {
       _xplay.getscene().addChild(_overlay);
     } else {
       _xplay.setobject(_overlay.ABXPParentName,_overlay);
     }
     _xplay.setobject(_overlay.ABXPName,_overlay);
     return false;
   }
   catch(err) {
     console.log(err.message + ' ' + err.stack);
   }
   };

3. Your own methods can be converted too

You can create your own methods that need to be translated to Javascript. The same rules as for a B4JS event apply. The method MUST have a prefix B4JS:

Example:

B4X:
Sub B4JSRotateFilter(xplay As ABMXPlay, sprite As ABMXPSprite, index As Int)
   ' when initialized
     If B4JSCharFilterStates(index) = 0 Then
     B4JSCharFilterStates(index) = 1
   End If
  
     B4JSCharFilterStates(index) = B4JSCharFilterStates(index) + 1
     If B4JSCharFilterStates(index) = 8 Then B4JSCharFilterStates(index) = 1

    ' set a new filter
   Select Case B4JSCharFilterStates(index)
       Case 1
          ' remove the previous filter
          sprite.RemoveFilter(ABM.XP.FILTERTYPE_RGBSPLITTER)
       Case 2 ' Blur
          Dim filter As ABMXPFilterBlur
          filter.Initialize(xplay,15,15)
          sprite.AddFilter(filter)
       Case 3 ' Pixelate
          ' remove the previous filter
          sprite.RemoveFilter(ABM.XP.FILTERTYPE_BLUR)
          Dim filter2 As ABMXPFilterPixelate
          filter2.Initialize(xplay, 5,5)
          sprite.AddFilter(filter2)
       Case 4 'Invert
          ' remove the previous filter
          sprite.RemoveFilter(ABM.XP.FILTERTYPE_PIXELATE)
          Dim filter3 As ABMXPFilterInvert
          filter3.Initialize(xplay, 1)
          sprite.AddFilter(filter3)
       Case 5 'Grayscale
         ' remove the previous filter
         sprite.RemoveFilter(ABM.XP.FILTERTYPE_INVERT)
         Dim filter4 As ABMXPFilterGrayScale
         filter4.Initialize(xplay,1)
         sprite.AddFilter(filter4)
       Case 6 ' Sepia
         ' remove the previous filter
         sprite.RemoveFilter(ABM.XP.FILTERTYPE_GRAYSCALE)
         Dim filter5 As ABMXPFilterSepia
         filter5.Initialize(xplay,1)
         sprite.AddFilter(filter5)
       Case 7 'RGBSplitter
         ' remove the previous filter
         sprite.RemoveFilter(ABM.XP.FILTERTYPE_SEPIA)
         Dim filter6 As ABMXPFilterRGBSplitter
         filter6.Initialize(xplay, 20,20,-20,20,20,-20)
         sprite.AddFilter(filter6)
  End Select
End Sub

Will be translated to:

B4X:
this.b4jsrotatefilter = function (_xplay,_sprite,_index){
   try {
     if (this._b4jscharfilterstates[_index] == 0) {
       this._b4jscharfilterstates[_index]=1;
     }
     this._b4jscharfilterstates[_index]=this._b4jscharfilterstates[_index]+1;
     if (this._b4jscharfilterstates[_index] == 8) {
       this._b4jscharfilterstates[_index]=1;
     }
     switch (this._b4jscharfilterstates[_index]) {
       case 1:
         for (var _abmrem=0;_abmrem<_sprite.ApplyFilters.length;_abmrem++) {
           if (_sprite.ApplyFilters[_abmrem].ABXPType==11) {
             _sprite.ApplyFilters.splice(_abmrem,1);
             break;
           }
         }
         _sprite.filters = _sprite.ApplyFilters.length > 0 ? _sprite.ApplyFilters : null;
         break;
       case 2:
         var _filter;
         _filter=new PIXI.filters.BlurFilter();
         _filter.ABXPType=2;
         _filter.blurX=15;
         _filter.blurY=15;
         _sprite.ApplyFilters.push(_filter);
         _sprite.filters = _sprite.ApplyFilters;
         break;
       case 3:
         for (var _abmrem=0;_abmrem<_sprite.ApplyFilters.length;_abmrem++) {
           if (_sprite.ApplyFilters[_abmrem].ABXPType==2) {
             _sprite.ApplyFilters.splice(_abmrem,1);
             break;
           }
         }
         _sprite.filters = _sprite.ApplyFilters.length > 0 ? _sprite.ApplyFilters : null;
         var _filter2;
         _filter2=new PIXI.filters.PixelateFilter();
         _filter2.ABXPType = 3;
         _filter2.size.x=5;
         _filter2.size.y=5;
         _sprite.ApplyFilters.push(_filter2);
         _sprite.filters = _sprite.ApplyFilters;
         break;
       case 4:
         for (var _abmrem=0;_abmrem<_sprite.ApplyFilters.length;_abmrem++) {
           if (_sprite.ApplyFilters[_abmrem].ABXPType==3) {
             _sprite.ApplyFilters.splice(_abmrem,1);
             break;
           }
         }
         _sprite.filters = _sprite.ApplyFilters.length > 0 ? _sprite.ApplyFilters : null;
         var _filter3;
         _filter3=new PIXI.filters.InvertFilter();
         _filter3.ABXPType=4;
         _filter3.invert=1;
         _sprite.ApplyFilters.push(_filter3);
         _sprite.filters = _sprite.ApplyFilters;
         break;
       case 5:
         for (var _abmrem=0;_abmrem<_sprite.ApplyFilters.length;_abmrem++) {
           if (_sprite.ApplyFilters[_abmrem].ABXPType==4) {
             _sprite.ApplyFilters.splice(_abmrem,1);
             break;
           }
         }
         _sprite.filters = _sprite.ApplyFilters.length > 0 ? _sprite.ApplyFilters : null;
         var _filter4;
         _filter4=new PIXI.filters.GrayFilter();
         _filter4.ABXPType=5;
         _filter4.gray=1;
         _sprite.ApplyFilters.push(_filter4);
         _sprite.filters = _sprite.ApplyFilters;
         break;
       case 6:
         for (var _abmrem=0;_abmrem<_sprite.ApplyFilters.length;_abmrem++) {
           if (_sprite.ApplyFilters[_abmrem].ABXPType==5) {
             _sprite.ApplyFilters.splice(_abmrem,1);
             break;
           }
         }
         _sprite.filters = _sprite.ApplyFilters.length > 0 ? _sprite.ApplyFilters : null;
         var _filter5;
         _filter5=new PIXI.filters.SepiaFilter();
         _filter5.ABXPType=6;
         _filter5.sepia=1;
         _sprite.ApplyFilters.push(_filter5);
         _sprite.filters = _sprite.ApplyFilters;
         break;
       case 7:
         for (var _abmrem=0;_abmrem<_sprite.ApplyFilters.length;_abmrem++) {
           if (_sprite.ApplyFilters[_abmrem].ABXPType==6) {
             _sprite.ApplyFilters.splice(_abmrem,1);
             break;
           }
         }
         _sprite.filters = _sprite.ApplyFilters.length > 0 ? _sprite.ApplyFilters : null;
         var _filter6;
         _filter6=new PIXI.filters.RGBSplitFilter();
         _filter6.ABXPType=11;
         _filter6.red.x=20;
         _filter6.red.y=20;
         _filter6.green.x=-20;
         _filter6.green.y=20;
         _filter6.blue.x=20;
         _filter6.blue.y=-20;
         _sprite.ApplyFilters.push(_filter6);
         _sprite.filters = _sprite.ApplyFilters;
         break;
     }
   }
   catch(err) {
     console.log(err.message + ' ' + err.stack);
   }
   };

That is it for now for the introduction. Still a lot of work to do, but currently I'm already able to convert the Filter demo. I'll keep you up to date on my progress in this topic, so keep an eye on it!

Alwaysbusy
 
Last edited:

alwaysbusy

Expert
Licensed User
Longtime User
After your compiling to Java, I read the .bas files in ABMaterial and transpile the B4JS prefixed methods and vars to javascript. This new javascript is then written into the pages .js file. I'm not there yet, but I'm thinking it should be possible in debug mode to pass through the B4J methods instead of the Javascript ones. This way, one could continue to use the B4J debugging facilities. (it is not a 100% guarantee there is no error in the generated Javascript code, but it could be a start). In the B4J log, I also give some feedback when transpiling. E.g. [ERROR: module, method, B4J line number]: myvar is of a type MyClass and can not be translated to Javascript.
 
Top