| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1023 人关注过本帖
标题:一个贪吃蛇的游戏,请高手帮忙修改一下
只看楼主 加入收藏
八画小子
Rank: 11Rank: 11Rank: 11Rank: 11
等 级:贵宾
威 望:37
帖 子:709
专家分:2063
注 册:2010-11-11
结帖率:96.55%
收藏
 问题点数:0 回复次数:1 
一个贪吃蛇的游戏,请高手帮忙修改一下
我写了一个贪吃蛇的游戏,几乎没有考虑界面的问题,只是想实现功能。但问题非常多,请各位高手帮忙修改一下。我知道的问题就有三个,但不限于这些。
1、按下空格之后,即便不动他,程序在一段时间后就会异常,是不是越界了。?
2、吃下一个豆子后,键盘的输入和处理就不协调了,是不是得得用多线程编写?
3、这也是我无法理解的,每一次吃下一颗豆子之后,右上角就会出现描绘出的一块,一段时间后会消失,但我没有这么设计啊
如果能够帮我在代码中修改,更好。谢谢各位高手
程序代码:
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.' \
                version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' \
                language='*'\"")

#include <windows.h>

const int    MAX = 35;
const int    INITIALLENGTH = 19;
const int    iRectSide = 20;
const int    IDT_TIMER1 = 1;
const int    IDT_TIMER2 = 2;

enum SnakeDirection
{
    UP        = 0,
    DOWN    = 1,
    LEFT    = 2,
    RIGHT    = 3,
};

enum SnakeStatus
{
    STOP    = 0,
    RUN        = 1,
    PAUSE    = 2,
};

struct SnakeBody
{
    int x;
    int y;
};

struct Snake
{
    SnakeDirection        direction;
    SnakeStatus            status;
    int                    iBodyNum;
    int                    iHead;
    int                    iTail;
    SnakeBody            bodys[MAX * MAX];               
};

static Snake        snake;
static SnakeBody    bean;

static SnakeDirection keyboardInput = RIGHT;

static HRGN            hRgnSnake;
static HRGN            hRgnBean;
static HRGN            hRgnEmpty = CreateRectRgn(0, 0, 0, 0);
HRGN                hRgnNewBody;

LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
    static TCHAR        szAppName[] = TEXT ("Snake");        // 添加
    HWND                hwnd;
    MSG                    msg;
    WNDCLASSEX            wndclassex = {0};

    wndclassex.cbSize                = sizeof(WNDCLASSEX);
    wndclassex.style                = CS_HREDRAW | CS_VREDRAW;
    wndclassex.lpfnWndProc            = WndProc;
    wndclassex.cbClsExtra            = 0;
    wndclassex.cbWndExtra            = 0;
    wndclassex.hInstance            = hInstance;
    wndclassex.hIcon                = LoadIcon (NULL, IDI_APPLICATION);
    wndclassex.hCursor                = LoadCursor (NULL, IDC_ARROW);
    wndclassex.hbrBackground        = (HBRUSH) GetStockObject (WHITE_BRUSH);
    wndclassex.lpszMenuName            = NULL;
    wndclassex.lpszClassName        = szAppName;
    wndclassex.hIconSm                = wndclassex.hIcon;
   
    if (!RegisterClassEx (&wndclassex))
    {
        MessageBox (NULL, TEXT ("RegisterClassEx failed!"), szAppName, MB_ICONERROR);
        return 0;
    }

    hwnd = CreateWindowEx (WS_EX_OVERLAPPEDWINDOW,
                           szAppName,
                           TEXT ("Snake"),                    // 添加
                           WS_OVERLAPPEDWINDOW & ~WS_MAXIMIZEBOX & ~WS_THICKFRAME,
                           CW_USEDEFAULT,
                           CW_USEDEFAULT,
                           (MAX + 1) * iRectSide,
                           (MAX + 2) * iRectSide,
                           NULL,
                           NULL,
                           hInstance,
                           NULL);
                         
    ShowWindow (hwnd, iCmdShow);
    UpdateWindow (hwnd);

    while (GetMessage (&msg, NULL, 0, 0))
    {
        TranslateMessage (&msg);
        DispatchMessage (&msg);
    }
    return msg.wParam;
}

VOID CreateSnake(HWND hwnd, Snake & snake);
VOID RunSnake(HWND hwnd, Snake & snake, SnakeBody & bean);
VOID FindSnakeRgn(HWND hwnd, Snake & snake);
VOID ThrowBean(HWND hwnd, SnakeBody & bean);

LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    HDC                    hdc;
    PAINTSTRUCT            ps;
    HBRUSH                hBrushGray        = (HBRUSH) GetStockObject(GRAY_BRUSH);
    HBRUSH                hBrushGreen        = CreateSolidBrush(RGB(0, 255, 0));

    static int            cxClient, cyClient;

    switch (message)
    {
    case WM_CREATE:
        hdc    = GetDC (hwnd);
        CreateSnake(hwnd, snake);
        ReleaseDC (hwnd, hdc);       
        ThrowBean(hwnd, bean);
        return 0;

    case WM_SIZE:
        cxClient = LOWORD(lParam);
        cyClient = HIWORD(lParam);
        return 0;

    case WM_PAINT:
        hdc = BeginPaint (hwnd, &ps);
        for (int x = 1; x <= MAX; ++x)
        {
            MoveToEx(hdc, x * iRectSide, 0, NULL);
            LineTo(hdc, x * iRectSide, MAX * iRectSide);
        }
        for (int y = 1; y <= MAX; ++y)
        {
            MoveToEx(hdc, 0, y * iRectSide, NULL);
            LineTo(hdc, MAX * iRectSide, y * iRectSide);
        }
        FindSnakeRgn(hwnd, snake);
        SelectObject(hdc, hRgnSnake);
        FillRgn(hdc, hRgnSnake, hBrushGray);
        SelectObject(hdc, hRgnBean);
        FillRgn(hdc, hRgnBean, hBrushGreen);
        EndPaint (hwnd, &ps);
        return 0;

    case WM_KEYDOWN:
        switch (wParam)
        {
        case VK_SPACE:
            if (snake.status == PAUSE)
            {
                SetTimer(hwnd, IDT_TIMER2, 200, NULL);
                snake.status = RUN;
            }
            else
            {
                KillTimer(hwnd, IDT_TIMER2);
                snake.status = PAUSE;
            }
            break;

        case VK_UP:
            keyboardInput = UP;
            break;

        case VK_DOWN:
            keyboardInput = DOWN;
            break;

        case VK_LEFT:
            keyboardInput = LEFT;
            break;

        case VK_RIGHT:
            keyboardInput    = RIGHT;
            break;       
        }
        return 0;

    case WM_TIMER:
        if(snake.status)
        {
            RunSnake(hwnd, snake, bean);
            InvalidateRect(hwnd, NULL, TRUE);
        }
        return 0;

    case WM_CLOSE:
        snake.status = PAUSE;
        KillTimer(hwnd, IDT_TIMER2);
        if(IDYES == MessageBox(hwnd, TEXT("你真的不玩了吗?"), TEXT("Snake"), MB_YESNO | MB_ICONQUESTION | MB_DEFBUTTON2))
            DestroyWindow(hwnd);
        return 0;

    case WM_DESTROY:
        DeleteObject(hBrushGray);
        DeleteObject(hBrushGreen);
        DeleteObject(hRgnSnake);
        DeleteObject(hRgnBean);
        DeleteObject(hRgnEmpty);
        DeleteObject(hRgnNewBody);
        PostQuitMessage (0);
        return 0;
    }
   
    return DefWindowProc (hwnd, message, wParam, lParam);
}

VOID CreateSnake(HWND hwnd, Snake & snake)
{
    snake.status        = PAUSE;
    snake.direction        = RIGHT;
    snake.iBodyNum        = INITIALLENGTH;
    snake.iHead            = INITIALLENGTH - 1;
    snake.iTail            = 0;
    hRgnSnake = hRgnEmpty;
    for (int i = 0; i < INITIALLENGTH; ++i)
    {
        snake.bodys[i].x = (MAX - INITIALLENGTH) / 2  - 1 + i;
        snake.bodys[i].y = MAX / 2;
        hRgnNewBody = CreateRectRgn(snake.bodys[i].x * iRectSide, snake.bodys[i].y * iRectSide, (snake.bodys[i].x + 1) * iRectSide, (snake.bodys[i].y + 1) * iRectSide);
        CombineRgn(hRgnSnake, hRgnNewBody, hRgnSnake, RGN_OR);
    }

    //InvalidateRect(hwnd, NULL, TRUE);
}

VOID RunSnake(HWND hwnd, Snake & snake, SnakeBody & bean)
{
    SnakeBody newBody, oldBody, tempBody;

    switch (keyboardInput)
    {
    case UP:
        if(snake.direction != DOWN)
        {
            tempBody.x = snake.bodys[snake.iBodyNum - 1].x;
            tempBody.y = snake.bodys[snake.iBodyNum - 1].y - 1;
            snake.direction = keyboardInput;
        }
        else
            tempBody = snake.bodys[snake.iBodyNum - 1];
        break;

    case DOWN:
        if(snake.direction != UP)
        {
            tempBody.x = snake.bodys[snake.iBodyNum - 1].x;
            tempBody.y = snake.bodys[snake.iBodyNum - 1].y + 1;
            snake.direction = keyboardInput;
        }       
        else
            tempBody = snake.bodys[snake.iBodyNum - 1];
        break;

    case LEFT:
        if(snake.direction != RIGHT)
        {
            tempBody.x = snake.bodys[snake.iBodyNum - 1].x - 1;
            tempBody.y = snake.bodys[snake.iBodyNum - 1].y;
            snake.direction = keyboardInput;
        }   
        else
            tempBody = snake.bodys[snake.iBodyNum - 1];
        break;

    case RIGHT:
        if(snake.direction != LEFT)
        {
            tempBody.x = snake.bodys[snake.iBodyNum - 1].x + 1;
            tempBody.y = snake.bodys[snake.iBodyNum - 1].y;
            snake.direction = keyboardInput;
        }   
        else
            tempBody = snake.bodys[snake.iBodyNum - 1];
        break;
    }

    newBody.x = (tempBody.x + MAX) % MAX;
    newBody.y = (tempBody.y + MAX) % MAX;

    oldBody = snake.bodys[snake.iTail];

    if(newBody.x == bean.x && newBody.y == bean.y)
    {
        snake.iBodyNum += 1;
        hRgnBean = hRgnEmpty;
        ThrowBean(hwnd, bean);
    }
    else
        snake.iTail += 1;

    for (int i = snake.iTail; i < snake.iHead; ++i)
        if(newBody.x == snake.bodys[i].x && newBody.y == snake.bodys[i].y)
        {
            snake.status = STOP;
            if(IDYES == MessageBox(hwnd, TEXT("你太贪吃了,都咬到自己了!你是否要重新开始?"), TEXT("Snake"), MB_YESNO | MB_ICONQUESTION | MB_DEFBUTTON2))
            {
                SendMessage(hwnd, WM_CREATE, 0, 0);
                return;
            }
            else
                SendMessage(hwnd, WM_CLOSE, 0, 0);
        }

    if (snake.iHead == MAX * MAX - 1)
        for (int i = 0, j = snake.iTail; j <= snake.iHead; ++i, ++j)
            snake.bodys[i] = snake.bodys[j];
    snake.bodys[snake.iBodyNum] = newBody;
    snake.iBodyNum += 1;
    snake.iHead += 1;

    //InvalidateRect(hwnd, NULL, TRUE);
}

VOID FindSnakeRgn(HWND hwnd, Snake & snake)
{
    hRgnSnake = CreateRectRgn(0, 0, 0, 0);
    for (int i = snake.iTail; i <= snake.iHead; ++i)
    {
        hRgnNewBody = CreateRectRgn(snake.bodys[i].x * iRectSide, snake.bodys[i].y * iRectSide, (snake.bodys[i].x + 1) * iRectSide, (snake.bodys[i].y + 1) * iRectSide);
        CombineRgn(hRgnSnake, hRgnNewBody, hRgnSnake, RGN_OR);
    }
    //InvalidateRect(hwnd, NULL, TRUE);
}

VOID ThrowBean(HWND hwnd, SnakeBody & bean)
{
    loop:
        bean.x = rand()    % MAX;
        bean.y = rand() % MAX;
        for (int i = snake.iTail; i <= snake.iHead; ++i)
            if(bean.x == snake.bodys[i].x && bean.y == snake.bodys[i].y)
                goto loop;
    hRgnBean = CreateRectRgn(bean.x * iRectSide, bean.y * iRectSide, (bean.x + 1) * iRectSide, (bean.y + 1) * iRectSide);
    //InvalidateRect(hwnd, NULL, TRUE);
}
搜索更多相关主题的帖子: 游戏 comment 贪吃蛇 多线程 
2011-10-06 22:30
tsyking
Rank: 2
等 级:论坛游民
帖 子:23
专家分:50
注 册:2007-6-12
收藏
得分:0 
最好要用多线程去编程,,,
要不就用加一个计时器,,让蛇的动作用计时器去作就好了

  www . vckf  .net   专业的VC开发网站
2011-10-26 10:24
快速回复:一个贪吃蛇的游戏,请高手帮忙修改一下
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.028410 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved