Tile mapper questions

Understanding the language, error messages, etc.

Re: Tile mapper questions

Postby Marcus » Tue Jul 14, 2015 10:59 am

Looking good!

Oh yeah, that's amazing 8x8 sprite art! (Now I'm jealous :-) )
I've also seen
http://www.team-arg.org/ELV-manual.html and http://www.team-arg.org/DUN-manual.html
But at least I wasn't able to pull off the Secret of Mana enemy variety in 8x8, the weaponry, the NPC... :-) The details always end up stylized. More stick-man then character :-) But perhaps I'll doodle a bit more.

Anyway, good luck with your project, looking forward to it :-) I hope I can get it nearly as smooth and implement the "following AI" of the secondary characters :-)
Marcus
 
Posts: 143
Joined: Fri Jan 09, 2015 6:51 pm

Re: Tile mapper questions

Postby deeph » Wed Jul 15, 2015 8:35 pm

Ok my tilemapper is almost done 8-)

Image

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.
deeph
 
Posts: 52
Joined: Mon Jul 13, 2015 6:09 am
Location: France

Re: Tile mapper questions

Postby Marcus » Wed Jul 15, 2015 8:38 pm

Wow. That turned out great.
Thanks for sharing!
I played around with 8x8 sprites a bit more but I think I am trying to get too many details squeezed into them :)

Your source code will come in handy when I start coding again !
Marcus
 
Posts: 143
Joined: Fri Jan 09, 2015 6:51 pm

Re: Tile mapper questions

Postby erico » Wed Jul 15, 2015 9:35 pm

Extremely charming! Well done job! :)
User avatar
erico
 
Posts: 671
Joined: Thu Mar 27, 2014 9:29 pm
Location: Brazil

Re: Tile mapper questions

Postby Sorunome » Wed Jul 15, 2015 10:27 pm

Yes, it is looking quite awesome indeed, great job!
User avatar
Sorunome
 
Posts: 629
Joined: Sun Mar 01, 2015 1:58 pm

Re: Tile mapper questions

Postby Drakker » Wed Jul 15, 2015 10:49 pm

Looks great!
User avatar
Drakker
 
Posts: 297
Joined: Sun Mar 30, 2014 2:54 am
Location: Québec, Canada

Re: Tile mapper questions

Postby Jolly » Thu Jul 16, 2015 8:04 am

Oh wow, that looks amazing. :shock:
Jolly
 
Posts: 40
Joined: Fri Jul 25, 2014 9:07 pm
Location: Germany

Previous

Return to Programming Questions

Who is online

Users browsing this forum: No registered users and 68 guests

cron