C++贪吃蛇代码

 

这里贴出主要源码如下:

#include "StdAfx.h"
#include "Snake.h"

Snake::Snake():m_NewDrection(m_right),m_OldDrection(m_right)
{
 int i;
 for (i = 0; i < 400; i++)
 {
  m_NewSnakePos[i].x = 1;
  m_NewSnakePos[i].y = 1;
  m_NewSnakePos[i].Status = 1;
  m_NewLenth = 0;
 }
 Object::GetPosition(m_OldSnakePos);
 m_OldLenth = Object::GetPosNum();
}

Snake::~Snake()
{

}

void
Snake::initSnake()
{
 m_NewLenth = 6;
 for (int i = 0; i < 6; i++)
 {
  m_NewSnakePos[i].x = i+1;
  m_NewSnakePos[i].y = 1;
  m_NewSnakePos[i].Status = 1;
 }

}

void
Snake::GetNewSnakePos(Pos* pos)
{
 int i;
 for (i = 0; i < 400; ++i)
 {
  pos[i].Status = m_NewSnakePos[i].Status;
  pos[i].x = m_NewSnakePos[i].x;
  pos[i].y = m_NewSnakePos[i].y;
 }
}

void
Snake::Move()
{
 int i;
 for (i = 0; i < m_NewLenth; ++i)  // 把当前蛇的位置及蛇身长度拷贝到OldSnake中保存
 {
  m_OldSnakePos[i].x = m_NewSnakePos[i].x;
  m_OldSnakePos[i].y = m_NewSnakePos[i].y;
  m_OldSnakePos[i].Status = m_NewSnakePos[i].Status;
 }
 m_OldLenth = m_NewLenth;
 switch (m_NewDrection)
 {
 case m_right:
  m_NewSnakePos[m_NewLenth - 1].x = m_OldSnakePos[m_NewLenth - 1].x + 1;
  break;
 case m_left:
  m_NewSnakePos[m_NewLenth - 1].x = m_OldSnakePos[m_NewLenth - 1].x - 1;
  break;
 case m_up:
  m_NewSnakePos[m_NewLenth - 1].y = m_OldSnakePos[m_NewLenth - 1].y - 1;
  break;
 case m_down:
  m_NewSnakePos[m_NewLenth - 1].y = m_OldSnakePos[m_NewLenth - 1].y + 1;
  break;
 }
 m_NewSnakePos[m_NewLenth - 1].Status = 1;
 m_NewSnakePos[m_NewLenth].x = m_OldSnakePos[0].x;  // 在蛇身体数组后增加一个点,来记录蛇尾位置,并设置为空地状态,实现蛇尾的擦除
 m_NewSnakePos[m_NewLenth].y = m_OldSnakePos[0].y;
 m_NewSnakePos[m_NewLenth].Status = 0;

 for (i = 1; i < m_NewLenth; ++i)  // 从OldSnake获取除了蛇头蛇尾外的所有位置信息
 {
  m_NewSnakePos[i - 1].x = m_OldSnakePos[i].x;
  m_NewSnakePos[i - 1].y = m_OldSnakePos[i].y;
 }

}

void
Snake::AddLenth()
{
 m_NewLenth = m_NewLenth + 1;

 m_NewSnakePos[m_NewLenth].x = m_NewSnakePos[m_NewLenth - 1].x;  // 记录需要擦除蛇尾的信息
 m_NewSnakePos[m_NewLenth].y = m_NewSnakePos[m_NewLenth - 1].y;
 m_NewSnakePos[m_NewLenth].Status = m_NewSnakePos[m_NewLenth - 1].Status;
 m_NewSnakePos[m_NewLenth - 1].Status = 1;

 switch (m_NewDrection)  // 在蛇头前增加一个点,设置为新蛇头,来实现蛇身的增长
 {
 case m_right:
  m_NewSnakePos[m_NewLenth - 1].x = m_NewSnakePos[m_NewLenth - 2].x + 1;
  m_NewSnakePos[m_NewLenth - 1].y = m_NewSnakePos[m_NewLenth - 2].y;
  break;
 case m_left:
  m_NewSnakePos[m_NewLenth - 1].x = m_NewSnakePos[m_NewLenth - 2].x - 1;
  m_NewSnakePos[m_NewLenth - 1].y = m_NewSnakePos[m_NewLenth - 2].y;
  break;
 case m_up:
  m_NewSnakePos[m_NewLenth - 1].x = m_NewSnakePos[m_NewLenth - 2].x;
  m_NewSnakePos[m_NewLenth - 1].y = m_NewSnakePos[m_NewLenth - 2].y - 1;
  break;
 case m_down:
  m_NewSnakePos[m_NewLenth - 1].x = m_NewSnakePos[m_NewLenth - 2].x;
  m_NewSnakePos[m_NewLenth - 1].y = m_NewSnakePos[m_NewLenth - 2].y + 1;
  break;
 default:
  break;

 }
}

void
Snake::KeyInput(Drection m_drection)
{
 switch(m_drection)
 {
 case m_right:
  if (m_NewDrection == m_up || m_NewDrection == m_down)
  {
   m_OldDrection = m_NewDrection;
   m_NewDrection = m_drection;
  }
  break;
 case  m_left:
  if (m_NewDrection == m_up || m_NewDrection == m_down)
  {
   m_OldDrection = m_NewDrection;
   m_NewDrection = m_drection;
  }
  break;
 case m_up:
  if (m_NewDrection == m_left || m_NewDrection == m_right)
  {
   m_OldDrection = m_NewDrection;
   m_NewDrection = m_drection;
  }
  break;
 case m_down:
  if (m_NewDrection == m_left || m_NewDrection == m_right)
  {
   m_OldDrection = m_NewDrection;
   m_NewDrection = m_drection;
  }
  break;
 }
}

#include "StdAfx.h"
#include "Food.h"

Food::Food():isfoodexist(0)
{

}

Food::~Food()
{

}

void
Food::initFood()
{
 Pos* m_Foodposition = new Pos[1];
 m_Foodposition[0].x = 10;
 m_Foodposition[0].y = 2;
 m_Foodposition[0].Status = 3;
 int num = 1;
 Object::SetPosNum(num);
 Object::SetPosition(m_Foodposition);
 delete[] m_Foodposition;
 m_Foodposition = NULL;
}

 

void
Food::CreatFood()
{
 Pos* m_Foodposition = new Pos[1];
 srand((unsigned) time(NULL));
 m_Foodposition[0].x = rand()%30;
 while ((m_Foodposition[0].x < 2) || (m_Foodposition[0].x >33))
 {
  m_Foodposition[0].x = rand()%30;
 }

 m_Foodposition[0].y = rand()%30;
 while ((m_Foodposition[0].y < 2) || (m_Foodposition[0].y >33))
 {
  m_Foodposition[0].y = rand()%30;
 }

 m_Foodposition[0].Status = 3;
 Object::SetPosition(m_Foodposition);
 delete [1] m_Foodposition;
 m_Foodposition = NULL; 
}

void
Food::SetFlag(bool existflag)
{
 isfoodexist = existflag;
}

bool
Food::GetFlag()
{
 return isfoodexist;
}

#include "StdAfx.h"
#include "Wall.h"

Wall::Wall(void):
m_width(36),m_hight(36)
{
}

Wall::~Wall(void)
{
}
void
Wall::InitWall()
{
 Pos* position = new Pos[400];
 int x;
 int y;
 int num = 0;
 for (x = 0; x < m_width; x++)
 {
  position[num].x = x;
  position[num].y = 0;
  position[num].Status = 2;
  num++;
  position[num].x = x;
  position[num].y = m_width - 1;
  position[num].Status = 2;
  num++;
 }
 for (y = 0; y < m_hight; y++)
 {
  position[num].x = 0;
  position[num].y = y;
  position[num].Status = 2;
  num++;
  position[num].x = m_hight - 1;
  position[num].y = y;
  position[num].Status = 2;
  num++;
 }
 Object::SetPosNum(num);
 Object::SetPosition(position);

 delete[] position;
 position = NULL;
}

#include "StdAfx.h"

#ifndef CXX_OBJECT_H
#include "Object.h"
#endif

Object::Object():m_PosNum(0)
{
 int i;
 for (i = 0;i < 400; i++)
 {
  m_Position[i].x = 0;
  m_Position[i].y = 0;
  m_Position[i].Status = 0;
 }
}

Object::~Object(void)
{

}

void
Object::SetPosNum(int num)
{
 m_PosNum = num;
}

int
Object::GetPosNum()
{
 return m_PosNum;
}

/// 通过传入的pos,设置m_Position的X,Y坐标及状态。
void
Object::SetPosition(Pos* pos)
{
 int i;
 for (i = 0; i < m_PosNum + 1; ++i)
 {
  m_Position[i].Status = pos[i].Status;
  m_Position[i].x = pos[i].x;
  m_Position[i].y = pos[i].y;
 }
}

void
Object::GetPosition(Pos* pos)
{
 int i;
 for (i = 0; i < 400; ++i)
 {
  pos[i].Status = m_Position[i].Status;
  pos[i].x = m_Position[i].x;
  pos[i].y = m_Position[i].y;
 }
}

#include "StdAfx.h"
#include "PlayGround.h"

PlayGround::PlayGround(void):m_live(0)
{
 m_playground = new int*[36];
 int i;
 for (i = 0; i < 36; ++i)
 {
  m_playground[i] = new int[36];
 }
 int m;
 int n;
 for (m = 0; m < 36; ++m)
 {
  for (n = 0; n < 36; ++n)
  {
   m_playground[m][n] = 0;
  }
 }
}

PlayGround::~PlayGround(void)
{

}

void
PlayGround::SetStatues()
{
 m_wall.InitWall();
 Pos* position = new Pos[400];
 m_wall.GetPosition(position);

 int num;
 for (num = 0;num < m_wall.GetPosNum();num++)
 {
  int x = position[num].x;
  int y = position[num].y;
  int status = position[num].Status;
  m_playground[x][y] = status;
 }
 delete[400] position;
 position = NULL;

 m_snake.initSnake();
 Pos* snakeposition = new Pos[400];
 m_snake.GetNewSnakePos(snakeposition);
 for (num = 0;num < m_snake.GetNewLenth();num++)
 {
  int x = snakeposition[num].x;
  int y = snakeposition[num].y;
  int status = snakeposition[num].Status;
  m_playground[x][y] = status;
 }
 delete[400] snakeposition;
 snakeposition = NULL;

 m_food.initFood();
 Pos* foodposition =new Pos[400];
 m_food.GetPosition(foodposition);
 int x = foodposition[0].x;
 int y = foodposition[0].y;
 int status = foodposition[0].Status;
 m_playground[x][y] = status;
 delete[400] foodposition;
 foodposition = NULL;
}

int
PlayGround::GetStatus(Pos* pos,int len)
{
 int i;
 int j;
 int status;
 i = pos[len - 1].x;
 j = pos[len - 1].y;
 status = m_playground[i][j];
 return status;
}

/// 返回m_Playground,提供给CSnakeView进行屏幕输出。
int**
PlayGround::GetPlayground()
{
 return m_playground;
}

void
PlayGround::AddFood()
{
 bool existflag;
 existflag = m_food.GetFlag();
 if (1 == existflag)
 { 
  m_food.CreatFood();
  Pos* fruit = new Pos[400];
  m_food.GetPosition(fruit);
  int fruitstatus = PlayGround::GetStatus(fruit,1);
  if ((2 == fruitstatus) || (1 ==fruitstatus))  // 如果m_Playground中水果对应位置状态是墙或者蛇,则重新生成
  {
   m_food.CreatFood();
  }
  m_food.SetFlag(0);
  delete[400] fruit;
  fruit = NULL;
 } 
}

void
PlayGround::UpdatePosition()
{
 Pos* position = new Pos[400];  // 获取蛇的坐标点,更新m_Playground
 m_snake.GetNewSnakePos(position);
 int num = m_snake.GetNewLenth();
 int m;
 for (m = 0; m < num + 1; ++m)
 {
  int x = position[m].x;
  int y = position[m].y;
  int status = position[m].Status;
  m_playground[x][y] = status;
 }
 delete[400] position;
 position = NULL;

 Pos* fruitposition = new Pos[400];  // 获取水果的坐标点,更新m_Playground
 m_food.GetPosition(fruitposition);
 int x;
 int y;
 int status;
 x = fruitposition[0].x;
 y = fruitposition[0].y;
 status = fruitposition[0].Status;
 m_playground[x][y] = status;
 delete[400] fruitposition;
 fruitposition = NULL;
}

void
PlayGround::SnakeMove()
{
 m_snake.Move();  // 蛇身坐标进行变化  
 Pos* snakehead = new Pos[400];
 m_snake.GetNewSnakePos(snakehead);
 int len;
 int status;
 len = m_snake.GetNewLenth();
 status = PlayGround::GetStatus(snakehead,len);
 if (3 == status)  // 如果m_Playground中蛇头所在位置的状态为食物则增加蛇身长度,设置水果Flag为1,即不存在
 {
 m_snake.AddLenth();
 m_food.SetFlag(1);
 }
 delete[400] snakehead;
 snakehead = NULL;
}

void
PlayGround::ChangeDrection(Drection m_drection)
{
 m_snake.KeyInput(m_drection);
}

bool
PlayGround::IsGameOver()
{
 Pos* snakehead = new Pos[400];
 m_snake.GetNewSnakePos(snakehead);
 int len;
 int status;
 len = m_snake.GetNewLenth();
 status = PlayGround::GetStatus(snakehead,len);
 if (1 == status || 2 == status)  
 {
  m_live = 1;
 }
 delete[400] snakehead;
 snakehead = NULL;
 return m_live;
}

int
PlayGround::GetScore()
{
 return m_score;
}

void
PlayGround::SetScore()
{
 m_score = (m_snake.GetNewLenth() - 6)*10;
}

 

// SnakeHTView.cpp : implementation of the CSnakeHTView class
//

#include "stdafx.h"
#include "SnakeHT.h"

#include "SnakeHTDoc.h"
#include "SnakeHTView.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// CSnakeHTView

IMPLEMENT_DYNCREATE(CSnakeHTView, CView)

BEGIN_MESSAGE_MAP(CSnakeHTView, CView)
 // Standard printing commands
 ON_COMMAND(ID_FILE_PRINT, &CView::OnFilePrint)
 ON_COMMAND(ID_FILE_PRINT_DIRECT, &CView::OnFilePrint)
 ON_COMMAND(ID_FILE_PRINT_PREVIEW, &CView::OnFilePrintPreview)
 ON_COMMAND(ID_32771, &CSnakeHTView::OnStart)
 ON_COMMAND(ID_32772, &CSnakeHTView::OnPause)
 ON_COMMAND(ID_32773, &CSnakeHTView::OnContinue)
 ON_COMMAND(ID_32774, &CSnakeHTView::OnGameOver)
 ON_WM_KEYDOWN()
 ON_WM_TIMER()
END_MESSAGE_MAP()

// CSnakeHTView construction/destruction

CSnakeHTView::CSnakeHTView()
{

// TODO: add construction code here

}

CSnakeHTView::~CSnakeHTView()
{


}

BOOL CSnakeHTView::PreCreateWindow(CREATESTRUCT& cs)
{
 // TODO: Modify the Window class or styles here by modifying
 //  the CREATESTRUCT cs

 return CView::PreCreateWindow(cs);
}

// CSnakeHTView drawing

void CSnakeHTView::OnDraw(CDC* /*pDC*/)
{
 CSnakeHTDoc* pDoc = GetDocument();
 ASSERT_VALID(pDoc);
 if (!pDoc)
  return;

 m_playground.SetStatues(); 
 CSnakeHTView::OnInitialUpdate(m_playground.GetPlayground());

}

// CSnakeHTView printing

BOOL CSnakeHTView::OnPreparePrinting(CPrintInfo* pInfo)
{  
           // default preparation
 return DoPreparePrinting(pInfo);
}

void CSnakeHTView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
           // TODO: add extra initialization before printing
}

void CSnakeHTView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
           // TODO: add cleanup after printing
}


// CSnakeHTView diagnostics

#ifdef _DEBUG
void CSnakeHTView::AssertValid() const
{
 CView::AssertValid();
}

void CSnakeHTView::Dump(CDumpContext& dc) const
{
 CView::Dump(dc);
}

CSnakeHTDoc* CSnakeHTView::GetDocument() const // non-debug version is inline
{
 ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CSnakeHTDoc)));
 return (CSnakeHTDoc*)m_pDocument;
}
#endif //_DEBUG

 

void CSnakeHTView::OnStart()
{  
 SetTimer(1,300,NULL);    // TODO: Add your command handler code here
}

void CSnakeHTView::OnPause()
{
          // TODO: Add your command handler code here
}

void CSnakeHTView::OnContinue()
{
          // TODO: Add your command handler code here
}

void CSnakeHTView::OnGameOver()
{
          // TODO: Add your command handler code here
}

void CSnakeHTView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{         
 Drection m_drection = m_right;
 switch (nChar)
 {
 case VK_UP:
  m_drection = m_up;
  break;
 case VK_DOWN:
  m_drection = m_down;
  break;
 case VK_LEFT:
  m_drection = m_left;
  break;
 case VK_RIGHT:
  m_drection = m_right;
  break;
 }
 m_playground.ChangeDrection(m_drection);
 CView::OnKeyDown(nChar, nRepCnt, nFlags);
}

void CSnakeHTView::OnTimer(UINT_PTR nIDEvent)
{         // TODO: Add your message handler code here and/or call default
 m_playground.UpdatePosition();
 m_playground.AddFood();
 CSnakeHTView::OnInitialUpdate(m_playground.GetPlayground());
 m_playground.SnakeMove();
 bool snakelive;
 snakelive = m_playground.IsGameOver();
 if (snakelive == 1)
 {
  KillTimer(1);
  m_playground.SetScore();
  int score = m_playground.GetScore();
  CString message;
  message.Format(_T("GameOver!Your Score Is: %d"),score);
  AfxMessageBox(message);
 }
 CView::OnTimer(nIDEvent);
}

void
CSnakeHTView::OnInitialUpdate(int** Playground)
{
 //CView::OnInitialUpdate();
 int x;
 int y;
 x = 0;
 y = 0;
 CDC* pDC = GetDC();
 CBrush DrawBrushEmpty = (RGB(255, 255, 255));  // 设置空白地的颜色
 CBrush DrawBrushWall = (RGB(180, 60, 45));   // 设置墙及障碍物的颜色
 CBrush DrawBrushSnake = (RGB(0, 255, 0));   // 设置蛇的颜色
 CBrush DrawBrushFruit = (RGB(220, 120, 60));  // 设置水果的颜色
 CPen pen(PS_SOLID, 1, RGB(255, 255, 255));   // 矩形边框设置白色
 for (y = 0; y < 36; ++y)
 {
  for (x = 0; x < 36; ++x)
  {
   pDC->SelectObject(&pen);
   pDC->Rectangle(x * 20, y * 20, (x + 1) * 20, (y + 1) * 20);  // 绘制矩形边框为白色

   switch (Playground[x][y])  // 根据playground中各个坐标的状态来绘制不同的颜色
   {
   case 0:
    pDC->SelectObject(DrawBrushEmpty);
    pDC->Rectangle(x * 20, y * 20, (x + 1) * 20, (y + 1) * 20);
    break;
   case 1:      
    pDC->SelectObject(DrawBrushSnake);
    pDC->Rectangle(x * 20, y * 20, (x + 1) * 20, (y + 1) * 20);
    break;
   case 2:
    pDC->SelectObject(DrawBrushWall);
    pDC->Rectangle(x * 20, y * 20, (x + 1) * 20, (y + 1) * 20);
    break;
   case 3:
    pDC->SelectObject(DrawBrushFruit);
    pDC->Rectangle(x * 20, y * 20, (x + 1) * 20, (y + 1) * 20);
    break;
   default:
    break;
   }
  }
 }
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值