Page 1 of 1

Tilemapper

PostPosted: Mon Jul 20, 2015 12:04 am
by Sorunome
Soooooo, Marcus was making yet another tilemapper routine so I thought: wouldn't it be great to have something like that in the default library?
Here I am, the tree with that can be found here: https://github.com/Sorunome/Gamebuino/tree/tilemapper
It allows for things like this:
Code: Select all
#include <SPI.h>
#include <Gamebuino.h>
Gamebuino gb;

// define some sprites
const byte sprite0[] PROGMEM = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
const byte sprite1[] PROGMEM = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

// define the spritesheet
const byte *spritesheet[] = {sprite0,sprite1};

// define the tilemap
const byte tilemap[] PROGMEM = {12,12,
  8,8,
  0,1,0,1,0,1,0,1,0,1,0,1,
  1,0,1,0,1,0,1,0,1,0,1,0,
  0,1,0,1,0,1,0,1,0,1,0,1,
  1,0,1,0,1,0,1,0,1,0,1,0,
  0,1,0,1,0,1,0,1,0,1,0,1,
  1,0,1,0,1,0,1,0,1,0,1,0,
  0,1,0,1,0,1,0,1,0,1,0,1,
  1,0,1,0,1,0,1,0,1,0,1,0,
  0,1,0,1,0,1,0,1,0,1,0,1,
  1,0,1,0,1,0,1,0,1,0,1,0,
  0,1,0,1,0,1,0,1,0,1,0,1,
  1,0,1,0,1,0,1,0,1,0,1,0,
};
void setup() {
  // put your setup code here, to run once:
  gb.begin();
  gb.titleScreen(F("test"));
  gb.display.clear();
  gb.display.drawTilemap(-3,-1,tilemap,spritesheet,4,4,76,30); // draw the tilemap
  gb.display.drawRect(2,2,80,34);
  gb.display.update();
}

void loop() {
  // put your main code here, to run repeatedly:
}

Now, as you can see gb.display.drawTilemap(); is the new function.
the last four parameters are optional, here is how stuff is working:
gb.display.drawTilemap(x,y,tilemap,spritesheet[,drawX,drawY,drawWidth,drawHeight]);

so, tilemap and spritesheet should be pretty straight forward, x and y are for offsets, so that if y is -5 for example the whole tilemap is displayed five pixels up, that is so that you could easily make it so that a character walks around and the tilemap moves.

Now, what are those mysterious last four parameters? If defined the tilmap will ONLY be rendered in that area! Be sure to note that x/y is actually relative to drawX/drawY.
That means that something like gb.display.drawTilemap(x,y,tilemap,spritesheet,0,0,LCDWIDTH,LCDHEIGHT-8); for example would always leave the lower 8 pixels of the screen free, so you could, for example, draw some stats there!

I hope you enjoy!


Oh, also, any-sized tiles are allowed, in the tilemap definition the first two numbers are width/height of the tilemap, the second two width/height of the tiles! The tiles themselves don't have any width/height stored to save space.

EDIT: Also rodot, as my browser is acting up right now i can't create a pull request :/

Re: Tilemapper

PostPosted: Mon Jul 20, 2015 12:44 am
by Marcus
me2shock.png
me2shock.png (1.92 KiB) Viewed 5704 times
Wow!!!

Thanks!

//Edit: This works really great. Too sleepy to make something worthwhile, but I just made a simple "road tile test" if you want a map to scroll around on; Using 5x5 tiles instead of the common 8x8.

Code: Select all
    #include <SPI.h>
    #include <Gamebuino.h>
    Gamebuino gb;
 
//map followed by tilesprites

const byte

tilemap[] PROGMEM = {24,24,
  0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  0,6,1,1,3,0,4,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  0,0,0,0,2,0,6,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  1,1,1,1,8,1,1,1,1,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  0,0,0,0,2,0,0,0,0,6,1,1,1,1,8,0,0,0,0,0,0,0,0,0,
  0,0,0,0,2,0,0,4,1,1,1,1,1,1,8,1,1,1,1,3,0,0,0,0,
  0,0,4,1,8,1,1,5,0,0,0,0,0,0,2,0,0,0,0,6,1,1,1,1,
  0,0,2,0,6,1,1,1,1,3,0,0,0,0,2,0,0,0,0,0,0,0,0,0,
  0,0,2,0,0,0,0,0,0,2,0,0,0,0,6,1,1,3,0,0,0,0,0,0,
  1,1,5,0,0,0,0,0,0,2,0,0,0,0,0,0,0,2,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,2,0,0,0,0,0,0,
  0,0,0,0,2,0,0,0,0,8,3,0,0,0,0,0,0,2,0,0,0,0,0,0,
  0,0,0,1,8,1,0,0,0,8,5,0,0,0,0,0,0,0,0,0,0,0,0,0,
  0,0,0,0,2,0,0,0,0,8,3,0,0,0,4,3,0,0,4,3,0,0,0,0,
  0,0,0,0,0,0,0,0,0,8,5,0,0,0,6,5,0,0,6,5,0,0,0,0,
  0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0,0,2,0,0,0,2,0,0,0,0,0,0,2,0,0,0,
  0,0,0,4,1,1,1,1,1,5,0,0,0,6,1,1,1,1,1,1,5,0,0,0,
  0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,
  0,0,0,2,0,0,0,0,0,0,0,0,2,0,0,0,0,8,0,0,0,0,0,0,
  0,0,0,2,0,0,0,0,0,0,2,0,2,0,0,0,0,0,8,0,0,0,0,0,
  0,0,0,2,0,0,0,0,2,0,2,0,2,0,0,0,0,0,0,8,0,0,0,0,
 
 
},


sprite0[] PROGMEM = {5,5, 
B00000000,
B00000000,
B00000000,
B00000000,
B00000000,
},

// -
sprite1[] PROGMEM = {5,5, 
B00000000,
B11111000,
B10001000,
B11111000,
B00000000,
},

// |
sprite2[] PROGMEM = {5,5, 
B01110000,
B01010000,
B01010000,
B01010000,
B01110000,
},

//  -.
sprite3[] PROGMEM = {5,5, 
B00000000,
B11100000,
B10110000,
B11010000,
B01110000,
},

//  .-
sprite4[] PROGMEM = {5,5, 
B00000000,
B00111000,
B01101000,
B01011000,
B01110000,
},

//  -'
sprite5[] PROGMEM = {5,5, 
B01110000,
B11010000,
B10110000,
B11100000,
B00000000,
},

//   '-
sprite6[] PROGMEM = {5,5, 
B01110000,
B01011000,
B01101000,
B00111000,
B00000000,
},


//   '-
sprite7[] PROGMEM = {5,5, 
B11111000,
B10001000,
B10001000,
B10001000,
B11111000,
},

//   '-
sprite8[] PROGMEM = {5,5, 
B01110000,
B11011000,
B10000000,
B11011000,
B01110000,
};


    // define the spritesheet
    const byte *spritesheet[] = {sprite0,sprite1,sprite2,sprite3,sprite4,sprite5,sprite6,sprite7,sprite8};

 

      int x=0,y=0;
   
    void setup() {

      gb.begin();
      gb.titleScreen(F("test"));
      gb.display.clear();
}
    void loop() {

     
  if(gb.update()){
   
if (gb.buttons.repeat(BTN_RIGHT,1)){x--;}
if (gb.buttons.repeat(BTN_LEFT,1)){x++;}
if (gb.buttons.repeat(BTN_DOWN,1)){y--;}
if (gb.buttons.repeat(BTN_UP,1)){y++;}


   
    }
  gb.display.clear();
       gb.display.drawTilemap(x,y,tilemap,spritesheet); // draw the tilemap
      gb.display.drawRect(2,2,x,y);

       

 gb.display.cursorY = 12; gb.display.println( x );gb.display.println( y );


      gb.display.update();


   
     

Re: Tilemapper

PostPosted: Tue Jul 21, 2015 8:48 pm
by Sorunome
Glad it is working for you!
You have some in-efficient code, though, allow me to make that more efficient:
Code: Select all
void setup() {
  gb.begin();
  gb.titleScreen(F("test"));
  gb.display.persistence = false;
}
void loop() {
  if(gb.update()){
    if (gb.buttons.repeat(BTN_RIGHT,1)){x--;}
    if (gb.buttons.repeat(BTN_LEFT,1)){x++;}
    if (gb.buttons.repeat(BTN_DOWN,1)){y--;}
    if (gb.buttons.repeat(BTN_UP,1)){y++;}
    gb.display.drawTilemap(x,y,tilemap,spritesheet); // draw the tilemap
    gb.display.drawRect(2,2,x,y);
    gb.display.cursorY = 12; gb.display.println( x );gb.display.println( y );
  }
}
The thing is you only need to update the screen if gb.update() returns true, so now you actually draw way fewer. I also set hte persistence to false so that the screen gets cleared automatically.



Also, i created a pull request on github! :D

Re: Tilemapper

PostPosted: Wed Jul 22, 2015 12:38 am
by Marcus
Sorunome wrote:
You have some in-efficient code, though, allow me to make that more efficient:
...
The thing is you only need to update the screen if gb.update() returns true, so now you actually draw way fewer. I also set hte persistence to false so that the screen gets cleared automatically.

Yes, I was just pasting the different things together (4am?) to test it, I won't win any prices with the spaghetti copypasta coding :-)
Funny that you left the draw rectangle x y in :-)

Re: Tilemapper

PostPosted: Sun Jul 26, 2015 10:39 pm
by Sorunome
Ok so i just changed a bit how data is laid out to save some bytes so that not every tile needs a width/height, check the first post for documentation
Or just check out https://github.com/Sorunome/Gamebuino/b ... ilemap.ino