@@ -241,6 +241,13 @@ if (backgrounds.length > 0) {
241
241
HIDE_IMAGE("BACKGROUND");
242
242
}
243
243
244
+ let midgrounds = FIELDS_OR_LIBRARY("midground");
245
+ if (midgrounds.length > 0) {
246
+ SHOW_IMAGE("MIDGROUND", midgrounds, 1, 0, 0);
247
+ } else if (IS_TAGGED(EVENT, "clear-midground")) {
248
+ HIDE_IMAGE("MIDGROUND");
249
+ }
250
+
244
251
let foregrounds = FIELDS_OR_LIBRARY("foreground");
245
252
if (foregrounds.length > 0) {
246
253
SHOW_IMAGE("FOREGROUND", foregrounds, 2, 0, 0);
@@ -540,57 +547,75 @@ class BipsiPlayback extends EventTarget {
540
547
this . render ( ) ;
541
548
}
542
549
543
- render ( frame = undefined ) {
550
+ addRoomToScene ( scene , dest , frame ) {
544
551
// find avatar, current room, current palette
545
552
const avatar = getEventById ( this . data , this . avatarId ) ;
546
553
const room = roomFromEvent ( this . data , avatar ) ;
547
554
const palette = this . getActivePalette ( ) ;
548
555
const tileset = this . stateManager . resources . get ( this . data . tileset ) ;
549
556
550
557
// find current animation frame for each tile
551
- frame = frame ?? this . frameCount ;
552
558
const tileToFrame = makeTileToFrameMap ( this . data . tiles , frame ) ;
553
559
554
- // sort images
555
- const images = Array . from ( this . images . values ( ) ) ;
556
- images . sort ( ( a , b ) => a . layer - b . layer ) ;
557
- const images_below_all = images . filter ( ( image ) => image . layer < 1 ) ;
558
- const images_below_events = images . filter ( ( image ) => image . layer >= 1 && image . layer < 2 ) ;
559
- const images_above_events = images . filter ( ( image ) => image . layer >= 2 && image . layer < 3 ) ;
560
- const images_above_all = images . filter ( ( image ) => image . layer >= 3 ) ;
560
+ function upscaler ( func ) {
561
+ return ( ) => {
562
+ fillRendering2D ( TEMP_ROOM ) ;
563
+ func ( ) ;
564
+ dest . drawImage ( TEMP_ROOM . canvas , 0 , 0 , 256 , 256 ) ;
565
+ } ;
566
+ }
567
+
568
+ scene . push ( { layer : 1 , func : upscaler ( ( ) => drawTilemapLayer ( TEMP_ROOM , tileset , tileToFrame , palette , room ) ) } ) ;
569
+ scene . push ( { layer : 2 , func : upscaler ( ( ) => drawEventLayer ( TEMP_ROOM , tileset , tileToFrame , palette , room . events ) ) } ) ;
570
+ }
561
571
572
+ addImagesToScene ( scene , dest , frame ) {
562
573
function drawImage ( { image, x, y } ) {
563
- TEMP_ROOM . drawImage ( image [ frame % image . length ] , x , y ) ;
574
+ dest . drawImage ( image [ frame % image . length ] , x , y ) ;
564
575
}
565
576
566
- fillRendering2D ( this . rendering ) ;
567
- images_below_all . forEach ( drawImage ) ;
568
- drawTilemapLayer ( TEMP_ROOM , tileset , tileToFrame , palette , room ) ;
569
- images_below_events . forEach ( drawImage ) ;
570
- drawEventLayer ( TEMP_ROOM , tileset , tileToFrame , palette , room . events ) ;
571
- images_above_events . forEach ( drawImage ) ;
572
-
573
- // upscale tilemaps to display area
574
- this . rendering . drawImage ( TEMP_ROOM . canvas , 0 , 0 , 256 , 256 ) ;
575
-
576
- // render dialogue box if necessary
577
- if ( ! this . dialoguePlayback . empty ) {
578
- // change default dialogue position based on avatar position
579
- const top = avatar . position [ 1 ] >= 8 ;
580
- this . dialoguePlayback . options . anchorY = top ? 0 : 1 ;
581
-
582
- // redraw dialogue and copy to display area
583
- this . dialoguePlayback . render ( ) ;
584
- this . rendering . drawImage ( this . dialoguePlayback . dialogueRendering . canvas , 0 , 0 ) ;
577
+ const images = [ ...this . images . values ( ) ] ;
578
+ const draws = images . map ( ( image ) => ( { layer : image . layer , func : ( ) => drawImage ( image ) } ) ) ;
579
+
580
+ scene . push ( ...draws ) ;
581
+ }
582
+
583
+ addDialogueToScene ( scene , dest , frame ) {
584
+ if ( this . dialoguePlayback . empty )
585
+ return ;
586
+
587
+ // change default dialogue position based on avatar position
588
+ const avatar = getEventById ( this . data , this . avatarId ) ;
589
+ const top = avatar . position [ 1 ] >= 8 ;
590
+ this . dialoguePlayback . options . anchorY = top ? 0 : 1 ;
591
+
592
+ // redraw dialogue and copy to display area
593
+ this . dialoguePlayback . render ( ) ;
594
+ scene . push ( { layer : 3 , func : ( ) => dest . drawImage ( this . dialoguePlayback . dialogueRendering . canvas , 0 , 0 ) } ) ;
595
+ }
596
+
597
+ addLayersToScene ( scene , dest , frame ) {
598
+ if ( ! this . ended ) {
599
+ this . addRoomToScene ( scene , dest , frame ) ;
600
+ this . addDialogueToScene ( scene , dest , frame ) ;
601
+ this . addImagesToScene ( scene , dest , frame ) ;
585
602
}
603
+ }
604
+
605
+ render ( frame = undefined ) {
606
+ frame = frame ?? this . frameCount ;
607
+
608
+ const scene = [ ] ;
586
609
587
- fillRendering2D ( TEMP_ROOM ) ;
588
- images_above_all . forEach ( drawImage ) ;
589
- this . rendering . drawImage ( TEMP_ROOM . canvas , 0 , 0 , 256 , 256 ) ;
610
+ // add visual layers to scene
611
+ this . addLayersToScene ( scene , this . rendering , frame ) ;
590
612
591
- if ( this . ended ) {
592
- fillRendering2D ( this . rendering ) ;
593
- }
613
+ // sort visual layers
614
+ scene . sort ( ( a , b ) => a . layer - b . layer ) ;
615
+
616
+ // clear and draw layers
617
+ fillRendering2D ( this . rendering ) ;
618
+ scene . forEach ( ( { func } ) => func ( ) ) ;
594
619
595
620
// signal, to anyone listening, that rendering happened
596
621
this . dispatchEvent ( new CustomEvent ( "render" ) ) ;
0 commit comments