Spelprogrammering Demonstration och konsultation Arbetsbokens avsnitt 8 Ett exempel på spelprogrammering Kan vara till hjälp inför laboration 5 Demonstrationsövning 6 1
Spel exempel: - Tile baserat. - 16x8 tiles - Spelaren förflyttar sig i steg om 8 pixels i x och y led. - Mål: Ta nyckeln, gå till dörren. - Speltillstånd. Demonstrationsövning 6 2
Spelprogrammering: - Rita grafik tiles. - Konvertera data (för att rita effektivt). - Beskriva och rita rum - Interagera med spelarfigur. - Kollisioner. - Speltillstånd. Demonstrationsövning 6 3
unsigned char wall1[64] = {1,1,1,1,1,1,1,1, 1,0,0,1,0,0,1,0, 1,0,0,1,0,0,1,0, 1,1,1,1,1,1,1,1, 0,0,1,0,0,0,1,0, 0,0,1,0,0,0,1,0, 1,1,1,1,1,1,1,1, 1,0,0,0,1,0,0,1; Rita tiles - Enkelt sätt att beskriva en tile. Men ej effektivt att rita! unsigned char wall2[64] = {1,0,0,0,1,0,0,1, 1,1,1,1,1,1,1,1, 1,0,0,1,0,0,1,1, 1,0,0,1,1,1,1,0, 1,0,0,1,0,0,1,0, 1,1,1,1,1,1,1,1, 1,0,0,0,1,0,0,1, 1,0,0,0,1,0,0,1; Demonstrationsövning 6 4
unsigned char wall1[64] = {1,1,1,1,1,1,1,1, 1,0,0,1,0,0,1,0, 1,0,0,1,0,0,1,0, 1,1,1,1,1,1,1,1, 0,0,1,0,0,0,1,0, 0,0,1,0,0,0,1,0, 1,1,1,1,1,1,1,1, 1,0,0,0,1,0,0,1; unsigned char wall2[64] = {1,0,0,0,1,0,0,1, 1,1,1,1,1,1,1,1, 1,0,0,1,0,0,1,1, 1,0,0,1,1,1,1,0, 1,0,0,1,0,0,1,0, 1,1,1,1,1,1,1,1, 1,0,0,0,1,0,0,1, 1,0,0,0,1,0,0,1; Rita tiles - Enkelt sätt att beskriva en tile. Men ej effektivt att rita! unsigned char c_wall[8] = {0xF3, 0x92,0x9E, 0xF2, 0X93,0x92,0xFE,0x93; Demonstrationsövning 6 5
void draw8x8(unsigned char *pattern, int x, int y) /*x 1-16, y 1-8 */ { unsigned char controller; int col; int phys_x, phys_y; if( (x > 16 ) (y > 8) ) return; phys_y = y - 1; if(x > 8){ controller = B_CS2; x = x - 9; else{ controller = B_CS1; x = x - 1; for (col = 0; col < 8; col ++) { phys_x = (x*8 + col); graphic_writecommand(lcd_set_add phys_x, controller ); graphic_writecommand(lcd_set_page phys_y, controller ); graphic_writedata( pattern[col], controller); Demonstrationsövning 6 6
Konvertera tiles : void convert8x8(unsigned char *in, unsigned char *out){ int row, col; unsigned char current_col; for (col = 0; col < 8; col ++) { /* for each column */ current_col = 0; for (row = 0; row < 8; row ++) { if (in[row * 8 + col]) current_col = (1 << row); out[col] = current_col; Demonstrationsövning 6 7
Beskriva rum : unsigned char room1[128] = {1,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1, 2,0,1,0,0,0,0,0,0,0,0,0,0,0,0,2, 1,0,2,0,0,0,0,0,0,0,0,0,0,0,0,3, 2,0,1,0,0,0,0,0,0,1,2,1,2,0,0,2, 1,0,2,1,2,1,2,0,0,2,0,0,1,0,0,1, 2,0,0,0,0,0,0,0,0,1,0,0,2,0,0,2, 1,0,0,0,0,0,0,0,0,2,0,0,0,0,0,1, 2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,2; Demonstrationsövning 6 8
Beskriva rum : Mönster uppsättningar: unsigned char room1[128] = {1,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1, 2,0,1,0,0,0,0,0,0,0,0,0,0,0,0,2, 1,0,2,0,0,0,0,0,0,0,0,0,0,0,0,3, 2,0,1,0,0,0,0,0,0,1,2,1,2,0,0,2, 1,0,2,1,2,1,2,0,0,2,0,0,1,0,0,1, 2,0,0,0,0,0,0,0,0,1,0,0,2,0,0,2, 1,0,0,0,0,0,0,0,0,2,0,0,0,0,0,1, 2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,2; unsigned char *patterns[4] = {(unsigned char *)0x0, c_wall1, c_wall2, c_door1; Demonstrationsövning 6 9
Rita rum : void draw_room(unsigned char *room, unsigned char **patterns) { int wall_type; int i,j; for (i = 0; i < 8; i ++) { for (j = 0; j < 16; j ++) { wall_type = room[i*16+j]; if (wall_type) draw8x8(patterns[wall_type],j+1,i+1); Demonstrationsövning 6 10
Styra spelaren: - Flytta spelaren vid knapptryck: 2,4,6,8. Repetera ej förflyttning vid nedtryckt knapp. Demonstrationsövning 6 11
Styra spelaren: - Flytta spelaren vid knapptryck: 2,4,6,8. Repetera ej förflyttning vid nedtryckt knapp. Spara knapptillstånd mellan avläsningar : unsigned char keystatus[16] = {0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0; Demonstrationsövning 6 12
int set_keyboard_status(unsigned char c, unsigned char *keystats) { int i; if (keystats[c]) return 0; /* return false */ for (i = 0; i < 16; i ++) { keystats[i] = 0; keystats[c] = 1; return 1; void clear_keyboard_status(unsigned char *keystats) { int i; for (i = 0; i < 16; i ++) { keystats[i] = 0; Demonstrationsövning 6 13
Spelarens tillstånd: int player_x = 2; /* start position x */ int player_y = 2; int player_old_x=2; /* föregående position */ int player_old_y=2; int player_moves = 0; /* försöker spelaren flytta på sig */ Demonstrationsövning 6 14
/* läs från tangentbord */ c = keyb(); /* Upp ner höger vänster? */ switch(c) { case 2: /* upp */ case 8: /* ner */ case 4: /* vänster */ case 6: /* höger */ cefault: /* någon annan knapp */ Demonstrationsövning 6 15
/* läs från tangentbord */ c = keyb(); /* Upp ner höger vänster? */ switch(c) { case 2: /* upp */ case 8: /* ner */ case 4: /* vänster */ case 6: /* höger */ cefault: /* någon annan knapp */ case 2: if (set_keyboard_status(c,keystatus)) { player_moves = 1; player_y--; else player_moves = 0; break; Demonstrationsövning 6 16
Upptäck kollision med vägg: int player_collides(unsigned char *room,int player_x, int player_y) { if (player_x > 16 player_x < 1) return 1; if (player_y > 8 player_y < 1) return 1; player_x = player_x-1; player_y = player_y-1; int index = player_y * 16 + player_x; if (room[index]) return 1; return 0; Demonstrationsövning 6 17
Hantera kollisioner: if (player_moves) { /* Är detta en tillåten förflyttning av spelaren? */ if (player_collides(room1,player_x,player_y)) { /* ej ok att gå hit */ player_x = player_old_x; player_y = player_old_y; else { erase8x8(player_avatar,player_old_x,player_old_y); player_old_x = player_x; player_old_y = player_y; draw8x8(player_avatar,player_x,player_y); Demonstrationsövning 6 18
Övrigt spelbeteende: if (!player_has_key && player_x == key_x && player_y == key_y) { /* remove key */ erase8x8(c_key,key_x,key_y); /* rita tillbaka förstörd spelare */ draw8x8(player_avatar,player_x,player_y); /* spelaren har nu nyckeln */ player_has_key = 1; if (player_has_key && player_x == 15 && player_y == 3) { yay(); Demonstrationsövning 6 19
TODO: - Fler rum. - Monster. - Förbättra kbd hanteringen. - Timing behöver justeras (hw). - Animationer. Demonstrationsövning 6 20
Demonstrationsövning 6 21