Skip to content

Instantly share code, notes, and snippets.

@zrbecker
Created March 28, 2011 21:33
Show Gist options
  • Save zrbecker/891330 to your computer and use it in GitHub Desktop.
Save zrbecker/891330 to your computer and use it in GitHub Desktop.
#include <allegro5/allegro.h>
#include <allegro5/allegro_primitives.h>
#include <math.h>
typedef struct vertex_s {
float x;
float y;
} vertex;
typedef struct edge_s {
int v1;
int v2;
ALLEGRO_COLOR color;
} edge;
typedef struct vector_s {
float x;
float y;
} vector;
#define NUM_VERTICIES 10
#define NUM_EDGES 15
vertex verticies[NUM_VERTICIES] = {{100, 200}, {400, 100}, {700, 200},
{600, 500}, {200, 500}, {240, 280}, {400, 200}, {560, 280},
{500, 400}, {300, 400}};
#define BLUE {0, 0, 255, 255}
#define RED {255, 0, 0, 255}
#define GREEN {0, 255, 0, 255}
edge edges[NUM_EDGES] = {
{0, 1, BLUE},
{1, 2, BLUE},
{2, 3, BLUE},
{3, 4, BLUE},
{4, 0, BLUE},
{9, 6, RED},
{6, 8, RED},
{8, 5, RED},
{5, 7, RED},
{7, 9, RED},
{0, 5, GREEN},
{1, 6, GREEN},
{2, 7, GREEN},
{3, 8, GREEN},
{4, 9, GREEN}
};
bool animating = false;
int frame = 0;
vector animation_vectors[NUM_VERTICIES];
vector animation_goal[NUM_VERTICIES];
int vertex_held = -1;
int VertexAt(int x, int y);
void AnimateVerticies();
void Permute();
void Update();
void Draw();
int main(int argc, char **argv)
{
ALLEGRO_DISPLAY* display = NULL;
ALLEGRO_EVENT_QUEUE* queue = NULL;
ALLEGRO_TIMER* timer = NULL;
if (!al_init() || !al_init_primitives_addon()) {
fprintf(stderr, "Could not initialize allegro.\n");
exit(-1);
}
display = al_create_display(800, 600);
if (!display) {
fprintf(stderr, "Could not create display.\n");
exit(-1);
}
Draw();
queue = al_create_event_queue();
if (!queue) {
al_destroy_display(display);
fprintf(stderr, "Could not create event queue.\n");
exit(-1);
}
timer = al_create_timer(1.0 / 60.0);
if (!timer) {
al_destroy_display(display);
al_destroy_event_queue(queue);
fprintf(stderr, "Could not create timer.\n");
exit(-1);
}
al_install_keyboard();
al_install_mouse();
al_register_event_source(queue, al_get_display_event_source(display));
al_register_event_source(queue, al_get_timer_event_source(timer));
al_register_event_source(queue, al_get_mouse_event_source());
al_register_event_source(queue, al_get_keyboard_event_source());
bool playing = true;
ALLEGRO_EVENT event;
al_start_timer(timer);
while(playing) {
al_wait_for_event(queue, &event);
switch(event.type) {
case ALLEGRO_EVENT_DISPLAY_CLOSE:
playing = false;
break;
case ALLEGRO_EVENT_TIMER:
if (animating)
AnimateVerticies();
Update();
Draw();
break;
case ALLEGRO_EVENT_MOUSE_BUTTON_DOWN:
if(!animating) {
vertex_held = VertexAt(event.mouse.x, event.mouse.y);
}
break;
case ALLEGRO_EVENT_MOUSE_BUTTON_UP:
if (vertex_held >= 0) {
vertex_held = -1;
}
break;
case ALLEGRO_EVENT_KEY_DOWN:
if (event.keyboard.keycode == ALLEGRO_KEY_SPACE)
if (!animating && vertex_held == -1)
Permute();
break;
default:
break;
}
}
return 0;
}
int VertexAt(int x, int y)
{
int i;
for (i = 0; i < NUM_VERTICIES; ++i) {
if (12 >= sqrt(pow(verticies[i].x - x, 2) + pow(verticies[i].y - y, 2))) {
return i;
}
}
return -1;
}
void AnimateVerticies()
{
++frame;
if (frame >= 120) {
animating = false;
int i;
for (i = 0; i < NUM_VERTICIES; ++i) {
verticies[i].x = animation_goal[i].x;
verticies[i].y = animation_goal[i].y;
}
} else {
int i;
for (i = 0; i < NUM_VERTICIES; ++i) {
verticies[i].x += animation_vectors[i].x;
verticies[i].y += animation_vectors[i].y;
}
}
}
void Permute()
{
int perm[NUM_VERTICIES] = {9, 6, 8, 5, 7, 4, 1, 3, 0, 2}; // inside out
int i;
for (i = 0; i < NUM_VERTICIES; ++i) {
animation_goal[perm[i]].x = verticies[i].x;
animation_goal[perm[i]].y = verticies[i].y;
animation_vectors[perm[i]].x = (verticies[i].x - verticies[perm[i]].x) / 120.0;
animation_vectors[perm[i]].y = (verticies[i].y - verticies[perm[i]].y) / 120.0;
}
animating = true;
frame = 0;
}
void Update()
{
if (vertex_held != -1) {
ALLEGRO_MOUSE_STATE state;
al_get_mouse_state(&state);
verticies[vertex_held].x = state.x;
verticies[vertex_held].y = state.y;
}
}
void Draw()
{
al_clear_to_color(al_map_rgb(255, 255, 255));
int i;
for (i = 0; i < NUM_EDGES; ++i) {
edge e = edges[i];
vertex v1 = verticies[e.v1];
vertex v2 = verticies[e.v2];
al_draw_line(v1.x, v1.y, v2.x, v2.y, al_map_rgb(0, 0, 0), 16);
al_draw_line(v1.x, v1.y, v2.x, v2.y, e.color, 10);
}
for (i = 0; i < NUM_VERTICIES; ++i) {
al_draw_filled_circle(verticies[i].x, verticies[i].y,
12, al_map_rgb(0, 0, 0));
al_draw_filled_circle(verticies[i].x, verticies[i].y,
9, al_map_rgb(255, 255, 0));
}
al_flip_display();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment