C语言书写羊了个羊第一关(详解版)(二)

简介: C语言书写羊了个羊第一关(详解版)(二)

加载游戏图片(重点)

void updategame()
{
  BeginBatchDraw();               // 双缓冲区, 加载图片的时候, 防止闪烁
  putimage(0, 0, &BG);
  int distanceX = (504 - 61 * 3 - 15 * 2) / 2;
  int distanceY = 270;
  for (int i = 0; i < 3; i++)
  {
    for (int j = 0; j < 3; j++)
    {
      if (map[i][j] == 0)      //
      {
        continue;
      }
      else
      {
        int x = distanceX + j * (61 + 15);
        int y = distanceY + i * (68 + 15);
        putimage(x, y, &Role[map[i][j] - 1]);
      }
    }
  }
  for (int i = 0; i < 7; i++)
  {
    if (cao[i] != 0)
    {
      int x = 26 + 64.7 * i;
      int y = 696;
      putimage(x, y, &Role[cao[i] - 1]);
    }
  }
  EndBatchDraw();
}

1.在加载图片的过程中,可能会出现图片的闪烁
解决办法:建立一个双缓冲区

用BeighBatchDraw()函数和EedBatchDraw()函数。

将加载图片的步骤,放在两个函数的中间。

2.放置背景图片

3… 放置游戏图片 , 数组中1代表的是 第一张图片, 2代表的是第二张图片, 3代表的是第三张图片,0则不打印图片(即直接continue)

这里需要做一些简单的计算, 通过背景图片的大小和游戏图片的大小,,计算出相对应的距离,让图片放在相应的位置

distancex是图片离,游戏左框框的位置(初始值需要具体计算)

distancey是图片离, 游戏上框框的位置(图片没在中间, 初始值随便恰当给个距离)

15(可以自己随便设置) 为2张图片的间隔距离

4.放置羊槽的图片,羊槽中最多可以放置7张图片, 这里需要在画图工具,用刻度尺,自己量一下羊槽的总距离,在根据元游戏图片的大小,进行一个简单的计算。

羊槽的元素最开始初始化为0, 打印图片,

肯定是cao[i] ! = 0;

图片的点击

typedef struct location
{
  int row;
  int col;
}LO;
bool userClick(LO* Location)
{
  ExMessage m;
  if (peekmessage(&m) && m.message == WM_LBUTTONDOWN)   //检查是否有鼠标左键的消息
  {
    int distanceX = (504 - 61 * 3 - 15 * 2) / 2;
    int distanceY = 270;
    int col = (m.x - distanceX) / (61 + 15);
    int row = (m.y - distanceY) / (68 + 15);
    if (row >= 0 && row < 3 && col >= 0 && col < 3)
    {
      Location->row = row;
      Location->col = col;
      return true;
    }
    printf("%d %d\n", col, row);
  }
  return false;
}

函数作用:通过鼠标的左键点击图片,并且记录鼠标点击位置

这里使用了结构体(int row int col 分别代表行和列), 通过指针传递,同时函数用的是bool类型,为真肯定句调用,为假就不调用。

1.先定义一个结构体。

2.用easxy库, 检查有无鼠标左键的消息。

3.鼠标点击的范围的设置(只能在游戏那个三维数组中才能够生效)。

4.这里也需要做一些计算,算出三维数组的位置,而结构体记录鼠标点击的位置。

游戏图片的删除,消掉与转移(重点)

void work(LO* Location)
{
  int index = map[Location->row][Location->col];
  int i = 0;
  //for (; i < 7 && cao[i]; i++); //如果第一个槽为0,结束, 如果第一个槽不为0, 就继续++,直到找到槽为0的时候,此时i的值结束。
  //if (i < 7)
  //{
  //  cao[i] = index;
  //
  //}
  for (int i = 0; i < 7; i++)
  {
    if (cao[i] == 0)
    {
      cao[i] = index;
      break;
    }
  }
  int cout = 0;
  for (int i = 0; i < 7; i++)
  {
    if (cao[i] == map[Location->row][Location->col])
    {
      cout++;
    }
  }
  if (cout == 3)
  {
    for (int i = 0; i < 7; i++)
    {
      if (cao[i] == map[Location->row][Location->col])
      {
        cao[i] = 0;
      }
    }
  }
  map[Location->row][Location->col] = 0;
}

1.这里用 int index 来接受 鼠标点击数组元素的大小(通过结构体记录鼠标点击的位置)

2.图片的转移, 图片转移到羊槽上去,就如果羊槽中的元素为0,

就让它 = index,让它从左到右,挨个打印照片, 具体操作这里写了2种方法,代码注释读的部分是方法二

3.图片的消除,在羊槽中3个一样的便会消除, 这里我用cout这个变量来记录的图片重复出现的次数, (用循环)如果羊槽中数组的值等于游戏三维数组的值,那么cout++。 (用循环)if cout == 3, 那么羊槽中 这个元素与三维数组元素相等的,cao[i] = 0;,消掉

4.图片的删除,就让鼠标点击的那个三维数组的值

游戏结束

bool gameover()

{

for (int i = 0; i < 3; i++)
{
  for (int j = 0; j < 3; j++)
    if (map[i][j] == 1)
    {
      return false;
    }
    else if (map[i][j] == 2)
    {
      return false;
    }
    else if (map[i][j] == 3)
    {
      return false;
    }
}
return true;

}

游戏结束,也是用bool 类型来判断,结束的话就返回 true

游戏结束的标志:,三维数组中的值 不等于1,不等于2,不等于3(都不等于的话,代表着,三维数组值都为0,没有了图片,都在羊槽中被消掉了)

主函数

int main()
{
  initgraph(504, 900);
  initmenu();
  initgame();
  LO Location;
  while (1)
  {   
    if (userClick(&Location))
    {
      work(&Location);
    }
    updategame();
    if (gameover())
    {
      setbkmode(TRANSPARENT);
      settextcolor(YELLOW);
      settextstyle(50, 0, "楷体");
      outtextxy(30, 300, "不愧是你!!");
      outtextxy(100, 400, "恭喜通关!!");
      outtextxy(200, 500, "你赢了!!");
      break;
    }
  }
  system("pause");
  return 0;
}

当然主函数中,调用游戏结束那部分,后面也用了easyx库的东西,打印字,以及字体的颜色,模式,大小。

注意:别忘了用initgraph()函数,创建一个窗口。

头文件和定义的变量,以及函数的声明

#include<stdio.h>
#include<graphics.h>
#include<mmsystem.h>
#pragma comment(lib, "winmm.lib")
#include<time.h>
#include<stdlib.h>
#include<conio.h>
IMAGE MENU1;
IMAGE MENU2[4];
IMAGE MENU3;
IMAGE BG;
IMAGE Role[3];
int map[3][3];
int cao[7];
void initmenu();
void initgame();
void initMap();
void updategame();
bool gameover();
typedef struct location
{
  int row;
  int col;
}LO;
bool userClick(LO* location);
void work(LO* Location);

这部分代码,很简单,有的就是一些固定的格式,就不在讲解了

源码和图片素材领取(百度网盘)

百度网盘图片素材和源码链接

提取码:1111

老铁们,这是压缩包,下载后,直接解压就行。

点个关注,点个赞。
你们的关注和点赞以及收藏真的对我很重要, 后续会与大家分享更多优质的博客


相关文章
|
定位技术 C语言 C++
C语言书写推箱子(坤坤版easyx库)
C语言书写推箱子(坤坤版easyx库)
|
C语言
C语言:二进制、八进制、十六进制整数的书写及输出
C语言:二进制、八进制、十六进制整数的书写及输出
|
定位技术 C语言 C++
C语言书写羊了个羊第一关(详解版)(一)
C语言书写羊了个羊第一关(详解版)
|
消息中间件 人工智能 算法
C语言程序书写规范
C语言程序书写规范 我做C语言底层开发,积累了一些代码书写的经验供大家参考: 1.C语言书写规范 1.1符号命名规则
386 0
|
2月前
|
C语言 C++
C语言 之 内存函数
C语言 之 内存函数
37 3
|
8天前
|
存储 缓存 算法
【C语言】内存管理函数详细讲解
在C语言编程中,内存管理是至关重要的。动态内存分配函数允许程序在运行时请求和释放内存,这对于处理不确定大小的数据结构至关重要。以下是C语言内存管理函数的详细讲解,包括每个函数的功能、标准格式、示例代码、代码解释及其输出。
33 6
|
26天前
|
C语言
c语言调用的函数的声明
被调用的函数的声明: 一个函数调用另一个函数需具备的条件: 首先被调用的函数必须是已经存在的函数,即头文件中存在或已经定义过; 如果使用库函数,一般应该在本文件开头用#include命令将调用有关库函数时在所需要用到的信息“包含”到本文件中。.h文件是头文件所用的后缀。 如果使用用户自己定义的函数,而且该函数与使用它的函数在同一个文件中,一般还应该在主调函数中对被调用的函数做声明。 如果被调用的函数定义出现在主调函数之前可以不必声明。 如果已在所有函数定义之前,在函数的外部已做了函数声明,则在各个主调函数中不必多所调用的函数在做声明
31 6
|
2月前
|
存储 缓存 C语言
【c语言】简单的算术操作符、输入输出函数
本文介绍了C语言中的算术操作符、赋值操作符、单目操作符以及输入输出函数 `printf` 和 `scanf` 的基本用法。算术操作符包括加、减、乘、除和求余,其中除法和求余运算有特殊规则。赋值操作符用于给变量赋值,并支持复合赋值。单目操作符包括自增自减、正负号和强制类型转换。输入输出函数 `printf` 和 `scanf` 用于格式化输入和输出,支持多种占位符和格式控制。通过示例代码详细解释了这些操作符和函数的使用方法。
44 10
|
1月前
|
存储 算法 程序员
C语言:库函数
C语言的库函数是预定义的函数,用于执行常见的编程任务,如输入输出、字符串处理、数学运算等。使用库函数可以简化编程工作,提高开发效率。C标准库提供了丰富的函数,满足各种需求。
|
2月前
|
机器学习/深度学习 C语言
【c语言】一篇文章搞懂函数递归
本文详细介绍了函数递归的概念、思想及其限制条件,并通过求阶乘、打印整数每一位和求斐波那契数等实例,展示了递归的应用。递归的核心在于将大问题分解为小问题,但需注意递归可能导致效率低下和栈溢出的问题。文章最后总结了递归的优缺点,提醒读者在实际编程中合理使用递归。
68 7