void draw() { { double left = VIEW.ll().x + 1; double top = VIEW.ur().y - 1; for (int i = 0; i < SCORE; i++) { glColor3f(1,1,1); glBegin(GL_QUADS); glVertex2f(left, top); glVertex2f(left+0.3, top); glVertex2f(left+0.3, top-0.3); glVertex2f(left, top-0.3); glEnd(); left += 0.6; } } glColor3f(1,1,1); for (std::list<Powerup*>::iterator i = POWERUPS.begin(); i != POWERUPS.end(); ++i) { (*i)->draw(); } for (std::list<Enemy>::iterator i = ENEMIES.begin(); i != ENEMIES.end(); ++i) { switch (i->color) { case RED: glColor3f(0.7,0,0); break; case GREEN: glColor3f(0,0.7,0); break; case BLUE: glColor3f(0,0,0.7); break; } glBegin(GL_TRIANGLES); glVertex2f(i->pos.x, i->pos.y + 0.3); glVertex2f(i->pos.x - 0.21, i->pos.y - 0.15); glVertex2f(i->pos.x + 0.21, i->pos.y - 0.15); glEnd(); } glEnable(GL_BLEND); glBlendFunc(GL_ONE, GL_ONE); glColor3f(0,1,0); draw_avatar(&AV[1]); glColor3f(0,0,1); draw_avatar(&AV[2]); glColor3f(1,0,0); draw_avatar(&AV[0]); glPushMatrix(); glTranslatef(AV[0].pos.x, AV[0].pos.y, 0); glColor3f(1,1,1); glBegin(GL_LINES); glVertex2f(0,0); glVertex2f(cos(AV[0].theta), sin(AV[0].theta)); glEnd(); glPopMatrix(); glDisable(GL_BLEND); if (FLASH) { FLASH = false; glClearColor(1,1,1,1); glClear(GL_COLOR_BUFFER_BIT); glClearColor(0,0,0,1); } }
// function to test threads // This function will run concurrently. void* avatar(void* ptr) { // Initial variables int sockfd = 0; struct sockaddr_in servaddr; avatarInfo a = *((avatarInfo *) ptr); fprintf(a.pLog, "\n\nTHREAD FOR %i", a.avID); ///////////////////////// create socket //Create a socket for the client //If sockfd<0 there was an error in the creation of the socket if ((sockfd = socket (AF_INET, SOCK_STREAM, 0)) <0) { perror("Problem in creating the socket"); exit(2); } //Creation of the socket memset(&servaddr, 0, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr= inet_addr(a.ip); servaddr.sin_port = htons(a.MazePort); //convert to big-endian order //Connection of the client to the socket int connected = connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr)); if (connected <0) { perror("Problem in connecting to the server"); exit(3); } fprintf(a.pLog, "Avatar %d connected to socket: %i\n", a.avID, connected); //////////////////////////// send initial message AM_Message *ready = calloc(1, sizeof(AM_Message)); if (!ready) { perror("No memory\n"); exit(4); } ready->type = htonl(AM_AVATAR_READY); ready->avatar_ready.AvatarId = htonl(a.avID); //send ready message to server int sent = send(sockfd, ready, sizeof(AM_Message), 0); fprintf(a.pLog, "Avatar ready message sent: %i, for av %i\n", sent, a.avID); free(ready); sleep(1); ////////////////////////// initialize a move message and a rec message AM_Message *rec_message = calloc(1, sizeof(AM_Message)); if(!rec_message) { perror("\nNo memory"); exit(4); } ////////////////////////////////// listen to server while (1) { memset(rec_message, 0, sizeof(AM_Message)); //printf("\n thread %i, socket %i", a.avID, sockfd); int x = recv(sockfd, rec_message, sizeof(AM_Message), 0); if ( x== 0) { //error: server terminated prematurely //printf("\n server error"); return NULL; } ///////////////////////////////////////// if turnID matches avID, make a move if(ntohl(rec_message->type) == AM_AVATAR_TURN) { pthread_mutex_lock(&turn_lock); // if turn id is my id int move = -1; if(ntohl(rec_message->avatar_turn.TurnId) == a.avID) { // write board to the log fprintf(a.pLog, "\n\nits my turn: %i", a.avID); fprintf(a.pLog, "\nCurrent board:"); XYPos pos; //look through the positions received from the server and add them to the Avatars, if they aren't there, or use them to update the maze based on the last move for(int b = 0; b < a.nAvatars; b++) { pos.x = ntohl(rec_message->avatar_turn.Pos[b].x); pos.y = ntohl(rec_message->avatar_turn.Pos[b].y); fprintf(a.pLog, "\nPosition of avatar %i - x: %i y: %i", b,pos.x, pos.y); //printf("\nCurrent position of avatar %i - x: %i y: %i", b,pos.x, pos.y); //printf("\nAvatar %d: pos.x: %i, pos.y: %i, direction: %d, last_move: %d \n", b, Avatars[b].pos.x, Avatars[b].pos.y, Avatars[b].direction, Avatars[b].last_move); if (Avatars[b].last_move == -1) { //if the avatar doesn't have a position yet Avatars[b].pos = pos; Avatars[b].last_move = M_NULL_MOVE; } else if (Avatars[b].last_move != M_NULL_MOVE) { if ((pos.x == Avatars[b].pos.x) && (pos.y == Avatars[b].pos.y)) { fprintf(a.pLog, "Avatar %d encountered a wall and did not move.", b); AddWall(Avatars[b].pos.y, Avatars[b].pos.x, Avatars[b].last_move, 1); Avatars[b].last_move = M_NULL_MOVE; } else { fprintf(a.pLog, "Avatar %d moved successfully.", b); switch(Avatars[b].last_move) { case M_NORTH: if (maze->maze[Avatars[b].pos.y][Avatars[b].pos.x].north_wall != 2) { AddWall(Avatars[b].pos.y, Avatars[b].pos.x, Avatars[b].last_move, 0); } break; case M_SOUTH: if (maze->maze[Avatars[b].pos.y][Avatars[b].pos.x].south_wall != 2) { AddWall(Avatars[b].pos.y, Avatars[b].pos.x, Avatars[b].last_move, 0); } break; case M_EAST: if (maze->maze[Avatars[b].pos.y][Avatars[b].pos.x].east_wall != 2) { AddWall(Avatars[b].pos.y, Avatars[b].pos.x, Avatars[b].last_move, 0); } break; case M_WEST: if (maze->maze[Avatars[b].pos.y][Avatars[b].pos.x].west_wall != 2) { AddWall(Avatars[b].pos.y, Avatars[b].pos.x, Avatars[b].last_move, 0); } break; default: AddWall(Avatars[b].pos.y, Avatars[b].pos.x, Avatars[b].last_move, 0); break; } Avatars[b].pos = pos; Avatars[b].direction = Avatars[b].last_move; Avatars[b].last_move = M_NULL_MOVE; } } } ////////////////graphics//////////////// //initscr(); clear(); raw(); //start_color(); create_border(maze->num_col, maze->num_row); draw_inside(maze); //draw_fakes(maze); int f; for (f = 0; f<a.nAvatars; f++) { draw_avatar(2*Avatars[f].pos.y+1, 2*Avatars[f].pos.x+1); } //unsigned int microseconds; //microseconds = 200; //usleep(microseconds); refresh(); /* Determine the direction of the move for the current Avatar */ /* Avatar 0 has a fixed location - it never moves */ if (a.avID == 0) { if(!final_destination) { final_destination = (XYPos *) calloc(1, sizeof(XYPos)); final_destination->x = Avatars[a.avID].pos.x; final_destination->y = Avatars[a.avID].pos.y; } move = M_NULL_MOVE; } // if(!final_destination){ // for(int i = 0; i < a.nAvatars; i++){ // if (i == a.avID) continue; // //if the Avatar is in the same place as another Avatar, save position as final_destination // if((Avatars[i].pos.x == Avatars[a.avID].pos.x) && (Avatars[i].pos.y == Avatars[a.avID].pos.y)){ // final_destination = (XYPos *) calloc(1, sizeof(XYPos)); // final_destination->x = Avatars[a.avID].pos.x; // final_destination->y = Avatars[a.avID].pos.y; // move = M_NULL_MOVE; // break; // } // } // } /* Determine the direction of the move for Avatars that aren't Avatar 0 */ //if Avatar is at final_destination, it should not move if((final_destination) && (Avatars[a.avID].pos.x == final_destination->x) && (Avatars[a.avID].pos.y == final_destination ->y)) { move = M_NULL_MOVE; } else { //if the Avatar is alone, use the rightHandRule to determine the next move move = rightHandRule(Avatars[a.avID]); } //temporary fix to diagnose the initial -1 rightHandRule return if(move == -1) { ClearFakeWalls(Avatars[a.avID].pos.y, Avatars[a.avID].pos.x); move = rightHandRule(Avatars[a.avID]); move = (move == -1) ? M_NULL_MOVE : move; } Avatars[a.avID].last_move = move; //int move = rand() % 4; // write move to the log fprintf(a.pLog, "\nMove: %i", move); //printf("\nMove: %i", move); //send a move message for the current avatar AM_Message *ready = calloc(1, sizeof(AM_Message)); if (!ready) { perror("No memory\n"); exit(4); } ready->type = htonl(AM_AVATAR_MOVE); ready->avatar_move.AvatarId = htonl(a.avID); ready->avatar_move.Direction =htonl(move); //send ready message to server int sent = send(sockfd, ready, sizeof(AM_Message), 0); fprintf(a.pLog, "\nAvatar move message sent: %i, for av %i", sent, a.avID); free(ready); //sleep(1); } pthread_mutex_unlock(&turn_lock); } // else if the message is success, break else if(ntohl(rec_message->type) == AM_MAZE_SOLVED) { pthread_mutex_lock(&solved_lock); if(!thread_return) { time_t myTime; char buff[100]; thread_return = (char *) calloc(100, sizeof(char)); myTime = time(NULL); strftime(buff, 100, "%a %d %Y, %H:%M", localtime(&myTime)); //printf("%s\n", buff); sprintf(thread_return, "\nMaze Solved on %s!\n", buff); //printf("\nSolved!\n"); //free(rec_message); //free(ptr); } //stop at solution, wait for an input to end graphics //refresh(); //sleep(1); //clear(); //printw("Maze solved!"); //getch(); //clear(); //endwin(); //delwin(stdscr); if(a.avID == 0) { //stop at solution, wait for an input to end graphics refresh(); sleep(1); clear(); printw("Maze solved!"); getch(); clear(); //endwin(); } pthread_mutex_unlock(&solved_lock); break; } else if(ntohl(rec_message->type) == AM_TOO_MANY_MOVES) { pthread_mutex_lock(&too_many_moves_lock); printf("\nToo many moves! You lose.\n"); //fprintf(a.pLog,"\nToo many moves! You lose.\n"); thread_return = "\nToo many moves! You lose.\n"; //free(rec_message); //free(ptr); pthread_mutex_unlock(&too_many_moves_lock); break; } else if(IS_AM_ERROR(ntohl(rec_message->type))) { pthread_mutex_lock(&error_lock); thread_return = (char *) calloc(100, sizeof(char)); printf("\nReceived Error code\n"); sprintf(thread_return, "\nReceived Error code: %u\n", ntohl(rec_message->type)); //free(rec_message); //free(ptr); pthread_mutex_unlock(&error_lock); break; } } //CleanupMaze(); free(rec_message); free(ptr); pthread_exit(thread_return); }
/* * Application entry point */ int main(int argc, char *argv[]) { ALLEGRO_DISPLAY *display = NULL; ALLEGRO_EVENT_QUEUE *event_queue = NULL; ALLEGRO_TIMER *timer = NULL; ALLEGRO_KEYBOARD_STATE keyboard_state; ALLEGRO_MAP *map; Avatar *tar; bool running = true; bool redraw = true; int map_x = 0, map_y = 0; int screen_width = 640; int screen_height = 480; //{{{ initialization // Initialize allegro if (!al_init()) { fprintf(stderr, "Failed to initialize allegro.\n"); return 1; } // Initialize allegro_image addon if (!al_init_image_addon()) { fprintf(stderr, "Failed to initialize image addon.\n"); return 1; } // Initialize the timer timer = al_create_timer(1.0 / FPS); if (!timer) { fprintf(stderr, "Failed to create timer.\n"); return 1; } // Install the keyboard if (!al_install_keyboard()) { fprintf(stderr, "Failed to install keyboard.\n"); return 1; } // Create the display display = al_create_display(screen_width, screen_height); if (!display) { fprintf(stderr, "Failed to create display.\n"); return 1; } else { al_set_window_title(display, "Hello Tiled!"); } // Create the event queue event_queue = al_create_event_queue(); if (!event_queue) { fprintf(stderr, "Failed to create event queue.\n"); return 1; } // Register event sources al_register_event_source(event_queue, al_get_display_event_source(display)); al_register_event_source(event_queue, al_get_timer_event_source(timer)); al_register_event_source(event_queue, al_get_keyboard_event_source()); //}}} // Start the timer al_start_timer(timer); // Parse the map map = al_open_map(MAP_FOLDER, "level1.tmx"); // Create avatar tar = create_avatar(0, 0, "data/avatar.png"); // Draw the map al_clear_to_color(al_map_rgb(0, 0, 0)); al_draw_map_region(map, map_x, map_y, screen_width, screen_height, 0, 0, 0); al_flip_display(); #if DEBUG // FPS counter double old_time = al_get_time(), fps = 0; int frames_done = 0; #endif // Main loop while (running) { ALLEGRO_EVENT event; ALLEGRO_TIMEOUT timeout; // Initialize the timeout (not the game's clock) al_init_timeout(&timeout, 0.06); // Fetch the event (if one exists) bool get_event = al_wait_for_event_until(event_queue, &event, &timeout); // Handle the event if (get_event) { switch (event.type) { case ALLEGRO_EVENT_TIMER: // is an arrow key being held? al_get_keyboard_state(&keyboard_state); int x_move = 0; int y_move = 0; if (al_key_down(&keyboard_state, ALLEGRO_KEY_RIGHT)) { x_move += 2; } if (al_key_down(&keyboard_state, ALLEGRO_KEY_LEFT)) { x_move -= 2; } if (al_key_down(&keyboard_state, ALLEGRO_KEY_UP)) { y_move -= 2; } if (al_key_down(&keyboard_state, ALLEGRO_KEY_DOWN)) { y_move += 2; } walk(tar, x_move, y_move); //gravity(tar, center_viewport(tar, screen_width, screen_height, map, &map_x, &map_y); redraw = true; break; case ALLEGRO_EVENT_DISPLAY_CLOSE: running = false; break; case ALLEGRO_EVENT_KEY_DOWN: // ignore break; case ALLEGRO_EVENT_KEY_UP: // ignore break; case ALLEGRO_EVENT_KEY_CHAR: if (event.keyboard.keycode == ALLEGRO_KEY_SPACE) { ALLEGRO_MAP_LAYER *collide_layer = al_get_map_layer(map, "Blocks 1"); ALLEGRO_MAP_TILE **tiles = get_occupied_tile_ids(tar, collide_layer, map); fprintf(stdout, "Avatar on tiles: {%s, %s, %s, %s}\n", al_get_tile_property(tiles[0], "collide", "null"), al_get_tile_property(tiles[1], "collide", "null"), al_get_tile_property(tiles[2], "collide", "null"), al_get_tile_property(tiles[3], "collide", "null")); free(tiles); tiles = NULL; } break; default: fprintf(stderr, "Unsupported event received: %d\n", event.type); break; } } if (redraw && al_is_event_queue_empty(event_queue)) { // Clear the screen al_clear_to_color(al_map_rgb(0, 0, 0)); #if DEBUG double game_time = al_get_time(); if(game_time - old_time >= 1.0) { fps = frames_done / (game_time - old_time); frames_done = 0; old_time = game_time; fprintf(stderr, "FPS:%f\n", fps); } frames_done++; #endif al_draw_map_region(map, map_x, map_y, screen_width, screen_height, 0, 0, 0); draw_avatar(tar, map, map_x, map_y); al_flip_display(); redraw = false; } } // Clean up and return free_avatar(tar); al_free_map(map); al_destroy_display(display); al_destroy_event_queue(event_queue); return 0; }