jump animation using winapi





  • Naja, zeig mal etwas Code her / show us some code 🙂

    MfG SideWinder



  • hier findet man die zugehörigen sounddateien:
    applause.wav
    crowd-groan-02.wav
    zombie.wav
    die braucht man aber nicht unbedingt.

    hier kommt der code, das programmm ist inzwischen um einige funktionen angewachsen 😃 , im vergleich zum video

    #include <windows.h>
    #include <process.h>
    #include <conio.h>
    #include <stdio.h>
    
    #define FIELD_WIDTH 15
    #define FIELD_HEIGHT 15
    #define FIELD_BUFSIZE (FIELD_WIDTH*FIELD_HEIGHT)
    
    HANDLE h_mutex;
    HANDLE h_in, h_out;
    INPUT_RECORD inbuf;
    
    CHAR_INFO field [ FIELD_BUFSIZE ];
    int field_bg_color = BACKGROUND_INTENSITY;
    
    int jump_speed;
    BOOL b_jump, b_jumping, b_falling, b_program_run = TRUE;
    
    const char CLOVER = 5;
    const char LIFE = 2;
    const char DEAD = 1;
    int lifeposx = 5 , lifeposy = 24;
    
    CRITICAL_SECTION CriticalSection;
    
    COORD thing [ ] = { 
    		{40, 24}, {40, 23},  {40, 22},  {40, 21},  {40, 20},  {40, 19},  {40, 18},  
    		{40, 17},  {40, 16},  {40, 15},  {40, 14}, {40, 13}, {40, 12}, {40, 11},
    		{40, 10}, {39, 10}, {38, 10}, {37, 10}, {36, 10}, {35, 10}, {34, 10}, {33, 10}
    };
    
    COORD death_wall [] = { {36, 9},  {36, 8},  {36, 7},  {36, 6}
    }; 
    
    COORD clover = {37, 9}; 
    
    void print_char ( int c, int x, int y );
    
    void draw_thing()
    {
    	int n = sizeof(thing)/sizeof(thing[0]), i;
    	for ( i = 0; i < n; i++ )
    		print_char ( 219, thing[i].X, thing[i].Y );
    }
    
    void draw_death_wall()
    {
    	int n = sizeof(death_wall)/sizeof(death_wall[0]), i;
    	SetConsoleTextAttribute ( h_out, FOREGROUND_BLUE|FOREGROUND_INTENSITY );
    	for ( i = 0; i < n; i++ )
    		print_char ( 219, death_wall[i].X, death_wall[i].Y );
    	SetConsoleTextAttribute ( h_out, FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE );
    }
    
    void draw_clover()
    {	
    	SetConsoleTextAttribute ( h_out, FOREGROUND_GREEN|FOREGROUND_INTENSITY );
    	print_char ( CLOVER, clover.X, clover.Y );
    	SetConsoleTextAttribute ( h_out, FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE );
    }
    
    BOOL b_playing=TRUE;
    void play_applause (  VOID* pv )
    {
    	mciSendString("open applause.wav alias applause", NULL, 0, 0); 
    	mciSendString("play applause", NULL, 0, 0);
    	while(b_playing){}
    		mciSendString("close applause", NULL, 0, 0);	
    }
    
    void play_dying( )
    {
    	b_playing = FALSE;
    	mciSendString("open zombie.wav alias dying", NULL, 0, 0); 
    	mciSendString("play dying", NULL, 0, 0);
    	Sleep(1000);
    	mciSendString("open crowd-groan-02.wav alias groan", NULL, 0, 0); 
    	mciSendString("play groan", NULL, 0, 0);
    }
    
    void gotoxy (short x, short y)
    {
    	COORD position; position.X = x, position.Y = y;
    	SetConsoleCursorPosition (h_out, position);
    }   
    
    BOOL init_console ( void )
    {
    	h_in = GetStdHandle(STD_INPUT_HANDLE);
    	h_out = GetStdHandle(STD_OUTPUT_HANDLE);
    	return NULL != h_out && NULL != h_in;
    }
    
    void init_field()
    {
    	int i;
    //	srand(time(NULL)); 
    	for ( i = 0;  i < FIELD_BUFSIZE; i++ )
    	{
    		field[i].Attributes = field_bg_color;// | rand() % 4; //FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE;
    		field[i].Char.AsciiChar = 'x';
    	}
    }
    void show_field ()
    {
    	SMALL_RECT r = { 0, 0, FIELD_WIDTH-1, FIELD_HEIGHT-1 }; // Coordinates of the screenbuffer rectangle.
        	COORD bs = { FIELD_WIDTH, FIELD_HEIGHT };   // Column-row size of source buffer.
    	COORD bc = {0};    // Upper-left cell to write from.
     	WriteConsoleOutput( h_out, field, bs, bc, &r );
    }
    
    void increase_jump_speed()
    {
    	gotoxy(0, 24-jump_speed);
    	putchar(219);
    	jump_speed++;
    }
    
    void erease_jump_speed_bar()
    {
    	int i;
    	WaitForSingleObject ( h_mutex, INFINITE );
    	for( i = 0; i < 25; i++)
    	{
    		gotoxy(0, i);
    		putchar(' ');
    	}
    	gotoxy(0, 24);
    	jump_speed = 0;
    	ReleaseMutex ( h_mutex );
    }
    
    BOOL would_hit_thing ( int x, int y )
    {
    	int n = sizeof(thing)/sizeof(thing[0]), i;
    	for ( i = 0; i < n; i++ )
    		if ( x == thing [ i ].X && y == thing [ i ].Y ) 
    			return TRUE;
    	return FALSE;
    }
    
    void got_clover ()
    {
    	gotoxy ( 10, lifeposy );
    	puts ("Well done!");	
    	clover.X = clover.Y = -1;
    	_beginthread ( play_applause, 0, (void*) "applause.wav" );
    
    }
    
    BOOL would_hit_death_wall ( int x, int y )
    {
    	int n = sizeof ( death_wall )/sizeof ( death_wall [0] ), i;
    	for ( i = 0; i < n; i++ )
    		if ( x == death_wall [ i ].X && y == death_wall [ i ].Y ) 
    			return TRUE;
    	return FALSE;
    }
    
    BOOL would_hit_clover ( int x, int y )
    {
    	if ( x == clover.X && y == clover.Y ) 
    		return TRUE;
    	return FALSE;
    }
    
    BOOL coords_valid ( int x, int y )
    {
    	return x > 1 && x  < 79 && y > -1 && y < 25;
    }
    
    void print_char ( int c, int x, int y )
    {
    	gotoxy ( x, y );
    	putchar ( c );
    }
    
    void set_life_pos ( int x, int y )
    {
    	if ( coords_valid ( lifeposx, lifeposy ) )
    		print_char ( ' ', lifeposx, lifeposy );
    	if ( coords_valid ( x, y ) )
    		print_char ( LIFE, x, y );
    	lifeposx = x, lifeposy = y;
    }
    
    void die()
    {
    	print_char(DEAD, lifeposx, lifeposy);
    	b_playing = FALSE;
    
    	gotoxy ( 10, lifeposy );
    	puts ("You are dead !");
    
    	play_dying();
    	Sleep(3000);
    	exit(0);
    }
    
    void fall ( VOID* pv )
    {
    	while ( lifeposy < 24 )
    	{
    		b_falling = TRUE;
    
    		WaitForSingleObject ( h_mutex, INFINITE );
    
    		if ( would_hit_thing ( lifeposx, lifeposy +1 ) )
    		{
    			b_falling = FALSE; ReleaseMutex ( h_mutex ); return;
    		}
    
    		if ( would_hit_death_wall ( lifeposx, lifeposy +1 ) )
    			die();
    		if ( would_hit_clover ( lifeposx, lifeposy +1) )
    			got_clover();
    
    		set_life_pos ( lifeposx, lifeposy  + 1 );
    		Sleep(80);
    
    		b_falling = FALSE;
    
    		ReleaseMutex ( h_mutex );
    	}
    }
    
    void ascend()
    {	int i;
    	for ( i = 0; i < jump_speed; i++ )
    	{
    		WaitForSingleObject ( h_mutex, INFINITE );
    
    		if ( would_hit_thing ( lifeposx, lifeposy -1 ) )
    			break;
    		if ( would_hit_death_wall ( lifeposx, lifeposy -1 ) )
    			die();
    		set_life_pos ( lifeposx, lifeposy - 1 );
    		Sleep(80);
    
    		ReleaseMutex ( h_mutex );
    	}
    }
    
    void move_right()
    {
    	WaitForSingleObject ( h_mutex, INFINITE );
    
    	if ( would_hit_death_wall ( lifeposx+1, lifeposy ) )
    		die();
    	if ( !would_hit_thing ( lifeposx+1, lifeposy ) ) 
    		set_life_pos ( lifeposx+1, lifeposy );
    
    	ReleaseMutex ( h_mutex );
    }
    
    void move_left()
    {
    	WaitForSingleObject ( h_mutex, INFINITE );
    	if ( would_hit_death_wall ( lifeposx -1, lifeposy ) )
    		die();
    	if ( would_hit_clover ( lifeposx -1, lifeposy ) )
    		got_clover();
    	if ( !would_hit_thing ( lifeposx -1, lifeposy ) )
    		set_life_pos ( lifeposx -1, lifeposy );
    
    	ReleaseMutex ( h_mutex );
    }
    
    VOID key_event(KEY_EVENT_RECORD ker)
    {
    	if ( ker.wVirtualKeyCode == VK_RIGHT && ker.bKeyDown )
    	{
    		move_right();
    		if ( ! b_jumping && ! b_falling)
    			_beginthread ( fall, 0, NULL );  // maybe, if the thing is not beneath :)
    	      return;
    	}
    
    	if ( ker.wVirtualKeyCode == VK_LEFT && ker.bKeyDown )
    	{
    		move_left();
    		if ( ! b_jumping && ! b_falling)
    			_beginthread ( fall, 0, NULL );  // maybe, if the thing is not beneath :)
    		return;
    	}
    
    	if ( b_jumping ) return;
    
    	if ( ker.wVirtualKeyCode == VK_UP )
    	{
    		if( ker.bKeyDown )
    		{
    
    			if ( jump_speed < 25 )
    				increase_jump_speed();
    
    		}
    		else
    		{
    			b_jump = TRUE;
    		}
    	}
    }
    
    void jump (  VOID* pv )
    {
    	ascend();
    	fall ( NULL );
    	erease_jump_speed_bar();
    	b_jump = b_jumping = FALSE;
    }
    
    void cursor_visibility ( BOOL b );
    
    int main()
    {
    	init_console();
    	cursor_visibility ( FALSE );
    	unsigned num_records_read;
    SetConsoleTitle("Big Brothers Console Animation Demo");
    	InitializeCriticalSectionAndSpinCount ( &CriticalSection, 0x00000400 );
    	set_life_pos ( lifeposx, lifeposy );
    	draw_thing();
    	draw_death_wall();
    	draw_clover();
    
    	gotoxy ( 5, 4 ); puts ("Try to get the clover. Don't touch the deadly blue magnet-wall !");
    	_getch();
    	gotoxy ( 5, 4 ); puts ("                                                                                           ");
    
    	h_mutex = CreateMutex ( NULL, FALSE, NULL ) ;
    
    	while ( b_program_run )
    	{
    		if ( b_jump && !b_jumping )
    		{
    			b_jumping = TRUE;
    			_beginthread ( jump, 0,  NULL );
    		}
    
    		ReadConsoleInput ( h_in, &inbuf, 1, &num_records_read );
    		FlushConsoleInputBuffer ( h_in );
    
    		switch(inbuf.EventType) 
     	    	{ 
    			case KEY_EVENT: 
    				key_event ( inbuf.Event.KeyEvent );
    
    				if (inbuf.Event.KeyEvent.wVirtualKeyCode == VK_SPACE )
    				{
    					//if (inbuf.Event.KeyEvent.bKeyDown)
    						//gotoxy ( 70, 22 ), puts("GAME OVER");
    					//stop_sound ( "applause.wav" );
    					b_playing = FALSE;
    				}
    			break; 
              	}
    	}	
    
    	return 0;
    }
    
    void cursor_visibility( BOOL b )
    {
    	CONSOLE_CURSOR_INFO cci;
    	cci.dwSize = 10;
    	cci.bVisible = b;
    	SetConsoleCursorInfo(h_out, &cci);
    }
    

    dies ist lediglich testcode! d.h. da sind noch diverse optimierungsmöglichkeiten, verbesserungen etc. möglich

    🙂



  • Sehr nett 🙂 Bei mir hat es aber nicht sofort kompiliert. Ich habe in Zeile 345 einen Cast hinzufügen müssen:

    ReadConsoleInput ( h_in, &inbuf, 1, (LPDWORD) &num_records_read );
    

Anmelden zum Antworten