您的位置:首页 > 其它

MFC-贪吃蛇

2016-03-15 16:56 246 查看
项目代码:
https://yunpan.cn/cYvqi5UmBdJEJ (提取码:05a6)

// 定义一个贪吃蛇的其中之一
typedef struct ty_snake {
int x;
int y;
COLORREF color;
} snake;

// 游戏区域左侧与顶部
const int GAME_SIDE_LEFT = 10;
const int GAME_SIDE_TOP = 10;

// 游戏区域中的一个方块的宽度
const int GAME_WIDTH = 20;

// 游戏区域宽和高有多少个方块
const int NUMT = 20;

// 随机的颜色
#define COLOR_RAND RGB(rand()%200+30,rand()%200+30,rand()%200+30)

// 定义方向
enum DIRECT {UP = -1,DOWN = 1,LEFT = -2,RIGHT = 2};


---------

#pragma once
#include <list>
class CSnake
{
public:
CSnake();
~CSnake();
std::list<snake> m_snake;
void makeSnake();
int m_direction;
void Draw();
CRect getSnakePos(snake sn);
void makeOneSnake();
snake m_onesnake;
BOOL move();
void alterDirect(int direct);
BOOL dealOut(snake sn);
BOOL haveSnake(snake sn);
};
-----------

#include "stdafx.h"
#include "Snake.h"
#include "time.h"
#include <string>
#include <algorithm>
CSnake::CSnake()
{
m_direction = UP;
}

CSnake::~CSnake()
{
}

void CSnake::makeSnake()
{
srand((unsigned)time(0));
snake sn1 = {NUMT/2,NUMT/2,COLOR_RAND};
m_snake.push_back(sn1);
snake sn2 = { NUMT / 2+1,NUMT / 2,COLOR_RAND };
m_snake.push_back(sn2);
}

void CSnake::makeOneSnake()
{
srand((unsigned)time(0));
m_onesnake = { rand()%NUMT,rand() % NUMT,COLOR_RAND };
}

void CSnake::Draw()
{
CClientDC* dc = (CClientDC*)AfxGetMainWnd()->GetDC();
dc->FillSolidRect(CRect(GAME_SIDE_LEFT,GAME_SIDE_TOP,GAME_SIDE_LEFT+GAME_WIDTH*NUMT,GAME_SIDE_TOP+GAME_WIDTH*NUMT), RGB(255,255,255));
std::for_each(m_snake.begin(), m_snake.end(), [=](snake sn) {
dc->FillSolidRect(getSnakePos(sn), sn.color);
});
dc->FillSolidRect(getSnakePos(m_onesnake), m_onesnake.color);
dc->DeleteDC();
dc = nullptr;
}

CRect CSnake::getSnakePos(snake sn)
{
return CRect(GAME_SIDE_LEFT+sn.x*GAME_WIDTH,
GAME_SIDE_TOP+sn.y*GAME_WIDTH,
GAME_SIDE_LEFT + (sn.x+1)*GAME_WIDTH,
GAME_SIDE_TOP + (sn.y+1)*GAME_WIDTH);
}

BOOL CSnake::move()
{
snake asn;
switch (m_direction)
{
case UP: {
asn = {m_snake.front().x,m_snake.front().y-1,m_snake.back().color};
break;
}
case DOWN: {
asn = { m_snake.front().x,m_snake.front().y + 1,m_snake.back().color };
break;
}
case LEFT: {
asn = { m_snake.front().x-1,m_snake.front().y,m_snake.back().color };
break;
}
case RIGHT: {
asn = { m_snake.front().x+1,m_snake.front().y,m_snake.back().color };
break;
}
default:
break;
}
if (dealOut(asn)) {
return FALSE;
}
if (haveSnake(asn)) {
m_snake.push_front(m_onesnake);
makeOneSnake();
move();
return TRUE;
}
m_snake.push_front(asn);
m_snake.pop_back();
return TRUE;
}

void CSnake::alterDirect(int direct)
{
if (direct == m_direction) {
return;
}
if (direct == -m_direction) {
return;
}
m_direction = direct;
}

BOOL CSnake::dealOut(snake sn)
{
if (sn.x < 0 || sn.y < 0 || sn.x >= NUMT || sn.y >= NUMT) {
return TRUE;
}
for (auto e : m_snake) {
if (sn.x == e.x && sn.y == e.y) {
return TRUE;
}
}
return FALSE;
}

BOOL CSnake::haveSnake(snake sn)
{
if (sn.x == m_onesnake.x && sn.y == m_onesnake.y) {
return TRUE;
}
return FALSE;
}


-----------

初始化

m_stop = 1;
m_start = 0;
snk = new CSnake;


void CSnakeGameDlg::OnBnClickedOk()
{
if (!m_start) {
snk->makeSnake();
snk->makeOneSnake();
snk->Draw();
SetTimer(1002, 500, 0);
m_start = 1;
m_stop = 0;
return;
}
if (m_start) {
if (m_stop) {
SetTimer(1002, 500, 0);
m_stop = 0;
}
else {
KillTimer(1002);
m_stop = 1;
}
}

}

void CSnakeGameDlg::OnBnClickedAgain()
{
m_stop = 0;
m_start = 1;
snk->m_snake.clear();
snk->makeSnake();
snk->makeOneSnake();
snk->Draw();
SetTimer(1002, 500, 0);
}

void CSnakeGameDlg::OnBnClickedCancel()
{

CDialog::OnCancel();
}

void CSnakeGameDlg::OnTimer(UINT_PTR nIDEvent)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
switch (nIDEvent)
{
case 1002: {
if (snk->move() == FALSE) {
KillTimer(nIDEvent);
m_start = 0;
m_stop = 1;
AfxMessageBox(L"游戏结束");
}
snk->Draw();
break;
}
default:
break;
}
CDialog::OnTimer(nIDEvent);
}

BOOL CSnakeGameDlg::PreTranslateMessage(MSG* pMsg)
{
// TODO: 在此添加专用代码和/或调用基类
if (pMsg->message == WM_KEYDOWN) {
switch (pMsg->wParam)
{
case VK_LEFT: {
snk->alterDirect(LEFT);
break;
}
case VK_RIGHT: {
snk->alterDirect(RIGHT);
break;
}
case VK_DOWN: {
snk->alterDirect(DOWN);
break;
}
case VK_UP: {
snk->alterDirect(UP);
break;
}
default:
break;
}
return TRUE;
}
return CDialog::PreTranslateMessage(pMsg);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: