C语言小游戏:贪吃蛇
#include <graphics.h> #include <conio.h> #include <stdio.h> #define WIDTH 40 //设置宽 #define HEIGHT 30 //设置高 #define BLOCK_SIZE 20 //设置每个正方形格子边长 int Blocks[HEIGHT][WIDTH] = { 0 }; //我为什么要这个二维数组?是用来描述蛇身跟食物的! int food_i, food_j; char moveDirection; //用字符记录小蛇的移动方向 int isFailure = 0; void test() { //cleardevice();不能用清屏函数 //如何绘画出一个背景板? initgraph(WIDTH * BLOCK_SIZE, HEIGHT * BLOCK_SIZE); //如何布格子? //尝试一下画线来布置格子 setlinecolor(RGB(255,235,205));//并没有用处 //是否还缺什么函数? BeginBatchDraw(); FlushBatchDraw(); //以上两个绘图函数并没有绘出格子效果! } //尝试一下童晶的start代码 //void startup() // 初始化函数 //{ // int i; // Blocks[HEIGHT / 2][WIDTH / 2] = 1; // 画面中间画蛇头,数字为1 // for (i = 1; i <= 4; i++) // 向左依次4个蛇身,数值依次为2,3,4,5 // Blocks[HEIGHT / 2][WIDTH / 2 - i] = i + 1; // //moveDirection = 'd'; // 初始向右移动 // food_i = rand() % (HEIGHT - 5) + 2; // 初始化随机食物位置 // food_j = rand() % (WIDTH - 5) + 2; // // initgraph(WIDTH * BLOCK_SIZE, HEIGHT * BLOCK_SIZE); // 新开画面 // setlinecolor(RGB(200, 200, 200)); // 设置线条颜色 // BeginBatchDraw(); // 开始批量绘制 // //以下是我写的 // //} //到底哪里出问题??????? //自己写一个定义蛇蛇移动方向的函数 //自己写一个定义蛇蛇移动方向的函数 void My_move() //有大问题!蛇自己消失,不会往前移动的 { int i, j; for (i = 0; i < HEIGHT; i++) { for (j = 0; j < WIDTH; j++) { if (Blocks[i][j] > 0) { Blocks[i][j]++; //让旧小蛇中的数组元素加1 } } } int oldHead_i, oldHead_j, oldTail_i, oldTail_j; int max = 0; //利用max来找到蛇尾 for (i = 0; i < HEIGHT; i++) { for (j = 0; j < WIDTH; j++) { if (Blocks[i][j] > max) //利用max来找到蛇尾 { max = Blocks[i][j]; //更新max的大小 oldTail_i = i; oldTail_j = j; } if (Blocks[i][j] == 2) //记录蛇尾的位置 { oldHead_i = i; oldHead_j = j; } } } int newHead_i = oldHead_i; int newHead_j = oldHead_j; //if (moveDirection == 'd') //{ // newHead_j = oldHead_j + 1; //} if (moveDirection == 'w') //向上移动 newHead_i = oldHead_i - 1; else if (moveDirection == 's') //向下移动 newHead_i = oldHead_i + 1; else if (moveDirection == 'a') //向左移动 newHead_j = oldHead_j - 1; else if (moveDirection == 'd') //向右移动 newHead_j = oldHead_j + 1; //这里原来自己手写的代码没有加上边界判断,现在自己手动加上 if (newHead_i >= HEIGHT || newHead_i < 0 || newHead_j >= WIDTH || newHead_j < 0 || Blocks[newHead_i][newHead_j] > 0) //这里是判断头位置是否大于0,如果头元素大于0就 { isFailure = 1; //判断失败 return; //函数返回 } //Blocks[newHead_i][newHead_j] = 1; // 新蛇头位置数值为1 //判断没有游戏失败后 //开始判断是否吃到食物 Blocks[newHead_i][newHead_j] = 1; //新蛇头的元素置为1 if (newHead_i == food_i && newHead_j == food_j) //判断新蛇头是否碰到食物 { food_i = rand() % (HEIGHT - 3) + 2; food_j = rand() & (WIDTH - 3) + 2; //不用对旧蛇处理了,相当于蛇的长度+1 } else { Blocks[oldTail_i][oldTail_j] = 0; //旧蛇尾位置变空白,不吃食物时保持蛇的长度 } } void My_startup() { Blocks[HEIGHT / 2][WIDTH / 2] = 1; //将整个方块的中间格子设置为蛇头,为1 for (int i = 1; i <= 4; i++) { Blocks[HEIGHT / 2][WIDTH / 2 - i] = i + 1; //从左向右以此画四个蛇身 } moveDirection = 'd'; // 初始向右移动,忘记加默认方向了!! //开始画方向 food_i = rand() % (HEIGHT - 3) + 2; //应该会出现在角落的位置 food_j = rand() % (WIDTH - 3) + 2; //应该会出现在角落的位置 initgraph(WIDTH * BLOCK_SIZE, HEIGHT * BLOCK_SIZE);// 新开画面 setlinecolor(RGB(200, 150, 100));// 设置线条颜色 BeginBatchDraw();// 开始批量绘制 } //自己写一个展示背景格子的函数 void My_Show() { cleardevice(); int i, j; for (int i = 0; i < HEIGHT; i++) { for (int j = 0; j < WIDTH; j++) { //现在添加回显示蛇身的代码 if (Blocks[i][j] > 0) // 元素大于0表示是蛇,这里让蛇的身体颜色色调渐变 { setfillcolor(HSVtoRGB(Blocks[i][j] * 9, 0.9, 1)); } else setfillcolor(RGB(255,193,193)); // 元素为0表示为空,颜色为灰色 fillrectangle(BLOCK_SIZE *j, BLOCK_SIZE * i, BLOCK_SIZE * (j+1), BLOCK_SIZE * (i+1));// 在对应位置处,以对应颜色绘制小方格 } } setfillcolor(RGB(0, 255, 0)); // 食物为绿色 // 绘制食物小方块 fillrectangle(food_j * BLOCK_SIZE, food_i * BLOCK_SIZE, (food_j + 1) * BLOCK_SIZE, (food_i + 1) * BLOCK_SIZE); if (isFailure) // 如果游戏失败 { setbkmode(TRANSPARENT); // 文字字体透明 settextcolor(RGB(255, 0, 0));// 设定文字颜色 settextstyle(80, 0, _T("宋体")); // 设定文字大小、样式 outtextxy(240, 220, _T("游戏失败")); // 输出文字内容 } FlushBatchDraw(); } //自己定义一个在不按键的情况下蛇蛇自己移动的函数 void My_movewithNothing() { if (isFailure) // 如果游戏失败,函数返回 return; //尝试定义一个静态变量来用while 1 循环去驱动 static int move = 1; move++; if (move == 10) { My_move(); //moveSnake(); move = 1; } } //添加了按键后蛇会根据方向进行移动的函数 void My_movewithTouch() { if (kbhit() && isFailure == 0) //如果有按键输入并且没有出错的话 { char input = getch(); if (input == 'w' || input == 's' || input == 'a' || input == 'd') { moveDirection = input; My_move(); } } } int main() // 主函数 { //test(); //startup();//直接用这个初始化函数后,界面完全是黑色的,没有格子出现 My_startup(); //可以尝试一下用while 1 不断show出画面 while (1) { //show(); My_Show();//调用了这个函数后就出现背景格子了 My_movewithNothing(); My_movewithTouch(); } return 0; }