Camera scrolling function update to higher resolution

I’m pretty certain it’s ok (maybe even encouraged), it just pays to give as much detail as possible upfront so people can clearly see the post is about a non-Arduboy specific topic. (It’s a bit of a grey area as to what topic it should be under though.)

No problem, sometimes it just helps to have a fresh pair of eyes.
The easiness of the ‘dialling in’ is one of the main reasons I restructured the code the way I did.
Having well named constants instead of ‘magic numbers’ really helps with both clarity and making code easy to change.

Thank you. Programming isn’t always about high level maths or complicated algorithms, sometimes it’s just remembering to do a bit of spring cleaning every now and again and knowing techniques to keep code ‘clean’ (i.e. readable and reusable). Stopping to think “if I come back in a year and I’ve forgotten everything about this, how horrified am I going to be?” is a good skill to have. (It’s not always easy, I’ve got several folders full of code I’m too scared to go back to.)

Zelda has some simple concepts behind it but can be hard to get right.
It’s a good game to attempt though because it’s a very well known example of tile maps.
(Also it’s one of my favourite game series. My favourite 2D title is probably Minish Cap, followed closely by the ‘Oracle Of’ duet.)

I just made it look better, I didn’t change any functionality - if it was broken before, it’s still broken.
If you’ve switched to a new library there will probably be some library differences involved.

You won’t get in trouble for that. There’s no rule that says people have to use the Arduboy2 library or that there can’t be any alternative libraries, just that Arduboy2 is considered the ‘preferred’ library.
I found the whole code anyway (the header on your github page, the github of the original ILI9341 project and your pjrc post - my google-fu knows no bounds). (The history of that file is a bit of a mess, it looks like it’s been passed around quite a lot.)

I’ve had a quick skim and it looks functionally sound (I’m particularly impressed that it’s using the rectangle collisions to make bitmap collisions faster).

What aspect of the collisions aren’t working?
Just the if(tft.collideRectRect(player_x, player_y,16,16,tft.solid[i].x,tft.solid[i].y,16,16)) line?

I love Zelda. It was one of the first games I played way back nin the good ole days of 8 bit gaming. I followed the series after that. I think mmy favorite though is sprit tracks.

when I first started building the library about a year and a half ago I started small with a color 8bit parelell screen that was a lil bigger than the arduboys but I sooned learned that spi was much easier and is included in all the fastest libraries. Plus the wiring would have made it all hard to fit in case that fits in your pocket. So then I started with a library that was compatible with mcu,s from arduino to esp. But that particular library had many drawbacks that were just too much for me to fix on my own. looking around I found Kurts library that had a buffer built in and some other cool stuff so I started converting it and updating a lot of the functions to work the way they need to for gaming. this went through many changes as you can guess. But what we came up with is a nice lil library. The esp library is a direct offshoot from the t3 version and let me tell you. Its fast!!! Im gonna pull the master though in favor of the two specific versions. I also need to make a regular arduino version for people who want, that can build smaller games. The great thing about using the ili9341 drivers is that they cover a good variety of screens so your not stuck using one size.

Yep, lol I use the same handle every where so im not hard to find. Im into a lot of stuff. I build guitars and robots and quadcopters and now ive been playing with 3d printing. So nice having my own.

All right so on the collision… its just not working. The function that’s in my sketch should see the 16x16 bitmaps as named then use the list to confirm whether or not to keep going when it hits solid but it never stops on anything marked solid. I added the popup as a test but I think my pop up function needs debugging as well. I guess I could do a serial print and see that way if its even recognizing the 4bpp bitmaps.

I asked this before but is there any way to speed the camera scroll up where it shows two rows or columns instead of one every time it updates? I have the boundaries all locked in and I can control player speed with in the boundary but when it hits the camera boundary and starts moving it is painfully slow. I mean slow!!!

Odd choice, a lot of people don’t like Spirit Tracks.
(It’s not my favourite but I don’t dislike it either. It had some nice dungeon designs, a few good gadgets and some very nice music.)

Serial printing is better for debugging in my experience.

I looked over it for several minutes and can’t see a reason why the comparisons would be failing or why the rectangle collision would be failing, so I looked to see where checkcolision was being called and I noticed that in the movement bit where you’re checking for collisions you’ve got the lines:

player_y = player_y - 5;
if(checkcolision()) player_y--; 

This doesn’t seem right to me.
You move the player up 5, then if it’s colliding with something you move it up 1. Surely you should be moving the player down 5 instead?
It seems to me that it’s more likely that the collision function is working fine and that this is your problem.

Didn’t notice you’d asked this, must have missed it.
In short, yes:

// Camera offset
int cameraX = -20;
int cameraY = -10;

// Camera speed in pixels per update
int cameraXSpeed = 2;
int cameraYSpeed = 2;

// Camera offset boundaries
const int cameraXMin = -52;
const int cameraXMax = 0;
const int cameraYMin = -40;
const int cameraYMax = 0;

// Player offset
int playerX = 70;
int playerY = 40;

// Player offset boundaries
const int playerXMin = 15;
const int playerXMax = 59;
const int playerYMin = 15;
const int playerYMax = 28;

// By clamping the camera before the checks
// you can avoid a lot of unnecessary comparisons
// as well as avoiding a frame where nothing happens.

// Clamp cameraX
if(cameraX < cameraXMin)
{
	cameraX = cameraXMin;
}
else if(cameraX > cameraXMax)
{
	 cameraX = cameraXMax;
}

// Clamp cameraY
if(cameraY < cameraYMin)
{
	cameraY = cameraYMin;
}
else if(cameraY > cameraYMax)
{
	 cameraY = cameraYMax;  
}

// Check if player is beyond X boundary
if(playerX < playerXMin)
{
	cameraX += cameraXSpeed;
	if(cameraX > cameraXMin && cameraX < cameraXMax)
	{
		playerX = playerXMin;
	}
}
else if(playerX > playerXMax)
{
	cameraX -= cameraXSpeed;
	if(cameraX > cameraXMin && cameraX < cameraXMax)
	{
		playerX = playerXMax;
	}
}

// Check if player is beyond Y boundary
if(playerY < playerYMin)
{
	cameraY += cameraYSpeed;
	if(cameraY > cameraYMin && cameraY < cameraYMax)
	{
		playerY = playerYMin;
	}
}
else if(playerY > playerYMax)
{
	cameraY -= cameraYSpeed;
	if(cameraY > cameraYMin && cameraY < cameraYMax)
	{
		playerY = playerYMax;
	}
}

You could just use one ‘speed’, but I put two in just in case you want to make it go quicker on one axis than the other for some reason. Also it’s not const in case you want to change it in-game for some reason (e.g. you have a speed powerup or something).

Awesome!!! Thank you so much. I’ve been busy still with development and encoding my sprites by hand, but I just flashed my board and gave it shot and it’s far less annoyingly slow. Lol. Actually it’s perfect. I left at +2 and it scrolls just right.

No problem.

If the boards you’re using have the same sprite format as the Arduboy, there are many converters available.

If not you should probably have a go at writing a converter or find someone who can.
What format do the sprites have to be in?

That’s the movement sorted then.

Did my suggestion about the issue with the collisions fix the collisions?

Ok I’m trying to understand what you were saying about the collision. I have the player movement set to 5 because the tilemap slows down the player movement. +5 takes care of that.

I still don’t really understand the function enough though.

Player _y = player_y - 5;
If(checkcollsion()) player_y --;

Both parts of the above should move the player down. Maybe I need to set the player_y–; to ++? So when the player is moving down and it hits a solid object it causes it to move back up 1?

Assuming you are using screen coordinates, this line should move the player up 5 pixels:
player_y = player_y - 5;

And this line:
if(checkcolision()) player_y--;
Checks if the player is colliding with something, and if they are, moves them up 1 pixel. Presumably this means you’re actually moving them further into the thing they’re colliding with, when you should be undoing the previous up motion (which, to the player, will look like the character hasn’t actually moved because the sprite will be drawn afterwards).

If your coordinates aren’t screen coordinates (i.e. they are world coordinates), that might be moving the player down.

In pretty much all screens it’s conventional to make the top-left corner of the screen the point (0, 0).
(It’s partly a hangover from the day of cathode ray tube monitors; their electron guns would start drawing at the top left and partly because text is read from top left in most languages.)

Ahhhh ok. So I looked up the original 8bit B&W sketch and saw what you meant. I changed the ++ to – and vice versa then set the player speed back to 1. Then ran the sketch once more but no change. I also tried adding more + or - but that gives Lvalue errors.

My cable is getting kinda wonky so using the serial monitor is out. Instead I told it to fill the screen with purple when it hits a tile but the screen never flashes purple.

What I’m saying is that instead of this:

 if (ButtonUp.fallingEdge()){
   tft.writeRectNBPP(player_x, player_y,16,16,4,paul_rearwalk1,palette);
                   player_direction = 1;
         player_y = player_y - 5;
         if(checkcolision())player_y--;} 
       if(player_y <= 16){
          player_y = 16;}

The code should be this:

if(ButtonUp.fallingEdge())
{
	tft.writeRectNBPP(player_x, player_y,16,16,4,paul_rearwalk1,palette);
	player_direction = 1;
	player_y -= 5;
	if(checkcolision())
	{
		player_y += 5;
	}
}
if(player_y <= 16)
{
	player_y = 16;
}

So you’re undoing the movement when there’s a collision.
(And doing the same for the other 3 directions.)

If you mean you changed ++ to +++ there’s a good reason that didn’t work. ++ is an operator that means ‘add 1’, but there’s no such operator as +++, that gets interpreted as a ++ and a +, which usually results in the code being grammatically incorrect (i.e. it won’t compile).

Which bit of code did you change to do that?
Where abouts were you testing?

ok here is my sketch now…

#include <GrafxT3.h>
#include <SPIN.h>
#include "SPI.h"
#include <Bounce.h>
#include "bitmaps.h"
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
#define TFT_DC  9
#define TFT_CS 10
#define TFT_RST 7
#define TFT_SCK 13
#define TFT_MISO 12
#define TFT_MOSI 11
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
uint8_t use_fb = 0;
uint8_t use_clip_rect = 0;
uint8_t use_set_origin = 0;
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
GrafxT3 tft = GrafxT3(TFT_CS, TFT_DC, TFT_RST, TFT_MOSI, TFT_SCK, TFT_MISO, &SPIN);
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
 int player_x = 240;
 int player_y = 320;
 int player_direction = 2;
 int x=-0,y=0;
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// Camera offset
int cameraX = -160;  /////starting position X 0f camera on tilemap
int cameraY = -120;  /////starting position Y of camera on tilemap

// Camera speed in pixels per update
int cameraXSpeed = 3;
int cameraYSpeed = 3;

// Camera offset boundaries
const int cameraXMin = -2352;
const int cameraXMax = 0;
const int cameraYMin = -2352;
const int cameraYMax = 0;

// Player offset boundaries
const int playerXMin = 80;
const int playerXMax = 240;
const int playerYMin = 80;
const int playerYMax = 160;
///////////////////////////////////////////////////////////////////////////////
///////////////////////////Pixel Color Includes////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
uint16_t palette[16];  // Should probably be 256, but I don't use many colors...
uint16_t pixel_data[2500];

//Extra integers for color palette
int a = 0xa; int b = 0xb; int c = 0xc; 
int d = 0xd; int e = 0xe; int f = 0xf;

/////////////////////////////////////////////////////////////////////////////
/////////////////////////////Button assignments//////////////////////////////
/////////////////////////////////////////////////////////////////////////////
//////dpad + select buttons
const int buttonUp = 33; //up button
Bounce ButtonUp = Bounce(buttonUp, 10);  // 10 ms debounce
const int buttonDown = 38; //down_button
Bounce ButtonDown = Bounce(buttonDown, 10);  // 10 ms debounce
const int buttonLeft = 35; //left button
Bounce ButtonLeft = Bounce(buttonLeft, 10);  // 10 ms debounce
const int buttonRight = 17; //right button
Bounce ButtonRight = Bounce(buttonRight, 10);  // 10 ms debounce
const int buttonS = 21; //select button
Bounce ButtonS = Bounce(buttonS, 10);  // 10 ms debounce

//////action + start buttons
const int buttonX = 32; // X button up
Bounce ButtonX = Bounce(buttonX, 10);  // 10 ms debounce
const int buttonY = 26; // Y button left
Bounce ButtonY = Bounce(buttonY, 10);  // 10 ms debounce
const int buttonA = 21; // A button right
Bounce ButtonA = Bounce(buttonA, 10);  // 10 ms debounce
const int buttonB = 28; // B buttun down
Bounce ButtonB = Bounce(buttonB, 10);  // 10 ms debounce
const int buttonT = 4; // Start button
Bounce ButtonT = Bounce(buttonT, 10);  // 10 ms debounce

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////Set-up//////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

void setup() {
  while (!Serial && (millis() < 4000)) ;
  Serial.begin(115200);
  tft.begin();
  tft.setRotation(1);
  tft.fillScreen(BLACK);
  //tft.setFrameRate(60);
  tft.persistence = false;
   pinMode(buttonUp, INPUT_PULLUP);
   pinMode(buttonDown, INPUT_PULLUP);
   pinMode(buttonLeft, INPUT_PULLUP);
   pinMode(buttonRight, INPUT_PULLUP);
   pinMode(buttonS, INPUT_PULLUP);
   pinMode(buttonX, INPUT_PULLUP);
   pinMode(buttonY, INPUT_PULLUP);
   pinMode(buttonA, INPUT_PULLUP);
   pinMode(buttonB, INPUT_PULLUP);
   pinMode(buttonT, INPUT_PULLUP); 
 
   tft.useFrameBuffer(use_fb);
     uint32_t start_time = millis(); 
       use_fb = !use_fb;
 
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////Loop////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void loop(void) {
   //updates the GameRIot (the display, the sound, the buttons, everyyhing)
  //returns true when it's time to render a new frame (20 times/second)
//   if(tft.updateAll()){

///////////////////////////////////////////////////////////////////////////////
////////////////////////////////camera controls////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// Clamp cameraX
if(cameraX < cameraXMin)
{
  cameraX = cameraXMin;
}
else if(cameraX > cameraXMax)
{
   cameraX = cameraXMax;
}

// Clamp cameraY
if(cameraY < cameraYMin)
{
  cameraY = cameraYMin;
}
else if(cameraY > cameraYMax)
{
   cameraY = cameraYMax;  
}

// Check if player is beyond X boundary
if(player_x < playerXMin)
{
  cameraX += cameraXSpeed;
  if(cameraX > cameraXMin && cameraX < cameraXMax)
  {
    player_x = playerXMin;
  }
}
else if(player_x > playerXMax)
{
  cameraX -= cameraXSpeed;
  if(cameraX > cameraXMin && cameraX < cameraXMax)
  {
    player_x = playerXMax;
  }
}

// Check if player is beyond Y boundary
if(player_y < playerYMin)
{
  cameraY += cameraYSpeed;
  if(cameraY > cameraYMin && cameraY < cameraYMax)
  {
    player_y = playerYMin;
  }
}
else if(player_y > playerYMax)
{
  cameraY -= cameraYSpeed;
  if(cameraY > cameraYMin && cameraY < cameraYMax)
  {
    player_y = playerYMax;
  }
}
//////////////////////////////////////////////////////////////////////////////
///////////////////////////////Palette////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
 palette[0] = 0;
       palette[1] = BLACK;
             palette[2] = BLUE;
                   palette[3] = BROWN;
                         palette[4] = DARKGREEN;
                              palette[5] = GREY;
                                    palette[6] = PINK;
                                          palette[7] = RED;
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////                                                
                                           palette[8] = LIGHTBROWN;
                                     palette[9] = GREEN;
                               palette[a]= DARKGREY;
                         palette[b] = LIGHTGREY;
                   palette[c] = YELLOW; 
             palette[d] = PURPLE; 
       palette[e] = WHITE;
 palette[f] = NAVY;
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////Tilemap/////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

tft.drawTilemap(cameraX, cameraY, dune_demo, spritesheet, palette);
 
///////////////////////////////////////////////////////////////////////////////
///////////////////////////Buttons/////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////  
       if (ButtonUp.update());
               if (ButtonDown.update());
                       if (ButtonLeft.update());
                             if (ButtonRight.update());
                                       if (ButtonA.update());
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
                                       ButtonUp.rebounce(10);
                               ButtonDown.rebounce(10);
                       ButtonLeft.rebounce(10);
            ButtonRight.rebounce(10);
     ButtonA.rebounce(10);
///////////////////////////////////////////////////////////////////////////////
//////////////////////////Down/////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
 if (ButtonUp.fallingEdge()){
     tft.writeRectNBPP(player_x, player_y,16,16,4,paulrearw,palette);
     player_direction = 1;
     player_y -= 8;
     if(checkcolision())
     {
      player_y += 8;} 
     }
     if(player_y <= 16){
        player_y = 16;}
//////////////////////////////////////////////////////////////////////////////
/////////////////////////////////Up///////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
 if (ButtonDown.fallingEdge()){
   tft.writeRectNBPP(player_x, player_y,16,16,4,paulfrontw,palette);
   player_direction = 2;
   player_y += 8;
    if(checkcolision())
    {
    player_y -=8;}
    }
    if(player_y >= 216){
       player_y = 216;}
//////////////////////////////////////////////////////////////////////////////
//////////////////////////Left////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
 if (ButtonLeft.fallingEdge()){
   tft.writeRectNBPP(player_x, player_y,16,16,4,paulleftw,palette);
   player_direction = 3;
   player_x -= 8;
   if(checkcolision())
   {
      player_x += 8;}  
   }
   if(player_x >= 288){
      player_x = 288;}
//////////////////////////////////////////////////////////////////////////////
////////////////////////////Right////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
if (ButtonRight.fallingEdge()){
  tft.writeRectNBPP(player_x, player_y,16,16,4,paulrightw,palette);
  player_direction = 4;
  player_x += 8;
  if(checkcolision())
  {
    player_x -= 8;}
  }
            if(player_x <= 32){
              player_x = 32;}
///////////////////////////////////////////////////////////////////////////////     
//////////////////////////////PLAYER DIRECTION/////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
if (player_direction == 1){
  tft.writeRectNBPP(player_x, player_y,16,16,4,paulrear,palette);
}
/////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////
else if (player_direction == 2){
   tft.writeRectNBPP(player_x, player_y,16,16,4,paulfront,palette);
}
/////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////
else if (player_direction == 3){
    tft.writeRectNBPP(player_x, player_y,16,16,4,paulleft,palette);
}
/////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////
else if (player_direction == 4){
     tft.writeRectNBPP(player_x, player_y,16,16,4,paulright,palette);
        }
        
      tft.updateScreen();
    use_fb = !use_fb;
     }
//}
/////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////collision/////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////
   bool checkcolision() { // Transformed it into a function 
    uint16_t i;  
     for(i=0; i < tft.numcolision + 1; i++)
   {
    if(tft.collideRectRect(player_x, player_y,16,16,tft.solid[i].x,tft.solid[i].y,16,16))
{
     if(tft.solid[i].spritecol == blank_tile)return false; //Do nothing because it's floor - this line not needed
else if(tft.solid[i].spritecol == cave)return true;
else if(tft.solid[i].spritecol == grass)return false;
else if(tft.solid[i].spritecol == grassbl)return false;
else if(tft.solid[i].spritecol == grassbr)return false;
else if(tft.solid[i].spritecol == grasstl)return false;
else if(tft.solid[i].spritecol == grasstr)return false;
else if(tft.solid[i].spritecol == rock){tft.fillScreen(PURPLE); return true;} //Return True if character have touched the wall
else if(tft.solid[i].spritecol == rockbl)return true;
else if(tft.solid[i].spritecol == rockbr)return true;
else if(tft.solid[i].spritecol == rocktl)return true;
else if(tft.solid[i].spritecol == rocktr)return true;
else if(tft.solid[i].spritecol == sand)return false;
else if(tft.solid[i].spritecol == seitch)return true;
else if(tft.solid[i].spritecol == stairsl)return true;
else if(tft.solid[i].spritecol == stairsr)return true;
else if(tft.solid[i].spritecol == tree)return false;
   }
}
return false; // Return false if don't touch anything
}
//////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////
 

I haven’t changed everything over yet to the new way… But when I made the change above I was able to get a purple flash of the screen but only going left and only every now and then if I keep going right and left and vice versa. and it stops too but only on rock.

I am not sure why your code doesn’t work … in your code, you use two functions ‘numcolision’ and ‘collideRectRect’ as shown below. The first appears to return a number of collisions between objects on the screen. It appears you then make sure that the collision is between your player and an object (as some collisions may not be of interest). Is this correct?

I am not sure what the solid[] array is … what is it?

Finally, what is the solid[i].spritecol returning? A column or a color?? If your images are multicoloured (not a single solid colour) than what value does it return.

Can you debug out to the serial port and see what values the tft.solid[i].spritecol is returning?

for(i=0; i < tft.numcolision + 1; i++)
{
  if(tft.collideRectRect(player_x, player_y,16,16,tft.solid[i].x,tft.solid[i].y,16,16)) {
    if(tft.solid[i].spritecol == blank_tile)return false; //Do nothing because it's floor - this line not needed
    else if(tft.solid[i].spritecol == cave)return true;
    else if(tft.solid[i].spritecol == grass)return false;
    ...
    else if(tft.solid[i].spritecol == rock){tft.fillScreen(PURPLE); return true;}

Some other comments…

The following code is inside the loop but it does not change. Is it better in the setup? Also why the indentation in your code?

palette[0] = 0;
palette[1] = BLACK;
palette[2] = BLUE;
palette[3] = BROWN;
palette[4] = DARKGREEN;
palette[5] = GREY;
palette[6] = PINK;
palette[7] = RED;
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
palette[8] = LIGHTBROWN;
palette[9] = GREEN;
palette[a]= DARKGREY;
palette[b] = LIGHTGREY;
palette[c] = YELLOW;
palette[d] = PURPLE;
palette[e] = WHITE;
palette[f] = NAVY;

What is this code achieving? The test seems to do nothing - I am surprised it compiles.

if (ButtonUp.update());
if (ButtonDown.update());
if (ButtonLeft.update());
if (ButtonRight.update());
if (ButtonA.update());

that’s where this comes in. the col should stand for collision…

 void        drawBitmapTM(int16_t x, int16_t y, int16_t w, int16_t h, const uint8_t *bitmap, uint16_t dx, uint16_t dy, uint16_t dw, uint16_t dh,  uint16_t color);
	boolean     getBitmapPixel(const uint8_t* bitmap, uint16_t x, uint16_t y);

	void        drawTilemap(int x, int y, const uint8_t *tilemap, const uint8_t **spritesheet, const uint16_t * palette);
	void        drawTilemap(int x, int y, const uint8_t *tilemap, const uint8_t **spritesheet, uint16_t dx, uint16_t dy, uint16_t dw, uint16_t dh, const uint16_t * palette);

	typedef struct {       //line 171 "Public Variables   - ADD by Summoner123
		int x;                    //X coordinate                 - ADD by Summoner123
		int y;                    //Y coordinate                 - ADD by Summoner123
		const byte *spritecol;    //Sprite of object             - ADD by Summoner123
	}object;
	object solid[60];         // Matriz were saved a Sprite, X and Y cordinates of all tiles on the screen - ADD by Summoner123

	byte numcolision = 0;     //count of solid objects indacat how many tiles drawed on the screen - ADD by Summoner123

	bool flagcollision = true;

////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
//////////////-----------------------------Collision--------------------------//////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////

	boolean collidePointRect(int16_t x1, int16_t y1, int16_t x2, int16_t y2, int16_t w, int16_t h);
	boolean collideRectRect(int16_t x1, int16_t y1, int16_t w1, int16_t h1, int16_t x2, int16_t y2, int16_t w2, int16_t h2);
	boolean collideBitmapBitmap(int16_t x1, int16_t y1, const uint8_t* b1, int16_t x2, int16_t y2, const uint8_t* b2);

also this with in the drawtilemap command

void GrafxT3::drawTilemap(int x, int y, const uint8_t *tilemap, const uint8_t **spritesheet, uint16_t dx, uint16_t dy, uint16_t dw, uint16_t dh, const uint16_t * palette){
	uint16_t tilemap_width = pgm_read_byte(tilemap);
	uint16_t tilemap_height = pgm_read_byte(tilemap + 1);
	uint16_t tile_width = pgm_read_byte(tilemap + 2);
	uint16_t tile_height = pgm_read_byte(tilemap + 3);
	tilemap += 4; // now the first tiyleis at tilemap
	uint16_t ddw = dw + dx;
	uint16_t ddh = dh + dy;
	uint16_t maxDdx = (dw - x + tile_width - 1) / tile_width;
	uint16_t maxDdy = (dh - y + tile_height - 1) / tile_height;
	if (tilemap_width < maxDdx){
		maxDdx = tilemap_width;
	}
	if (tilemap_height < maxDdy){
		maxDdy = tilemap_height;
	}
	int16_t startDdx = (-x) / tile_width;
	int16_t startDdy = (-y) / tile_height;
	if (startDdx < 0){
		startDdx = 0;
	}
	if (startDdy < 0){
		startDdy = 0;
	}
	if (flagcollision)numcolision = 0;                                 //Line 735 - clear numcolision - ADD by Summoner123

	for (uint16_t ddy = startDdy; ddy < maxDdy; ddy++){
		for (uint16_t ddx = startDdx; ddx < maxDdx; ddx++){
			int16_t drawX = ddx*tile_width + x + dx;
			int16_t drawY = ddy*tile_height + y + dy;
			uint16_t tile = pgm_read_byte(tilemap + ddy*tilemap_width + ddx);
			if (drawX >= dx && drawY >= dy && drawX <= (ddw - tile_width) && drawY <= (ddh - tile_height)){
				writeRectNBPP(drawX, drawY,tile_width, tile_height, 4, spritesheet[tile], palette );

				if (flagcollision){
					solid[numcolision].x = drawX;                     //Save X coordinate      - ADD by Summoner123
					solid[numcolision].y = drawY;                     //Save Y coordinate      - ADD by Summoner123
					solid[numcolision].spritecol = spritesheet[tile]; //Save Sprite of tile    - ADD by Summoner123
					numcolision++;                                    //Increment numcolision  - ADD by Summoner123
				}
			}
			else{ // we need to draw a partial bitmap
				writeRect4BPPtm(drawX, drawY, tile_width, tile_height, spritesheet[tile], dx, dy, dw, dh, palette);
			}
		}
	}
}

here is the original sketch

#include <SPI.h>
#include <Gamebuino.h>
Gamebuino gb;



const byte room_1_1[] PROGMEM = {15,9,
8,8,
2,2,2,2,2,2,2,8,8,2,2,2,2,2,2,
2,2,2,2,2,1,4,8,8,2,2,2,2,2,2,
2,2,2,2,4,8,8,8,8,2,2,2,2,2,2,
2,2,2,4,8,8,8,8,8,2,2,2,2,2,2,
2,2,4,8,8,8,8,8,8,3,2,2,2,2,2,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
2,2,8,8,8,8,8,8,8,8,8,8,8,2,2,
2,2,8,8,8,8,8,8,8,8,8,8,8,2,2,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2};

const byte room_1_2[] PROGMEM = {15,9,
8,8,
2,0,8,0,8,0,8,8,8,0,8,0,8,0,2,
2,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
4,8,8,8,8,0,8,8,8,0,8,0,8,0,8,
8,0,8,0,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,0,8,8,8,0,8,0,8,0,8,
8,0,8,0,8,8,8,8,8,8,8,8,8,8,8,
6,8,8,8,8,0,8,8,8,0,8,0,8,0,8,
2,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
2,0,0,0,0,0,0,0,0,0,0,0,0,0,2};

const byte room_1_3[] PROGMEM = {15,9,
8,8,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
3,2,2,2,8,8,8,8,8,8,8,8,3,2,2,
8,3,2,2,8,8,8,8,8,8,8,8,8,2,2,
8,8,3,2,8,8,8,8,7,8,8,8,8,3,2,
8,8,8,8,8,8,8,7,8,7,8,8,8,8,8,
8,8,8,8,8,8,8,8,7,8,8,8,8,5,2,
8,8,8,8,8,8,8,8,8,8,8,8,8,2,2,
8,8,5,2,6,8,8,8,8,8,8,8,5,2,2,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2};

const byte room_1_4[] PROGMEM = {15,9,
8,8,
2,2,2,2,2,2,2,2,4,3,2,2,2,2,2,
2,2,2,2,2,2,2,4,8,8,8,8,3,2,2,
2,2,2,2,4,8,8,8,8,8,8,8,8,2,2,
3,4,3,4,8,8,8,8,8,8,8,8,8,2,2,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
5,6,5,6,8,8,8,8,8,8,8,8,8,2,2,
2,2,2,2,6,8,8,8,8,8,8,8,8,2,2,
2,2,2,2,2,2,2,6,8,8,8,8,8,2,2,
2,2,2,2,2,2,2,2,6,5,2,2,2,2,2};

const byte room_1_5 [] PROGMEM = {15,9,
8,8,
2,2,2,2,2,2,2,2,2,2,2,8,8,8,0,
2,4,8,8,8,8,8,8,8,8,8,8,8,8,8,
4,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,11,17,17,17,17,17,17,17,
6,8,8,8,8,8,8,11,16,16,16,16,16,16,16,
2,2,2,6,8,8,8,10,16,16,16,16,16,16,16,
2,2,2,2,2,2,2,10,16,16,16,16,16,16,16};

const byte room_1_6[] PROGMEM = {15,9,
8,8,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
16,16,16,16,16,16,16,16,16,16,16,16,16,16,16};

const byte room_1_7[] PROGMEM = {15,9,
8,8,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
16,16,16,16,16,16,16,16,16,16,16,16,16,16,16};

const byte room_1_8[] PROGMEM = {15,9,
8,8,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,
8,8,3,2,4,3,4,3,4,3,2,4,3,2,2,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
16,16,16,16,16,16,16,16,16,16,16,16,16,16,16};

const byte room_1_9[] PROGMEM = {15,9,
8,8,
2,2,2,2,2,2,2,8,8,8,10,16,16,16,16,
4,3,2,4,3,2,4,8,8,8,10,16,16,16,16,
8,8,8,8,8,8,8,8,8,8,10,16,16,16,16,
8,8,8,8,8,8,8,8,8,8,10,16,16,16,16,
8,8,8,8,8,8,8,8,8,8,10,16,16,16,16,
17,17,17,17,17,17,17,17,17,16,16,16,16,16,16,
16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
16,16,16,16,16,16,16,16,16,16,16,16,16,16,16};


const byte room_2_1[] PROGMEM = {15,9,
8,8,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
2,2,4,8,8,8,8,8,8,2,8,8,8,3,2,
2,4,8,8,7,8,7,8,8,8,8,7,8,8,3,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,7,8,7,8,8,8,8,7,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
2,6,8,8,7,8,7,8,8,8,8,7,8,8,5,
2,2,6,8,8,8,8,8,8,2,8,8,8,5,2,
2,2,2,2,2,2,2,8,8,2,2,2,2,2,2};

const byte room_2_2[] PROGMEM = {15,9,
8,8,
2,0,8,0,8,0,8,8,8,0,8,0,8,8,0,
2,0,8,8,8,8,8,8,8,8,8,8,8,8,2,
4,8,8,8,0,8,8,8,8,0,8,8,0,8,8,
8,8,0,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,0,8,0,8,8,0,8,0,8,8,8,
8,8,0,8,8,8,8,8,8,8,8,8,8,8,8,
6,8,8,8,0,8,8,8,8,0,8,8,0,8,8,
2,0,8,8,8,8,8,8,8,8,8,8,8,8,2,
2,0,8,0,8,0,8,8,8,0,8,0,8,8,0};

const byte rooom_2_3[] PROGMEM = {15,9,
8,8,
0,0,0,0,0,0,0,0,8,8,8,11,16,16,16,
0,0,8,8,8,8,8,8,8,8,8,10,16,16,16,
0,8,8,8,8,8,0,8,8,0,8,10,16,16,16,
8,8,8,0,8,8,8,8,8,8,8,10,16,16,16,
8,8,8,8,8,8,0,8,8,8,8,9,15,15,15,
8,8,8,0,8,8,8,8,8,8,8,8,8,8,8,
0,8,8,8,8,8,0,8,8,8,8,8,8,8,8,
0,0,8,8,8,8,8,8,8,8,8,8,8,8,8,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

const byte room_2_4[] PROGMEM = {15,9,
8,8,
16,16,16,14,8,8,8,0,0,0,8,0,0,8,0,
16,16,16,14,8,8,8,0,0,0,8,0,0,8,0,
16,16,16,14,8,8,8,8,8,8,8,8,8,8,8,
15,15,15,12,8,8,8,0,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

const byte room_2_5[] PROGMEM = {15,9,
8,8,
0,8,0,8,8,8,0,8,0,8,0,8,8,8,0,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,0,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,0,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,0,8,8,8,8,
8,8,0,8,8,8,0,8,0,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,0,8,8,8,0,
0,8,8,8,8,8,8,8,8,8,8,8,8,8,0,
0,0,0,0,0,0,0,0,0,0,0,8,8,8,0};

const byte room_2_6[] PROGMEM = {15,9,
8,8,
0,0,0,0,0,0,0,8,0,0,0,0,8,0,0,0,
0,0,0,0,0,0,0,8,0,0,8,8,8,8,8,8,
0,0,0,0,0,0,0,8,0,8,8,8,8,0,0,0,
8,8,8,8,8,8,8,8,0,8,8,8,8,0,0,0,
8,8,8,8,8,8,8,8,0,8,8,8,8,0,0,0,
8,8,8,8,8,8,8,8,0,8,8,8,8,0,0,0,
0,0,0,0,0,0,0,0,0,8,8,8,8,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,8,8,8,8,8,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

const byte room_2_7[] PROGMEM = {15,9,
8,8,
0,0,0,8,0,0,0,0,0,0,0,0,0,8,0,0,
8,8,8,8,8,8,8,8,8,8,8,0,8,8,0,0,
0,0,8,8,0,0,0,0,0,0,0,0,0,8,0,0,
0,0,8,8,0,0,0,0,0,0,0,0,0,8,8,8,
0,0,8,8,0,0,0,0,0,0,0,0,0,8,8,8,
0,0,8,8,0,0,0,0,0,0,0,0,0,8,8,8,
0,0,8,8,0,0,0,0,0,0,0,0,0,0,0,0,
8,8,8,8,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

const byte room_2_8[] PROGMEM = {15,9,
8,8,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
2,4,8,8,8,8,8,3,2,2,2,4,8,3,2,
2,8,8,8,8,8,8,8,3,2,4,8,8,8,2,
8,8,8,8,0,8,8,8,8,8,8,8,0,8,2,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,2,
2,8,8,8,0,8,8,8,8,8,8,8,0,8,2,
2,8,8,8,8,8,8,8,5,2,6,8,8,8,2,
2,6,8,8,8,8,8,5,2,2,2,6,8,5,2,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2};

const byte room_2_9[] PROGMEM = {15,9,
8,8,
2,2,2,2,2,2,2,8,8,8,10,16,16,16,16,
2,2,2,2,2,2,4,8,8,8,10,16,16,16,16,
8,8,8,8,8,8,8,8,8,8,10,16,16,16,16,
8,8,8,8,8,8,8,8,8,8,10,16,16,16,16,
8,8,8,8,8,8,8,8,8,8,10,16,16,16,16,
8,8,8,8,8,8,8,8,8,8,10,16,16,16,16,
8,8,8,8,8,8,8,8,8,8,10,16,16,16,16,
2,2,2,2,2,2,6,8,8,8,10,16,16,16,16,
2,2,2,2,2,2,2,8,8,8,10,16,16,16,16};

const byte room_3_1[] PROGMEM = {15,9,
8,8,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,0,8,0,8,8,8,0,8,0,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,0,8,0,8,0,8,0,8,0,8,0,8,0,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,0,8,0,8,8,8,0,8,0,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

const byte room_3_2[] PROGMEM = {15,9,
8,8,
0,0,0,0,0,0,0,8,8,8,0,0,0,0,0,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
0,8,0,8,8,8,0,8,8,8,0,8,0,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
0,8,0,8,8,8,0,8,8,8,0,8,0,8,0,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
0,8,0,8,8,8,0,8,8,8,0,8,0,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
0,8,0,8,0,8,0,8,8,8,0,8,0,8,0};

const byte room_3_3[] PROGMEM = {15,9,
8,8,
0,0,0,0,0,0,0,8,8,8,0,0,0,0,0,
0,0,8,8,8,0,0,8,8,8,0,0,0,0,0,
0,0,8,8,8,0,0,8,8,8,0,0,0,0,0,
0,0,8,8,8,8,8,8,8,8,8,8,8,8,8,
0,0,8,7,8,8,8,8,8,8,8,8,8,8,8,
0,0,8,8,8,8,8,8,8,8,8,8,8,8,8,
0,0,8,8,8,0,0,8,8,8,0,0,0,0,0,
0,0,8,8,8,0,0,8,8,8,0,0,0,0,0,
0,0,0,0,0,0,0,8,8,8,0,0,0,0,0};

const byte room_3_4[] PROGMEM ={15,9,
8,8,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
17,17,17,14,8,8,8,8,8,8,8,8,8,8,8,
16,16,16,13,8,8,8,8,8,8,8,8,8,8,8,
16,16,16,13,8,8,8,0,0,0,8,0,0,8,0,
16,16,16,13,8,8,8,0,0,0,8,0,0,8,0};

const byte room_3_5[] PROGMEM = {15,9,
8,8,
0,8,0,8,8,8,0,8,0,8,0,8,8,8,0,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,0,8,8,8,0,8,0,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,0,8,8,8,8,
8,8,0,8,8,8,0,8,0,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,0,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
0,8,0,8,8,8,0,8,0,8,0,8,8,8,0};

const byte room_3_6[] PROGMEM = {15,9,
8,8,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
8,8,8,8,8,8,8,8,8,8,8,8,8,0,0,
0,0,0,0,0,0,0,0,0,0,0,8,8,0,0,
0,0,0,0,0,0,0,0,0,0,0,8,8,8,8,
0,0,0,0,0,0,0,0,0,0,0,8,8,8,8,
0,0,0,0,0,0,0,0,0,0,0,8,8,8,8,
0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,
8,8,8,8,8,8,8,0,0,0,0,8,0,0,0,
0,0,0,0,0,0,8,0,0,0,0,8,0,0,0};

const byte room_3_7[] PROGMEM = {15,9,
0,0,0,8,0,0,0,0,0,0,0,0,8,0,0,
0,0,0,8,0,0,0,0,0,0,0,0,8,0,0,
0,0,0,8,0,0,0,0,0,0,0,0,8,0,0,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
0,0,0,8,0,0,0,0,0,0,0,0,8,0,0,
0,0,0,8,0,0,0,0,0,0,0,0,8,0,0,
0,0,0,8,0,0,0,0,0,0,0,0,8,0,0};

const byte room_3_8[] PROGMEM = {15,9,
8,8,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
2,4,8,8,8,8,8,3,2,2,2,4,8,3,2,
2,8,8,8,8,8,8,8,3,2,4,8,8,8,2,
8,8,8,8,0,8,8,8,8,8,8,8,0,8,2,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,2,
8,8,8,8,0,8,8,8,8,8,8,8,0,8,2,
2,8,8,8,8,8,8,8,5,2,6,8,8,8,2,
2,6,8,8,8,8,8,5,2,2,2,6,8,5,2,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2};

const byte room_3_9[] PROGMEM = {15,9,
8,8,
2,2,2,2,2,2,8,8,8,8,10,16,16,16,16,
2,2,2,2,2,4,8,8,8,8,10,16,16,16,16,
2,2,2,2,4,8,8,8,8,8,10,16,16,16,16,
2,2,2,4,8,8,8,8,8,8,10,16,16,16,16,
2,2,2,8,8,8,8,8,8,8,10,16,16,16,16,
2,2,2,8,8,8,8,8,8,8,10,16,16,16,16,
2,2,2,6,8,8,8,8,8,8,10,16,16,16,16,
2,2,2,2,6,8,8,8,8,8,10,16,16,16,16,
2,2,2,2,2,8,8,8,8,8,10,16,16,16,16};


const byte room_4_1[] PROGMEM = {15,9,
8,8,
16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

const byte room_4_2[] PROGMEM = {15,9,
8,8,
16,16,16,16,16,16,13,8,8,8,0,0,0,0,0,
16,16,16,16,16,16,13,8,8,8,8,8,8,0,0,
16,16,16,16,16,16,13,8,8,8,8,8,8,0,0,
15,15,15,15,15,15,12,8,8,8,8,8,8,0,0,
8,8,8,8,8,8,8,8,8,8,8,8,8,0,0,
8,8,8,8,8,8,8,8,8,8,8,8,8,0,0,
8,8,8,8,8,8,8,8,8,8,8,8,8,0,0,
0,8,8,8,8,8,8,8,8,8,8,8,8,0,0,
0,0,0,0,0,0,0,8,8,8,0,0,0,0,0};

const byte room_4_3[] PROGMEM = {15,9,
8,8,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
2,4,8,8,8,8,8,8,8,8,8,8,8,3,2,
2,8,8,8,8,8,8,8,8,8,8,8,8,8,2,
2,8,0,8,8,11,17,17,17,14,8,8,0,8,2,
2,8,8,8,8,10,16,16,16,13,8,8,8,8,2,
2,8,0,8,8,9,15,15,15,12,8,8,0,8,2,
2,8,8,8,8,8,8,8,8,8,8,8,8,8,2,
2,6,8,8,8,8,8,8,8,8,8,8,8,5,2,
2,2,2,2,2,2,2,8,8,8,2,2,2,2,2};

const byte room_4_4[] PROGMEM = {15,9,
8,8,
2,2,2,2,2,2,2,8,8,8,2,2,2,2,2,
2,2,4,8,8,8,8,8,8,8,8,8,3,2,2,
2,4,8,8,8,8,8,8,8,8,8,8,8,3,2,
8,8,8,8,0,8,8,8,8,8,0,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,0,8,8,8,8,8,0,8,8,8,8,
2,6,8,8,8,8,8,8,8,8,8,8,8,5,2,
2,2,6,8,8,8,8,8,8,8,8,8,5,2,2,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2};

const byte room_4_5[] PROGMEM ={15,9,
8,8,
0,0,0,0,0,0,0,0,0,0,0,8,8,8,0,
0,8,8,8,8,8,8,8,8,8,0,8,8,8,0,
0,8,8,8,8,0,8,8,8,8,0,8,8,8,0,
8,8,8,8,8,8,8,0,8,8,0,8,8,8,0,
8,8,0,8,8,0,8,8,8,8,0,8,8,8,0,
8,8,8,8,8,8,8,0,8,8,0,8,8,8,0,
0,8,8,8,8,0,8,8,8,8,0,8,8,8,0,
0,8,8,8,8,8,8,8,8,8,0,8,8,8,0,
0,8,0,8,8,8,0,8,0,8,0,8,8,8,0};

const byte room_4_6[] PROGMEM = {15,9,
8,8,
2,2,4,3,2,2,18,2,2,2,4,3,2,2,2,
2,4,8,8,3,2,18,2,2,2,8,8,8,2,2,
2,8,8,8,8,2,18,2,2,4,8,8,8,2,2,
4,8,8,8,8,3,18,2,2,4,8,8,8,2,2,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
6,8,8,8,8,8,8,8,8,8,8,8,8,2,2,
2,8,8,8,8,8,8,8,8,8,8,8,8,2,2,
2,8,8,8,8,8,8,8,8,8,8,8,8,2,2,
2,6,5,2,2,6,5,2,2,2,6,5,2,2,2};

const byte room_4_7[] PROGMEM = {15,9,
8,8,
0,8,0,8,0,8,0,8,8,8,0,8,0,8,0,
0,8,8,8,8,8,8,8,8,8,8,8,8,8,0,
0,8,8,8,8,8,0,8,8,8,0,8,8,8,0,
8,8,0,8,0,8,8,8,0,8,8,8,0,8,8,
8,8,8,8,8,8,0,8,8,8,0,8,8,8,8,
8,8,0,8,0,8,8,8,0,8,8,8,0,8,8,
0,8,8,8,8,8,0,8,8,8,0,8,8,8,0,
0,8,8,8,8,8,8,8,8,8,8,8,8,8,0,
0,0,0,8,0,0,0,0,0,0,0,0,8,0,0};

const byte room_4_8[] PROGMEM = {15,9,
8,8,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,8,8,8,8,8,8,8,8,8,8,8,0,0,
0,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,0,8,8,8,8,8,0,8,8,8,0,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,0,
8,8,8,8,0,8,8,8,8,8,0,8,8,8,0,
0,8,8,8,8,8,8,8,8,8,8,8,8,8,0,
0,0,8,8,8,8,8,8,8,8,8,8,8,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

const byte room_4_9[] PROGMEM = {15,9,
8,8,
2,2,2,2,2,2,8,8,8,8,10,16,16,16,16,
2,2,2,2,2,4,8,8,8,8,10,16,16,16,16,
2,2,2,2,4,8,8,8,8,8,10,16,16,16,16,
2,2,2,4,8,8,8,8,8,8,10,16,16,16,16,
2,2,2,8,8,8,8,8,8,8,10,16,16,16,16,
2,2,2,8,8,8,8,8,8,8,10,16,16,16,16,
2,2,2,6,8,8,8,8,8,8,10,16,16,16,16,
2,2,2,2,6,8,8,8,8,8,10,16,16,16,16,
2,2,2,2,2,8,8,8,8,8,10,16,16,16,16};

const byte bush[] PROGMEM = {B00101100,B01010010,B10001001,B01000010,B10010001,B01001010,B00100100,B01111110,};
const byte port_noir[] PROGMEM = {B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,};
const byte rock_terrain_master[] PROGMEM = {B01001101,B10100100,B10010001,B01001010,B10010000,B01100101,B10001001,B01011010,};
const byte rock_valley_ne[] PROGMEM = {B10101010,B10010101,B01000100,B00101001,B00110010,B00001010,B00000100,B00000011,};
const byte rock_valley_nw[] PROGMEM = {B01010101,B10101001,B00100010,B10010100,B01001100,B01010000,B00100000,B11000000,};
const byte rock_valley_se[] PROGMEM = {B00000011,B00000100,B0011001,B00010010,B00101001,B01000110,B10110001,B10001010,};
const byte rock_valley_sw[] PROGMEM = {B11000000,B00100000,B10011000,B01001000,B10010100,B01100010,B10001101,B01010001,};
const byte turtle_rock[] PROGMEM = {B01101100,B10110010,B11010001,B01010101,B01010010,B10011001,B10000001,B11111110,};
const byte void_tile[] PROGMEM = {B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,};
const byte water_left_bottom[] PROGMEM = {B10001111,B10000000,B11110000,B10000000,B10001111,B10000000,B11110000,B11111111,};
const byte water_left_middle[] PROGMEM = {B10001111,B10000000,B11110000,B10000000,B10001111,B10000000,B11110000,B10000000,};
const byte water_left_top[] PROGMEM = {B11111111,B10000000,B11110000,B10001111,B10000000,B10000000,B11110000,B10000000,};
const byte water_right_bottom[] PROGMEM = {B1110001,B00000001,B0000111,B00000001,B11110001,B00000001,B00001111,B11111111,};
const byte water_right_middle[] PROGMEM = {B11110001,B00000001,B00001111,B00000001,B11110001,B00000001,B00001111,B00000001,};
const byte water_right_top[] PROGMEM = {B11111111,B00000001,B00001111,B00000001,B11110001,B00000001,B00001111,B00000001,};
const byte water_middle_bottom[] PROGMEM = {B11110000,B00000000,B00001111,B00000000,B11110000,B00000000,B00001111,B11111111,};
const byte water_middle_middle[] PROGMEM = {B11110000,B00000000,B00001111,B00000000,B11110000,B00000000,B00001111,B00000000,};
const byte water_middle_top[] PROGMEM = {B11111111,B00000000,B11110000,B00000000,B00001111,B00000000,B11110000,B00000000,};
const byte steps[] PROGMEM = {B10000001,B01111110,B10000001,B01111110,B10000001,B01111110,B10000001,B01111110,};
const byte dead_tree[] PROGMEM = {B10101001,B01010110,B01001001,B10101010,B01011010,B00111100,B00011000,B00011000,};
const byte dungeon_left_bottom[] = {B11111111,B10001111,B01001111,B11111111,B10001111,B01001111,B11111111,B10001111,};
const byte dungeon_left_top[] = {B00010001,B00101110,B00101010,B00101110,B01000000,B01000001,B10010010,B10001000,};
const byte dungeon_right_bottom[] = {B11111111,B11110001,B11110010,B11111111,B11110001,B11110010,B11111111,B11110001,};
const byte dungeon_right_top[] = {B10001000,B01110100,B01010100,B01110100,B00000010,B10000010,B01001001,B00010001,};
const byte statue[] = {B10111010,B11000110,B01101100,B11101110,B11111110,B11111110,B01101100,B01101100,};
const byte bridge[] = {B01110111,B10001000,B10101010,B10001000,B10001000,B10101010,B10001000,B01110111,};
const byte grave_marker[] PROGMEM = {B00011000,B00111100,B01100110,B0100010,B01100110,B01100110,B00111100,B11111111,};
const byte dungeon_middle[] = {B10000001,B01000010,B00111100,B00000000,B00000000,B10011001,B00011000,B01000010,};
const byte sand[] PROGMEM = {B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,};

const byte *spritesheet[] = {bush, port_noir, rock_terrain_master, rock_valley_ne, 
rock_valley_nw, rock_valley_se, rock_valley_sw, turtle_rock, void_tile, water_left_bottom,
water_left_middle, water_left_top, water_right_bottom, water_right_middle, water_right_top, 
water_middle_bottom, water_middle_middle, water_middle_top, steps, dead_tree, dungeon_left_bottom,
dungeon_left_top, dungeon_right_bottom, dungeon_right_top, statue, bridge, grave_marker, dungeon_middle,}; 

const byte sever_front_black[] PROGMEM = {8,8,0x39,0x7d,0x01,0x01,0xfe,0x01,0x7c,0x46};
const byte sever_front_grey[] PROGMEM = {8,8,0x82,0x82,0xd6,0x7c,0x01,0xa8,0x00,0x00,};
const byte sever_left_black[] PROGMEM = {8,8,0x9f,0xbe,0x80,0x82,0x7f,0x00,0x3e,0x62,};
const byte sever_left_grey[] PROGMEM = {8,8,0x00,0x00,0x17,0x3c,0x00,0x95,0x00,0x00,};
const byte sever_rear_black[] PROGMEM = {8,8,0x9c,0xbe,0xbe,0x80,0x7f,0x88,0x3e,0x62,};
const byte sever_rear_grey[] PROGMEM = {8,8,0x41,0x41,0x7f,0x3e,0x80,0x15,0x00,0x00,};
const byte sever_right_black[] PROGMEM = {8,8,0xf9,0x7d,0x01,0x41,0xfe,0x00,0x7c,0x46,};
const byte sever_right_grey[] PROGMEM = {8,8,0x00,0x00,0xe8,0x3c,0x00,0xa9,0x00,0x00,};

  int player_x = 70;
  int player_y = 40;
  int player_direction = 0;

int x=0,y=0;

int camerax = -20 ;
int cameray = -10 ;
int xmax = -68;

void setup() {
  gb.begin();
  gb.titleScreen(F("test"));
  gb.setFrameRate(62);
  gb.display.persistence = false;
}

/////////PLAYER_MOVEMENT\\\\\\\\\

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++;} 
     
//////camera controls
if(player_x > 59 && camerax <  0 && camerax  > -52){player_x = 59;camerax--;}   
//value 59 equals player position on right when camera will start to follow 
//value 0 and -52 equals camera boundary positions
else  if(player_x < 15 && camerax <  0 && camerax  > -52){player_x = 15;camerax++;}
//value 15 equals player position on left when camera will start to follow 
//value 0 and -52 equals camera boundary positions
else  if(player_x > 59 && camerax <= 0 && camerax >= -52)camerax--;
else  if(player_x < 15 && camerax <= 0 && camerax >= -52)camerax++;   
  
  
      if(player_y > 28 && cameray < 0 && cameray >  -40){player_y = 28;cameray--;}
//value 28 equals player position on right when camera will start to follow 
//value 0 and -40 equals camera boundary positions
else  if(player_y < 15 && cameray < 0 && cameray >  -40){player_y = 15;cameray++;}
//value 15 equals player position on left when camera will start to follow 
//value 0 and -40 equals camera boundary positions
else  if(player_y > 28 && cameray <= 0 && cameray >= -40)cameray--;
else  if(player_y < 15 && cameray <= 0 && cameray >= -40)cameray++;  

      if(camerax > 0)camerax= 0;
else  if(camerax < -52) camerax = -52;
//value 0 and -52 equals camera boundary positions 
      if(cameray > 0)cameray= 0;   
else  if(cameray < -40) cameray = -40;
//value 0 and -40 equals camera boundary positions
  
 
     gb.display.drawTilemap(camerax,cameray,room_1_1,spritesheet);

 if(gb.buttons.repeat(BTN_UP,1)){
       gb.display.setColor(BLACK);{
    gb.display.drawBitmap(player_x,player_y,sever_rear_black);
       }
    gb.display.setColor(GRAY);{
    gb.display.drawBitmap(player_x,player_y,sever_rear_grey);
    }
      player_direction = 1;
      player_y = player_y - 1;
      if(checkcolision())player_y++;  // ADD by Summoner123 - If have colision on the new position regreat one Pixel
      }

      
    if(player_y <= 0){
      player_y = 0;}



    if(gb.buttons.repeat(BTN_DOWN,1)){
      gb.display.setColor(BLACK);{
    gb.display.drawBitmap(player_x,player_y,sever_front_black);
    }
     gb.display.setColor(GRAY);{
    gb.display.drawBitmap(player_x,player_y,sever_front_grey);
    } 
      player_direction = 2;
      player_y = player_y + 1;
      if(checkcolision())player_y--;  // ADD by Summoner123 - If have colision on the new position regreat one Pixel
      }
      
    if(player_y >= 40){
      player_y = 40;}
  


    if(gb.buttons.repeat(BTN_RIGHT,1)){
       gb.display.setColor(BLACK);{
    gb.display.drawBitmap(player_x,player_y,sever_right_black);
    }
     gb.display.setColor(GRAY);{
    gb.display.drawBitmap(player_x,player_y,sever_right_grey);
    }
      player_direction = 3;
      player_x = player_x + 1;
      if(checkcolision())player_x--;  // ADD by Summoner123 - If have colision on the new position regreat one Pixel
      }
      
      
    if(player_x >= 77){
      player_x = 77;}


    if(gb.buttons.repeat(BTN_LEFT,1)){
       gb.display.setColor(BLACK);{
    gb.display.drawBitmap(player_x,player_y,sever_left_black);
    }
    gb.display.setColor(GRAY);{
    gb.display.drawBitmap(player_x,player_y,sever_left_grey);
    }
      player_direction = 4;
      player_x = player_x - 1;
      
      if(checkcolision())player_x++;  // ADD by Summoner123 - If have colision on the new position regreat one Pixel
      }
      
    if(player_x <= -2){
      player_x = -2;}
      
      ////////////PLAYER DIRECTION/////////////

 if (player_direction == 1){
        gb.display.setColor(BLACK);{
        gb.display.drawBitmap(player_x,player_y,sever_rear_black);
      }
        gb.display.setColor(GRAY);{
        gb.display.drawBitmap(player_x,player_y,sever_rear_grey);
        }
 }
      
      else if (player_direction == 2){
        gb.display.setColor(BLACK);{
        gb.display.drawBitmap(player_x,player_y,sever_front_black);
      }
        gb.display.setColor(GRAY);{
        gb.display.drawBitmap(player_x,player_y,sever_front_grey);
        }
      }
else if (player_direction == 3){
        gb.display.setColor(BLACK);{
        gb.display.drawBitmap(player_x,player_y,sever_left_black);
      }
        gb.display.setColor(GRAY);{
        gb.display.drawBitmap(player_x,player_y,sever_left_grey);
        }
}
      else if (player_direction == 4){
        gb.display.setColor(BLACK);{
        gb.display.drawBitmap(player_x,player_y,sever_right_black);
      }
        gb.display.setColor(GRAY);{
        gb.display.drawBitmap(player_x,player_y,sever_right_grey);
        }
      }
      else {  gb.display.setColor(BLACK);{
        gb.display.drawBitmap(player_x,player_y,sever_front_black);
      }
        gb.display.setColor(GRAY);{
        gb.display.drawBitmap(player_x,player_y,sever_front_grey);
        }
      }
} 
  
}
     bool checkcolision() // Transformed it into a function
   {
    uint16_t i;
     for(i=0; i < gb.display.numcolision + 1; i++)
   {
    if(gb.collideRectRect(player_x,player_y,8,8,gb.display.solid[i].x,gb.display.solid[i].y,8,8))
    {
          if(gb.display.solid[i].spritecol == void_tile); //Do nothing because it's floor - This line not needed
          if(gb.display.solid[i].spritecol == bush)return true;
else      if(gb.display.solid[i].spritecol == port_noir)return true; 
else      if(gb.display.solid[i].spritecol == rock_terrain_master){gb.popup(F(" ""Rock"" "),1); return true;} //Return True if character have touched the wall
else      if(gb.display.solid[i].spritecol == rock_valley_ne)return true;
else      if(gb.display.solid[i].spritecol == rock_valley_nw)return true;
else      if(gb.display.solid[i].spritecol == rock_valley_se)return true;
else      if(gb.display.solid[i].spritecol == rock_valley_sw)return true;
else      if(gb.display.solid[i].spritecol == turtle_rock)return true;
else      if(gb.display.solid[i].spritecol == water_left_bottom)return true;
else      if(gb.display.solid[i].spritecol == water_left_middle)return true;
else      if(gb.display.solid[i].spritecol == water_left_top)return true;
else      if(gb.display.solid[i].spritecol == water_right_bottom)return true;
else      if(gb.display.solid[i].spritecol == water_right_middle)return true;
else      if(gb.display.solid[i].spritecol == water_right_top)return true;
else      if(gb.display.solid[i].spritecol == water_middle_bottom)return true;
else      if(gb.display.solid[i].spritecol == water_middle_middle)return true;
else      if(gb.display.solid[i].spritecol == water_middle_top)return true;
else      if(gb.display.solid[i].spritecol == steps)return true;
else      if(gb.display.solid[i].spritecol == dead_tree)return true;
else      if(gb.display.solid[i].spritecol == dungeon_left_bottom)return true;
else      if(gb.display.solid[i].spritecol == dungeon_left_top)return true;
else      if(gb.display.solid[i].spritecol == dungeon_right_bottom)return true;
else      if(gb.display.solid[i].spritecol == dungeon_right_top)return true;
else      if(gb.display.solid[i].spritecol == statue)return true;
else      if(gb.display.solid[i].spritecol == bridge)return true;
  
      }
   }
    return false; // Return false if don't touch anything
       
}


The colors palette stuff is for the writerect bitmaps for coloration. I wanted the color palettes to be custom so the user isn’t stuck using the library predefined colors or the order they are in. I need to do re do it I know.

black      1
blue       2
brown      3
green      4
grey       5
pink       6
red        7
lightbrown 8
lightgreen 9
darkgrey   a
lightgrey  b
yellow     c
purple     d
white      e

const byte gurneyrightw[] = {
0x00,0x06,0x66,0x66,0x66,0x60,0x00,0x00,
0x00,0x66,0x65,0x55,0x66,0x66,0x00,0x00,
0x00,0x55,0x55,0x56,0x66,0x66,0x10,0x00,
0x00,0x55,0x55,0x56,0x65,0x56,0x10,0x00,
0x00,0x55,0x55,0x56,0x66,0x66,0x10,0x00,
0x00,0x15,0x55,0x55,0x66,0x16,0x10,0x00,
0x00,0x01,0x56,0x65,0x66,0x16,0x10,0x00,
0x00,0x00,0x16,0x66,0x66,0x66,0x10,0x00,
0x00,0x00,0x01,0x16,0x66,0x61,0x00,0x00,
0x00,0x00,0x01,0x11,0x11,0x50,0x00,0x00,
0x00,0x01,0x16,0x61,0x11,0x11,0x10,0x00,
0x00,0x18,0x16,0x61,0x58,0x15,0x51,0x00,
0x00,0x15,0x81,0x11,0x11,0x85,0x10,0x00,
0x00,0x15,0x51,0x00,0x01,0x11,0x00,0x00,
0x00,0x15,0x50,0x00,0x00,0x00,0x00,0x00,
0x00,0x01,0x10,0x00,0x00,0x00,0x00,0x00};

When I was writing the buttons I had a hard time getting the usual button pressed button release stuff down and paul over at teensy suggested using the bounce library which worked instantly, The update button and rebounce update the buttons constantly so the presses are accurate and the rebounce of course repeats a button press while its held.

You have included bits and pieces from the original sketch and your version. I don;t think I have a full picture of what yours looks like. In your version, do you have a collection of sprite / images that includes the cave, grass, etc?

Can you debug to the serial port? If so, add the following lines and show us the output. What values are you expecting?

Probably, you need to print out all of your items that you could possibly collide with - just add them to the list below. Show us the debug prints just as you are about the ‘hit’ something you shouldn’t be able to walk over.

@filmote

Just to bring you up to speed a bit:

The GrafxT3 library is here (.h) and here (.cpp).
As you can see, solid is an array of object which is just a struct holding an int x, an int y and a const byte *spritecol.

cave, rock, grass etc are all pointers to sprites (which presumably are in progmem). It would be good to know whether the pointers are matching up with spritecol (I’ve got a feeling there could be some odd alignment reasons or something causing them to not be the same, but I can’t think why that might be, especially since I don’t know the hardware details), but debugging with Serial is apparently out of the question for now:


That’s very strange.
I’m assuming that means that input code was at least part of the problem since it’s actually going purple at times.

As you can’t use serial, perhaps try filling the screen with other colours on other colours to see if you can identify which collisions are working and which aren’t.

Also I can’t think of a reason why up and down wouldn’t be colliding.
(Though I must admit I do still think it’s odd that up is +Y and down is -Y, are you sure that’s right?)

The hardware pieces are an ili9341 spi tft and a Teensy 3.6 for the screen and mcu. Tactile switches for buttons,3.7v lipo @ 1500mah and a tp4056 charger. You get a whole megabyte for flash. Also we aren’t actually using progmem we are using the flash memory. I looked at the sketch for the original B and W version and then compiled the code and used the hex code in an emulator and its all correct.

if(gb.buttons.repeat(BTN_UP,1)){
       gb.display.setColor(BLACK);{
    gb.display.drawBitmap(player_x,player_y,sever_rear_black);
       }
    gb.display.setColor(GRAY);{
    gb.display.drawBitmap(player_x,player_y,sever_rear_grey);
    }
      player_direction = 1;
      player_y = player_y - 1;
      if(checkcolision())player_y++;  // ADD by Summoner123 - If have colision on the new position regreat one Pixel
      }

      
    if(player_y <= 0){
      player_y = 0;}



    if(gb.buttons.repeat(BTN_DOWN,1)){
      gb.display.setColor(BLACK);{
    gb.display.drawBitmap(player_x,player_y,sever_front_black);
    }
     gb.display.setColor(GRAY);{
    gb.display.drawBitmap(player_x,player_y,sever_front_grey);
    } 
      player_direction = 2;
      player_y = player_y + 1;
      if(checkcolision())player_y--;  // ADD by Summoner123 - If have colision on the new position regreat one Pixel
      }
      
    if(player_y >= 40){
      player_y = 40;}

Maybe its looking for the pixel by pixel in the bitmap? These 16,16, is missing from bitmap declaration. This was because the write rectangle function reads those as extra pixels and reorders the pixels on the bitmap. Instead they are listed in the function call to display the bitmap.

Or maybe I should be using collide bitmap bitmap? I can’t find an example for it though.

I agree … that’s why I was hoping to see the pointer values and the sprite collection. I think there is something fishy going on there.

I would sugest you go and buy another cable. Without it debugging this may be difficult.

1 Like

For what it’s worth:

player_y++; is the same as player_y = player_y + 1;.
player_y--; is the same as player_y = player_y - 1;.
player_y += 5; is the same as player_y = player_y + 5;.
player_y -= 5; is the same as player_y = player_y - 5;.

Which is why

had to be changed to

Also notice that in the original code the code for the down button is doing player_y = player_y + 1; and the code for the up button is doing player_y = player_y - 1;, meaning +Y is down and -Y is up which is the opposite to how you’ve got it in your code, so I think you might have up and down the wrong way round as I mentioned earlier.