数字雨-贪吃蛇

数字雨

#include "windows.h"
#include "stdlib.h"
#include "stdio.h"
#include "time.h"
#include "string.h"
#define ID_TIMER 1
#define STRMAXLEN 25
#define STRMINLEN 8
LRESULT CALLBACK WndProc (HWND,UINT,WPARAM,LPARAM);
typedef struct tagCharChain
{  
    struct tagCharChain*prev;
    TCHAR ch;
    struct tagCharChain*next;
}CharChain,*pCharChain;

typedef struct tagCharColumn
{
    CharChain *head,*current,*point;
    int x,y,iStrLen;
    int iStopTimes,iMustStopTimes;
}CharColumn,*pCharColumn;
int main(HINSTANCE hInstance, HINSTANCE hPrevInstance,PSTR szCmdLine, int iCmdShow)
{
    static TCHAR szAppName[] = TEXT ("matrix") ;
    HWND    hwnd;
    MSG    msg;
    WNDCLASS   wndclass;
    wndclass.style  = CS_HREDRAW | CS_VREDRAW;
    wndclass.lpfnWndProc  =WndProc;
    wndclass.cbClsExtra = 0 ;
    wndclass.cbWndExtra = 0 ;
    wndclass.hInstance= hInstance ;
    
    wndclass.hIcon    =LoadIcon(NULL,IDI_APPLICATION);
    wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
    wndclass.hbrBackground = (HBRUSH) GetStockObject (BLACK_BRUSH) ; 
    wndclass.lpszMenuName = NULL ;
    wndclass.lpszClassName  =szAppName;
    
    if(!RegisterClass(&wndclass))
    {
        MessageBox (NULL,TEXT ("此程序必须运行在NT下!"),szAppName,MB_ICONERROR);
        return 0;}
    
    hwnd =CreateWindow(szAppName,NULL,WS_DLGFRAME| WS_THICKFRAME|WS_POPUP,0,0,GetSystemMetrics(SM_CXSCREEN),GetSystemMetrics(SM_CYSCREEN),NULL,NULL,hInstance,NULL);
    ShowWindow(hwnd,SW_SHOWMAXIMIZED);
    UpdateWindow (hwnd);
    ShowCursor(FALSE);
    
    srand ((int )GetCurrentTime());
    while(GetMessage (&msg,NULL,0,0)){
        TranslateMessage(&msg);
        DispatchMessage (&msg);
    }
    ShowCursor(TRUE);
    return msg.wParam;
}

TCHAR randomChar(){
    return (TCHAR)(rand()%(126-33)+33);
}
int init(CharColumn *cc,int cyScreen,int x){
    int j;
    cc->iStrLen=rand()%(STRMAXLEN-STRMINLEN)+STRMINLEN;
    cc->x=x+3;
    cc->y=rand()%3?rand()%cyScreen:0;
    cc->iMustStopTimes=rand()%6;
    cc->iStopTimes=0;
    cc->head=cc->current=(pCharChain)calloc(cc->iStrLen,sizeof(CharChain));
    for(j=0;j<cc->iStrLen-1;j++)
    {
        cc->current->prev = cc->point;//cc->current->prev = cc->point;
        cc->current->ch = '';
        cc->current->next = cc->current+1;
        cc->point = cc->current++;
    }
    cc->current->prev = cc->point;
    cc->current->ch = '';
    cc->current->next = cc->head;
    cc->head->prev  = cc->current;
    
    cc->current = cc->point = cc->head;
    cc->head->ch=randomChar();
    return 0;
}

LRESULT CALLBACK WndProc (HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{
    HDC   hdc;
    int i,j,temp,ctn;
    static HDC hdcMem;
    HFONT hFont;
    static HBITMAP hBitmap;
    static int cxScreen,cyScreen;
    static int iFontWidth=10,iFontHeight=15,iColumnCount;
    static CharColumn *ccChain;
    switch(message)
    {
        case WM_CREATE:
        cxScreen=GetSystemMetrics(SM_CXSCREEN);
        cyScreen=GetSystemMetrics(SM_CYSCREEN);
        SetTimer (hwnd,ID_TIMER,10,NULL);
        
        hdc=GetDC(hwnd);
        hdcMem=CreateCompatibleDC(hdc);
        hBitmap=CreateCompatibleBitmap(hdc,cxScreen,cyScreen);
        SelectObject(hdcMem,hBitmap);
        ReleaseDC(hwnd,hdc);
        
        hFont=CreateFont(iFontHeight,iFontWidth-5,0,0,FW_BOLD,0,0,0,DEFAULT_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DRAFT_QUALITY,FIXED_PITCH | FF_SWISS,TEXT("Fixedays"));
        SelectObject(hdcMem,hFont);
        DeleteObject(hFont);
        SetBkMode(hdcMem,TRANSPARENT);
        iColumnCount=cxScreen/(iFontWidth*3/2);
        ccChain=(pCharColumn)calloc(iColumnCount,sizeof(CharColumn));
        for(i=0;i<iColumnCount;i++)
        {
            init(ccChain+i,cyScreen,cyScreen,(iFontWidth*3/2)*i);
        }
        return 0 ;
        case WM_TIMER:
        hdc=GetDC(hwnd);
        PatBlt(hdcMem,0,0,cxScreen,cyScreen,BLACKNESS);
         for(i=0;i<iColumnCount;i++){
         ctn=(ccChain+i)->iStopTimes++>(ccChain+i)->iMustStopTimes;
         (ccChain+i)->point=(ccChain+i)->head;
         SetTextColor(hdcMem,RGB(255,255,255));
         TextOut(hdcMem,(ccChain+i)->x,(ccChain+i)->y,&((ccChain+i)->point->ch),1);
         j=(ccChain+i)->y;
         (ccChain+i)->point=(ccChain+i)->point->next;
         temp=0;
         while((ccChain+i)->point !=(ccChain+i)->head &&(ccChain+i)->point->ch)
         {
             SetTextColor(hdcMem,RGB(0,255-(255*(temp++)/(ccChain+i)->iStrLen),0));
             TextOut(hdcMem,(ccChain+i)->x,j-=iFontHeight,&((ccChain+i)->point->ch),1);
             (ccChain+i)->point=(ccChain+i)->point->next;
          }
          if(ctn)
          (ccChain+i)->iStopTimes=0;
          else continue;
          (ccChain+i)->y+=iFontHeight;
          
          if((ccChain+i)->y-(ccChain+i)->iStrLen*iFontHeight>cyScreen)
          {
             free((ccChain+i)->current);
       init(ccChain+i,cyScreen,(iFontWidth*3/2)*i);
         }
         (ccChain+i)->head=(ccChain+i)->head->prev;
         (ccChain+i)->head->ch=randomChar();
         }
         BitBlt(hdc,0,0,cxScreen,cyScreen,hdcMem,0,0,SRCCOPY);
         ReleaseDC(hwnd,hdc);
         return 0;
         
         case WM_RBUTTONDOWN:
            KillTimer(hwnd,ID_TIMER);
            return 0;
            case WM_KEYDOWN:
            case WM_LBUTTONDOWN:
            case WM_DESTROY:
            KillTimer (hwnd,ID_TIMER);
            DeleteObject(hBitmap);
            DeleteDC(hdcMem);
            for(i=0;i<iColumnCount;i++)
            {
               free((ccChain+i)->current);
               }
               free(ccChain);
               PostQuitMessage(0);
               return 0;
               }
               return DefWindowProc (hwnd,message,wParam,lParam);
            }

贪吃蛇

#include  "string.h" 
#include "stdio.h"
#include  "stdlib.h"
#include "time.h"
#include "conio.h"
#include "windows.h"
const int H = 16;   //地图的高  
const int L = 30;  //地图的长  
char GameMap[16][30];   //游戏地图  
int  key;  //按键保存  
int  sum = 1, over = 0;  //蛇的长度, 游戏结束(自吃或碰墙)  
int  dx[4] = {0, 0, -1, 1};  //左、右、上、下的方向  
int  dy[4] = {-1, 1, 0, 0};
int arr=15;  
struct Snake   //蛇的每个节点的数据类型  
{  
 int x, y;  //左边位置  
 int now;   //保存当前节点的方向, 0,1,2,3分别为左右上下  
}Snake[16*30];
const char Shead = '@';  //蛇头  
const char Sbody = '#';  //蛇身  
const char Sfood = '*';  //食物  
const char Snode = '.';  //'.'在地图上标示为空  
void Initial();  //地图的初始化  
void Create_Food(); //在地图上随机产生食物  
void Show();   //刷新显示地图  
void Button();  //取出按键,并判断方向  
void Move();   //蛇的移动  
void Check_Border();  //检查蛇头是否越界  
void Check_Head(int x, int y);   //检查蛇头移动后的位置情况 
int color(int c)
{
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),c);
    return 0;
}
int main()   
{  
 Initial();  
 Show();  
 return 0;  
}  
void Initial()  //地图的初始化  
{  
 int i, j;  
 int hx, hy;  
 system("title 贪吃蛇");  //控制台的标题  
 memset(GameMap, '.', sizeof(GameMap));  //初始化地图全部为空'.'  
 system("cls");  
 srand(time(0));   //随机种子  
 hx = rand()%16;    //产生蛇头  
 hy = rand()%30;  
 GameMap[hx][hy] = Shead;  
 Snake[0].x = hx;  Snake[0].y = hy;  
 Snake[0].now = -1;  
 Create_Food();   //随机产生食物  
 for(i = 0; i < 16; i++)   //地图显示  
 {   
  for(j = 0; j < 30; j++)  
   printf(" %c", GameMap[i][j]);  
   printf("
");  
 }  

 printf("
			小小C语言贪吃蛇
");  
 printf("		     按任意方向键开始游戏
");  

 getch();   //先接受一个按键,使蛇开始往该方向走  
 Button();  //取出按键,并判断方向  
}  
void Create_Food()  //在地图上随机产生食物  
{  
 int fx, fy;  
 while(1)  
 {  
  fx = rand()%16;  
     fy = rand()%30;  

  if(GameMap[fx][fy] == '.')  //不能出现在蛇所占有的位置  
  {   
   GameMap[fx][fy] = Sfood;  
      break;  
  }  
 }  
}  
void Show()  //刷新显示地图  
{  
 int i, j;  
 while(1)  
 {    
  _sleep(250); //延迟半秒(1000为1s),即每半秒刷新一次地图  
  Button();   //先判断按键在移动  
  Move();  
  if(over)  //自吃或碰墙即游戏结束  
  {   
   printf("
**游戏结束**
");  
   printf("			>_<
");  
   getchar();  
      break;  
  }  
  system("cls");   //清空地图再显示刷新吼的地图  
  for(i = 0; i < 16; i++)   
  {   
   for(j = 0; j < 30; j++)  
    printf(" %c", GameMap[i][j]);  
   printf("
");  
  }  

  printf("
小小C语言贪吃蛇
");  
  printf("按任意方向键开始游戏
");  
 }  
}  
void Button()  //取出按键,并判断方向  
{  
 if(kbhit() != 0) //检查当前是否有键盘输入,若有则返回一个非0值,否则返回0  
 {   
  while(kbhit() != 0)  //可能存在多个按键,要全部取完,以最后一个为主  
      key = getch(); //将按键从控制台中取出并保存到key中  
  switch(key)  
  {   //
   case 75:  Snake[0].now = 0;  
          break;  
            //
   case 77:  Snake[0].now = 1;       
          break;  
            //
   case 72:  Snake[0].now = 2;  
          break;  
            //
   case 80:  Snake[0].now = 3;  
          break;  
  }  
 }  
}  
void Move()   //蛇的移动  
{  
 int i, x, y;  
    int t = sum;  //保存当前蛇的长度  
 //记录当前蛇头的位置,并设置为空,蛇头先移动  
 x = Snake[0].x;  y = Snake[0].y;  GameMap[x][y] = '.';  
 Snake[0].x = Snake[0].x + dx[ Snake[0].now ];  
 Snake[0].y = Snake[0].y + dy[ Snake[0].now ];  
 Check_Border();   //蛇头是否越界  
 Check_Head(x, y);  //蛇头移动后的位置情况,参数为: 蛇头的开始位置  
 if(sum == t)  //未吃到食物即蛇身移动哦  
    for(i = 1; i < sum; i++)  //要从蛇尾节点向前移动哦,前一个节点作为参照  
 {  
  if(i == 1)   //尾节点设置为空再移动  
   GameMap[ Snake[i].x ][ Snake[i].y ] = '.';  

  if(i == sum-1)  //为蛇头后面的蛇身节点,特殊处理  
  {  
   Snake[i].x = x;  
         Snake[i].y = y;  
      Snake[i].now = Snake[0].now;  
  }  
  else   //其他蛇身即走到前一个蛇身位置  
  {  
   Snake[i].x = Snake[i+1].x;  
         Snake[i].y = Snake[i+1].y;  
      Snake[i].now = Snake[i+1].now;  
  }  

  GameMap[ Snake[i].x ][ Snake[i].y ] = '#'; //移动后要置为'#'蛇身   
 }  
}  
void Check_Border()  //检查蛇头是否越界  
{  
 if(Snake[0].x < 0 || Snake[0].x >= 16  
 || Snake[0].y < 0 || Snake[0].y >= 30)  
     over = 1;  
}  
void Check_Head(int x, int y)  //检查蛇头移动后的位置情况  
{  

 if(GameMap[ Snake[0].x ][ Snake[0].y ] == '.')  //为空  
  GameMap[ Snake[0].x ][ Snake[0].y ] = '@';  
 else 
  if(GameMap[ Snake[0].x ][ Snake[0].y ] == '*')  //为食物  
  {  
   color(arr);
   GameMap[ Snake[0].x ][ Snake[0].y ] = '@';    
   Snake[sum].x = x;   //新增加的蛇身为蛇头后面的那个  
      Snake[sum].y = y;  
      Snake[sum].now = Snake[0].now;  
      GameMap[ Snake[sum].x ][ Snake[sum].y ] = '#';   
   sum++;  
   Create_Food();  //食物吃完了马上再产生一个食物 

  }  
  else 
   over = 1;  
}
原文地址:https://www.cnblogs.com/TimVerion/p/11188606.html