【C言語】ヘビ食いゲームの実現(三)


ゲームの静的初期化が完了しました.次は動的ロジックの作成です.ゲームが開始された後、私たちが実現しなければならない機能はいくつかあります.ボタン(上下左右)を押さないうちに、蛇はデフォルトの方向に進み、方向キーを押すと、蛇は前進方向を変え、蛇が壁にぶつかったり自分を噛んだりしたら、ゲームは終わります.では、問題は、キーボードで方向を制御する方法です.ここではshort GetAsyncKeyState(int nVirtKey)を使います.メソッドでは,このメソッドが伝達するパラメータnVirtKeyが仮想キーボード値定数であるため,伝達するnVirtKeyパラメータによりヘビの方向を制御でき,同様に加速減速や一時停止などの機能も実現できる.
/*
	      
*/
void keyboardControl()
{
	status=R;       //       
    while(1)
    {
		scoreandtips();
        if(GetAsyncKeyState(VK_UP) && status!=D)            //GetAsyncKeyState                   
        {
            status=U;           //            ,   ,        
        }
        else if(GetAsyncKeyState(VK_DOWN) && status!=U)     //            ,   ,        
        {
            status=D;
        }
        else if(GetAsyncKeyState(VK_LEFT)&& status!=R)      //            ,   ,      
        {
            status=L;
        }
        else if(GetAsyncKeyState(VK_RIGHT)&& status!=L)     //            ,   ,      
        {
            status=R;
        }
        if(GetAsyncKeyState(VK_SPACE))		//    ,  pause    
        {
            while(1)
			{
				Sleep(300); //sleep()  ,   #include        ,              
				if(GetAsyncKeyState(VK_SPACE))      //      
				{
					break;
				}
				
			}       
        }
        else if(GetAsyncKeyState(VK_ESCAPE))
        {
            endgamestatus=3;    // esc ,       
            break;
        }
        else if(GetAsyncKeyState(VK_F1))    // F1 ,  
        {
            speedup();
        }
        else if(GetAsyncKeyState(VK_F2))    // F2 ,  
        {
        	speeddown();
            
        }
        Sleep(sleeptime);
        snakemove();
    }
}

ヘビは前進時に頭ノードを新設し,尾ノードを拭き取ることで実現し,食べ物を食べると自動的に加速する.
/*
	    
*/
void snakemove()	//   , U, D, L, R
{
	snake * nexthead;
    cantcrosswall();
    nexthead=(snake*)malloc(sizeof(snake));		//        
    if(status==U)
    {
        nexthead->x=head->x;        //     ,x    ,y  -1
        nexthead->y=head->y-1;
        nexthead->next=head;
        head=nexthead;
        q=head;						//  q    
        if(nexthead->x==food->x && nexthead->y==food->y)	//                         
        {
            
            while(q!=NULL)
            {
                gotoxy(q->x,q->y);
				color(14);
                printf("◆");       //       , ●  ◆
                q=q->next;          //  q                  
				
            }
            score=score+add;        //      ,          
			speedup();
            createfood();           //    
        }
        else                        
        {
            while(q->next->next!=NULL)	//       
            {
                gotoxy(q->x,q->y);
                color(14);
                printf("◆");           //      ,         
                q=q->next;              //        
            }
            gotoxy(q->next->x,q->next->y);  //       ,q    ,      ,         
			color(3);
            printf("■");
            free(q->next);			//    ■  ,          
            q->next=NULL;			//        
        }
    }
    if(status==D)
    {
        nexthead->x=head->x;        //     ,x    ,y  +1
        nexthead->y=head->y+1;
        nexthead->next=head;
        head=nexthead;
        q=head;
        if(nexthead->x==food->x && nexthead->y==food->y)  //   
        {
            
            while(q!=NULL)
            {
                gotoxy(q->x,q->y);
                color(14);
                printf("◆");
                q=q->next;
            }
            score=score+add;
			speedup();
            createfood();
        }
        else                               //    
        {
            while(q->next->next!=NULL)
            {
                gotoxy(q->x,q->y);
                color(14);
                printf("◆");
                q=q->next;
            }
            gotoxy(q->next->x,q->next->y);
			color(3);
            printf("■");
            free(q->next);
            q->next=NULL;
        }
    }
    if(status==L)
    {
        nexthead->x=head->x-2;        //     ,x      -2,y    
        nexthead->y=head->y;
        nexthead->next=head;
        head=nexthead;
        q=head;
        if(nexthead->x==food->x && nexthead->y==food->y)//   
        {
            while(q!=NULL)
            {
                gotoxy(q->x,q->y);
                color(14);
                printf("◆");
                q=q->next;
            }
            score=score+add;
			speedup();
            createfood();
        }
        else                                //    
        {
            while(q->next->next!=NULL)
            {
                gotoxy(q->x,q->y);
                color(14);
                printf("◆");
                q=q->next;        
            }
            gotoxy(q->next->x,q->next->y);
			color(3);
            printf("■");
            free(q->next);
            q->next=NULL;
        }
    }
    if(status==R)
    {
        nexthead->x=head->x+2;        //     ,x      +2,y    
        nexthead->y=head->y;
        nexthead->next=head;
        head=nexthead;
        q=head;
        if(nexthead->x==food->x && nexthead->y==food->y)//   
        {
            while(q!=NULL)
            {
                gotoxy(q->x,q->y);
                color(14);
                printf("◆");
                q=q->next;
            }
            score=score+add;
			speedup();
            createfood();
        }
        else                                         //    
        {
            while(q->next->next!=NULL)
            {
                gotoxy(q->x,q->y);
                color(14);
                printf("◆");
                q=q->next;        
            }
            gotoxy(q->next->x,q->next->y);
			color(3);
            printf("■");
            free(q->next);
            q->next=NULL;
        }
    }
    if(biteself()==1)       //         
    {
        endgamestatus=2;
        endgame();
    }
}

加速コードは時間間隔を短縮し、得点を増加させる.
/*
	  ,          ,   F1   
*/
void speedup()
{
	if(sleeptime>=50)
	{
		sleeptime=sleeptime-10;
		add=add+2;

    }
}

減速も同じだ.
/*
	  , F2   
*/
void speeddown()
{
	if(sleeptime<350)               //        350
    {
        sleeptime=sleeptime+30;     //      30
        add=add-2;                  //          2

    }
}

ヘビが自分を噛んだかどうかをどのように判断するかは,ヘビ体ノードを巡ることによって繰り返し実現したかどうかを判断する.
/*
	         
*/
int biteself()
{
    snake *self;            //  self         
    self=head->next;        //self            
    while(self!=NULL)
    {
        if(self->x==head->x && self->y==head->y)    //  self         
        {
            return 1;       //  1
        }
        self=self->next;
    }
    return 0;
}

壁にぶつかる検査はもっと簡単で、ヘッドノードと上下左右の「壁」の座標値が重なるかどうかを判断すればいい.
/*
	        
*/
void cantcrosswall()
{  
    if(head->x==0 || head->x==56 ||head->y==0 || head->y==26) //         
    {
        endgamestatus=1;        //       
        endgame();              //        
    }
}

これで、ゲームのダイナミックロジックの作成が完了しました.