How to do the painted backdrop thing


Hey, so quick tech update in case anyone else wants to do something similar.
Please bear in mind that I am not a javascript dev -  there are probably less stupid ways to do this.

------ UPDATE : A much less stupid way ------

The brilliant AYo (https://ayolland.itch.io/) and Sean (https://seansleblanc.itch.io/) have put the hack into the excellent Bitsy hack applying tool Borksy -- this makes it super easy to apply, just follow the instructions given. This particular hack is called "Backdrops".

I've left the below in place in case it's helpful for anyone trying to make a variant on this approach, but honestly in all other cases, much better to use the above.

-----------------------------------------------
(Original text)

There are 3 basic parts:

  • Transparent Sprites (so they don't carry a chunk of background with them)
  • Transparent Background
  • Per room backdrops

As with any hacks, get your game working in vanilla bitsy first -- it will save you a lot of pain.

1) Transparent Sprites

This is the easy bit - use Borksy and Sean's excellent Transparent Sprites hack. Instructions are on the Borksy page.

2) Transparent Background

Fortunately, Freya gave me the exact code to do this:

Change:

//clear screen   
if (room.pal != null && palette[paletteId] != undefined) {
paletteId = room.pal;
}
context.fillStyle = "rgb(" + getPal(paletteId)[0][0] + "," + getPal(paletteId)[0][1] + "," + getPal(paletteId)[0][2] + ")";
context.fillRect(0,0,canvas.width,canvas.height);

to

//clear screen   
if (room.pal != null && palette[paletteId] != undefined) {
paletteId = room.pal;
}
context.fillStyle = "rgba(" + getPal(paletteId)[0][0] + "," + getPal(paletteId)[0][1] + "," + getPal(paletteId)[0][2] + "," + getPal(curPal())[0][3] + ")";
context.clearRect(0,0,canvas.width,canvas.height);

and

ctx.fillStyle = "rgb(" + getPal(curPal())[0][0] + "," + getPal(curPal())[0][1] + "," + getPal(curPal())[0][2] + ")";
ctx.fillRect(0,0,canvas.width,canvas.height);

to

ctx.fillStyle = "rgba(" + getPal(curPal())[0][0] + "," + getPal(curPal())[0][1] + "," + getPal(curPal())[0][2] + "," + getPal(curPal())[0][3] + ")";
ctx.clearRect(0,0,canvas.width,canvas.height);


3) Backdrops

To expand on how this works, my approach assumes that you'll have an image with the same name as the room plus ".png", and an extra image called "title.png" to drop behind the title. These images should be in a /images folder in your game's directory.

So, for a room called "village" you'd have a background called "images/village.png".

a) In the #game css set the background size to "cover"

And I also set the title background, though we overwrite it in a moment.

#game {
    background:#000;
    background-image:url("images/title.png");     /*NEW*/
    background-size: cover;    /*NEW*/

b) At the top of the script section, define an array for the background images

var room = {};
var tile = {};
var sprite = {};
var item = {};
var dialog = {};
var bgimages = {};   //NEW

(A smarter approach might have been to have the bg image be a room attribute, but nevermind.)

c) In the room parse we want to load this array

        else if (getType(lines[i]) === "NAME") {
            var name = lines[i].split(/\s(.+)/)[1];
            room[id].name = name;
            names.room.set(name, id);
            bgimages[id] = new Image();                        //NEW - initialise
            bgimages[id].src = "images/"+ name +".png";        //NEW - set src based on name            
            document.getElementById('game').style.backgroundImage="url("+ bgimages[id].src +")";   //NEW - see note  
        }

The last line is the dodgy one. It temporarily sets the BG to the image we've just initialised. It may help with pre-loading the images, but I couldn't prove this conclusively.

d) At the end of the start up function set the BG to the title image.

This is only needed because we also set the BG when populating the array, otherwise we could just do it in the CSS.

    document.getElementById('game').style.backgroundImage="url(images/title.png)";   //NEW     
    if(startWithTitle) { // used by editor         
        startNarrating(getTitle());
    }

e) In the Room Clear function, set the background image

This is the same bit of code we amended for transparent backgrounds, above.

    //clear screen
    document.getElementById('game').style.backgroundImage="url("+ bgimages[room.id].src +")"; //NEW
    if (room.pal != null && palette[paletteId] != undefined) {
        paletteId = room.pal;
    }
    context.fillStyle = "rgba(" + getPal(paletteId)[0][0] + "," + getPal(paletteId)[0][1] + "," + getPal(paletteId)[0][2] + "," + getPal(curPal())[0][3] + ")";

Note the BG is probably being set more often than it needs to be, but it doesn't seem to be a problem.


And that's it. 

As I say, there are probably better ways to do this. I am not a Javascript person. If you do a better engineered version, please do a devlog and drop me a link.

Let me know if you have difficulty getting it working.

Leave a comment

Log in with itch.io to leave a comment.