大家好,又见面了,我是你们的朋友全栈君。
前引
这个贪吃蛇是在我学完C语言的基本部分 在跟着哈工大的c语言程序设计Mooc课程完了之后做的 因为学完C语言很迷茫 不晓得应该学什么 学校里面的题库感觉刷起来又没有实际我能看到的东西 我认为在阶段性的学习过程中应该找到自己能够看得到的成果 才能刺激自己继续往前进 继续学习 不然很枯燥的学习谁都坚持不下去
这也是在看了视频教程后 自己一步步敲出来的 其实还是建议大家在看懂 了代码后自己实现 因为不要怕自己忘不忘 这又不是理论知识 敲出来的代码就是自己的 一步步的提升 加油qwq
另外 此代码保证可以运行
在这篇博客发布后一年 我需要用这个交大作业时用的还是这个博客的代码
编译无错 依然能够流畅无阻的运行
主要问题部分集中于头文件部分
详情多看一下头文件注释部分
头文件注释部分
这里是head.h头文件 因为可以使主文件看起来更整洁更清晰
因为我用的是code:blocks 头文件的创建是在File->New->Class中 然后点击创建就ok了 记得如果想看一下这个代码的实现效果 自己也创建头文件名字是head哦 不然头文件名字匹配不了hhhh 或者大家自己把代码一起copy到主程序里面也可以qwq 还有记得要把cpp给取消掉qwq
头文件创建截图
头文件部分
#ifndef HEAD_H
#define HEAD_H
#define SnakeMaxLength 20
typedef int bool;
#define true 1
#define false -1
//背景布置
//这里解释一下 一个特殊字符实线格子在横列是占两格
//所以空白格子在圈中要以两倍的间隔空格隔开
char MyBackGround[22][80]={
"■■■■■■■■■■■■■■■■■■■■\n",
"■ ■\n",
"■ ■\n",
"■ ■\n",
"■ ■\n",
"■ ■\n",
"■ ■\t\t\t欢乐时光就要开始了\n",
"■ ■\n",
"■ ■\t\t\tW A S D控制操作\n",
"■ ■\n",
"■ ■\t\t\t碰到墙壁死亡\n",
"■ ■\n",
"■ ■\t\t\t祝好运\n",
"■ ■\n",
"■ ■\n",
"■ ■\n",
"■ ■\n",
"■ ■\n",
"■ ■\n",
"■■■■■■■■■■■■■■■■■■■■\n"};
//这里使用了枚举 为什么这里go_ease = -2 因为这里特殊字符在横向占两格
//数列只占一个格子
enum Direction{
go_east = -2,go_west = 2,go_north = -1,go_south = 1};
int ArrSnake[SnakeMaxLength][3]={
{
0,0,0}};
//判断蛇默认开始方向
int SnakeDirection = go_east;
//判断食物是否还存在
bool OptionFoodAlive = false;
int x,y;
#endif
这里是主函数main.h的实现
里面有音乐播放功能 但只能用WAV文件格式
wav格式的音乐文件甩到你的exe文件旁边
因为用的是相对路径 然后歌名改成1.wav就ok了如果不想改音乐文件的话就把程序中的MyMusic那里1.wav改成你的音乐名字即可
主函数部分
#include <stdio.h>
#include <stdlib.h>
#include <string.h>//使用strncpy函数
#include <conio.h>//_getch()要用
#include <windows.h>//这个是有些函数要用
#include "head.h"//包含头文件
#include <time.h>//随机值懂得奥
#define true 1
#define false -1
typedef int bool;
int scores = 0;
//首页
void FirstPage();
//播放音乐
void MyMusic();
//按回车键进入游戏
void EnterGame();
//停止音乐
void StopMusic();
//清空页面
void CleanScreen();
//背景基础函数
void BackGround();
//蛇爹的初始位置
void SetSnakePos();
//画蛇的位置
bool GiveSnake();
//给蛇的位置赋值
void MoveSnake();
//删除蛇
void DeleteSnake();
//控制蛇
void ControlSnake();
//判断蛇是否死亡
bool IsSnakeAlive();
//制造食物
void ProduceFood();
//蛇变长
void LengthenSnake();
//首页
void FirstPage()
{
printf("\n\n\n\n\n\n");
printf("\t\t\t\t\t 《欢迎来到贪吃蛇的世界》\n\n\n");
printf("\t\t\t\t\t 《W A S D 控制蛇前进后退》\n\n\n");
printf("\t\t\t\t\t 《按下ENTER键开始新游戏》\n\n\n\n");
printf("\t\t\t\t\t 《再次感谢游玩此游戏》\n");
}
//播放音乐
//这里可以删除功能 不想添加因为删掉就ok了
void MyMusic()
{
PlaySound("1.wav",NULL,SND_FILENAME | SND_ASYNC );
}
//按回车键进入游戏
void EnterGame()
{
while('\r'!=_getch());
}
//停止音乐
void StopMusic()
{
PlaySound(NULL, 0, 0);
}
//清空页面
void CleanScreen()
{
system("cls");
}
//背景基础函数
//布置背景嗷 头文件里面的背景
void BackGround()
{
int i;
for(i=0; i<20; i++)
{
printf("%s",MyBackGround[i]);
}
}
//蛇爹的初始位置
void SetSnakePos()
{
//其实这里的x , y我在后面加备注的时候我觉得会错意了
//这里的x 我想表示的是他的行数
//这里的y 我想表示的是他的列数 就是第几列
//如果大家想改程序可以改成
//x是rows y是lines即可 我懒我就懒得改了 大家懂的就ok了
int x=-1;
int y=-1;
srand(time(NULL));
y = rand()%16+1;//给蛇的位置赋值 默认蛇初始有三个格子
x = rand()%16+1;
ArrSnake[0][0] = x;
ArrSnake[0][1] = y*2;//为什么乘以二呢 因为特殊格子在横向是占两格
ArrSnake[0][2] = go_east;
ArrSnake[1][0] = x;
ArrSnake[1][1] = y*2 + 2;//加二是因为一个字符两个格子
ArrSnake[1][2] = go_east;
ArrSnake[2][0] = x;
ArrSnake[2][1] = y*2 + 4;
ArrSnake[2][2] = go_east;
}
//画蛇的位置
bool GiveSnake()
{
int i;
for(i=0; ArrSnake[i][0] != 0;i++)
{
//为什么使用strncpy呢 因为更安全hhhh 可以限制格子数
strncpy(&MyBackGround[ArrSnake[i][0]][ArrSnake[i][1]],"■",2);
if(i && ArrSnake[0][0] == ArrSnake[i][0] && ArrSnake[0][1] == ArrSnake[i][1]) return false;
}
return true;
}
//删除蛇
//为什么要删除蛇呢 因为这个蛇的移动就是一个 赋值 删除 赋值 删除的过程
//删除掉原来的蛇 然后再把现在的蛇表示出来 不然的话
//原来的蛇和现在的蛇就一直重复 导致原来的蛇一直在屏幕上
void DeleteSnake()
{
int i;
for(i=0; ArrSnake[i][0] != 0;i++)
{
strncpy(&MyBackGround[ArrSnake[i][0]][ArrSnake[i][1]]," ",2);
}
}
//蛇的坐标赋值
void MoveSnake()
{
int i=SnakeMaxLength-1;
ArrSnake[0][2]=SnakeDirection;
for(;i>=1;i--)
{
//过滤坐标为0
if(0 == ArrSnake[i][0])
{
continue;
}
//将上一个物块的值赋值给下一个物块(除蛇头)
ArrSnake[i][0]=ArrSnake[i-1][0];
ArrSnake[i][1]=ArrSnake[i-1][1];
ArrSnake[i][2]=ArrSnake[i-1][2];
}
//处理蛇头
if( go_east == ArrSnake[0][2] || go_west == ArrSnake[0][2])
{
ArrSnake[0][1]+=ArrSnake[0][2];
}
else
{
ArrSnake[0][0]+=ArrSnake[0][2];
}
}
//控制蛇的方向
//这里是控制蛇的方向
//具体为什么用这个函数 大家可以自急查询一下
//这个Asyn的意思就是 异步的意思 表示你在操作的时候同时读入你键盘的值
//如果是同步的话 大家可以想象一下 需要你敲下回车 蛇才移动 不是嘛hhhh
void ControlSnake()
{
if(GetAsyncKeyState('W'))
{
if(SnakeDirection != go_south)
SnakeDirection=go_north;
}
else if(GetAsyncKeyState('S'))
{
if(SnakeDirection != go_north)
SnakeDirection=go_south;
}
else if(GetAsyncKeyState('A'))
{
if(SnakeDirection != go_west)
SnakeDirection=go_east;
}
else if(GetAsyncKeyState('D'))
{
if(SnakeDirection != go_east)
SnakeDirection=go_west;
}
}
//判断蛇是否死亡
bool IsSnakeAlive()
{
if(0 == strncmp(&MyBackGround[ArrSnake[0][0]][ArrSnake[0][1]],"■",2))
{
return false;
}
else
{
return true;
}
}
//制造食物
void ProduceFood()
{
//蛇的坐标
int i;
srand(time(NULL));
//蛇的坐标给予
if(true == OptionFoodAlive)
{
return;
}
while(1)
{
bool tempbool = true;
x=rand()%18 + 1;
y=rand()%18 + 1;
for(i=0 ; i<ArrSnake[i][0] ; i++)
{
if(x == ArrSnake[i][0] && 2*y == ArrSnake[i][1])
{
tempbool = false;
break;
}
}
if(true == tempbool)
{
break;
}
}
strncpy(&MyBackGround[x][y*2],"★",2);
OptionFoodAlive = true;
}
//这里就是加长蛇的长度了
void LengthenSnake()
{
int i=0;
if(x == ArrSnake[0][0] && 2*y == ArrSnake[0][1])
{
OptionFoodAlive = false;
scores += 10;
for(; ;i++)
{
if(ArrSnake[i][0] == 0)
{
if(ArrSnake[i][2] == go_north || ArrSnake[i][2] == go_south)
{
ArrSnake[i][0]=ArrSnake[i-1][0]-ArrSnake[i-1][2];
ArrSnake[i][1]=ArrSnake[i-1][1];
ArrSnake[i][2]=ArrSnake[i-1][2];
}
else
{
ArrSnake[i][0]=ArrSnake[i-1][0];
ArrSnake[i][1]=ArrSnake[i][1]-ArrSnake[i][2];
ArrSnake[i][2]=ArrSnake[i][2];
}
break;
}
}
}
}
//这里就是主函数具体怎么实现的了
//这个贪吃蛇还包含了重启功能
//这个注释还是挺详细的了 希望能对大家有所帮助 大家一起加油
int main()
{
FirstPage();//首页显示
MyMusic();//音乐播放
EnterGame();//按回车键进入游戏
StopMusic();//停止音乐
CleanScreen();//清空屏幕(为正式游戏做铺垫)
SetSnakePos();//设置蛇的初始坐标
while(1)
{
int flag = 0;
ProduceFood();//制造食物
DeleteSnake();//删除蛇
ControlSnake();//控制蛇的移动
MoveSnake();//蛇移动图案
if(false == IsSnakeAlive()) flag = 1;
LengthenSnake();
if(false == GiveSnake()) flag = 1;//给予蛇在背景中图案
BackGround();//布置背景
Sleep(300);
system("cls");
if(flag)
{
printf("Ur scores = %d\n",scores);
printf("Thanks for playing this game!\n");
break;
}
system("pause");
}
return 0;
}
实现效果
一年后 重新复制本篇博客到
新的文件 codeblocks 本地运行 运行编译正确 运行流畅
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/154066.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...