void entity_update(entity* e) { if (e->_flags & EF_DESTROYED) return; int clipped = 0; if (!(e->_flags & EF_NO_PHYSICS)) { e->_old_pos = e->_pos; clipped = move_entity(e, e->_pos + e->_vel * (1.0f / 60.0f)); //e->_pos = e->_pos + e->_vel * (1.0f / 60.0f); } e->tick(clipped); }
void gameLoop() { // Set our game data shipRow = 55; shipCol = 0; enemyCol = 225; enemy_num = 0; projectile_num = 0; time_diff = 0; kills = 0; REG_DISPCNT = MODE3 | BG2_ENABLE; EntityClass player_ship; initialize_entity( &player_ship, SHIP_WIDTH, SHIP_HEIGHT, shipRow, shipCol ); EntityClass enemy; initialize_entity( &enemy, 0, 0, 0, 0 ); enemies[max_enemies+1] = enemy; while (lives != 0) { // Check if player won the level. if( kills == 10 ) { state = WIN; break; } // Draw background drawImage3( 0, 0, BACKGROUND_WIDTH, BACKGROUND_HEIGHT, background ); // Draw ship draw_entity( &player_ship, ship ); // Generate enemy if( time_diff <= 0 && enemy_num < 10 ) { time_diff = 75; int rand_row = ( rand() % (120+1-20) ) + 20; generate_enemy( rand_row, enemyCol ); } // Draw Enemy update_enemies(); // Draw each projectile update_projectiles(); // Check if player is dead. if( is_player_dead( &player_ship ) == 1 ) { lives--; gameLoop(); } check_collisions(); remove_old_projectiles(); remove_old_enemies(); // Draw lives for( int i = 0; i < lives; i++ ) { drawImage3( 140, 170 + ( i * 25 ), SHIP_WIDTH, SHIP_HEIGHT, ship ); } waitForVblank(); // If player hits 'select' return to titleScreen and start game over. if( KEY_DOWN_NOW( BUTTON_SELECT ) ) { state = TITLE; break; } // Player Actions if( KEY_DOWN_NOW( BUTTON_DOWN ) ) { if( get_row( &player_ship ) < 121 ) move_entity( &player_ship, 2, 0 ); } if( KEY_DOWN_NOW( BUTTON_UP ) ) { if( get_row( &player_ship ) > 20 ) move_entity( &player_ship, -2, 0 ); } if( KEY_DOWN_NOW( BUTTON_A ) ) { while( KEY_DOWN_NOW( BUTTON_A ) ) { ; } fire_weapon( &player_ship ); } time_diff--; } if( lives == 0 ) { state = GAME_OVER; } else if( state == WIN ) return; }
void templateAppDraw( void ) { glClearColor( 0.5f, 0.5f, 0.5f, 1.0f ); glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT ); GFX_set_matrix_mode( MODELVIEW_MATRIX ); GFX_load_identity(); if( view_delta.x || view_delta.y ) { if( view_delta.y ) next_rotz -= view_delta.y; if( view_delta.x ) { next_rotx -= view_delta.x; next_rotx = CLAMP( next_rotx, 0.0f, 90.0f ); } view_delta.x = view_delta.y = 0.0f; } rotx = rotx * 0.9f + next_rotx * 0.1f; rotz = rotz * 0.9f + next_rotz * 0.1f; eye.x = center.x + distance * cosf( rotx * DEG_TO_RAD ) * sinf( rotz * DEG_TO_RAD ); eye.y = center.y - distance * cosf( rotx * DEG_TO_RAD ) * cosf( rotz * DEG_TO_RAD ); eye.z = center.z + distance * sinf( rotx * DEG_TO_RAD ); rotx = rotx * 0.9f + next_rotx * 0.1f; rotz = rotz * 0.9f + next_rotz * 0.1f; center.x = maze->location.x; center.y = maze->location.y; center.z = maze->location.z; GFX_look_at( &eye, ¢er, &up ); if( double_tap ) { vec3 location; if( GFX_unproject( view_location.x, viewport_matrix[ 3 ] - view_location.y, 1.0f, GFX_get_modelview_matrix(), GFX_get_projection_matrix(), viewport_matrix, &location.x, &location.y, &location.z ) ) { btVector3 ray_from( eye.x, eye.y, eye.z ), ray_to( location.x + eye.x, location.y + eye.y, location.z + eye.z ); btCollisionWorld::ClosestRayResultCallback collision_ray( ray_from, ray_to ); dynamicsworld->rayTest( ray_from, ray_to, collision_ray ); if( collision_ray.hasHit() && collision_ray.m_collisionObject == maze->btrigidbody ) { collision_ray.m_hitNormalWorld.normalize(); if( collision_ray.m_hitNormalWorld.z() == 1.0f ) { navigationpath_player.start_location.x = player->location.x; navigationpath_player.start_location.y = player->location.y; navigationpath_player.start_location.z = player->location.z; navigationpath_player.end_location.x = collision_ray.m_hitPointWorld.x(); navigationpath_player.end_location.y = collision_ray.m_hitPointWorld.y(); navigationpath_player.end_location.z = collision_ray.m_hitPointWorld.z(); if( NAVIGATION_get_path( navigation, &navigationpath_player, &navigationpathdata_player ) ) { player_next_point = 1; unsigned int i = 0; while( i != navigationpathdata_player.path_point_count + 1 ) { console_print( "%d: %f %f %f\n", i, navigationpathdata_player.path_point_array[ i ].x, navigationpathdata_player.path_point_array[ i ].y, navigationpathdata_player.path_point_array[ i ].z ); ++i; } printf( "\n" ); } } } } double_tap = 0; } if( navigationpathdata_player.path_point_count ) { move_entity( player, &navigationpathdata_player, &player_next_point, 3.0f ); } PROGRAM_draw( program ); glUniform1i( PROGRAM_get_uniform_location( program, ( char * )"DIFFUSE" ), 1 ); unsigned int i = 0; while( i != obj->n_objmesh ) { OBJMESH *objmesh = &obj->objmesh[ i ]; GFX_push_matrix(); mat4 mat; objmesh->btrigidbody->getWorldTransform().getOpenGLMatrix( ( float * )&mat ); memcpy( &objmesh->location, ( vec3 * )&mat.m[ 3 ], sizeof( vec3 ) ); GFX_multiply_matrix( &mat ); glUniformMatrix4fv( PROGRAM_get_uniform_location( program, ( char * )"MODELVIEWPROJECTIONMATRIX" ), 1, GL_FALSE, ( float * )GFX_get_modelview_projection_matrix() ); OBJ_draw_mesh( obj, i ); GFX_pop_matrix(); ++i; } NAVIGATION_draw( navigation ); dynamicsworld->stepSimulation( 1.0f / 60.0f ); }
void templateAppDraw( void ) { glClearColor( 0.5f, 0.5f, 0.5f, 1.0f ); glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT ); GFX_set_matrix_mode( PROJECTION_MATRIX ); GFX_load_identity(); GFX_set_perspective( 80.0f, ( float )viewport_matrix[ 2 ] / ( float )viewport_matrix[ 3 ], 1.0f, 1000.0f, -90.0f ); if( game_over == 2 ) { templateAppExit(); load_game(); game_over = 0; } GFX_set_matrix_mode( MODELVIEW_MATRIX ); GFX_load_identity(); if( view_delta.x || view_delta.y ) { if( view_delta.y ) next_rotz -= view_delta.y; if( view_delta.x ) { next_rotx -= view_delta.x; next_rotx = CLAMP( next_rotx, 0.0f, 90.0f ); } view_delta.x = view_delta.y = 0.0f; } rotx = rotx * 0.9f + next_rotx * 0.1f; rotz = rotz * 0.9f + next_rotz * 0.1f; eye.x = center.x + distance * cosf( rotx * DEG_TO_RAD ) * sinf( rotz * DEG_TO_RAD ); eye.y = center.y - distance * cosf( rotx * DEG_TO_RAD ) * cosf( rotz * DEG_TO_RAD ); eye.z = center.z + distance * sinf( rotx * DEG_TO_RAD ); rotx = rotx * 0.9f + next_rotx * 0.1f; rotz = rotz * 0.9f + next_rotz * 0.1f; center.x = maze->location.x; center.y = maze->location.y; center.z = maze->location.z; GFX_look_at( &eye, ¢er, &up ); if( double_tap ) { vec3 location; if( GFX_unproject( view_location.x, viewport_matrix[ 3 ] - view_location.y, 1.0f, GFX_get_modelview_matrix(), GFX_get_projection_matrix(), viewport_matrix, &location.x, &location.y, &location.z ) ) { btVector3 ray_from( eye.x, eye.y, eye.z ), ray_to( location.x + eye.x, location.y + eye.y, location.z + eye.z ); btCollisionWorld::ClosestRayResultCallback collision_ray( ray_from, ray_to ); dynamicsworld->rayTest( ray_from, ray_to, collision_ray ); if( collision_ray.hasHit() && collision_ray.m_collisionObject == maze->btrigidbody ) { collision_ray.m_hitNormalWorld.normalize(); if( collision_ray.m_hitNormalWorld.z() == 1.0f ) { navigationpath_player.start_location.x = player->location.x; navigationpath_player.start_location.y = player->location.y; navigationpath_player.start_location.z = player->location.z; navigationpath_player.end_location.x = collision_ray.m_hitPointWorld.x(); navigationpath_player.end_location.y = collision_ray.m_hitPointWorld.y(); navigationpath_player.end_location.z = collision_ray.m_hitPointWorld.z(); if( NAVIGATION_get_path( navigation, &navigationpath_player, &navigationpathdata_player ) ) { player_next_point = 1; unsigned int i = 0; while( i != navigationpathdata_player.path_point_count + 1 ) { console_print( "%d: %f %f %f\n", i, navigationpathdata_player.path_point_array[ i ].x, navigationpathdata_player.path_point_array[ i ].y, navigationpathdata_player.path_point_array[ i ].z ); ++i; } printf( "\n" ); } } } } double_tap = 0; } if( navigationpathdata_player.path_point_count ) { vec3 color = { 0.0f, 0.0f, 1.0f }; draw_navigation_points( &navigationpathdata_player, &color ); move_entity( player, &navigationpathdata_player, &player_next_point, 3.0f ); } static unsigned int start_time = get_milli_time(); if( get_milli_time() - start_time > 1000 ) { navigationpath_enemy.start_location.x = enemy->location.x; navigationpath_enemy.start_location.y = enemy->location.y; navigationpath_enemy.start_location.z = enemy->location.z; navigationpath_enemy.end_location.x = player->location.x; navigationpath_enemy.end_location.y = player->location.y; navigationpath_enemy.end_location.z = player->location.z; NAVIGATION_get_path( navigation, &navigationpath_enemy, &navigationpathdata_enemy ); enemy_next_point = 1; start_time = get_milli_time(); } if( navigationpathdata_enemy.path_point_count ) { vec3 color = { 1.0f, 0.0f, 0.0f }; move_entity( enemy, &navigationpathdata_enemy, &enemy_next_point, 4.0f ); draw_navigation_points( &navigationpathdata_enemy, &color ); } PROGRAM_draw( program ); glUniform1i( PROGRAM_get_uniform_location( program, ( char * )"DIFFUSE" ), 1 ); unsigned int i = 0; while( i != obj->n_objmesh ) { OBJMESH *objmesh = &obj->objmesh[ i ]; GFX_push_matrix(); mat4 mat; objmesh->btrigidbody->getWorldTransform().getOpenGLMatrix( ( float * )&mat ); memcpy( &objmesh->location, ( vec3 * )&mat.m[ 3 ], sizeof( vec3 ) ); GFX_multiply_matrix( &mat ); glUniformMatrix4fv( PROGRAM_get_uniform_location( program, ( char * )"MODELVIEWPROJECTIONMATRIX" ), 1, GL_FALSE, ( float * )GFX_get_modelview_projection_matrix() ); OBJ_draw_mesh( obj, i ); GFX_pop_matrix(); ++i; } if( !game_over ) dynamicsworld->stepSimulation( 1.0f / 60.0f ); else { GFX_set_matrix_mode( PROJECTION_MATRIX ); GFX_load_identity(); float half_width = ( float )viewport_matrix[ 2 ] * 0.5f, half_height = ( float )viewport_matrix[ 3 ] * 0.5f; GFX_set_orthographic_2d( -half_width, half_width, -half_height, half_height ); GFX_rotate( -90.0f, 0.0f, 0.0f, 1.0f ); GFX_translate( -half_height, -half_width, 0.0f ); GFX_set_matrix_mode( MODELVIEW_MATRIX ); GFX_load_identity(); vec4 color = { 0.0f, 0.0f, 0.0f, 1.0f }; char msg[ MAX_CHAR ] = {"GAME OVER!"}; if( !font ) { font = FONT_init( ( char * )"foo.ttf" ); FONT_load( font, font->name, 1, 64.0f, 512, 512, 32, 96 ); } float posx = ( viewport_matrix[ 3 ] * 0.5f ) - ( FONT_length( font, msg ) * 0.5f ), posy = viewport_matrix[ 2 ] - font->font_size; FONT_print( font, posx + 4.0f, posy - 4.0f, msg, &color ); color.y = 1.0f; FONT_print( font, posx, posy, msg, &color ); } }
void templateAppDraw(void) { glClearColor(0.5f, 0.5f, 0.5f, 1.0f); glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); gfx->set_matrix_mode(MODELVIEW_MATRIX); gfx->load_identity(); if (view_delta->x || view_delta->y) { if (view_delta->y) next_rotz -= view_delta->y; if (view_delta->x) { next_rotx -= view_delta->x; next_rotx = CLAMP(next_rotx, 0.0f, 90.0f); } view_delta->x = view_delta->y = 0.0f; } rotx = rotx * 0.9f + next_rotx * 0.1f; rotz = rotz * 0.9f + next_rotz * 0.1f; eye->x = center->x + distance * cosf(rotx * DEG_TO_RAD) * sinf(rotz * DEG_TO_RAD); eye->y = center->y - distance * cosf(rotx * DEG_TO_RAD) * cosf(rotz * DEG_TO_RAD); eye->z = center->z + distance * sinf(rotx * DEG_TO_RAD); rotx = rotx * 0.9f + next_rotx * 0.1f; rotz = rotz * 0.9f + next_rotz * 0.1f; center = maze->location; gfx->look_at(eye, center, up); if (double_tap) { /* Variable to hold the 3D location on the far plane of the frustum. */ vec3 location; /* This function converts a 2D point from the screen coordinates * to a 3D point in space. The return value is true or false, depending on * whether or not the query is successful. It's a GFX helper, but built * basically the same way as the standard gluUnproject * (http://www.opengl.org/sdk/docs/man/xhtml/gluUnproject.xml) * function. */ if (gfx->unproject(view_location->x, /* The origin of the OpenGLES color buffer is down * left, but its location for iOS and Android is up * left. To handle this situation, simply use the * viewport matrix height data (viewport_matrix[3]) * to readjust the Y location of the picking point * onscreen. */ viewport_matrix[3] - view_location->y, /* This parameter represents the depth that you want * to query, with 1 representing the far clipping * plane and 0 representing the near clipping plane. * In this case, you are only interested in the far * clipping plane value, which explains the value 1. */ 1.0f, gfx->get_modelview_matrix(), gfx->get_projection_matrix(), viewport_matrix, location)) { /* Now that you have the XYZ location on the far plane, you can * create the collision ray. Begin by creating the starting point, * which is basically the current camera eye position. */ btVector3 ray_from(eye->x, eye->y, eye->z), /* Translate the resulting location of GFX::unproject based on the * current eye location to make sure that the coordinate system * will fit with what the player currently sees onscreen. */ ray_to(location->x + eye->x, location->y + eye->y, location->z + eye->z); /* Create the collision ray. */ btCollisionWorld::ClosestRayResultCallback collision_ray(ray_from, ray_to); /* Launch the ray in space. */ dynamicsworld->rayTest(ray_from, ray_to, collision_ray); /* Check if the collision ray gets a hit, and check if the * collision object involved is the maze btRigidBody. */ if (collision_ray.hasHit() && collision_ray.m_collisionObject == maze->btrigidbody) { collision_ray.m_hitNormalWorld.normalize(); /* Check if the normal Z is pointing upward to make sure * the hit is on the floor of the maze. */ if (collision_ray.m_hitNormalWorld.z() == 1.0f) { /* Since you got a valid hit, it is time to create the * pathfinding query to send to Detour. First, assign * the current player location as the starting point of * the query. */ navigationpath_player.start_location = player->location; /* Then simply use the collision ray hit position XYZ as * the end point of the path query. */ navigationpath_player.end_location->x = collision_ray.m_hitPointWorld.x(); navigationpath_player.end_location->y = collision_ray.m_hitPointWorld.y(); navigationpath_player.end_location->z = collision_ray.m_hitPointWorld.z(); /* The query is ready to be sent to Detour, so send it over. * If Detour was able to find a path, the function will * return 1 and will store the way points information * inside the navigationpathdata_player variable; othewise * the function will return 0. */ if (navigation->get_path(&navigationpath_player, &navigationpathdata_player)) { player_next_point = 1; /* Loop while you've got some way points. Please note * that by default, the function will assign the number * of path_point_count to be the way points returned by * Detour. However, the function implementation added * another point which is the exact same end location * that you specified in your query. The reason is * that, most of the time, the ending point not exactly * on the mavigation mesh, so the library will return * the closest pont. Depending on what you want to * achieve, you may or may not want to use this extra * way point. But for this tutorial, you are going to * take it into consideration. */ for (int i=0; i!=navigationpathdata_player.path_point_count + 1; ++i) console_print("%d: %f %f %f\n", i, navigationpathdata_player.path_point_array[i]->x, navigationpathdata_player.path_point_array[i]->y, navigationpathdata_player.path_point_array[i]->z); printf("\n"); } } } } double_tap = 0; } if (navigationpathdata_player.path_point_count) { move_entity(player, // The player OBJMESH pointer. &navigationpathdata_player, // The player navigation path // structure. &player_next_point, // The way point the player is // moving towards. 3.0f); // The speed to use as factor // to the linear velocity of // the btRigidBody. } program->draw(); glUniform1i(program->get_uniform_location(TM_Diffuse_String), TM_Diffuse); for (auto objmesh=obj->objmesh.begin(); objmesh!=obj->objmesh.end(); ++objmesh) { gfx->push_matrix(); mat4 mat; objmesh->btrigidbody->getWorldTransform().getOpenGLMatrix(mat.m()); objmesh->location = vec3(mat[3], true); gfx->multiply_matrix(mat); glUniformMatrix4fv(program->get_uniform_location((char *)"MODELVIEWPROJECTIONMATRIX"), 1, GL_FALSE, gfx->get_modelview_projection_matrix().m()); objmesh->draw(); gfx->pop_matrix(); } navigation->draw(gfx); dynamicsworld->stepSimulation(1.0f / 60.0f); }