J'ai ajouté les collisions tiles/ennemis/joueur, il me manque plus qu'à calculer les dégâts (la boite qui s'affiche au dessus de la tête du joueur c'est pour indiquer qu'il a été touché, mais c'est temporaire/juste pour débugger) :
test.c
#pragma string name C TEST
#include "..\dev\ti83p.h"
#include "..\dev\tilib.c"
#include "..\dev\gbalib2.c"
// Sprites
#include "..\dev\sprites\title.h"
#include "..\dev\sprites\map.h"
#include "..\dev\sprites\map_player.h"
#include "..\dev\sprites\tiles.h"
#include "..\dev\sprites\battle_player_up.h"
#include "..\dev\sprites\battle_player_up_attack.h"
#include "..\dev\sprites\battle_player_right.h"
#include "..\dev\sprites\battle_player_right_attack.h"
#include "..\dev\sprites\battle_player_down.h"
#include "..\dev\sprites\battle_player_down_attack.h"
#include "..\dev\sprites\battle_player_left.h"
#include "..\dev\sprites\battle_player_left_attack.h"
#include "..\dev\sprites\battle_ennemy.h"
// Map
extern char battle_map[];
#asm
._battle_map
defb 4,4,4,4,4,4,4,3,3,3,3,3,4,4,4,4,4,4,4,4
defb 4,0,0,0,0,0,0,1,3,3,3,4,4,0,1,1,1,0,0,4
defb 4,0,0,0,0,0,0,2,1,3,3,1,1,0,2,2,2,0,0,4
defb 4,0,0,4,4,4,0,0,2,3,0,2,2,0,0,0,0,0,0,4
defb 4,0,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,4
defb 4,0,0,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4
defb 4,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4
defb 4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4
defb 4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4
defb 4,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4
defb 4,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4
defb 4,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,4
defb 4,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,4
defb 4,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,4
defb 4,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,4
defb 4,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,4
defb 4,0,0,0,0,0,0,2,0,0,0,0,0,0,1,0,0,0,0,4
defb 4,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,4
defb 4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4
defb 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4
#endasm
// Constants
#define START 0
#define LOAD 1
#define QUIT 2
#define BATTLE_MAP_WIDTH 20
#define BATTLE_MAP_HEIGHT 20
// Global variables
unsigned char i, j, key, player_x = 80, player_y = 59, battle_player_x = 10, battle_player_y = 18, *battle_player_direction = 0, camera_x, camera_y, x_temp, y_temp;
typedef struct {
int x;
int y;
int hp;
} ennemy_struct;
ennemy_struct ennemy[4];
extern char text_menu[];
#asm
._text_menu
defm "Nouveau"&TL_NEWL&"Continuer"&TL_NEWL&"Quitter"&0
#endasm
extern char text_intro[];
#asm
._text_intro
defm "Vous viviez tranquillement"&TL_NEWL&"en dehors de la soci"&0x96&"t"&0x96&TL_NEWL&"jusqu'au jour o"&0xaf&" vous"&TL_NEWL&"d"&0x96&"couvrez qu'on vous a"&TL_NEWL&"vol"&0x96&"..."&TL_BRK&TL_NEWL&"Vous d"&0x96&"cidez alors de"&TL_NEWL&"partir "&0x8f&" la recherche"&TL_NEWL&"des voleurs."&TL_BRK&0
#endasm
extern char text_castle[];
#asm
._text_castle
defm "Garde :"&TL_NEWL&"Passez votre chemin sale"&TL_NEWL&"manant !"&TL_BRK&0
#endasm
//Functions prototypes
void main_menu(void);
char draw_cursor(unsigned char x, unsigned char y);
void handle_map(void);
void update_map(void);
char draw_player(unsigned char old_player_x, unsigned char old_player_y, unsigned char player_x, unsigned char player_y);
char check_place(unsigned char player_x, unsigned char player_y);
void battle(void);
void update_battle_screen(void);
void draw_ennemies(void);
char is_location_empty(unsigned char x, unsigned char y);
void hit_player(void);
//Functions
int main(){
switch(main_menu()){
case START:
TL_rectangle_filled(0, 0, 96, 64, TL_RECT_FILL_BLACK);
TL_rectangle_filled(1, 1, 94, 62, TL_RECT_FILL_WHITE);
TL_text(2, 1, text_intro, TL_TEXT_TYPE, 5);
handle_map();
break;
case LOAD:
break;
}
}
void main_menu(void){
unsigned char cursor_y = 0;
TL_large_sprite(5, 0, 11, 26, title);
TL_rectangle_filled(28, 33, 40, 21, TL_RECT_FILL_BLACK);
TL_rectangle_filled(29, 34, 38, 19, TL_RECT_FILL_WHITE);
TL_text(34, 34, text_menu, TL_TEXT_NOTYPE, 0);
TL_gbuf_to_lcd();
key = 0;
while(key != skey_2nd){
draw_cursor(30, 34+cursor_y*6);
key = TL_get_key();
switch(key){
case skey_up:
if(cursor_y > START){
TL_gbuf_to_lcd();
cursor_y-=1;
}
break;
case skey_down:
if(cursor_y < QUIT){
TL_gbuf_to_lcd();
cursor_y+=1;
}
break;
}
}
return cursor_y;
}
char draw_cursor(unsigned char x, unsigned char y){
#asm
res textwrite,(iy+sgrflags) ; reset some flag to write only to the screen (not the graph buffer)
ld hl,2
add hl,sp
ld b,(hl) ; get y from the parameters (stack)
inc hl
inc hl
ld c,(hl) ; get x
ld (pencol),bc
ld a,5
rst rbr_call
defw _vputmap ; write the cursor character
set textwrite,(iy+sgrflags) ; set the flag to write on the gbuf
#endasm
}
void handle_map(void){
update_map();
key = 0;
while(key != dkey_clear){
switch(TL_direct_input(dkey_group_1)){
case dkey_up:
if((TL_get_pixel(player_x, player_y-1) == TL_PIXEL_OFF) && (TL_get_pixel(player_x+1, player_y-1) == TL_PIXEL_OFF) && (TL_get_pixel(player_x+2, player_y-1) == TL_PIXEL_OFF)){
draw_player(player_x, player_y, player_x, player_y -= 1);
}else{
check_place(player_x+1, player_y-1);
update_map();
}
break;
case dkey_right:
if((TL_get_pixel(player_x+3, player_y) == TL_PIXEL_OFF) && (TL_get_pixel(player_x+3, player_y+1) == TL_PIXEL_OFF) && (TL_get_pixel(player_x+3, player_y+2) == TL_PIXEL_OFF)){
draw_player(player_x, player_y, player_x += 1, player_y);
}else{
check_place(player_x+3, player_y+1);
update_map();
}
break;
case dkey_left:
if((TL_get_pixel(player_x-1, player_y) == TL_PIXEL_OFF) && (TL_get_pixel(player_x-1, player_y+1) == TL_PIXEL_OFF) && (TL_get_pixel(player_x-1, player_y+2) == TL_PIXEL_OFF)){
draw_player(player_x, player_y, player_x -= 1, player_y);
}else{
check_place(player_x-1, player_y+1);
update_map();
}
break;
case dkey_down:
if((TL_get_pixel(player_x, player_y+3) == TL_PIXEL_OFF) && (TL_get_pixel(player_x+1, player_y+3) == TL_PIXEL_OFF) && (TL_get_pixel(player_x+2, player_y+3) == TL_PIXEL_OFF)){
draw_player(player_x, player_y, player_x, player_y += 1);
}else{
check_place(player_x+1, player_y+3);
update_map();
}
break;
}
key = TL_direct_input(dkey_group_2);
}
}
void update_map(void){
bcall(_cleargbuf);
TL_large_sprite(0, 0, 12, 64, map);
TL_small_sprite(player_x, player_y, 3, map_player);
TL_gbuf_to_lcd();
}
char draw_player(unsigned char old_player_x, unsigned char old_player_y, unsigned char player_x, unsigned char player_y){
TL_small_sprite(old_player_x, old_player_y, 3, map_player); // clear the player's sprite
TL_small_sprite(player_x, player_y, 3, map_player); // and re-draw it to its new place
TL_gbuf_to_lcd();
}
char check_place(unsigned char player_x, unsigned char player_y){
if(player_x > 5 && player_x < 19 && player_y > 4 && player_y < 31){
// TOWER
}else if(player_x > 25 && player_x < 58 && player_y > 3 && player_y < 36){
// CASTLE
TL_rectangle_filled(0, 37, 96, 27, TL_RECT_FILL_BLACK);
TL_rectangle_filled(1, 38, 94, 25, TL_RECT_FILL_WHITE);
TL_text(2, 38, text_castle, TL_TEXT_TYPE, 5);
}else if(player_x > 57 && player_x < 95 && player_y > 0 && player_y < 25){
// VOLCANO
}else if(player_x > 29 && player_x < 49 && player_y > 39 && player_y < 54){
// TOWN
}else if(player_x > 59 && player_x < 95 && player_y > 32 && player_y < 63){
if(player_x > 83 && player_x < 94 && player_y > 52 && player_y < 62){
// HOUSE
}else{
// FOREST
battle();
}
}
}
void battle(void){
bcall(_cleargbuf);
for(i = 0; i<4; i++){
generate_ennemy_coordinates:
x_temp = TL_random(BATTLE_MAP_WIDTH-2)+1;
y_temp = TL_random(BATTLE_MAP_HEIGHT/2)+1;
if(GBA_collision((x_temp-GBA_scroll_x)*8, (y_temp-GBA_scroll_y)*8) > 0)
goto generate_ennemy_coordinates;
ennemy[i].x = x_temp;
ennemy[i].y = y_temp;
ennemy[i].hp = 3;
}
x_temp = battle_player_x;
y_temp = battle_player_y;
battle_player_direction = battle_player_up;
while(key != skey_clear){
if(battle_player_x < screen_w/16){
camera_x = 0;
}else if(battle_player_x > BATTLE_MAP_WIDTH-screen_w/16){
camera_x = BATTLE_MAP_WIDTH-screen_w/8;
}else{
camera_x = battle_player_x-screen_w/16;
}
if(battle_player_y < screen_h/16){
camera_y = 0;
}else if(battle_player_y > BATTLE_MAP_HEIGHT-screen_h/16){
camera_y = BATTLE_MAP_HEIGHT-screen_h/8;
}else{
camera_y = battle_player_y-screen_h/16;
}
update_battle_screen();
key = TL_get_key();
switch(key){
case skey_up:
if(is_location_empty(battle_player_x, battle_player_y-1) && GBA_collision((battle_player_x-GBA_scroll_x)*8, (battle_player_y-1-GBA_scroll_y)*8) == 0){
battle_player_y -= 1;
x_temp = battle_player_x;
y_temp = battle_player_y-1;
}
battle_player_direction = battle_player_up;
break;
case skey_right:
if(is_location_empty(battle_player_x+1, battle_player_y) && GBA_collision((battle_player_x+1-GBA_scroll_x)*8, (battle_player_y-GBA_scroll_y)*8) == 0){
battle_player_x +=1 ;
x_temp = battle_player_x+1;
y_temp = battle_player_y;
}
battle_player_direction = battle_player_right;
break;
case skey_left:
if(is_location_empty(battle_player_x-1, battle_player_y) && GBA_collision((battle_player_x-1-GBA_scroll_x)*8, (battle_player_y-GBA_scroll_y)*8) == 0){
battle_player_x -= 1;
x_temp = battle_player_x-1;
y_temp = battle_player_y;
}
battle_player_direction = battle_player_left;
break;
case skey_down:
if(is_location_empty(battle_player_x, battle_player_y+1) && GBA_collision((battle_player_x-GBA_scroll_x)*8, (battle_player_y+1-GBA_scroll_y)*8) == 0){
battle_player_y +=1 ;
x_temp = battle_player_x;
y_temp = battle_player_y+1;
}
battle_player_direction = battle_player_down;
break;
case skey_2nd:
GBA_restore_map();
draw_ennemies();
battle_player_direction+=2*8; // go to the attack sprite
GBA_draw_mask_sprite((battle_player_x-GBA_scroll_x)*8, (battle_player_y-GBA_scroll_y)*8, 1, 8, battle_player_direction, GBA_CLIP_SPRITE);
TL_gbuf_to_lcd();
TL_delay(5);
battle_player_direction-=2*8; // go back to the normal sprite
// if !is_location_empty(x_temp, y_temp){
// someone has been touched
// }
break;
}
// IA
for(i = 0; i<4; i++){
if(ennemy[i].x < battle_player_x && is_location_empty(ennemy[i].x+1, ennemy[i].y) && GBA_collision((ennemy[i].x+1-GBA_scroll_x)*8, (ennemy[i].y-GBA_scroll_y)*8) == 0){
if(ennemy[i].x+1 == battle_player_x && ennemy[i].y == battle_player_y)
hit_player();
else
ennemy[i].x += 1;
}else if(ennemy[i].x > battle_player_x && is_location_empty(ennemy[i].x-1, ennemy[i].y) && GBA_collision((ennemy[i].x-1-GBA_scroll_x)*8, (ennemy[i].y-GBA_scroll_y)*8) == 0){
if(ennemy[i].x-1 == battle_player_x && ennemy[i].y == battle_player_y)
hit_player();
else
ennemy[i].x -= 1;
}
if(ennemy[i].y < battle_player_y && is_location_empty(ennemy[i].x, ennemy[i].y+1) && GBA_collision((ennemy[i].x-GBA_scroll_x)*8, (ennemy[i].y+1-GBA_scroll_y)*8) == 0){
if(ennemy[i].x == battle_player_x && ennemy[i].y+1 == battle_player_y)
hit_player();
else
ennemy[i].y += 1;
}else if(ennemy[i].y > battle_player_y && is_location_empty(ennemy[i].x, ennemy[i].y-1) && GBA_collision((ennemy[i].x-GBA_scroll_x)*8, (ennemy[i].y-1-GBA_scroll_y)*8) == 0){
if(ennemy[i].x == battle_player_x && ennemy[i].y-1 == battle_player_y)
hit_player();
else
ennemy[i].y -= 1;
}
}
}
}
void update_battle_screen(void){
GBA_init_map(camera_x, camera_y, 20, 20, tiles, battle_map);
GBA_restore_map();
GBA_draw_mask_sprite((battle_player_x-GBA_scroll_x)*8, (battle_player_y-GBA_scroll_y)*8, 1, 8, battle_player_direction, GBA_CLIP_SPRITE);
draw_ennemies();
TL_gbuf_to_lcd();
}
void draw_ennemies(void){
for(i = 0; i<4; i++){
GBA_draw_mask_sprite((ennemy[i].x-GBA_scroll_x)*8, (ennemy[i].y-GBA_scroll_y)*8, 1, 8, battle_ennemy, GBA_CLIP_SPRITE);
}
}
char is_location_empty(unsigned char x, unsigned char y){ // return 1 (TRUE) if there's noone at the location, otherwise return 0 (FALSE)
// check if an ennemy is there
int flag = 1;
for(j = 0; j<4; j++){
if(ennemy[j].x == x && ennemy[j].y == y){
flag = 0;
}
}
return flag;
}
void hit_player(void){
TL_rectangle_filled((battle_player_x-GBA_scroll_x)*8, (battle_player_y-GBA_scroll_y-1)*8, 10, 10, TL_RECT_FILL_BLACK);
TL_rectangle_filled((battle_player_x-GBA_scroll_x)*8+1, (battle_player_y-GBA_scroll_y-1)*8+1, 8, 8, TL_RECT_FILL_WHITE);
TL_gbuf_to_lcd();
TL_delay(10);
}