Ok my tilemapper is almost done
I added the player masked sprite, direction, animation, collision and animated tiles. Here's the code :
- Code: Select all
#include <SPI.h>
#include <Gamebuino.h>
#define MAP_WIDTH 15
#define MAP_HEIGHT 15
const int PROGMEM map_test[]={
5,5,7,0,7,5,5,5,8,11,11,15,5,5,5,
5,0,7,0,7,1,1,3,9,12,12,16,1,1,5,
5,0,0,0,0,3,1,1,10,13,14,17,1,3,5,
5,0,6,0,0,0,0,0,0,0,0,1,1,1,5,
5,0,0,0,0,0,0,0,0,0,0,0,1,1,5,
5,0,0,0,0,0,0,0,0,0,0,0,0,1,5,
5,8,11,11,15,0,0,0,0,0,0,0,0,1,5,
5,9,12,12,16,5,5,5,5,0,0,0,0,0,5,
5,10,13,14,17,3,1,1,1,0,0,0,0,0,5,
5,1,0,1,1,1,1,0,0,0,0,0,0,0,5,
5,0,0,0,0,0,0,0,0,0,0,0,0,0,5,
5,0,0,0,0,0,0,0,0,0,0,0,6,0,5,
5,2,2,2,2,2,2,2,2,2,0,0,0,0,5,
5,2,2,2,2,2,2,2,2,2,7,0,7,0,5,
5,5,5,5,5,5,5,5,5,5,7,0,7,5,5 };
#define TILE_WIDTH 8
#define TILE_HEIGHT 8
#define TILES_PASSABLE_NUM 4
#define TILES_ANIMATED_START 3
#define TILES_ANIMATED_END 3
#define ANIMATION_FREQUENCY 500 // ms
const byte PROGMEM tiles[]={
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x50,0x20,0x0a,0x04,0xa0,0x40,0x00,
0x00,0xaa,0xee,0x44,0x00,0xaa,0xee,0x44,
0x04,0x0a,0x04,0x4e,0xa4,0x40,0xe0,0x40,
0x02,0x05,0x02,0x2e,0x54,0x20,0xe0,0x40,
0x66,0xff,0x99,0x99,0x99,0x99,0x99,0x66,
0x7e,0x81,0xa9,0xb5,0x81,0x7e,0x18,0x18,
0x3c,0x42,0xc3,0xbf,0xa7,0xa7,0xa7,0x7e,
0x00,0x03,0x0f,0x3b,0xeb,0xab,0xab,0xab,
0xab,0xab,0xac,0xb0,0xe0,0x20,0x20,0x20,
0x20,0x20,0x20,0x20,0x30,0x2a,0x3d,0x1f,
0xff,0x7e,0xbd,0xdb,0xe7,0xdb,0xbd,0x7e,
0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x00,
0x7e,0xb9,0xc5,0xcd,0xd5,0xbb,0x83,0x81,
0xee,0x11,0x33,0x55,0xee,0x00,0x55,0xff,
0x00,0xc0,0xf0,0xfc,0xff,0xff,0xff,0xff,
0xff,0xff,0x3f,0x0f,0x07,0x04,0x04,0x04,
0x04,0x04,0x04,0x04,0x0c,0xb4,0x5c,0xf8 };
const byte PROGMEM player_down01[]={
8,8,0x3e,0x41,0x7f,0x55,0x41,0x3e,0x5d,0x36 };
const byte PROGMEM player_down02[]={
8,8,0x3e,0x41,0x7f,0x55,0x61,0x5f,0x7f,0x36 };
const byte PROGMEM player_down03[]={
8,8,0x3e,0x41,0x7f,0x55,0x43,0x7d,0x7f,0x36 };
const byte PROGMEM player_left01[]={
8,8,0x1e,0x21,0x7f,0x2b,0x21,0x1e,0x0a,0x1e };
const byte PROGMEM player_left02[]={
8,8,0x1e,0x21,0x7f,0x2b,0x21,0x1e,0x17,0x3f };
const byte PROGMEM player_left03[]={
8,8,0x1e,0x21,0x7f,0x2b,0x21,0x1e,0x1d,0x3f };
const byte PROGMEM player_mask01[]={
8,8,0x3e,0x7f,0x7f,0x7f,0x7f,0x3e,0x7f,0x36 };
const byte PROGMEM player_mask02[]={
8,8,0x3e,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x36 };
const byte PROGMEM player_mask03[]={
8,8,0x1e,0x3f,0x7f,0x3f,0x3f,0x1e,0x0e,0x1e };
const byte PROGMEM player_mask04[]={
8,8,0x1e,0x3f,0x7f,0x3f,0x3f,0x1e,0x1f,0x3f };
const byte PROGMEM player_mask05[]={
8,8,0x3c,0x7e,0x7f,0x7e,0x7e,0x3c,0x38,0x3c };
const byte PROGMEM player_mask06[]={
8,8,0x3c,0x7e,0x7f,0x7e,0x7e,0x3c,0x7c,0x7e };
const byte PROGMEM player_right01[]={
8,8,0x3c,0x42,0x7f,0x6a,0x42,0x3c,0x28,0x3c };
const byte PROGMEM player_right02[]={
8,8,0x3c,0x42,0x7f,0x6a,0x42,0x3c,0x74,0x7e };
const byte PROGMEM player_right03[]={
8,8,0x3c,0x42,0x7f,0x6a,0x42,0x3c,0x5c,0x7e };
const byte PROGMEM player_up01[]={
8,8,0x3e,0x41,0x7f,0x41,0x41,0x3e,0x5d,0x36 };
const byte PROGMEM player_up02[]={
8,8,0x3e,0x41,0x7f,0x41,0x43,0x7d,0x4f,0x36 };
const byte PROGMEM player_up03[]={
8,8,0x3e,0x41,0x7f,0x41,0x61,0x5f,0x79,0x36 };
const byte* player_sprites[]={
player_mask05,player_right01,player_mask06,player_right02,player_mask06,player_right03,
player_mask01,player_up01,player_mask02,player_up02,player_mask02,player_up03,
player_mask03,player_left01,player_mask04,player_left02,player_mask04,player_left03,
player_mask01,player_down01,player_mask02,player_down02,player_mask02,player_down03 };
Gamebuino gb;
void setup(){
gb.begin();
byte player_x = 2;
byte player_y = 2;
byte player_direction = 3;
byte player_animation = 0;
int camera_x = player_x*TILE_WIDTH-LCDWIDTH/2+4;
camera_x = camera_x*(camera_x > 0)+(MAP_WIDTH*TILE_WIDTH-LCDWIDTH-camera_x)*(camera_x > MAP_WIDTH*TILE_WIDTH-LCDWIDTH);
int camera_y = player_y*TILE_HEIGHT-LCDHEIGHT/2+4;
camera_y = camera_y*(camera_y > 0)+(MAP_HEIGHT*TILE_HEIGHT-LCDHEIGHT-camera_y)*(camera_y > MAP_HEIGHT*TILE_HEIGHT-LCDHEIGHT);
while(1){
if(gb.update()){
draw_map(camera_x, camera_y);
draw_player(player_x*TILE_WIDTH-camera_x, player_y*TILE_WIDTH-camera_y, player_direction, player_animation);
char x_temp = -gb.buttons.repeat(BTN_LEFT, 1)*(player_x > 0)+gb.buttons.repeat(BTN_RIGHT, 1)*(player_x < MAP_WIDTH-1);
char y_temp = -gb.buttons.repeat(BTN_UP, 1)*(player_y > 0)+gb.buttons.repeat(BTN_DOWN, 1)*(player_y < MAP_HEIGHT-1);
if(x_temp || y_temp){
player_direction = (1+x_temp)*(x_temp != 0);
player_direction = (2+y_temp)*(y_temp != 0 || player_direction == 0);
if(TILES_PASSABLE_NUM-pgm_read_byte(map_test+(player_y+y_temp)*MAP_WIDTH+player_x+x_temp) > 0){
for(byte i = 1; i <=8; i++){
player_animation += 1;
player_animation *= (player_animation < 3 && i < 8);
camera_x = (player_x*TILE_WIDTH-LCDWIDTH/2+4+i*x_temp);
camera_x = camera_x*(camera_x > 0)+(MAP_WIDTH*TILE_WIDTH-LCDWIDTH-camera_x)*(camera_x > MAP_WIDTH*TILE_WIDTH-LCDWIDTH);
camera_y = player_y*TILE_HEIGHT-LCDHEIGHT/2+4+i*y_temp;
camera_y = camera_y*(camera_y > 0)+(MAP_HEIGHT*TILE_HEIGHT-LCDHEIGHT-camera_y)*(camera_y > MAP_HEIGHT*TILE_HEIGHT-LCDHEIGHT);
gb.display.clear();
draw_map(camera_x, camera_y);
draw_player(player_x*TILE_WIDTH-camera_x+i*x_temp, player_y*TILE_WIDTH-camera_y+i*y_temp, player_direction, player_animation);
gb.display.update();
}
player_x += x_temp;
player_y += y_temp;
}
}
}
}
}
void loop(){
}
void draw_tile(int x, int y, byte tile_num){
tile_num += (tile_num >= TILES_ANIMATED_START && tile_num <= TILES_ANIMATED_END)*millis()/ANIMATION_FREQUENCY%2;
byte i, j;
for(i = 0; i < TILE_WIDTH; i++){
for(j = 0; j < TILE_HEIGHT; j++) {
if(pgm_read_byte(tiles+tile_num*TILE_HEIGHT+j)&(B10000000>>i)){
gb.display.drawPixel(x+i,y+j);
}
}
}
}
void draw_map(int camera_x, int camera_y){
for(byte y = 0; y <= 6; y++){
for(byte x = 0; x <= 11; x++){
int tile_x = camera_x/TILE_WIDTH+x;
int tile_y = camera_y/TILE_HEIGHT+y;
if(tile_x >= 0 && tile_x < MAP_WIDTH && tile_y >= 0 && tile_y < MAP_HEIGHT){
draw_tile(x*TILE_WIDTH-camera_x%TILE_WIDTH, y*TILE_HEIGHT-camera_y%TILE_HEIGHT, pgm_read_byte(map_test+tile_y*MAP_WIDTH+tile_x));
}
}
}
}
void draw_player(int x, int y, byte direction, byte animation){
gb.display.setColor(WHITE, BLACK);
gb.display.drawBitmap(x, y, player_sprites[direction*6+2*animation]);
gb.display.setColor(BLACK, WHITE);
gb.display.drawBitmap(x, y, player_sprites[direction*6+2*animation+1]);
}
I'll try to optimize it a little bit more and add a lot of comments so that hopefully it can help beginners.
And I'll do another topic when I'll have something more concrete.