Duhjoker
Well-known member
Quick catch up...... I'm building a DIY multiple MCU color gaming console using teensy3.6 and an ILI9341 tft. The master library offeres a wide range of mcu to use with spate libraries Teensy3 and ESP32. The gaming library is pretty easy to use but building it has been a challenge but thanks to guys and your patience I'm almost done.
The last issue I'm having, we have talked about in other threads but no real solution has been found. So thought it might be better to start a thread based purely on the problem and maybe get more eyes. At least I hope. In order to make good games we need a backdrop or tilemap made from bitmaps to give our player sprites a world to move around in and interact with. Normally..... we would do this using a drawtile map function something like this......
To do all that we use these functions....
and this....
This code can be found in any of my repositories here... https://github.com/Duhjoker
There is also the way found here...... https://github.com/Rodot/Gamebuino/tree/master/examples/2.Intermediate/TileMapRAM
The problem is that no matter what I try I cannot fill up the screen doing so. It cuts off the last 5 vertical rows leaving them blank or default color. I and awesomw101 did a lot work trying to solve the problem which can be seen from here on..... Please look we did a lot of work
http://gamebuino.com/forum/viewtopic.php?f=8&t=3745&start=20
Using tile map or the other example or any variation of nets the same results. I've tried changing variables across the tile map functions all so far net the result of no image at all being displayed. The original example is for a nokia 5110 lcd which has a resolution of 84 by 48 pixels BUT...... I've printed and walked around in maps using the same code with maps of 16bit bitmaps and 300 by 300 bitmaps on the nokia. So its STRANGE that it cuts off the last 5 bars. its like there is some kind of offset that's not allowing me to place the tilemap there. But I can put bitmaps one by one in the last five bars no problem. its just when using an array. Both my 2.4inch and 2.8inch have this problem. I read in one of my libraries that certain manufacturers use offsets that take propietory drivers or some stuff but my screens come from pjrc along with my teensy and spans every library and mcu.
Ok like I said we have talked about this here and there with no real dedication. I'm hoping this will improve my chances of fixing the problem. If I have mistakenly doubled a thread feel free to cancel which ever one and tell me. I don't want to needlessly take up space.
EDIT::
If I mess with these.....
I I play with these it cuts off the left side
I just noticed that when the tilemap is on the player navigates the blank area as it was part of the tilemap by moving slow in that and all areas compared to having the tilemap commented out where he moves fast.
The last issue I'm having, we have talked about in other threads but no real solution has been found. So thought it might be better to start a thread based purely on the problem and maybe get more eyes. At least I hope. In order to make good games we need a backdrop or tilemap made from bitmaps to give our player sprites a world to move around in and interact with. Normally..... we would do this using a drawtile map function something like this......
Code:
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
first we store the bitmaps in hex or binary form one color at a time
const byte rock_black[] PROGMEM = {16,16,
B00010101,B10110100,B00001101,B10001110,B00001101,B10001101,B00001101,B10000101,B00001001,B10000101,B00001001,B10000001,B00001001,B10000110,B00001011,B00000010,B00001001,B10000001,B00011001,B10000001,B00111011,B10000011,B00100011,B11000010,B01000001,B10000010,B01000001,B10000010,B00000001,B11000111,B10000001,B10100110};
const byte rock_beige[] PROGMEM = {16,16,
B00001000,B00001000,B00000010,B00000001,B00000010,B00000000,B10000010,B00000000,B10000100,B00000000,B00000100,B00000000,B00000100,B00011001,B00000100,B00100001,B00000100,B00100000,B00000100,B00010000,B10000100,B00100000,B10011100,B00000001,B00100000,B01000001,B00100000,B01000001,B01000000,B00000000,B01010010,B0011001};
const byte rock_brown[] PROGMEM = {16,16,
B11100010,B01000011,B11110000,B01110000,B11110000,B01110010,B01110000,B01111010,B01110010,B01111010,B11110010,B01111110,B11110010,B01100000,B11110010,B01011100,B11110010,B01011110,B11100010,B01011110,B01000000,B01011100,B01000000,B00111100,B10011110,B00111100,B10011110,B00111100,B10111110,B00111000,B00101100,B01000000};
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
const byte sand_brown[] PROGMEM = {16,16,
B00010001,B00010001,B00000000,B00000000,B10001000,B10001000,B00000000,B00000000,B00010001,B00010001,B00000000,B00000000,B10001000,B10001000,B00000000,B00000000,B00010001,B00010001,B00000000,B00000000,B10001000,B10001000,B00000000,B00000000,B00010001,B00010001,B00000000,B00000000,B10001000,B10001000,B00000000,B00000000};
const byte sand_beige[] PROGMEM = {16,16,
B11101110,B11101110,B11111111,B11111111,B01110111,B01110111,B11111111,B11111111,B11101110,B11101110,B11111111,B11111111,B01110111,B01110111,B11111111,B11111111,B11101110,B11101110,B11111111,B11111111,B01110111,B01110111,B11111111,B11111111,B11101110,B11101110,B11111111,B11111111,B01110111,B01110111,B11111111,B11111111};
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
const byte blank_tile1[] PROGMEM = {16,16,
B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000};
const byte blank_tile2[] PROGMEM = {16,16,
B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000};
const byte blank_tile3[] PROGMEM = {16,16,
B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000};
////////now we put them sprite sheets which gives each tile a number in ram 0 to what ever
const byte *spritesheet1[] = {blank_tile1,rock_black,};
const byte *spritesheet2[] = {blank_tile2, rock_brown, sand_brown,};
const byte *spritesheet3[] = {blank_tile3, rock_beige, sand_beige,};
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////next we take the integers from each sprite sheet and put them in an array where each integer is taken from the sprite sheet
///black
const byte tilemap1[] PROGMEM = {20,15,
16,16,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
0,0,0,0,1,1,1,1,1,0,0,0,0,0,1,1,1,1,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,1,1,1,1,0,0,0,0,0,0,1,1,1,1,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,1,1,1,1,0,0,0,0,0,0,1,1,1,1,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,1,1,1,1,0,0,0,0,0,0,1,1,1,1,0,0,
1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,
1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,
0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,1,0,0,
0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,1,0,0,
1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,};
///brown
const byte tilemap2[] PROGMEM = {20,15,
16,16,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
2,2,2,2,1,1,1,1,2,2,2,2,2,2,1,1,1,1,2,2,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
2,2,2,2,1,1,1,1,2,2,2,2,2,2,1,1,1,1,2,2,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
2,2,2,2,1,1,1,1,2,2,2,2,2,2,1,1,1,1,2,2,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
2,2,2,2,1,1,1,1,2,2,2,2,2,2,1,1,1,1,2,2,
1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,1,1,1,1,1,
1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,1,1,1,1,1,
2,2,2,2,1,1,1,1,2,2,2,2,2,2,1,1,1,1,2,2,
2,2,2,2,1,1,1,1,2,2,2,2,2,2,1,1,1,1,2,2,
1,1,1,1,1,1,1,1,2,2,2,2,2,2,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,2,2,2,2,2,1,1,1,1,1,1,1,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,};
///beige
const byte tilemap3[] PROGMEM = {20,15,
16,16,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
2,2,2,2,1,1,1,1,2,2,2,2,2,2,1,1,1,1,2,2,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
2,2,2,2,1,1,1,1,2,2,2,2,2,2,1,1,1,1,2,2,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
2,2,2,2,1,1,1,1,2,2,2,2,2,2,1,1,1,1,2,2,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
2,2,2,2,1,1,1,1,2,2,2,2,2,2,1,1,1,1,2,2,
1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,1,1,1,1,1,
1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,1,1,1,1,1,
2,2,2,2,1,1,1,1,2,2,2,2,2,2,1,1,1,1,2,2,
2,2,2,2,1,1,1,1,2,2,2,2,2,2,1,1,1,1,2,2,
1,1,1,1,1,1,1,1,2,2,2,2,2,2,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,2,2,2,2,2,1,1,1,1,1,1,1,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,};
//////////and then we draw the tiles to the screen using these functions
// tft.drawTilemap(x, y, tilemap1, spritesheet1, BLACK);
// tft.drawTilemap(x, y, tilemap2, spritesheet2, BROWN);
// tft.drawTilemap(x, y, tilemap3, spritesheet3, LIGHTBROWN);
To do all that we use these functions....
Code:
void drawBitmap1(int16_t x, int16_t y, const uint8_t *bitmap, int16_t w, int16_t h, uint16_t color);
////////TILEMAP and COLLISION
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, uint16_t color);
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, uint16_t color);
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);
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);
and this....
Code:
/ Draw a 1-bit image (bitmap) at the specified (x,y) position from the
// provided bitmap buffer (must be PROGMEM memory) using the specified
// foreground color (unset bits are transparent).
void Grafx::drawBitmap1(int16_t x, int16_t y,
const uint8_t *bitmap, int16_t w, int16_t h, uint16_t color) {
int16_t i, j, byteWidth = (w + 7) / 8;
uint16_t byte;
for (j = 0; j<h; j++) {
for (i = 0; i<w; i++) {
if (i & 7) byte <<= 1;
else byte = pgm_read_byte(bitmap + j * byteWidth + i / 8);
if (byte & 0x80) drawPixel(x + i, y + j, color);
}
}
}
//////////////////////////TILEMAP////////////////////////////////////////
boolean Grafx::getBitmapPixel(const uint8_t* bitmap, uint16_t x, uint16_t y) {
return pgm_read_byte(bitmap + 2 + y * ((pgm_read_byte(bitmap) + 7) / 8) + (x >> 3)) & (B10000000 >> (x % 8));
}
void Grafx::drawTilemap(int x, int y, const uint8_t *tilemap, const uint8_t **spritesheet, uint16_t color) {
drawTilemap(x, y, tilemap, spritesheet, 0, 0, Grafx_TFTWIDTH, Grafx_TFTHEIGHT, color);
}
void Grafx::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, uint16_t color) {
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)) {
drawBitmap1(drawX, drawY, spritesheet[tile], tile_width, tile_height, color);
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
drawBitmapTm(drawX, drawY, tile_width, tile_height, spritesheet[tile], dx, dy, dw, dh, color);
}
}
}
}
void Grafx::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) {
int16_t i, j, byteWidth = (w + 7) / 8;
dw += dx;
dh += dy;
int16_t largest = 0;
int16_t largesty = 0;
for (j = 0; j < h; j++) {
for (i = 0; i < w; i++) {
if (pgm_read_byte(bitmap + j * byteWidth + i / 8) & (B10000000 >> (i % 8))) {
int16_t drawX = x + i;
int16_t drawY = y + j;
if (drawX >= dx && drawX < dw && drawY >= dy && drawY < dh) {
drawPixel(drawX, drawY, color);
}
}
}
}
}
boolean Grafx::collidePointRect(int16_t x1, int16_t y1, int16_t x2, int16_t y2, int16_t w, int16_t h) {
if ((x1 >= x2) && (x1<x2 + w))
if ((y1 >= y2) && (y1<y2 + h))
return true;
return false;
}
boolean Grafx::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) {
return !(x2 >= x1 + w1 ||
x2 + w2 <= x1 ||
y2 >= y1 + h1 ||
y2 + h2 <= y1);
}
boolean Grafx::collideBitmapBitmap(int16_t x1, int16_t y1, const uint8_t* b1, int16_t x2, int16_t y2, const uint8_t* b2) {
int16_t w1 = pgm_read_byte(b1);
int16_t h1 = pgm_read_byte(b1 + 1);
int16_t w2 = pgm_read_byte(b2);
int16_t h2 = pgm_read_byte(b2 + 1);
if (collideRectRect(x1, y1, w1, h1, x2, y2, w2, h2) == false) {
return false;
}
int16_t xmin = (x1 >= x2) ? 0 : x2 - x1;
int16_t ymin = (y1 >= y2) ? 0 : y2 - y1;
int16_t xmax = (x1 + w1 >= x2 + w2) ? x2 + w2 - x1 : w1;
int16_t ymax = (y1 + h1 >= y2 + h2) ? y2 + h2 - y1 : h1;
for (uint8_t y = ymin; y < ymax; y++) {
for (uint8_t x = xmin; x < xmax; x++) {
if (getBitmapPixel(b1, x, y) && getBitmapPixel(b2, x1 + x - x2, y1 + y - y2)) {
return true;
}
}
}
return false;
}
This code can be found in any of my repositories here... https://github.com/Duhjoker
There is also the way found here...... https://github.com/Rodot/Gamebuino/tree/master/examples/2.Intermediate/TileMapRAM
Code:
#include <SPI.h>
#include <Gamebuino.h>
Gamebuino gb;
//store the different sprites in PROGMEM to save RAM
const byte grass[] PROGMEM = {16, 16, 0x10,0x0,0x28,0x2,0x10,0x0,0x0,0x0,0x0,0x0,0x10,0x40,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x0,0x0,0x40,0x0,0x0,0x0,0x0,0x8,0x4,0x0,0x0,0x0,};
const byte rocks[] PROGMEM = {16, 16, 0x20,0x0,0x50,0x0,0x21,0xe1,0x6,0x18,0x8,0xc,0x8,0x4,0x3c,0x6,0x42,0x7,0x40,0x37,0x40,0x1f,0x23,0x9e,0x1c,0x7e,0x8,0x3c,0x8,0x78,0x7,0xe0,0x0,0x0,};
const byte road_straight[] PROGMEM = {16, 16, 0x1f,0xf8,0x1f,0xf8,0x5e,0x78,0x1e,0x78,0x1e,0x78,0x1e,0x78,0x1e,0x79,0x1e,0x78,0x1f,0xf8,0x1f,0xf8,0x1e,0x78,0x1e,0x78,0x9e,0x78,0x1e,0x78,0x1e,0x78,0x1e,0x78,};
const byte road_turn[] PROGMEM = {16, 16, 0x1f,0xf8,0x1f,0xf8,0x1f,0xfc,0x1f,0xff,0x1f,0xff,0xf,0xff,0xf,0xff,0x7,0xff,0x87,0xff,0x3,0xff,0x1,0xff,0x0,0x7f,0x2,0x1f,0x0,0x0,0x0,0x0,0x40,0x0,};
// array containing the different sprites
#define NUM_SPRITES 4
const byte* sprites[NUM_SPRITES] = {
grass, rocks, road_straight, road_turn};
/*
The world is stored in bi-dimensional array of bytes.
This array is stored in RAM so it can be too large.
For large maps see the PROGMEM tile map examples.
Each tile of the world is stored in a byte. A byte is made of 8 bits.
The bits B000000XX define the sprite's ID (so there is 4 different sprites max)
The bits B0000XX00 define the sprite rotation (4 values of rotation)
You can notice that 4 bits are unused for each byte (these one: BXXXX0000).
This means that we could save even more memory by storing 2 tiles per byte,
but that would make accessing the the tiles coordinates more complicated.
It will be the subject of another example.
We could also store more than 4 different sprites.
*/
#define WORLD_W 16
#define WORLD_H 8
byte world[WORLD_W][WORLD_H];
byte getSpriteID(byte x, byte y){
return world[x][y] & B00000011;
}
byte getRotation(byte x, byte y){
return (world[x][y] >> 2) & B00000011;
}
void setTile(byte x, byte y, byte spriteID, byte rotation){
world[x][y] = (rotation << 2) + spriteID;
}
// cursor
int cursor_x, cursor_y;
int camera_x, camera_y;
void setup()
{
gb.begin();
initGame();
}
void loop(){
if(gb.update()){
//pause the game if C is pressed
if(gb.buttons.pressed(BTN_C)){
initGame();
}
updateCursor();
drawWorld();
drawCursor();
}
}
void initGame(){
gb.titleScreen(F("DYNAMIC TILE MAP DEMO"));
gb.pickRandomSeed(); //pick a different random seed each time for games to be different
initWorld();
gb.popup(F("\25:change \26:rotate"),60);
}
void initWorld(){
for(byte y = 0; y < WORLD_H; y++){
for(byte x = 0; x < WORLD_W; x++){
setTile(x, y, 0, random(0,4)); //fill with grass with random rotation
}
}
}
void drawWorld(){
for(byte y = 0; y < WORLD_H; y++){
for(byte x = 0; x < WORLD_W; x++){
byte spriteID = getSpriteID(x,y);
byte rotation = getRotation(x,y);
//coordinates on the screen depending on the camera position
int x_screen = x*16 - camera_x;
int y_screen = y*16 - camera_y;
if(x_screen < -16 || x_screen > LCDWIDTH || y_screen < -16 || y_screen > LCDHEIGHT){
continue; // don't draw sprites which are out of the screen
}
gb.display.drawBitmap(x_screen, y_screen, sprites[spriteID], rotation, 0);
}
}
}
void updateCursor(){
byte spriteID = getSpriteID(cursor_x,cursor_y);
byte rotation = getRotation(cursor_x,cursor_y);
if(gb.buttons.repeat(BTN_A, 4)){
spriteID = (spriteID+1) % NUM_SPRITES;
gb.sound.playOK();
}
if(gb.buttons.repeat(BTN_B, 4)){
rotation = (rotation+1) % 4;
gb.sound.playOK();
}
setTile(cursor_x, cursor_y, spriteID, rotation);
if(gb.buttons.repeat(BTN_RIGHT, 4)){
cursor_x = wrap(cursor_x+1, WORLD_W);
gb.sound.playTick();
}
if(gb.buttons.repeat(BTN_LEFT, 4)){
cursor_x = wrap(cursor_x-1, WORLD_W);
gb.sound.playTick();
}
if(gb.buttons.repeat(BTN_DOWN, 4)){
cursor_y = wrap(cursor_y+1, WORLD_H);
gb.sound.playTick();
}
if(gb.buttons.repeat(BTN_UP, 4)){
cursor_y = wrap(cursor_y-1, WORLD_H);
gb.sound.playTick();
}
//target position of the camera for the cursor to be centered
int camera_x_target = cursor_x*16 - LCDWIDTH/2 + 8;
int camera_y_target = cursor_y*16 - LCDHEIGHT/2 + 8;
//apply the target coordinate to the current coordinates with some smoothing
camera_x = (camera_x*3 + camera_x_target)/4;
camera_y = (camera_y*3 + camera_y_target)/4;
}
void drawCursor(){
int x_screen = cursor_x*16 - camera_x;
int y_screen = cursor_y*16 - camera_y;
if(!(x_screen < -16 || x_screen > LCDWIDTH || y_screen < -16 || y_screen > LCDHEIGHT)){
gb.display.drawRect(x_screen, y_screen, 16, 16);
}
gb.display.print(F("X"));
gb.display.print(cursor_x);
gb.display.print(F(" Y"));
gb.display.print(cursor_y);
byte spriteID = getSpriteID(cursor_x, cursor_y);
gb.display.print(F(" I"));
gb.display.print(spriteID);
byte rotation = getRotation(cursor_x, cursor_y);
gb.display.print(F(" R"));
gb.display.print(rotation);
}
The problem is that no matter what I try I cannot fill up the screen doing so. It cuts off the last 5 vertical rows leaving them blank or default color. I and awesomw101 did a lot work trying to solve the problem which can be seen from here on..... Please look we did a lot of work
http://gamebuino.com/forum/viewtopic.php?f=8&t=3745&start=20
Using tile map or the other example or any variation of nets the same results. I've tried changing variables across the tile map functions all so far net the result of no image at all being displayed. The original example is for a nokia 5110 lcd which has a resolution of 84 by 48 pixels BUT...... I've printed and walked around in maps using the same code with maps of 16bit bitmaps and 300 by 300 bitmaps on the nokia. So its STRANGE that it cuts off the last 5 bars. its like there is some kind of offset that's not allowing me to place the tilemap there. But I can put bitmaps one by one in the last five bars no problem. its just when using an array. Both my 2.4inch and 2.8inch have this problem. I read in one of my libraries that certain manufacturers use offsets that take propietory drivers or some stuff but my screens come from pjrc along with my teensy and spans every library and mcu.
Ok like I said we have talked about this here and there with no real dedication. I'm hoping this will improve my chances of fixing the problem. If I have mistakenly doubled a thread feel free to cancel which ever one and tell me. I don't want to needlessly take up space.
EDIT::
If I mess with these.....
Code:
uint16_t tilemap_width = pgm_read_byte(tilemap);
uint16_t tilemap_height = pgm_read_byte(tilemap + 1); /////////// kills screen no matter what
uint16_t tile_width = pgm_read_byte(tilemap + 2); /////// shrinks the screen if 0 does nothung after 2 tried up to 8
uint16_t tile_height = pgm_read_byte(tilemap + 3); ///////// sends all pixels to top row
tilemap += 4; // now the first tiyleis at tilemap ///////// just makes screen flash
I I play with these it cuts off the left side
Code:
if (startDdx < 0) {
startDdx = 0;
}
if (startDdy < 0) {
startDdy = 0;
I just noticed that when the tilemap is on the player navigates the blank area as it was part of the tilemap by moving slow in that and all areas compared to having the tilemap commented out where he moves fast.
Last edited: