Browse Source

GUI : Animation de rotation des pions ajoutée.

GUI : Modularité de l'affichage persistant.
master
Nikos 8 years ago
parent
commit
a58861ab19
5 changed files with 111 additions and 82 deletions
  1. +2
    -2
      Makefile
  2. +82
    -55
      gui.c
  3. +4
    -3
      gui.h
  4. +21
    -20
      guidemo.c
  5. +2
    -2
      main.c

+ 2
- 2
Makefile View File

@ -13,7 +13,7 @@ api.h : dameschinoises.h dameschinoises.patch
patch -o api.h dameschinoises.h dameschinoises.patch
main : main.o gui
gcc -Wall -pedantic $(LDFLAGS) -lSDL -lSDL_image -o main main.o gui.o
gcc -Wall -pedantic $(LDFLAGS) -lSDL -lSDL_image -lm -o main main.o gui.o
main.o : main.c api.h
gcc $(CFLAGS) -c -Wall main.c
@ -28,7 +28,7 @@ gui : gui.c api.h
gcc $(CFLAGS) -c -Wall gui.c
guidemo : guidemo.c gui
gcc -Wall $(CFLAGS) $(LDFLAGS) -lSDL -lSDL_image -o guidemo guidemo.c gui.o
gcc -Wall $(CFLAGS) $(LDFLAGS) -lSDL -lSDL_image -lm -o guidemo guidemo.c gui.o
clean :
rm -vf *.o


+ 82
- 55
gui.c View File

@ -1,7 +1,8 @@
#include <stdio.h>
#include <SDL/SDL.h>
#include <SDL/SDL_image.h>
#include <unistd.h> /* exit */
#include <stdio.h>
#include <math.h> /* sin, cos */
#include "api.h"
#include "gui.h"
@ -30,70 +31,64 @@ struct gui_resource_t display_start() {
return res;
}
SDL_Rect coord_rotate(SDL_Rect coord, enum hole_t currentplayer) {
SDL_Rect res;
#define CENTER_X ((short)400)
#define CENTER_Y ((short)300)
coord.x -= CENTER_X;
coord.y -= CENTER_Y;
switch(currentplayer) {
case 1:
res.x = coord.x/2 + (coord.y*13)/15; // sin60°~13/15, cos60°=1/2
res.y = -(coord.x*13)/15 + coord.y/2;
break;
case 2:
res.x = -coord.x/2 + (coord.y*13)/15;
res.y = -(coord.x*13)/15 - coord.y/2;
break;
case 3:
res.x = -coord.x;
res.y = -coord.y;
break;
case 4:
res.x = -coord.x/2 - (coord.y*13)/15;
res.y = (coord.x*13)/15 - coord.y/2;
break;
case 5:
res.x = coord.x/2 - (coord.y*13)/15;
res.y = (coord.x*13)/15 + coord.y/2;
break;
default:
res.x = coord.x;
res.y = coord.y;
break;
SDL_Event display_until_event(struct gui_resource_t res) {
#define FIXEDFRAMETIME 125 /* 125ms → 8fps */
SDL_Event event;
uint32_t time1, time2; /* mesure du temps de rendu de frame */
for(;;) {
time1 = SDL_GetTicks();
if(SDL_PollEvent(&event))
break;
SDL_Flip(res.screen);
/* attente du temps restant dans la frame */
time2 = SDL_GetTicks();
if(time2-time1 > FIXEDFRAMETIME)
fprintf(stderr,"(rant) fixed image: the machine is slow, frame took %dms\n", time2-time1);
else
SDL_Delay(FIXEDFRAMETIME - (time2-time1));
}
res.x += CENTER_X;
res.y += CENTER_Y;
return event;
}
SDL_Rect coord_rotate(SDL_Rect coord, double sin, double cos) {
SDL_Rect res;
res.x = (short)round( cos * ((double)coord.x) + sin * ((double)coord.y) );
res.y = (short)round( ((double)cos) * ((double)coord.y) - sin * ((double)coord.x) );
return res;
}
void display_render_board(struct gui_resource_t res, struct game_state_t gamestate /*, enum hole_t currentplayer*/) {
int i;
void draw_all(struct gui_resource_t res, struct game_state_t gamestate, double angle) {
/* pour ne les calculer qu'une fois */
double sinA = sin(angle), cosA = cos(angle);
/* positions pour les images */
SDL_Rect zero_pos = {0, 0}, pawn_pos, pawn_pos_postrot;
SDL_Rect zero_pos = {0, 0}, pawn_pos, pawn_pos_rot;
/* dessin du fond */
SDL_BlitSurface(res.bgnd_img, NULL, res.screen, &zero_pos);
SDL_BlitSurface(res.title_img, NULL, res.screen, &zero_pos);
SDL_BlitSurface(res.board_img, NULL, res.screen, &zero_pos);
/* #include <SDL/SDL_rotozoom.h>
/* #include <SDL/SDL_rotozoom.h> TODO rotation image plateau
SDL_Surface *rotated_board_img = rotozoomSurface(res.board_img, (360.0/6.0)*currentplayer, 0.0, 1); */
/* dessin du plateau */
SDL_BlitSurface(res.board_img, NULL, res.screen, &zero_pos);
/* dessin des pions */
int index_lines[] = {1, 3, 6, 10, 23, 35, 46, 56, 65, 75, 86, 98, 111, 115, 118, 120};
int index_line_offsets[] = {0, 0, 2, 2, 8, 11, 11, 9, 9, 8, 10, 10, 12, 7, 3, 1, 1};
int line = 0;
#define PAWNSIZE ((short)28)
#define FUZZSPACING ((short)18)
#define HORIZSPACING ((short)9)
#define VERTSPACING ((short)4)
pawn_pos.x = 400 - PAWNSIZE/2 - (PAWNSIZE+HORIZSPACING);
pawn_pos.y = (PAWNSIZE/2+16);
#define CENTER_X 400
#define CENTER_Y 300
#define PAWNSIZE 28
#define FUZZSPACING 19
#define HORIZSPACING 10
#define VERTSPACING 5
pawn_pos.x = CENTER_X - PAWNSIZE/2 - (PAWNSIZE+HORIZSPACING);
pawn_pos.y = (PAWNSIZE/2+8);
int i;
for(i = 0; i < 121; i++) {
if(i == index_lines[line]) {
line++;
@ -103,15 +98,47 @@ void display_render_board(struct gui_resource_t res, struct game_state_t gamesta
pawn_pos.x += PAWNSIZE+HORIZSPACING;
}
/* matrix rotation on pawn_pos using param currentplayer (1/6ths of a circle) */
pawn_pos.x += PAWNSIZE/2;
pawn_pos.y += PAWNSIZE/2;
pawn_pos_postrot = coord_rotate(pawn_pos, 0);
pawn_pos.x -= PAWNSIZE/2;
pawn_pos.y -= PAWNSIZE/2;
pawn_pos_postrot.x -= PAWNSIZE/2;
pawn_pos_postrot.y -= PAWNSIZE/2;
SDL_BlitSurface(res.pawn_img[gamestate.board[i]], NULL, res.screen, &pawn_pos_postrot);
pawn_pos_rot.x = pawn_pos.x + PAWNSIZE/2 - CENTER_X;
pawn_pos_rot.y = pawn_pos.y + PAWNSIZE/2 - CENTER_Y;
pawn_pos_rot = coord_rotate(pawn_pos_rot, sinA, cosA);
pawn_pos_rot.x -= PAWNSIZE/2 - CENTER_X;
pawn_pos_rot.y -= PAWNSIZE/2 - CENTER_Y;
SDL_BlitSurface(res.pawn_img[gamestate.board[i]], NULL, res.screen, &pawn_pos_rot);
}
}
void display_render_board(struct gui_resource_t res, struct game_state_t gamestate, enum hole_t currentplayer) {
draw_all(res, gamestate, ((((double)currentplayer)-1)*M_PI)/3);
}
int display_anirotate_board(struct gui_resource_t res, struct game_state_t gamestate, enum hole_t currentplayer, enum hole_t nextplayer) {
#define ANIFRAMETIME 40 /* 40ms → 25fps */
#define ANIMTIME 2000 /* 2000ms → 2s */
uint32_t time1, time2; /* mesure du temps de rendu de frame */
SDL_Event event;
int frame;
for(frame = 0; frame <= ANIMTIME/ANIFRAMETIME; frame++) {
time1 = SDL_GetTicks();
while(SDL_PollEvent(&event))
if(event.type == SDL_QUIT)
return 1;
/* progrès non-linéaire (cosinus) */
double anim_progress = ( ((double)nextplayer) - ((double)currentplayer) ) * ( cos(M_PI*((double)frame)/((double)(ANIMTIME/ANIFRAMETIME))+M_PI) + 1 ) / 2;
double angle = ( anim_progress + (((double)currentplayer)-1) ) * M_PI / 3;
draw_all(res, gamestate, angle);
SDL_Flip(res.screen);
/* attente du temps restant dans la frame : stabilisation de la vitesse d'exécution */
time2 = SDL_GetTicks();
if(time2-time1 > ANIFRAMETIME)
fprintf(stderr,"(rant) animation: the machine is slow, frame took %dms\n", time2-time1);
else
SDL_Delay(ANIFRAMETIME - (time2-time1));
}
return 0;
}
void display_close(struct gui_resource_t res) {


+ 4
- 3
gui.h View File

@ -3,10 +3,11 @@ struct gui_resource_t {
};
struct gui_resource_t display_start();
SDL_Event display_until_event(struct gui_resource_t res);
void display_render_board(struct gui_resource_t res, struct game_state_t gamestate, enum hole_t currentplayer);
int display_anirotate_board(struct gui_resource_t res, struct game_state_t gamestate, enum hole_t currentplayer, enum hole_t nextplayer);
void display_render_board(struct gui_resource_t res, struct game_state_t gamestate/*, enum hole_t currentplayer*/);
/*void display_move_pawn(struct gui_resource_t res, struct game_state_t board, int startpos, int endpos); */
/*void display_animove_pawn(struct gui_resource_t res, struct game_state_t board, int startpos, int endpos); */
/*
SDL_Rect pos_board = {0,0}; ou plus, à voir
(blit la board en utilisant du code commun à display_board() sans le pion de startpos) buffer


+ 21
- 20
guidemo.c View File

@ -1,5 +1,7 @@
#include <stdio.h>
#include <SDL/SDL.h>
#include <stdlib.h>
#include <time.h>
#include "api.h"
#include "gui.h"
@ -10,30 +12,29 @@ int main(int argc, char* argv[]) {
gui_res = display_start(gui_res);
display_render_board(gui_res, gamestate);
display_render_board(gui_res, gamestate, 1);
/* Gestion de l'interactivité */
int quit = 0; /* condition de sortie */
uint32_t framedelay = 200; /* 8fps→125ms ; temps de rafraîchissement */
uint32_t time1, time2; /* mesure du temps de rendu de frame */
/* un peu d'interactivité */
SDL_Event event;
while( ! quit ) {
time2 = SDL_GetTicks();
while(SDL_PollEvent(&event))
if(event.type == SDL_QUIT)
quit = 1;
SDL_Flip(gui_res.screen);
/* attente du temps restant dans la frame : stabilisation de la vitesse d'exécution */
time1 = SDL_GetTicks();
if(time1-time2 > framedelay)
fprintf(stderr,"(rant) the machine is slow, frame took %dms\n", time1-time2);
else
SDL_Delay(framedelay - (time1-time2));
for(;;) {
event = display_until_event(gui_res);
if(event.type == SDL_QUIT)
goto end;
if(event.type == SDL_MOUSEBUTTONDOWN)
break;
}
display_close(gui_res);
srand(time(NULL));
enum hole_t player1 = 1, player2;
for(;;) {
while(player2 == player1)
player2 = rand()%6;
if( display_anirotate_board(gui_res, gamestate, player1, player2) )
goto end;
player1 = player2;
}
end: display_close(gui_res);
return 0;
}

+ 2
- 2
main.c View File

@ -341,7 +341,7 @@ int main(int argc, char** argv) {
}
/* rafraîchissement du plateau à l'écran */
display_render_board(gui_res, game_state);
display_render_board(gui_res, game_state, 1/*joueur 1 en face*/);
SDL_Flip(gui_res.screen);
#ifdef debug
@ -388,7 +388,7 @@ int main(int argc, char** argv) {
}
}
/* le joueur a déplacé un pion, rafraîchissement du plateau à l'écran */
display_render_board(gui_res, game_state);
display_render_board(gui_res, game_state, i+1/*joueur, ∈[1-6]*/);
SDL_Flip(gui_res.screen);
} else {
#ifdef debug


Loading…
Cancel
Save