Ejemplo n.º 1
0
static void PlayGame()
{
    Uint8 *keystate;
    int quit = 0;
    int turn;
    int prev_ticks = 0, cur_ticks = 0; /* for keeping track of timing */

    /* framerate counter variables */
    int start_time, end_time;
    int frames_drawn = 0;
	
    /* Start audio playback. */
    StartAudio();
    StartMusic();

    /* Start the music update thread. */
    music_update_thread = SDL_CreateThread(UpdateMusicThread, NULL);
    if (music_update_thread == NULL) {
	printf("Unable to start music update thread.\n");
    }

    prev_ticks = SDL_GetTicks();
    start_time = time(NULL);
	
    while (quit == 0) {
		
	/* Determine how many milliseconds have passed since
	   the last frame, and update our motion scaling. */
		
	prev_ticks = cur_ticks;
	cur_ticks = SDL_GetTicks();
	time_scale = (double)(cur_ticks-prev_ticks)/30.0;
				
	/* Update SDL's internal input state information. */
	SDL_PumpEvents();
		
	/* Grab a snapshot of the keyboard. */
	keystate = SDL_GetKeyState(NULL);
		
	/* Respond to input. */
	if (keystate[SDLK_q] || keystate[SDLK_ESCAPE]) quit = 1;
		
	/* Left and right arrow keys control turning. */
	turn = 0;
	if (keystate[SDLK_LEFT]) turn += 15;
	if (keystate[SDLK_RIGHT]) turn -= 15;
		
	/* Forward and back arrow keys activate thrusters. */
	player.accel = 0;
	if (keystate[SDLK_UP]) player.accel = PLAYER_FORWARD_THRUST;
	if (keystate[SDLK_DOWN]) player.accel = PLAYER_REVERSE_THRUST;
		
	/* Spacebar slows the ship down. */
	if (keystate[SDLK_SPACE]) {
	    player.velocity *= 0.8;
	}
		
	/* Just an amusing way to test the particle system. */
	if (keystate[SDLK_e]) {
	    CreateParticleExplosion(
		player.world_x, player.world_y, 255, 255, 255, 10, 300);
	    CreateParticleExplosion(
		player.world_x, player.world_y, 255, 0, 0, 5, 100);
	    CreateParticleExplosion(
		player.world_x, player.world_y, 255, 255, 0, 2, 50);
	}
		
	/* Allow a turn of four degrees per frame. */
	player.angle += turn * time_scale;
	if (player.angle < 0) player.angle += 360;
	if (player.angle >= 360) player.angle -= 360;

	/* Update the player's position. */
	UpdatePlayer(&player);
	UpdatePlayer(&opponent);

	/* Make the camera follow the player (but impose limits). */
	camera_x = player.world_x - SCREEN_WIDTH/2;
	camera_y = player.world_y - SCREEN_HEIGHT/2;
		
	if (camera_x < 0) camera_x = 0;
	if (camera_x >= WORLD_WIDTH-SCREEN_WIDTH)
	    camera_x = WORLD_WIDTH-SCREEN_WIDTH-1;
	if (camera_y < 0) camera_y = 0;
	if (camera_y >= WORLD_HEIGHT-SCREEN_HEIGHT)
	    camera_y = WORLD_HEIGHT-SCREEN_HEIGHT-1;

	/* Update the particle system. */
	UpdateParticles();
				
	/* Keep OpenAL happy. */
	UpdateAudio(&player, &opponent);
	       
	/* Redraw everything. */
	DrawBackground(screen, camera_x, camera_y);
	DrawParallax(screen, camera_x, camera_y);
	DrawParticles(screen, camera_x, camera_y);
	DrawPlayer(&player);
	DrawPlayer(&opponent);
	
	/* Flip the page. */
	SDL_Flip(screen);

	frames_drawn++;

    }

    end_time = time(NULL);
    if (start_time == end_time) end_time++;

    /* Display the average framerate. */
    printf("Drew %i frames in %i seconds, for a framerate of %.2f fps.\n",
	   frames_drawn,
	   end_time-start_time,
	   (float)frames_drawn/(float)(end_time-start_time));

    /* Terminate the music update thread. */
    if (music_update_thread != NULL) {
	SDL_KillThread(music_update_thread);
	music_update_thread = NULL;
    }
	
    /* Stop audio playback. */
    StopAudio();
    StopMusic();

}
Ejemplo n.º 2
0
static void PlayGame()
{
    Uint8 *keystate;
    int quit = 0;
    int turn;
    int prev_ticks = 0, cur_ticks = 0; /* for keeping track of timing */
    int awaiting_respawn = 0;

    /* framerate counter variables */
    int start_time, end_time;
    int frames_drawn = 0;

    /* respawn timer */
    int respawn_timer = -1;
	
    prev_ticks = SDL_GetTicks();
	
    start_time = time(NULL);

    /* Reset the score counters. */
    player.score = 0;
    opponent.score = 0;

    /* Start sound playback. */
    StartAudio();
    StartMusic();

    /* Start the music update thread. */
    music_update_thread = SDL_CreateThread(UpdateMusicThread, NULL);
    if (music_update_thread == NULL) {
	printf("Unable to start music update thread.\n");
    }

    /* Start the game! */
    while ((quit == 0) && network_ok) {

	/* Determine how many milliseconds have passed since
	   the last frame, and update our motion scaling. */
	prev_ticks = cur_ticks;
	cur_ticks = SDL_GetTicks();
	time_scale = (double)(cur_ticks-prev_ticks)/30.0;
				
	/* Update SDL's internal input state information. */
	SDL_PumpEvents();
		
	/* Grab a snapshot of the keyboard. */
	keystate = SDL_GetKeyState(NULL);

	/* Lock the mutex so we can access the player's data. */
	SDL_LockMutex(player_mutex);
		
	/* If this is a network game, take note of variables
	   set by the network thread. These are handled differently
	   for a scripted opponent. */
	if (opponent_type == OPP_NETWORK) {

	    /* Has the opponent respawned? */
	    if (network_opponent_respawn) {
		printf("Remote player has respawned.\n");
		opponent.shields = 100;
		network_opponent_respawn = 0;
		awaiting_respawn = 0;
	    }
		
	    /* Has the local player been hit? */
	    if (local_player_hit) {
		local_player_hit--;
		player.shields -= PHASER_DAMAGE;
		ShowPhaserHit(&player);
				/* No need to check for death, the
				   other computer will tell us. */
	    }
		}

	/* Update phasers. */
	player.firing -= time_scale;
	if (player.firing < 0) player.firing = 0;
	opponent.firing -= time_scale;
	if (opponent.firing < 0) opponent.firing = 0;
	ChargePhasers(&player);

	/* If the local player is destroyed, the respawn timer will
	   start counting. During this time the controls are disabled
	   and explosion sequence occurs. */
	if (respawn_timer >= 0) {
	    respawn_timer++;

	    if (respawn_timer >= ((double)RESPAWN_TIME / time_scale)) {
		respawn_timer = -1;
		InitPlayer(&player);

				/* Set the local_player_respawn flag so the
				   network thread will notify the opponent
				   of the respawn. */
		local_player_respawn = 1;

		SetStatusMessage("GOOD LUCK, WARRIOR!");
	    }
	}

	/* Respond to input and network events, but not if we're in a respawn. */
	if (respawn_timer == -1) {
	    if (keystate[SDLK_q] || keystate[SDLK_ESCAPE]) quit = 1;
			
	    /* Left and right arrow keys control turning. */
	    turn = 0;
	    if (keystate[SDLK_LEFT]) turn += 10;
	    if (keystate[SDLK_RIGHT]) turn -= 10;
			
	    /* Forward and back arrow keys activate thrusters. */
	    player.accel = 0;
	    if (keystate[SDLK_UP]) player.accel = PLAYER_FORWARD_THRUST;
	    if (keystate[SDLK_DOWN]) player.accel = PLAYER_REVERSE_THRUST;
			
	    /* Spacebar fires phasers. */
	    if (keystate[SDLK_SPACE]) {

		if (CanPlayerFire(&player)) {

		    FirePhasers(&player);

		    /* If it's a hit, either notify the opponent
		       or exact the damage. Create a satisfying particle
		       burst. */
		    if (!awaiting_respawn &&
			CheckPhaserHit(&player,&opponent)) {

			ShowPhaserHit(&opponent);
			DamageOpponent();

			/* If that killed the opponent, set the
			   "awaiting respawn" state, to prevent multiple
			   kills. */
			if (opponent.shields <= 0 &&
			    opponent_type == OPP_NETWORK)
			    awaiting_respawn = 1;
       		    }
		}
	    }
			
	    /* Turn. */
	    player.angle += turn * time_scale;
	    if (player.angle < 0) player.angle += 360;
	    if (player.angle >= 360) player.angle -= 360;

	    /* If this is a network game, the remote player will
	       tell us if we've died. Otherwise we have to check
	       for failed shields. */
	    if (((opponent_type == OPP_NETWORK) && local_player_dead) ||
		(player.shields <= 0))
	    {
		printf("Local player has been destroyed.\n");
		local_player_dead = 0;
				
		/* Kaboom! */
		KillPlayer();
				
		/* Respawn. */
		respawn_timer = 0;
	    }
	}

	/* If this is a player vs. computer game, give the computer a chance. */
	if (opponent_type == OPP_COMPUTER) {
	    if (RunGameScript() != 0) {
		fprintf(stderr, "Ending game due to script error.\n");
		quit = 1;
	    }
			
	    /* Check for phaser hits against the player. */
	    if (opponent.firing) {
		if (CheckPhaserHit(&opponent,&player)) {
					
		    ShowPhaserHit(&player);
		    player.shields -= PHASER_DAMAGE;

		    /* Did that destroy the player? */
		    if (respawn_timer < 0 && player.shields <= 0) {
			KillPlayer();
			respawn_timer = 0;
		    }
		}
	    }

	    ChargePhasers(&opponent);
	    UpdatePlayer(&opponent);
	}

	/* Update the player's position. */
	UpdatePlayer(&player);

	/* Update the status information. */
	SetPlayerStatusInfo(player.score, player.shields, player.charge);
	SetOpponentStatusInfo(opponent.score, opponent.shields);

	/* Make the camera follow the player (but impose limits). */
	camera_x = player.world_x - SCREEN_WIDTH/2;
	camera_y = player.world_y - SCREEN_HEIGHT/2;
		
	if (camera_x < 0) camera_x = 0;
	if (camera_x >= WORLD_WIDTH-SCREEN_WIDTH)
	    camera_x = WORLD_WIDTH-SCREEN_WIDTH-1;
	if (camera_y < 0) camera_y = 0;
	if (camera_y >= WORLD_HEIGHT-SCREEN_HEIGHT)
	    camera_y = WORLD_HEIGHT-SCREEN_HEIGHT-1;

	/* Update the particle system. */
	UpdateParticles();

	/* Keep OpenAL happy. */
	UpdateAudio(&player, &opponent);
				
	/* Redraw everything. */
	DrawBackground(screen, camera_x, camera_y);
	DrawParallax(screen, camera_x, camera_y);
	DrawParticles(screen, camera_x, camera_y);
	if (opponent.firing)
	    DrawPhaserBeam(&opponent, screen, camera_x, camera_y);
	if (player.firing)
	    DrawPhaserBeam(&player, screen, camera_x, camera_y);

	if (respawn_timer < 0)
	    DrawPlayer(&player);
	if (!awaiting_respawn)
	    DrawPlayer(&opponent);
	UpdateStatusDisplay(screen);
		
	/* Release the mutex so the networking system can get it.
	   It doesn't stay unlocked for very long, but the networking
	   system should still have plenty of time. */
	SDL_UnlockMutex(player_mutex);
	
	/* Flip the page. */
	SDL_Flip(screen);

	frames_drawn++;
    }

    end_time = time(NULL);
    if (start_time == end_time) end_time++;

    /* Display the average framerate. */
    printf("Drew %i frames in %i seconds, for a framerate of %.2f fps.\n",
	   frames_drawn,
	   end_time-start_time,
	   (float)frames_drawn/(float)(end_time-start_time));


    /* Terminate the music update thread. */
    if (music_update_thread != NULL) {
	SDL_KillThread(music_update_thread);
	music_update_thread = NULL;
    }
	
    /* Stop audio playback. */
    StopAudio();
    StopMusic();
}
Ejemplo n.º 3
0
//-----------------------------------------------------------------------------------------
// This tutorial does the follow XACT related steps: 
//
//      1. Prepare to use XACT
//      2. Start playing background music when the streaming wave bank is prepared
//      3. Allow XACT to do work periodically when the message pump is idle
//      4. Plays sounds using XACT upon a user event
//      5. XACT shutdown and cleanup 
//
// We will look at each of these steps in detail below.
//-----------------------------------------------------------------------------------------
INT WINAPI wWinMain( HINSTANCE hInst, HINSTANCE, LPWSTR, INT )
{
    // Register the window class
    HBRUSH hBrush = CreateSolidBrush( 0xFF0000 );
    WNDCLASSEX wc =
    {
        sizeof( WNDCLASSEX ), 0, MsgProc, 0L, 0L, hInst, NULL,
        LoadCursor( NULL, IDC_ARROW ), hBrush,
        NULL, L"XACTTutorial", NULL
    };
    RegisterClassEx( &wc );

    // Create the application's window
    g_hWnd = CreateWindow( L"XACTTutorial", L"XACT Tutorial 2: Streaming",
                           WS_OVERLAPPED | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX,
                           CW_USEDEFAULT, CW_USEDEFAULT, 500, 400,
                           NULL, NULL, hInst, NULL );
    SetTimer( g_hWnd, 0, 100, NULL ); // update the text every so often

    // Prepare to use XACT
    HRESULT hr;
    if( FAILED( hr = PrepareXACT() ) )
    {
        if( hr == HRESULT_FROM_WIN32( ERROR_FILE_NOT_FOUND ) )
            MessageBox( g_hWnd, L"Failed to init XACT because media not found.", L"XACT Tutorial", MB_OK );
        else
            MessageBox( g_hWnd, L"Failed to init XACT.", L"XACT Tutorial", MB_OK );
        CleanupXACT();
        return 0;
    }

    // Book keeping - no song currently playing.
    g_audioState.nCurSongPlaying = -1;

    // Enter the message loop
    bool bGotMsg;
    MSG msg;
    msg.message = WM_NULL;

    while( WM_QUIT != msg.message )
    {
        // Use PeekMessage() so we can use idle time to render the scene and call pEngine->DoWork()
        bGotMsg = ( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) != 0 );

        if( bGotMsg )
        {
            // Translate and dispatch the message
            TranslateMessage( &msg );
            DispatchMessage( &msg );
        }
        else
        {
            UpdateAudio();

            Sleep( 10 ); // Yield CPU time to other apps.  Note that this is not normally needed when rendering
        }
    }

    // Clean up 
    UnregisterClass( L"XACT Tutorial", NULL );
    CleanupXACT();

    return 0;
}