parent
be2d9e16cc
commit
60f6078638
|
@ -9,15 +9,14 @@ LRESULT DealBeginMenuMsg( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam
|
|||
static int menuID = 0;
|
||||
static int oldMenuID = 0;
|
||||
|
||||
HDC hdc;
|
||||
HDC hdc;
|
||||
PAINTSTRUCT ps;
|
||||
|
||||
switch( message )
|
||||
{
|
||||
case WM_CREATE:
|
||||
hInst = ((LPCREATESTRUCT)lParam)->hInstance;
|
||||
PlaySound( MAKEINTRESOURCE( IDR_GAME_START ), hInst, SND_RESOURCE | SND_ASYNC | SND_LOOP );
|
||||
SetTimer( hwnd, TMR_BEGIN, 60, NULL );
|
||||
hInst =(HINSTANCE) GetWindowLong( hwnd, GWL_HINSTANCE );
|
||||
PostMessage( hwnd, CM_GAME_READY, 0, 0 );
|
||||
return 0;
|
||||
|
||||
case WM_PAINT:
|
||||
|
@ -26,8 +25,14 @@ LRESULT DealBeginMenuMsg( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam
|
|||
EndPaint( hwnd, &ps );
|
||||
return 0;
|
||||
|
||||
case CM_GAME_READY:
|
||||
SetTimer( hwnd, TMR_BEGIN, 60, NULL );
|
||||
PlaySound( MAKEINTRESOURCE( IDR_GAME_START ), (HINSTANCE)GetWindowLong( hwnd, GWL_HINSTANCE ), SND_RESOURCE | SND_ASYNC | SND_LOOP );
|
||||
return 0;
|
||||
|
||||
case CM_START_GAME:
|
||||
InvalidateRect( hwnd, NULL, TRUE );
|
||||
SetWindowLong( hwnd, GWL_WNDPROC, (long)PlayingProc );
|
||||
SetTimer( hwnd, TMR_PLAYING_READY, 500, NULL ); //开启游戏准备音效定时器
|
||||
PlaySound( NULL, NULL, SND_FILENAME ); //终止当前音效
|
||||
return CM_START_GAME;
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "Init_Begin_UI.h"
|
||||
#include "HelpDialogProc.h"
|
||||
#include "MacroDefine.h"
|
||||
#include "PlayingProc.h"
|
||||
#include "resource.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
#include "GameOverDlgProc.h"
|
||||
#include "MacroDefine.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
LRESULT CALLBACK GameOverProc( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam )
|
||||
{
|
||||
HWND hStatic;
|
||||
LOGFONT lf = {0};
|
||||
HFONT hFont;
|
||||
|
||||
strcpy( lf.lfFaceName, "ËÎÌå" );
|
||||
lf.lfWidth = 30;
|
||||
lf.lfHeight = 50;
|
||||
lf.lfWeight = FW_NORMAL;
|
||||
lf.lfCharSet = GB2312_CHARSET;
|
||||
lf.lfPitchAndFamily = 35;
|
||||
|
||||
hFont = CreateFontIndirect (&lf);
|
||||
|
||||
switch( message )
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
hStatic = CreateWindow( TEXT("static"), TEXT("GAME OVER !"), WS_CHILD | WS_VISIBLE, 25, 50, 400, 50, hDlg, NULL, NULL, NULL );
|
||||
SendMessage( hStatic, WM_SETFONT, (WPARAM)hFont, 0 );
|
||||
return TRUE;
|
||||
|
||||
case WM_COMMAND:
|
||||
switch( LOWORD(wParam) )
|
||||
{
|
||||
case IDC_EXIT_GAME:
|
||||
EndDialog( hDlg, GAME_EXIT );
|
||||
return TRUE;
|
||||
|
||||
case IDC_GAME_AGAIN:
|
||||
EndDialog( hDlg, GAME_AGAIN );
|
||||
return TRUE;
|
||||
|
||||
case IDC_RETURN_MAIN:
|
||||
EndDialog( hDlg, GAME_MAIN );
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
#pragma once
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <windows.h>
|
||||
#include "resource.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
LRESULT CALLBACK GameOverProc( HWND, UINT, WPARAM, LPARAM );
|
|
@ -4,20 +4,16 @@
|
|||
|
||||
LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam )
|
||||
{
|
||||
|
||||
static int gameStatus = CM_UN_START;
|
||||
LRESULT valReturn;
|
||||
|
||||
|
||||
switch( gameStatus )
|
||||
{
|
||||
case CM_UN_START:
|
||||
valReturn = DealBeginMenuMsg( hwnd, message, wParam, lParam );
|
||||
if( valReturn == CM_START_GAME )
|
||||
gameStatus = CM_START_ED;
|
||||
SetWindowLong( hwnd, GWL_WNDPROC, (long)PlayingProc );
|
||||
return valReturn;
|
||||
|
||||
case CM_START_ED:
|
||||
return PlayingProc( hwnd, message, wParam, lParam );
|
||||
}
|
||||
|
||||
return DefWindowProc( hwnd, message, wParam, lParam );
|
||||
|
|
|
@ -2,9 +2,22 @@
|
|||
#include <stdio.h>
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void InitPlayingMap( HWND hwnd, HDC hdc, HINSTANCE hInst )
|
||||
void InitPlayingMap( HWND hwnd, HDC hdc, POINT ptFood, CMAP *gm_map, int level )
|
||||
{
|
||||
HPEN hPen;
|
||||
HBRUSH hBrush;
|
||||
|
||||
hPen = CreatePen( PS_SOLID, 3, RGB(128, 128, 128) );
|
||||
hBrush = CreateSolidBrush( RGB(192, 192, 192) );
|
||||
SelectObject( hdc, hPen );
|
||||
SelectObject( hdc, hBrush );
|
||||
|
||||
DrawBrickWall( hwnd, hdc );
|
||||
DrawRandWall( hwnd, hdc, gm_map, level );
|
||||
DrawRandomFood( hdc, ptFood );
|
||||
|
||||
DeleteObject( hPen );
|
||||
DeleteObject( hBrush );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
@ -62,16 +75,14 @@ void DrawRandWall( HWND hwnd, HDC hdc, CMAP *gm_map, int lev )
|
|||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//绘制随机障碍物
|
||||
void drawWallLine( HDC hdc, int x1, int y1, int x2, int y2 )
|
||||
{
|
||||
int i = 0;
|
||||
int xPos = 0, yPos = 0;
|
||||
|
||||
FILE *fp;
|
||||
fp = fopen( "D:\\a.txt", "a" );
|
||||
fprintf( fp, "%d %d %d %d\n", x1, y1, x2, y2 );
|
||||
fclose( fp );
|
||||
|
||||
if( x2-x1 == 0 )
|
||||
{
|
||||
yPos = y1;
|
||||
|
@ -91,5 +102,25 @@ void drawWallLine( HDC hdc, int x1, int y1, int x2, int y2 )
|
|||
xPos += 10;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//绘制食物
|
||||
void DrawRandomFood( HDC hdc, POINT ptFood )
|
||||
{
|
||||
HPEN hPen;
|
||||
HBRUSH hBrush;
|
||||
|
||||
hPen = GetStockObject( WHITE_PEN );
|
||||
hBrush = CreateSolidBrush( RGB(255, 0, 0) );
|
||||
SelectObject( hdc, hPen );
|
||||
SelectObject( hdc, hBrush );
|
||||
|
||||
Ellipse( hdc, ptFood.x, ptFood.y, ptFood.x+10, ptFood.y+10 );
|
||||
|
||||
DeleteObject( hPen );
|
||||
DeleteObject( hBrush );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -12,10 +12,14 @@
|
|||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void InitPlayingMap( HWND, HDC, HINSTANCE );
|
||||
void InitPlayingMap( HWND, HDC, POINT, CMAP *, int );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void DrawBrickWall( HWND, HDC ); //画四周砖块
|
||||
void DrawBrickWall( HWND, HDC ); //绘制四周砖块
|
||||
|
||||
void DrawRandWall( HWND, HDC, CMAP*, int ); //绘制随机障碍物
|
||||
|
||||
void DrawRandomFood( HDC, POINT ); //绘制食物
|
||||
|
||||
|
||||
void DrawRandWall( HWND, HDC, CMAP*, int ); //随机墙壁
|
||||
|
|
|
@ -3,16 +3,37 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//游戏状态
|
||||
#define CM_UN_START 0 //停留在起始界面
|
||||
#define CM_START_ED 1 //正在进行游戏
|
||||
#define CM_UN_START 0 //停留在起始界面
|
||||
#define CM_START_ED 1 //正在进行游戏
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define CM_START_GAME (WM_USER + 100) //开始游戏消息
|
||||
#define CM_READY_GAME (WM_USER + 100) //准备游戏消息
|
||||
#define CM_START_GAME (WM_USER + 101) //开始游戏消息
|
||||
#define CM_MOVE_SNAKE (WM_USER + 102) //移动蛇身
|
||||
#define CM_GAME_OVER (WM_USER + 103) //游戏结束
|
||||
#define CM_GAME_NEXT (WM_USER + 104) //下一关
|
||||
#define CM_GAME_SUCCEED (WM_USER + 105) //全关成功
|
||||
#define CM_GAME_READY (WM_USER + 106) //游戏准备
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define TMR_BEGIN 10000 //开始界面定时器
|
||||
#define TMR_PLAYING_READY 10001 //播放准备音效
|
||||
#define TMR_PLAYING_GO 10002 //播放开始音效
|
||||
#define TMR_IMPACE_TEST 10003 //碰撞检测正确性测试
|
||||
#define TMR_IMPACE_TEST 10003 //碰撞检测正确性测试
|
||||
|
||||
#define TMR_START_MOVE 10004 //移动蛇身
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define DR_UP 20000 //上移动
|
||||
#define DR_DOWN 20001 //下移动
|
||||
#define DR_LEFT 20002 //左移动
|
||||
#define DR_RIGHT 20003 //右移动
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define GAME_AGAIN 30000 //再来一局
|
||||
#define GAME_MAIN 30001 //回主菜单
|
||||
#define GAME_EXIT 30003 //退出游戏
|
||||
|
|
418
PlayingProc.c
418
PlayingProc.c
|
@ -1,16 +1,19 @@
|
|||
#include "PlayingProc.h"
|
||||
#include "GameWndProc.h"
|
||||
#include "map_data.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void testImpace( HWND hwnd );
|
||||
void testFoodPlace( HWND hwnd );
|
||||
|
||||
static GM_STATUS APP = {
|
||||
TEXT("贪吃蛇"),
|
||||
0,
|
||||
{0},
|
||||
{0},
|
||||
0,
|
||||
{ {20, 20} },
|
||||
{-10, -10},
|
||||
DR_RIGHT,
|
||||
5,
|
||||
0
|
||||
};
|
||||
|
||||
|
@ -20,8 +23,6 @@ LRESULT PlayingProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam )
|
|||
{
|
||||
HDC hdc;
|
||||
PAINTSTRUCT ps;
|
||||
HPEN hPen;
|
||||
HBRUSH hBrush;
|
||||
POINT pt = {0};
|
||||
|
||||
switch( message )
|
||||
|
@ -30,48 +31,34 @@ LRESULT PlayingProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam )
|
|||
switch( wParam )
|
||||
{
|
||||
case TMR_PLAYING_READY:
|
||||
srand( (unsigned int)time(0) );
|
||||
SetTimer( hwnd, TMR_PLAYING_READY, 1000*60, NULL ); //调整定时器为60秒
|
||||
PlaySound( MAKEINTRESOURCE( IDR_READY ), (HINSTANCE)GetWindowLong( hwnd, GWL_HINSTANCE ), SND_RESOURCE | SND_ASYNC );
|
||||
KillTimer( hwnd, TMR_PLAYING_READY );
|
||||
SetTimer( hwnd, TMR_PLAYING_GO, 1500, NULL ); //启动游戏启动定时器
|
||||
GetRandomFoodPlace( hwnd, &APP.food );
|
||||
break;
|
||||
|
||||
case TMR_PLAYING_GO:
|
||||
KillTimer( hwnd, TMR_PLAYING_GO );
|
||||
PlaySound( MAKEINTRESOURCE( IDR_GO ), (HINSTANCE)GetWindowLong( hwnd, GWL_HINSTANCE ), SND_RESOURCE | SND_ASYNC );
|
||||
//SetTimer( hwnd, TMR_IMPACE_TEST, 0, NULL ); //碰撞检测正确性测试
|
||||
//MessageBox( hwnd, TEXT("游戏开始!"), TEXT("消息"), MB_OK );
|
||||
//游戏开始
|
||||
PostMessage( hwnd, CM_START_GAME, 0, 0 );
|
||||
SetTimer( hwnd, TMR_START_MOVE, 200, 0 );
|
||||
break;
|
||||
|
||||
//case TMR_IMPACE_TEST:
|
||||
// testImpace( hwnd );
|
||||
// break;
|
||||
}
|
||||
return 0;
|
||||
|
||||
case WM_PAINT:
|
||||
hdc = BeginPaint( hwnd, &ps );
|
||||
|
||||
hPen = CreatePen( PS_SOLID, 3, RGB(128, 128, 128) );
|
||||
hBrush = CreateSolidBrush( RGB(192, 192, 192) );
|
||||
SelectObject( hdc, hPen );
|
||||
SelectObject( hdc, hBrush );
|
||||
|
||||
InitPlayingMap( hwnd, hdc, (HINSTANCE)GetWindowLong( hwnd, GWL_HINSTANCE ) );
|
||||
//APP.level = 7;
|
||||
DrawRandWall( hwnd, hdc, gm_map, APP.level );
|
||||
|
||||
//APP.pt.x = 100;
|
||||
//APP.pt.y = 100;
|
||||
//PointImpaceTest( hwnd, APP.pt );
|
||||
|
||||
DeleteObject( hPen );
|
||||
DeleteObject( hBrush );
|
||||
|
||||
InitPlayingMap( hwnd, hdc, APP.food, gm_map, APP.level );
|
||||
EndPaint( hwnd, &ps );
|
||||
return 0;
|
||||
|
||||
case CM_START_GAME:
|
||||
SetWindowLong( hwnd, GWL_WNDPROC, (long)StartPlaying );
|
||||
return 0;
|
||||
|
||||
case WM_DESTROY:
|
||||
PostQuitMessage(0);
|
||||
return 0;
|
||||
|
@ -82,11 +69,11 @@ LRESULT PlayingProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam )
|
|||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void getWallLineRect( int, RECT *, RECT * ); //获取地图障碍物i在窗口中的实际位置
|
||||
BOOL borderImpace( RECT, POINT ); //边缘碰撞检测
|
||||
void getWallLineRect( int, RECT *, RECT *, int ); //获取地图障碍物i在窗口中的实际位置
|
||||
BOOL borderImpace( RECT, POINT, int ); //边缘碰撞检测
|
||||
|
||||
//点障碍物的碰撞检测
|
||||
BOOL PointImpaceTest( HWND hwnd, POINT pt )
|
||||
BOOL PointImpaceTest( HWND hwnd, POINT pt, int exc )
|
||||
{
|
||||
int i = 0;
|
||||
RECT rect = {0};
|
||||
|
@ -94,26 +81,30 @@ BOOL PointImpaceTest( HWND hwnd, POINT pt )
|
|||
|
||||
GetClientRect( hwnd, &rect );
|
||||
|
||||
if( borderImpace(rect, pt) ) //边缘碰撞
|
||||
if( borderImpace(rect, pt, exc) ) //边缘碰撞
|
||||
return TRUE;
|
||||
|
||||
for( i; i < 5; i++ )
|
||||
for( i = 0; i < 5; i++ )
|
||||
{
|
||||
getWallLineRect( i, &rect, &line );
|
||||
getWallLineRect( i, &rect, &line, exc );
|
||||
if( line.right - line.left == 0 ) //垂直障碍物
|
||||
if( pt.x > line.left && pt.x < line.left + 10 && pt.y > line.top && pt.y < line.bottom )
|
||||
if( pt.x >= line.left - exc && pt.x < line.left + 10 + exc && \
|
||||
pt.y >= line.top - exc && pt.y < line.bottom + exc )
|
||||
return TRUE;
|
||||
|
||||
|
||||
if( line.bottom - line.top == 0 ) //水平障碍物
|
||||
if( pt.x > line.left && pt.x < line.right && pt.y > line.top && pt.y < line.top + 10 )
|
||||
if( pt.x >= line.left - exc && pt.x < line.right + exc && \
|
||||
pt.y >= line.top - exc && pt.y < line.top + 10 + exc )
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//获取地图障碍物i在窗口中的实际位置
|
||||
void getWallLineRect( int i, RECT *rect, RECT *line )
|
||||
void getWallLineRect( int i, RECT *rect, RECT *line, int exc )
|
||||
{
|
||||
//获取地图数据在窗口中的映射位置
|
||||
line->left = (int)(gm_map[APP.level].line[i].x1 * rect->right); //x1
|
||||
|
@ -122,53 +113,348 @@ void getWallLineRect( int i, RECT *rect, RECT *line )
|
|||
line->bottom = (int)(gm_map[APP.level].line[i].y2 * rect->bottom); //y2
|
||||
|
||||
//添加偏移坐标
|
||||
line->left += 10 - line->left % 10;
|
||||
line->top += 10 - line->top % 10;
|
||||
line->right += 10 - line->right % 10;
|
||||
line->bottom += 10 - line->bottom % 10;
|
||||
if( line->left )
|
||||
{
|
||||
line->left += (10 - line->left % 10);
|
||||
line->top += (10 - line->top % 10);
|
||||
line->right += (10 - line->right % 10);
|
||||
line->bottom += (10 - line->bottom % 10);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//边缘碰撞检测
|
||||
BOOL borderImpace( RECT rect, POINT pt )
|
||||
BOOL borderImpace( RECT rect, POINT pt, int exc )
|
||||
{
|
||||
if( pt.x > rect.right-10 || pt.x < rect.left+10 )
|
||||
if( pt.x > rect.right-20-exc || pt.x < rect.left+10 )
|
||||
return TRUE;
|
||||
|
||||
if( pt.y > rect.bottom-10 || pt.y < rect.top+10 )
|
||||
if( pt.y > rect.bottom-20-exc || pt.y < rect.top+10 )
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
//检测碰撞正确性测试 - 测试结果: 正确
|
||||
void testImpace( HWND hwnd )
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//生成随机食物坐标
|
||||
void GetRandomFoodPlace( HWND hwnd, POINT *ptFood )
|
||||
{
|
||||
int i = 0;
|
||||
int i = 0, x = 0, y = 0;
|
||||
RECT rect = {0}, line = {0};
|
||||
POINT pt = {0};
|
||||
HDC hdc;
|
||||
|
||||
TCHAR szBuffer[28] = {0};
|
||||
wsprintf( szBuffer, "%s %i %s", TEXT("第"), APP.level+1, TEXT("关障碍物碰撞检测") );
|
||||
SetWindowText( hwnd, szBuffer );
|
||||
ptFood->x = ptFood->y = 0;
|
||||
|
||||
SetTimer( hwnd, TMR_IMPACE_TEST, 0, NULL );
|
||||
if( APP.level == 9 )
|
||||
GetClientRect( hwnd, &rect );
|
||||
while( PointImpaceTest( hwnd, *ptFood, 10 ) )
|
||||
{
|
||||
SetWindowText( hwnd, TEXT("贪吃蛇 - 碰撞检测正确性测试完毕") );
|
||||
KillTimer( hwnd, TMR_IMPACE_TEST );
|
||||
x = rand()%rect.right; y = rand()%rect.bottom;
|
||||
ptFood->x = x - x%10; ptFood->y = y - y%10;
|
||||
}
|
||||
hdc = GetDC(hwnd);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int dealKeywordMsg( HWND hwnd, WPARAM ); //处理键盘消息
|
||||
void moveSnake( ); //移动蛇身
|
||||
void eraseNode( HWND, POINT ); //擦除一个蛇身节点
|
||||
void drawSnakeBody( HWND ); //绘制蛇身
|
||||
BOOL testEating( HWND ); //检测食物是否被吃掉
|
||||
void updateGameInfo( HWND ); //更新游戏标题栏信息
|
||||
void resetGameStatus(); //重置游戏状态
|
||||
void nextLevel( HWND ); //下一关
|
||||
BOOL testEatSelf( HWND ); //测试是否吃到自己
|
||||
void gameOver( HWND ); //游戏结束
|
||||
void gameAgain( HWND ); //再来一局
|
||||
|
||||
void startSnakeMove( HWND ); //蛇开始移动(封装移动方法)
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//开始游戏
|
||||
LRESULT CALLBACK StartPlaying( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam )
|
||||
{
|
||||
HDC hdc;
|
||||
PAINTSTRUCT ps;
|
||||
|
||||
switch( message )
|
||||
{
|
||||
case WM_PAINT:
|
||||
hdc = BeginPaint( hwnd, &ps );
|
||||
InitPlayingMap( hwnd, hdc, APP.food, gm_map, APP.level );
|
||||
EndPaint( hwnd, &ps );
|
||||
return 0;
|
||||
|
||||
case WM_TIMER:
|
||||
switch( wParam )
|
||||
{
|
||||
case TMR_START_MOVE:
|
||||
startSnakeMove( hwnd );
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
|
||||
case CM_GAME_OVER:
|
||||
gameOver( hwnd );
|
||||
break;
|
||||
|
||||
case CM_GAME_NEXT:
|
||||
nextLevel( hwnd );
|
||||
break;
|
||||
|
||||
case CM_GAME_SUCCEED:
|
||||
MessageBox( NULL, "ok", "", 0 );
|
||||
break;
|
||||
|
||||
case WM_KEYDOWN:
|
||||
dealKeywordMsg( hwnd, wParam );
|
||||
return 0;
|
||||
|
||||
for( pt.x = 0; pt.x < 800; pt.x++ )
|
||||
for( pt.y = 0; pt.y < 600; pt.y++ )
|
||||
if( !PointImpaceTest(hwnd, pt) )
|
||||
SetPixel( hdc, pt.x, pt.y, RGB(0, 128, 0) );
|
||||
case WM_DESTROY:
|
||||
PostQuitMessage(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return DefWindowProc( hwnd, message, wParam, lParam );
|
||||
}
|
||||
|
||||
Sleep(2000);
|
||||
APP.level ++;
|
||||
InvalidateRect( hwnd, NULL, TRUE );
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//处理键盘消息
|
||||
int dealKeywordMsg( HWND hwnd, WPARAM wParam )
|
||||
{
|
||||
switch( wParam )
|
||||
{
|
||||
case VK_UP:
|
||||
case 'W':
|
||||
if(APP.direction != DR_DOWN) APP.direction = DR_UP; break;
|
||||
|
||||
case VK_DOWN:
|
||||
case 'S':
|
||||
if(APP.direction != DR_UP) APP.direction = DR_DOWN; break;
|
||||
|
||||
case VK_LEFT:
|
||||
case 'A':
|
||||
if(APP.direction != DR_RIGHT) APP.direction = DR_LEFT; break;
|
||||
|
||||
case VK_RIGHT:
|
||||
case 'D':
|
||||
if(APP.direction != DR_LEFT) APP.direction = DR_RIGHT; break;
|
||||
|
||||
case VK_CONTROL:
|
||||
PostMessage( hwnd, WM_TIMER, TMR_START_MOVE, 0 );
|
||||
break;
|
||||
|
||||
case VK_ESCAPE:
|
||||
if ( MessageBox( NULL, TEXT("游戏正在运行, 确定退出吗?"), \
|
||||
TEXT("确认"), MB_OKCANCEL | MB_ICONQUESTION ) == IDOK )
|
||||
PostQuitMessage(0);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//移动蛇身
|
||||
void moveSnake( )
|
||||
{
|
||||
int i = APP.len;
|
||||
for( i; i > 0; i-- )
|
||||
APP.body[i] = APP.body[i-1];
|
||||
|
||||
switch( APP.direction )
|
||||
{
|
||||
case DR_UP:
|
||||
APP.body[0].y -= 10; break;
|
||||
|
||||
case DR_DOWN:
|
||||
APP.body[0].y += 10; break;
|
||||
|
||||
case DR_LEFT:
|
||||
APP.body[0].x -= 10; break;
|
||||
|
||||
case DR_RIGHT:
|
||||
APP.body[0].x += 10; break;
|
||||
}
|
||||
}
|
||||
|
||||
//擦除蛇身的一个节点
|
||||
void eraseNode( HWND hwnd, POINT ptNode )
|
||||
{
|
||||
HDC hdc;
|
||||
HPEN hPen;
|
||||
HBRUSH hBrush;
|
||||
|
||||
hdc = GetDC( hwnd );
|
||||
hPen = CreatePen( PS_SOLID, 3, RGB(0, 0, 0) );
|
||||
hBrush = CreateSolidBrush( RGB(0, 0, 0) );
|
||||
SelectObject( hdc, hPen );
|
||||
SelectObject( hdc, hBrush );
|
||||
|
||||
Rectangle( hdc, ptNode.x, ptNode.y, ptNode.x+10, ptNode.y+10 );
|
||||
|
||||
DeleteObject( hBrush );
|
||||
ReleaseDC( hwnd, hdc );
|
||||
}
|
||||
*/
|
||||
|
||||
//绘制蛇身
|
||||
void drawSnakeBody( HWND hwnd )
|
||||
{
|
||||
int i = 0;
|
||||
HDC hdc;
|
||||
HPEN hPen;
|
||||
HBRUSH hBrush;
|
||||
|
||||
hdc = GetDC( hwnd );
|
||||
hPen = CreatePen( PS_SOLID, 3, RGB(0, 128, 0) );
|
||||
hBrush = CreateSolidBrush( RGB(0, 255, 0) );
|
||||
SelectObject( hdc, hPen );
|
||||
SelectObject( hdc, hBrush );
|
||||
|
||||
for( i; i <= APP.len; i++ )
|
||||
RoundRect( hdc, APP.body[i].x, APP.body[i].y, APP.body[i].x+10, APP.body[i].y+10, 3, 3 );
|
||||
eraseNode( hwnd, APP.body[APP.len] );
|
||||
|
||||
DeleteObject( hPen );
|
||||
DeleteObject( hBrush );
|
||||
ReleaseDC( hwnd, hdc );
|
||||
}
|
||||
|
||||
//检测食物是否被吃掉
|
||||
BOOL testEating( HWND hwnd )
|
||||
{
|
||||
if( APP.food.x == APP.body[0].x && APP.food.y == APP.body[0].y )
|
||||
{
|
||||
PlaySound( MAKEINTRESOURCE( IDR_EATING ), (HINSTANCE)GetWindowLong( hwnd, GWL_HINSTANCE ), SND_RESOURCE | SND_ASYNC );
|
||||
APP.len += 2;
|
||||
APP.score += 10;
|
||||
if( (APP.level == APP.score / 100-1) && (APP.level < 9) )
|
||||
{
|
||||
APP.level++;
|
||||
PostMessage( hwnd, CM_GAME_NEXT, 0, 0 );
|
||||
}
|
||||
|
||||
GetRandomFoodPlace( hwnd, &APP.food );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//更新游戏信息
|
||||
void updateGameInfo( HWND hwnd )
|
||||
{
|
||||
if( APP.score < 1000 )
|
||||
wsprintf( APP.szGameTitle, "贪吃蛇 第 %d 关 得分: %d 进度: %d/10",
|
||||
APP.level + 1, APP.score, APP.score/10%10 );
|
||||
else //第十关以后的无尽模式统计方案
|
||||
wsprintf( APP.szGameTitle, "贪吃蛇 第 %d 关 得分: %d 进度: %d/10",
|
||||
APP.level + 1, APP.score, (APP.score-1000)/10 );
|
||||
SetWindowText( hwnd, APP.szGameTitle );
|
||||
}
|
||||
|
||||
//重置游戏状态
|
||||
void resetGameStatus()
|
||||
{
|
||||
int i = APP.len;
|
||||
APP.direction = DR_RIGHT;
|
||||
|
||||
APP.body[0].x = 10; APP.body[0].y = 20;
|
||||
APP.food.x = -10; APP.food.y = -10;
|
||||
|
||||
for( i; i > 0; i-- )
|
||||
{
|
||||
APP.body[i].x = APP.body[0].x;
|
||||
APP.body[i].y = APP.body[0].y;
|
||||
}
|
||||
}
|
||||
|
||||
//下一关
|
||||
void nextLevel( HWND hwnd )
|
||||
{
|
||||
PlaySound( MAKEINTRESOURCE( IDR_NEXT ), (HINSTANCE)GetWindowLong( hwnd, GWL_HINSTANCE ), SND_RESOURCE | SND_ASYNC );
|
||||
resetGameStatus();
|
||||
InvalidateRect( hwnd, NULL, TRUE );
|
||||
}
|
||||
|
||||
//测试是否吃到自己
|
||||
BOOL testEatSelf( HWND hwnd )
|
||||
{
|
||||
int i = APP.len;
|
||||
for( i; i > 0; i-- )
|
||||
if( APP.body[0].x == APP.body[i].x && APP.body[0].y == APP.body[i].y )
|
||||
{
|
||||
PostMessage( hwnd, CM_GAME_OVER, 0, 0 );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//游戏结束
|
||||
void gameOver( HWND hwnd )
|
||||
{
|
||||
int menuID = 0;
|
||||
|
||||
KillTimer( hwnd, TMR_START_MOVE );
|
||||
PlaySound( MAKEINTRESOURCE( IDR_GAME_OVER ), (HINSTANCE)GetWindowLong( hwnd, GWL_HINSTANCE ), SND_RESOURCE );
|
||||
InvalidateRect( hwnd, NULL, TRUE );
|
||||
|
||||
menuID = DialogBox(
|
||||
(HINSTANCE)GetWindowLong( hwnd, GWL_HINSTANCE ),
|
||||
MAKEINTRESOURCE(IDD_GAMEOVER_DLG),
|
||||
hwnd, GameOverProc
|
||||
);
|
||||
|
||||
switch( menuID )
|
||||
{
|
||||
case GAME_AGAIN:
|
||||
gameAgain( hwnd );
|
||||
break;
|
||||
|
||||
case GAME_MAIN:
|
||||
SetWindowLong( hwnd, GWL_WNDPROC, (long)DealBeginMenuMsg );
|
||||
PostMessage( hwnd, CM_GAME_READY, 0, 0 );
|
||||
resetGameStatus();
|
||||
APP.level = 0; APP.score = 0;
|
||||
InvalidateRect( hwnd, NULL, TRUE );
|
||||
SetWindowText( hwnd, TEXT("贪吃蛇") );
|
||||
return ;
|
||||
|
||||
case GAME_EXIT:
|
||||
PostMessage( hwnd, WM_DESTROY, 0, 0 );
|
||||
return ;
|
||||
}
|
||||
}
|
||||
|
||||
//再来一局
|
||||
void gameAgain( HWND hwnd )
|
||||
{
|
||||
resetGameStatus();
|
||||
APP.level = 0;
|
||||
APP.score = 0;
|
||||
|
||||
SetWindowLong( hwnd, GWL_WNDPROC, (long)PlayingProc );
|
||||
PostMessage( hwnd, WM_TIMER, TMR_PLAYING_READY, 0 );
|
||||
InvalidateRect( hwnd, NULL, TRUE );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//蛇开始移动 (封装移动方法)
|
||||
void startSnakeMove( HWND hwnd )
|
||||
{
|
||||
if( PointImpaceTest(hwnd, APP.body[0], 0) )
|
||||
{
|
||||
PostMessage( hwnd, CM_GAME_OVER, 0, 0 );
|
||||
return ;
|
||||
}
|
||||
testEating( hwnd );
|
||||
drawSnakeBody( hwnd );
|
||||
moveSnake( );
|
||||
testEatSelf( hwnd );
|
||||
updateGameInfo( hwnd );
|
||||
InvalidateRect( hwnd, NULL, FALSE );
|
||||
}
|
|
@ -3,8 +3,12 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <windows.h>
|
||||
|
||||
#include "DealBeginMenuMsg.h"
|
||||
#include "GameOverDlgProc.h"
|
||||
#include "Init_Playing_Map.h"
|
||||
#include "MacroDefine.h"
|
||||
#include "cu_map.h"
|
||||
|
@ -16,8 +20,9 @@ typedef struct GameStatus
|
|||
{
|
||||
TCHAR szGameTitle[256]; //标题栏内容
|
||||
int level; //当前游戏关数
|
||||
POINT head; //蛇头部所在坐标
|
||||
POINT body[512]; //蛇身坐标
|
||||
POINT food; //食物所在坐标
|
||||
int direction; //当前行动方向
|
||||
int len; //蛇身长度
|
||||
int score; //游戏得分
|
||||
}GM_STATUS;
|
||||
|
@ -26,4 +31,9 @@ typedef struct GameStatus
|
|||
|
||||
LRESULT PlayingProc( HWND, UINT, WPARAM, LPARAM );
|
||||
|
||||
BOOL PointImpaceTest( HWND, POINT ); //点与障碍物的碰撞检测
|
||||
BOOL PointImpaceTest( HWND, POINT, int ); //点与障碍物的碰撞检测
|
||||
|
||||
void GetRandomFoodPlace( HWND, POINT* ); //生成随机食物坐标
|
||||
|
||||
LRESULT CALLBACK StartPlaying( HWND, UINT, WPARAM, LPARAM ); //开始游戏
|
||||
|
||||
|
|
12
Snake.c
12
Snake.c
|
@ -10,6 +10,7 @@ int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine
|
|||
static TCHAR szGameName[] = TEXT( "Snake" );
|
||||
|
||||
HWND hwnd;
|
||||
RECT rect;
|
||||
MSG msg;
|
||||
WNDCLASS wndclass;
|
||||
|
||||
|
@ -30,12 +31,17 @@ int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine
|
|||
return 0;
|
||||
}
|
||||
|
||||
rect.left = 0; rect.top = 0;
|
||||
rect.right = 800 + GetSystemMetrics(SM_CXFRAME);
|
||||
rect.bottom = 600 + GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CXFRAME);
|
||||
AdjustWindowRect( &rect, WS_CAPTION, FALSE );
|
||||
|
||||
hwnd = CreateWindow(
|
||||
szGameName, TEXT("̰³ÔÉß"),
|
||||
WS_CAPTION | WS_SYSMENU,
|
||||
(int)((GetSystemMetrics(SM_CXSCREEN)-800)/2),
|
||||
(int)((GetSystemMetrics(SM_CYSCREEN)-600)/2),
|
||||
800, 600,
|
||||
(int)((GetSystemMetrics(SM_CXSCREEN)-rect.right) /2),
|
||||
(int)((GetSystemMetrics(SM_CYSCREEN)-rect.bottom)/2),
|
||||
rect.right, rect.bottom,
|
||||
NULL, NULL, hInstance, NULL
|
||||
);
|
||||
|
||||
|
|
18
Snake.dsp
18
Snake.dsp
|
@ -43,7 +43,7 @@ RSC=rc.exe
|
|||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
|
||||
# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
|
||||
# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /FR /YX /FD /c
|
||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x804 /d "NDEBUG"
|
||||
|
@ -96,6 +96,10 @@ SOURCE=.\DealBeginMenuMsg.c
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\GameOverDlgProc.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\GameWndProc.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
@ -132,6 +136,10 @@ SOURCE=.\DealBeginMenuMsg.h
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\GameOverDlgProc.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\GameWndProc.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
@ -177,10 +185,18 @@ SOURCE=.\sounds\eating.wav
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\sounds\gameover.wav
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\sounds\go.wav
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\sounds\next.wav
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\sounds\ready.wav
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
|
10
resource.h
10
resource.h
|
@ -8,15 +8,21 @@
|
|||
#define IDR_EATING 103
|
||||
#define IDR_READY 104
|
||||
#define IDR_GO 105
|
||||
#define IDR_NEXT 106
|
||||
#define IDR_GAME_OVER 107
|
||||
#define IDD_GAMEOVER_DLG 108
|
||||
#define IDC_BTN_OK 1000
|
||||
#define IDC_GAME_AGAIN 1001
|
||||
#define IDC_RETURN_MAIN 1002
|
||||
#define IDC_EXIT_GAME 1003
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 106
|
||||
#define _APS_NEXT_RESOURCE_VALUE 109
|
||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||
#define _APS_NEXT_CONTROL_VALUE 1001
|
||||
#define _APS_NEXT_CONTROL_VALUE 1004
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
||||
|
|
71
resources.rc
71
resources.rc
|
@ -13,7 +13,7 @@
|
|||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Chinese (中国) resources
|
||||
// Chinese (P.R.C.) resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)
|
||||
#ifdef _WIN32
|
||||
|
@ -65,6 +65,8 @@ IDR_GAME_START WAVE DISCARDABLE "sounds\\start.wav"
|
|||
IDR_EATING WAVE DISCARDABLE "sounds\\eating.wav"
|
||||
IDR_READY WAVE DISCARDABLE "sounds\\ready.wav"
|
||||
IDR_GO WAVE DISCARDABLE "sounds\\go.wav"
|
||||
IDR_NEXT WAVE DISCARDABLE "sounds\\next.wav"
|
||||
IDR_GAME_OVER WAVE DISCARDABLE "sounds\\gameover.wav"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
@ -79,6 +81,17 @@ BEGIN
|
|||
DEFPUSHBUTTON "È·¶¨",IDC_BTN_OK,95,100,35,15,BS_CENTER
|
||||
END
|
||||
|
||||
IDD_GAMEOVER_DLG DIALOG DISCARDABLE 0, 0, 187, 97
|
||||
STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP
|
||||
FONT 10, "System"
|
||||
BEGIN
|
||||
PUSHBUTTON "再来一局",IDC_GAME_AGAIN,19,70,37,14,BS_CENTER |
|
||||
BS_VCENTER
|
||||
PUSHBUTTON "回主界面",IDC_RETURN_MAIN,74,70,37,14,BS_CENTER
|
||||
PUSHBUTTON "退出游戏",IDC_EXIT_GAME,130,70,37,14,BS_CENTER |
|
||||
BS_VCENTER
|
||||
END
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
@ -95,10 +108,64 @@ BEGIN
|
|||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 120
|
||||
END
|
||||
|
||||
IDD_GAMEOVER_DLG, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 180
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 90
|
||||
END
|
||||
END
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
#endif // Chinese (中国) resources
|
||||
|
||||
#ifndef _MAC
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Version
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 1,0,0,1
|
||||
PRODUCTVERSION 1,0,0,1
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
#else
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
FILEOS 0x40004L
|
||||
FILETYPE 0x1L
|
||||
FILESUBTYPE 0x0L
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "080404b0"
|
||||
BEGIN
|
||||
VALUE "Comments", "经典小游戏 - 贪吃蛇\0"
|
||||
VALUE "CompanyName", "wid\0"
|
||||
VALUE "FileDescription", "贪吃蛇 - 经典怀旧\0"
|
||||
VALUE "FileVersion", "1, 0, 0, 1\0"
|
||||
VALUE "InternalName", "Snake - 贪吃蛇\0"
|
||||
VALUE "LegalCopyright", "Copyright 2013, wid\0"
|
||||
VALUE "LegalTrademarks", "\0"
|
||||
VALUE "OriginalFilename", "Snake.exe\0"
|
||||
VALUE "PrivateBuild", "\0"
|
||||
VALUE "ProductName", "null Snake\0"
|
||||
VALUE "ProductVersion", "1, 0, 0, 1\0"
|
||||
VALUE "SpecialBuild", "\0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x804, 1200
|
||||
END
|
||||
END
|
||||
|
||||
#endif // !_MAC
|
||||
|
||||
#endif // Chinese (P.R.C.) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue