当前位置: 首页 > 编程笔记 >

C++实现基于控制台界面的吃豆子游戏

吉玉石
2023-03-14
本文向大家介绍C++实现基于控制台界面的吃豆子游戏,包括了C++实现基于控制台界面的吃豆子游戏的使用技巧和注意事项,需要的朋友参考一下

本文实例讲述了C++实现基于控制台界面的吃豆子游戏。分享给大家供大家参考。具体分析如下:

程序运行界面如下所示:

ESC键可退出游戏。

main.cpp源文件如下:

#include "lib.h"
#pragma once
extern int level;
int main()
{
 FOOD food;
 WALL wall;
 BODY CurPos;
 HALL hall;
 int iExit = 0;
 while(1)
 {
  if(iExit)
   break;
  Init(&food,&wall,&CurPos,&hall);
  MakeWall(&wall);
  while(1)
  {
   Sleep(200);
   int res = Move(&food,&wall,&CurPos);
   if(1 == res) //重新开局
    break;
   else if(-1 == res) //用户退出
   {
    iExit = 1;
    break;
   }
   ShowScore(&CurPos,&food);
  }
 }
 return 0;
}

lib.h头文件如下:

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <time.h>
//标识用户按下的方向键
#define KEY_UP    WM_USER + 1
#define KEY_DOWN   WM_USER + 2
#define KEY_LEFT   WM_USER + 3
#define KEY_RIGHT   WM_USER + 4
//标识用户当前运动方向
#define DIRECTION_UP  WM_USER + 5
#define DIRECTION_DOWN  WM_USER + 6
#define DIRECTION_LEFT  WM_USER + 7
#define DIRECTION_RIGHT  WM_USER + 8
//标识要打印的元素类型
#define PRINT_WALL   WM_USER + 9
#define PRINT_FOOD   WM_USER + 10
#define PRINT_BODY   WM_USER + 11
#define PRINT_CLEAN   WM_USER + 12
#define KNOCK_WALL   WM_USER + 13
#define KNOCK_FOOD   WM_USER + 14
struct POS
{
 int x;
 int y;
};
struct WALL
{
 POS pos[9999];
 int len;
};
struct FOOD
{
 POS pos[8];
 int len;
 int IsHidden;
};
struct BODY
{
 POS pos;
 int Direction;
};
struct HALL{
 POS pos[200];
 int len;
};
void Init(FOOD *pFood,WALL *pWall,BODY *pBody,HALL *pHall);
//进行一些初始化操作
void Print(POS *pos,int TYPE,int ix = 0);
//完成打印功能
void MakeWall(WALL *pWall);
//生成墙
void MakeFood(HALL *pHall,FOOD *pFood);
//生成食物
int Move(FOOD *pFood,WALL *pWall,BODY *pBody);
//用户移动
void ShowScore(BODY *pBody,FOOD *pFood);
//显示等级 和剩余豆子数
int IsOver(POS pos1,POS pos2,int TYPE);
//判断2点是否重合
int IsKnock(WALL *pWall,BODY *pBody,FOOD *pFood,int TYPE);
//判断是否撞墙、吃到豆子
int GetKey();
//得到用户按键

lib.cpp源文件如下:

#include "lib.h"
#pragma once
HANDLE hMain_Out;
HANDLE hMain_In;
CONSOLE_CURSOR_INFO info;
int iBeans = 0;
int level = 1;
//extern short wall[17][24];
short wall[17][24] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
     0,-1,0,0,0,0,0,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,
     0,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,-1,0,0,0,0,0,-1,-1,-1,0,0,
     0,-1,0,0,0,-1,0,0,0,0,0,0,0,-1,0,0,0,0,0,-1,0,0,0,0,
     0,-1,-1,-1,-1,-1,0,-1,-1,-1,-1,-1,0,-1,0,-1,-1,-1,-1,-1,-1,-1,0,0,
     0,-1,0,0,-1,0,-1,0,0,0,0,-1,0,-1,-1,-1,0,0,0,0,0,0,0,0,
     0,-1,-1,-1,-1,-1,-1,0,0,0,0,-1,0,0,0,-1,0,0,0,0,0,0,0,0,
     0,-1,0,0,0,0,0,0,0,0,0,-1,0,0,0,-1,-1,-1,-1,-1,-1,-1,-1,0,
     0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,-1,0,0,-1,0,0,0,0,
     0,0,0,0,0,0,-1,0,0,0,0,0,0,0,-1,0,-1,0,0,-1,0,0,0,0,
     0,0,0,0,0,0,-1,0,0,0,0,0,0,0,-1,0,-1,-1,-1,-1,0,-1,-1,0,
     0,0,0,0,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,-1,0,0,
     0,0,0,0,0,-1,0,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,-1,0,0,
     0,0,-1,-1,-1,-1,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,0,
     0,-1,-1,0,0,0,0,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,
     0,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,
     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
};
/**********************************
* 功能:
* 判断用户与墙相撞或吃到食物
***********************************/
int IsKnock(WALL *pWall,BODY *pBody,FOOD *pFood,int TYPE)
{
 if(KNOCK_WALL == TYPE)
 {
  int i;
  for(i = 0 ; i < pWall->len ; ++i)
  {
   if(IsOver(pBody->pos,pWall->pos[i],KNOCK_WALL))
    return 1; //与墙相撞
  }
 }
 else if(KNOCK_FOOD == TYPE)
 {
  int i;
  for(i = 1 ; i <= pFood->len ; ++i)
  {
   if(IsOver(pFood->pos[i],pBody->pos,KNOCK_WALL))
    return i; //与食物相撞
  }
 }
 return 0;
}
/**********************************
* 功能:
* 用户移动
***********************************/
int Move(FOOD *pFood,WALL *pWall,BODY *pBody)
{
 BODY prePos = *pBody;
// POS prePos = pBody->pos;
 int iKey = GetKey();
 if(-1 == iKey) //用户退出
  return -1;
 if(iKey)
 {
  pBody->Direction = iKey + 4;
  iKey = 0;
 }
 if(0 == iKey)
 {
  if(DIRECTION_UP == pBody->Direction)
   --pBody->pos.y;
  else if(DIRECTION_DOWN == pBody->Direction)
   ++pBody->pos.y;
  else if(DIRECTION_LEFT == pBody->Direction)
   --pBody->pos.x;
  else if(DIRECTION_RIGHT == pBody->Direction)
   ++pBody->pos.x;
 }
 
 if(IsKnock(pWall,pBody,pFood,KNOCK_WALL))
 {
  *pBody = prePos;
  return 0;
 }
 int ix = IsKnock(pWall,pBody,pFood,KNOCK_FOOD);
 if(ix)
 {
  ++iBeans;
  //删除初吃掉的食物
  int i;
  for(i = ix ; i <= (pFood->len - 1) ; ++i)
   pFood->pos[i] = pFood->pos[i + 1];
  --(pFood->len);
  if(0 == pFood->len) //当局完成
  {
   ++level;
   return 1;
  }
 }
 Print(&prePos.pos,PRINT_CLEAN); //先删除上一个输出
 Print(&pBody->pos,PRINT_BODY);
 return 0;
}
/**********************************
* 功能:
* 判断2点是否重合
***********************************/
int IsOver(POS pos1,POS pos2,int TYPE)
{
 if(KNOCK_WALL == TYPE) //pos1,the body. pos2,the wall
  if((pos1.x == pos2.x && pos1.y == pos2.y) || (pos2.x + 1 == pos1.x && pos2.y == pos1.y))
   return 1;
 return 0;
}
/**********************************
* 功能:
* 生成墙
***********************************/
void MakeWall(WALL *pWall)
{
 int x,y;
 int ix = 0;
 for(x = 0 ; x <= 16 ; ++x)
 {
  for(y = 0 ; y <= 23 ; ++y)
  {
   if(0 == wall[x][y])
   {
    pWall->pos[ix].x = 2 * y;
    pWall->pos[ix].y = x;
    Print(&pWall->pos[ix++],PRINT_WALL);
   }
  }
 }
 pWall->len = ix; //更新墙的数量
}
/**********************************
* 功能:
* 完成初始化操作
***********************************/
void Init(FOOD *pFood,WALL *pWall,BODY *pBody,HALL *pHall)
{
 //得到控制台标准输入输出句柄
 hMain_Out = GetStdHandle(STD_OUTPUT_HANDLE);
 hMain_In = GetStdHandle(STD_INPUT_HANDLE);
 //隐藏光标
 GetConsoleCursorInfo(hMain_Out,&info);
 info.bVisible = FALSE;
 SetConsoleCursorInfo(hMain_Out,&info);
 //初始化结构体
 pFood->len = 0;
 pWall->len = 0;
 pHall->len = 0;
 //改变控制台大小
 system("mode con cols=50 lines=21");
 //走廊结构体赋值
 int x,y;
 int ix = 0;
 for(x = 0 ; x < 17 ; ++x)
 {
  for(y = 0 ; y < 24 ; ++y)
  {
   if(wall[x][y]) //非墙
   {
    pHall->pos[ix].x = 2 * y;
    pHall->pos[ix++].y = x;
   }
  }
 }
 pHall->len = ix;
 pBody->pos.x = 2;
 pBody->pos.y = 1;
 pBody->Direction = DIRECTION_DOWN;
 printf("%d %d\n",pHall->pos[0].x,pHall->pos[0].y);
 //输出食物
 int i;
 MakeFood(pHall,pFood);
 for(i = 1 ; i <= 7 ; ++i)
 {
  Print(&pFood->pos[i],PRINT_FOOD,i);
 }
}
/**********************************
* 功能:
* 得到用户按键
***********************************/
int GetKey()
{
 if(GetAsyncKeyState(VK_UP))
  return KEY_UP;
 if(GetAsyncKeyState(VK_DOWN))
  return KEY_DOWN;
 if(GetAsyncKeyState(VK_LEFT))
  return KEY_LEFT;
 if(GetAsyncKeyState(VK_RIGHT))
  return KEY_RIGHT;
 if(GetAsyncKeyState(VK_ESCAPE))
  return -1; //用户退出
 return 0;//用户没有有效按键
}
/**********************************
* 功能:
* 完成打印功能
***********************************/
void Print(POS *p,int TYPE,int ix)
{
 COORD pos;
 pos.X = p->x;
 pos.Y = p->y;
 SetConsoleCursorPosition(hMain_Out,pos);
 if(PRINT_WALL == TYPE)
  printf("■");
 else if(PRINT_FOOD == TYPE)
  printf("%d",ix);
 else if(PRINT_BODY == TYPE)
  printf("\1");
 else if(PRINT_CLEAN == TYPE)
  printf(" ");
}
/**********************************
* 功能:
* 显示等级 和剩余豆子数
***********************************/
void ShowScore(BODY *pBody,FOOD *pFood)
{
 COORD pos;
 pos.X = 0;
 pos.Y = 18;
 SetConsoleCursorPosition(hMain_Out,pos);
 printf("\tBeans left : %d | pos : x=%d,y=%d\n",pFood->len,pBody->pos.x,pBody->pos.y);
 printf("\t\tLevel : %d",level);
// for(int i = 1 ; i <= pFood->len ; ++i)
//  printf("(x=%d,y=%d)",pFood->pos[i].x,pFood->pos[i].y);
}
/**********************************
* 功能:
* 生成食物
***********************************/
void MakeFood(HALL *pHall,FOOD *pFood)
{
 srand((unsigned)time(NULL));
 int tot;
 for(tot = 1 ; tot <= 7 ; ++tot)
 {
  int ixFood = rand() * pHall->len / RAND_MAX;
  pFood->pos[tot].x = pHall->pos[ixFood].x;
  pFood->pos[tot].y = pHall->pos[ixFood].y;
 }
 pFood->len = 7;
}

希望本文所述对大家的C++程序设计有所帮助。

 类似资料:
  • 本文向大家介绍基于C语言实现的贪吃蛇游戏完整实例代码,包括了基于C语言实现的贪吃蛇游戏完整实例代码的使用技巧和注意事项,需要的朋友参考一下 本文以实例的形式讲述了基于C语言实现的贪吃蛇游戏代码,这是一个比较常见的游戏,代码备有比较详细的注释,对于读者理解有一定的帮助。 贪吃蛇完整实现代码如下:

  • 本文向大家介绍C++控制台实现俄罗斯方块游戏,包括了C++控制台实现俄罗斯方块游戏的使用技巧和注意事项,需要的朋友参考一下 之前学了些C++的课程,一直想着说编点小游戏,可是MFC又不想学,所以就只能变成控制台的小游戏。 俄罗斯方块一定是很多人小时候玩过的游戏。接下来就说说设计想法。 主要实现,选择游戏的等级,加速下降,不同形状不同颜色,暂停和退出功能。 首先是类的设计。 接下来就是一些常量和光标

  • 本文向大家介绍java实现简单控制台五子棋游戏,包括了java实现简单控制台五子棋游戏的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了java实现简单控制台五子棋的具体代码,供大家参考,具体内容如下 GobangMain这个类是游戏的主方法,主要用于控制游戏的执行,值得注意的是输入的坐标的格式是3,4的样式,不能是其他的格式,也不能出现空格。 Point类 Gobang 类是游戏类,

  • 本文向大家介绍canvas实现绘制吃豆鱼效果,包括了canvas实现绘制吃豆鱼效果的使用技巧和注意事项,需要的朋友参考一下 话不多说,请看代码: 以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持呐喊教程!

  • 本文向大家介绍C语言控制台实现打飞机小游戏,包括了C语言控制台实现打飞机小游戏的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了C语言实现打飞机小游戏的具体代码,供大家参考,具体内容如下 初学C语言总觉得不能做些什么好玩的,这个小游戏只需 “一点点” (千真万确)C语言知识就能完成! 总计不到200行的非空白代码(没有强行压缩行数) 操作说明: 1.W、S、A、D 控制 上 、下、左、

  • 本文向大家介绍C#贪吃蛇游戏实现分析,包括了C#贪吃蛇游戏实现分析的使用技巧和注意事项,需要的朋友参考一下 今天无聊突发奇想做个贪吃蛇,虽然网上很多这东西了,不过自己写的感觉还行吧 贪吃蛇分析 游戏规则: 1、蛇起始长度5,每吃一个食物增加1,最大15过关 2、蛇用蓝色表示,食物用绿色,障碍物用黑色 3、当蛇碰到自己、墙壁、障碍物则游戏失败 4、方向键控制蛇的移动方向,蛇不可反方向移动,如正在向上

  • 本文向大家介绍Java控制台实现猜拳游戏小游戏,包括了Java控制台实现猜拳游戏小游戏的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了Java猜拳游戏的具体代码,供大家参考,具体内容如下 先来看一下效果图:  首先我们创建一个Person类,这个类有name和score两个属性,有play这个方法,源代码如下: 接下来是主程序入口: 源代码下载:Java猜拳游戏 以上就是本文的全部内

  • 本文向大家介绍linux控制台下实现2048小游戏,包括了linux控制台下实现2048小游戏的使用技巧和注意事项,需要的朋友参考一下 废话少说,直接奉上代码: main.c 2048.h 2048.c 以上就是本文分享的全部代码了,希望对大家学习Linux控制台能够有所帮助。