贪吃蛇

作者在 2009-03-10 14:13:30 发布以下内容
/*
  Name:贪吃蛇
  Copyright:
  Author: 随心
  Date: 08-02-08 22:43
  Description: dev-cpp 4.2.2.9 下编译通过
  更改记录:2008年2月9日 晚,第二关增加动态食物,增加支持最大化
*/
#include <stdio.h>
#include <windows.h>
#include <time.h>
#include <stdlib.h>
#define MAXLEN 35
#define HARD 1  //初始难度
#define true 1
#define false 0
/****定义结构体****/
typedef struct point
{
        int x;
        int y;   
}point;
/****函数声明****/
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
int GameOver(HWND *);
int IsPause(); 
void SetRandomPt(HWND*);  //设置“食物”的位置
void DrawBknd(HWND *);          
void DrawSnake(HWND *);     //画蛇身
void DrawRandomPt(HWND *);
void Move(HWND *);
void MoveUp();
void MoveDown();
void MoveLeft();
void MoveRight();
void SetNowWay(int);
int GetNowWay();
void Start(HWND *pWnd);
void MoveRandomPt(HWND *);
/****变量声明****/
char szClassName[ ] = "WindowsApp";
HWND hwnd;      /* This is the handle for our window */      
int isstop;
int snake_len;  //蛇身长度
point pt[MAXLEN];       //蛇节点数
point randPt;
int nowway;     //当前方向
int hard;
int speed;
int mark;
int totaltime;
/****主函数****/
int WINAPI WinMain (HINSTANCE hThisInstance,
                    HINSTANCE hPrevInstance,
                    LPSTR lpszArgument,
                    int nFunsterStil)
{       
        MSG messages;            /* Here messages to the application are saved */
        WNDCLASSEX wincl;        /* Data structure for the windowclass */
       
        /* The Window structure */
        wincl.hInstance = hThisInstance;
        wincl.lpszClassName = szClassName;
        wincl.lpfnWndProc = WindowProcedure;      /* This function is called by windows */
        wincl.style = CS_DBLCLKS;                 /* Catch double-clicks */
        wincl.cbSize = sizeof (WNDCLASSEX);
       
        /* Use default icon and mouse-pointer */
        wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
        wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
        wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
        wincl.lpszMenuName = NULL;                 /* No menu */
        wincl.cbClsExtra = 0;                      /* No extra bytes after the window class */
        wincl.cbWndExtra = 0;                      /* structure or the window instance */
        /* Use Windows's default color as the background of the window */
        wincl.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
       
        /* Register the window class, and if it fails quit the program */
        if (!RegisterClassEx (&wincl))
                return 0;
       
        /* The class is registered, let's create the program*/
        hwnd = CreateWindowEx (
                0,                   /* Extended possibilites for variation */
                szClassName,         /* Classname */
                "贪吃蛇(C&SDK版) V1.1 编程讨论群:21035626 2008年2月9日 晚 by 随心",
                WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_OVERLAPPEDWINDOW, //窗口风格
                260,       /* Windows decides the position */
                100,       /* where the window ends up on the screen */
                518,                 /* The programs width */
                425,                 /* and height in pixels */
                HWND_DESKTOP,        /* The window is a child-window to desktop */
                NULL,                /* No menu */
                hThisInstance,       /* Program Instance handler */
                NULL                 /* No Window Creation data */
                );
       
        /* Make the window visible on the screen */
        ShowWindow (hwnd, SW_MAXIMIZE);
        Start(&hwnd);
   
        /* Run the message loop. It will run until GetMessage() returns 0 */
        while (GetMessage (&messages, NULL, 0, 0))
        {
                /* Translate virtual-key messages into character messages */
                TranslateMessage(&messages);
                /* Send message to WindowProcedure */
                DispatchMessage(&messages);
        }
       
        /* The program return-value is 0 - The value that PostQuitMessage() gave */
        return messages.wParam;
}
/****回调函数****/
/*  This function is called by the Windows function DispatchMessage()  */
LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
        switch (message)                  /* handle the messages */
        {
        case WM_DESTROY:
                PostQuitMessage (0);       /* send a WM_QUIT to the message queue */
                break;
        case WM_PAINT:
                DrawBknd(&hwnd);
                DrawRandomPt(&hwnd);
                DrawSnake(&hwnd);
                break;  
        case WM_TIMER:
                if (isstop)
                        break;
                if (wParam == 1)
                {
                        switch(GetNowWay())
                        {
                                case 4:
                                        MoveRight();
                                        break;
                                case 2:
                                        MoveDown();
                                        break;
                                case 3:
                                        MoveLeft();
                                        break;
                                case 1:
                                        MoveUp();
                                        break;
                        }
                        GameOver(&hwnd);
                        Move(&hwnd);
                        if (hard >= 2)
                                MoveRandomPt(&hwnd);
                        SendMessage(hwnd, WM_PAINT, 0, 0); 
                }
                break; 
        case WM_KEYDOWN:
                if (wParam == VK_UP)
                        SetNowWay(1);
                else if (wParam == VK_DOWN)
                        SetNowWay(2);
                else if (wParam == VK_LEFT)
                        SetNowWay(3);
                else if (wParam == VK_RIGHT)
                        SetNowWay(4);
                else if (wParam == VK_SPACE)
                        isstop = !isstop;
                else if (wParam == VK_F2)
                        Start(&hwnd);
                break;                                                                                     
        }
       
        return DefWindowProc (hwnd, message, wParam, lParam);
}
/*初始化游戏数据*/
void Start(HWND *pWnd)
{             
        isstop = false;
        snake_len = 3;  //初始蛇身长度
        nowway = 4;     //初始方向
        hard = HARD;       //初始难度
        speed = 400;    //初始速度,越小越快
        mark = 0;       //初始分数
        totaltime = 0;  //初始游戏时间
        
        int ix = 0;
        for ( ; ix != snake_len; ++ix)
        {
                pt[ix].x = snake_len - ix - 2;
                pt[ix].y = 0;
        }
       
        srand(time(0)); //随机数种子
        SetRandomPt(pWnd);      
        SetTimer(*pWnd,1,speed,NULL);          
}
/****设置食物位置****/
void SetRandomPt(HWND *pWnd)
{
        RECT rect;
        GetClientRect(*pWnd, &rect);
        int x, y;
rerand: x = rand() % rect.right / 30;
        y = rand() % rect.bottom / 30;         
        int ix = 0;
        for ( ; ix != snake_len; ++ix)
                if (x == pt[ix].x && y == pt[ix].y)
                        if (hard == 2)
                        {
                                if (x < rand() % 16 && y > rand() % 12)
                                        goto rerand; 
                        }
                        else
                                goto rerand;
        randPt.x = x;
        randPt.y = y;
}
/****画蛇****/
void DrawSnake(HWND *pWnd)
{
        HDC dc = GetDC(*pWnd);
        HBRUSH brush;
        brush = CreateSolidBrush(RGB(50, 150, 0));
        HBRUSH temp_brush = (HBRUSH)SelectObject(dc, brush);
                     
        int ix = 1;
        for ( ; ix != snake_len; ++ix)  //开始画蛇身
        {
                Ellipse(dc, pt[ix].x * 30 + 3, pt[ix].y * 30 + 3,
                        pt[ix].x * 30 + 33, pt[ix].y * 30 + 33);
        }     
                 
        HBRUSH brushHead;       //画蛇头
        brushHead = CreateSolidBrush(RGB(243,177,48));
        SelectObject(dc, brushHead);
        Ellipse(dc, pt[0].x * 30 + 3, pt[0].y * 30 + 3,
                        pt[0].x * 30 + 33, pt[0].y * 30 + 33);
       
        SelectObject(dc, temp_brush);
}
/****画食物****/
void DrawRandomPt(HWND *pWnd)
{
        HDC dc = GetDC(*pWnd);
        HBRUSH brush;
        brush = CreateSolidBrush(RGB(0, 0, 255));
        HBRUSH temp_brush = (HBRUSH)SelectObject(dc, brush);
        Ellipse(dc, randPt.x * 30 + 3, randPt.y * 30 + 3,
                randPt.x * 30 + 33, randPt.y * 30 + 33);
        SelectObject(dc, temp_brush);
}
/****画背景****/
void DrawBknd(HWND *pWnd)
{
        HDC dc = GetDC(*pWnd);
        RECT rect;
        GetClientRect(*pWnd, &rect);      
        HBRUSH temp_brush = (HBRUSH)SelectObject(dc, GetStockObject(BLACK_BRUSH));
 Rectangle(dc, rect.left, rect.top, rect.right, rect.bottom);
 SetTextColor(dc, RGB(255,0,0));
 SetBkMode(dc, TRANSPARENT);
 
 char str[10];
 sprintf(str, "第%d关 得分:%d", hard, mark);
 TextOut(dc, 2, 2, str, strlen(str));
 
 char tim[10];
 sprintf(tim, "用时:%d秒", totaltime/1000);
 TextOut(dc, 2, 20, tim, strlen(tim));
 
 TextOut(dc, 2, 40, "空格暂停", strlen("空格暂停"));
 //TextOut(dc, 2, 60, "F2重新开始", strlen("F2重新开始"));
 
 char *help = "共六关";
        TextOut(dc, rect.right - 50, 2, help, strlen(help));
       
 char *info1 = "C/SDK/C++/MFC/算法/ 讨论群欢迎你的加入!期待高手,打造精英团队!";
 char *info2 = "我们的口号:超越自己,共同进步. 主群号:21035626 联盟论坛:http://yzfy.org";
 SetTextColor(dc,RGB(200,200,200));
 TextOut(dc, 2, rect.bottom - 44,  info1, strlen(info1));
 TextOut(dc, 2, rect.bottom - 22,  info2, strlen(info2));
 
}
/****得到当前运动方向****/
int GetNowWay()
{
        return nowway;
}
/****关卡****/
void HardStep(HWND *pWnd)
{
        if (mark == 50)
        {
                isstop = true;
                MessageBox(*pWnd, "恭喜你进入第二关\n获得100分奖励", ":-)",
                        MB_OK|MB_ICONINFORMATION);
                isstop = false;
                mark += 100;
                hard = 2;
                SetTimer(*pWnd, 1, speed - 100, NULL);                
        }
        else if (mark == 250)
        {
                isstop = true;
                MessageBox(*pWnd, "恭喜你进入第三关\n获得200分奖励", ":-)",
                        MB_OK|MB_ICONINFORMATION);
                isstop = false;
                mark += 200;
                hard = 3;
                SetTimer(*pWnd, 1, speed - 200, NULL);               
        }
        else if (mark == 650)
        {
                isstop = true;
                MessageBox(*pWnd, "恭喜你进入第四关\n获得300分奖励", ":-)",
                        MB_OK|MB_ICONINFORMATION);
                isstop = false;
                mark += 300;
                hard = 4;
                snake_len = 5;
                SetTimer(*pWnd, 1, speed - 250, NULL);                
        }
        else if (mark == 1050)
        {
                isstop = true;
                MessageBox(*pWnd, "恭喜你进入第五关\n获得500分奖励", ":-)",
                        MB_OK|MB_ICONINFORMATION);
                isstop = false;
                mark += 500;
                hard = 5;
                SetTimer(*pWnd, 1, speed - 270, NULL);             
        }
        else if (mark == 1600)
        {
                isstop = true;
                MessageBox(*pWnd, "恭喜你进入第六关\n获得1000分奖励", ":-)",
                        MB_OK|MB_ICONINFORMATION);
                isstop = false;
                mark += 1000;
                hard = 6;
                SetTimer(*pWnd, 1, speed - 290, NULL);              
        }
        else if (mark == 2650)
        {
                mark += 2350;
                char str[100];
                sprintf(str, "你羸了!\nYou are greate!\n得分%d用时 %d 秒\n欢迎你到QQ群:21035626来坐坐", totaltime/1000, mark);
                MessageBox(*pWnd, str, "贪吃蛇", MB_OK|MB_ICONINFORMATION);
                isstop = true;
        }
               
}
/****统计游戏时间****/
void StTime()
{
        if (hard == 1)
                totaltime += speed;
        else if (hard == 2)
                totaltime += (speed - 100);
        else if (hard == 3)
                totaltime += (speed - 200);
        else if (hard == 4)
                totaltime += (speed - 350);
        else if (hard == 5)
                totaltime += (speed - 270);
        else if (hard == 6)
                totaltime += (speed - 290);       
}
/****开始移动****/
void Move(HWND *pWnd)
{
        HardStep(pWnd); // 注意: 不要写成了*pWnd
        StTime();                
        int x = randPt.x;
        int y = randPt.y;            
        if (x == pt[0].x &&  y == pt[0].y)      //如果蛇头和食物相遇
        {
                ++snake_len;
                int ix = 1;                      
         for ( ; ix != snake_len; ++ix)
         {
          pt[snake_len-ix].x = pt[snake_len-ix-1].x;
          pt[snake_len-ix].y = pt[snake_len-ix-1].y;
         } 
         SetRandomPt(pWnd); //食物被吃掉以后重新设置食物位置
         mark += 10;
        }
}
/****向上移动****/
void MoveUp()
{
        int ix = 1;
        for ( ; ix != snake_len; ++ix)
 {
  pt[snake_len-ix].x = pt[snake_len-ix-1].x;
  pt[snake_len-ix].y = pt[snake_len-ix-1].y;
 }
 --pt[0].y;
 nowway = 1;       
}
/****向下移动****/
void MoveDown()
{
        int ix = 1;
        for ( ; ix != snake_len; ++ix)
 {
  pt[snake_len-ix].x = pt[snake_len-ix-1].x;
  pt[snake_len-ix].y = pt[snake_len-ix-1].y;
 }
 ++pt[0].y;
 nowway = 2;       
}
/****向左移动****/
void MoveLeft()
{
        int ix = 1;
        for ( ; ix != snake_len; ++ix)
 {
  pt[snake_len-ix].x = pt[snake_len-ix-1].x;
  pt[snake_len-ix].y = pt[snake_len-ix-1].y;
 }
 --pt[0].x;
 nowway = 3;       
}
/****向右移动****/
void MoveRight()
{
        int ix = 1;
        for ( ; ix != snake_len; ++ix)
 {
  pt[snake_len-ix].x = pt[snake_len-ix-1].x;
  pt[snake_len-ix].y = pt[snake_len-ix-1].y;
 }
 ++pt[0].x;
 nowway = 4;
}
/****设置当前运动方向****/
void SetNowWay(int nw)
{
        nowway = nw;
}
/****随机移动的食物 2008年2月9日 晚添加****/
void MoveRandomPt(HWND *pWnd)
{
        RECT rect;
        GetClientRect(*pWnd, &rect);
 int x, y;
 if (hard ==2)
 {
        re1: x = rand() % 17;
         y = rand() % 13;
        }
        else
        {
        re2:    x = rand() % rect.right / 30;
                y = rand() % rect.bottom / 30;
        }
 int ix = 0;
 for ( ; ix != snake_len; ++ix)
  if (x == pt[ix].x && y == pt[ix].y && x != randPt.x && y != randPt.y)
        if (hard == 2)
                goto re1;
        else
                goto re2;  
 if (x < randPt.x)
  --randPt.x;
 else if (randPt.x < x)
  ++randPt.x;
 if (y < randPt.y)
  --randPt.y;
 else if (y > randPt.y)
  ++randPt.y;
}
/****判断是否结束****/
int GameOver(HWND *pWnd)
{
        RECT rect;
        GetClientRect(*pWnd, &rect);
        char str[50];
        sprintf(str, "GameOver\n第%d关,得分%d,用时 %d 秒\n按F2键重新开始",
                hard, mark, totaltime/1000);
        if (pt[0].x < 0 || pt[0].x > rect.right / 30 || pt[0].y < 0 ||
                 pt[0].y > rect.bottom / 30)
        {
                KillTimer(*pWnd, 1);
                MessageBox(*pWnd, str, ":-(", MB_OK|MB_ICONINFORMATION);
                isstop = true;
        }
        else
        {
                int x = pt[0].x, y = pt[0].y;
                int ix = 1;
                for ( ; ix != snake_len ; ++ix)
                        if (x == pt[ix].x && y == pt[ix].y)      //如果与蛇身重叠
                        {
                                KillTimer(*pWnd, 1);                               
                                MessageBox(*pWnd, str, ":-(", MB_OK|MB_ICONINFORMATION);
                                isstop = true;  
                        }                        
        }
        return isstop;
}
/////////////////////////////////////////////////////////////////
默认分类 | 阅读 2131 次
文章评论,共0条
游客请输入验证码
浏览27347次
文章分类