首页 > 其他分享 >C语言“贪吃蛇”小游戏二次开发

C语言“贪吃蛇”小游戏二次开发

时间:2024-03-04 18:56:21浏览次数:32  
标签:int void Pos 小游戏 pf printf 二次开发 贪吃蛇

引言
当谈到经典的电子游戏时,贪吃蛇(Snake)无疑是首选之一。贪吃蛇游戏以简单却具有挑战性的玩法深受玩家喜爱。在游戏中,玩家需要操控一条蛇在游戏界面上不断移动,吃掉食物并尽可能长大,同时避免撞到墙壁或者自己的身体。其简单却耐玩的特点使得贪吃蛇成为了许多人童年时的美好回忆。
笔者选择了一个开源的贪吃蛇项目进行二次开发,以提升游戏的可玩性和趣味性,增加新的游戏元素,改进游戏界面设计,以期打造出更加吸引人的游戏版本。

原始代码

点击查看代码
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <time.h>

void welcome();  //欢迎界面 
void border();  //创建边界 
void Pos(int x, int y);  //改变控制台光标位置 
void getRandomPos(int *x, int *y);  //获取随机坐标
void initSnake();  //蛇的初始化
void createFood();  //生成食物
int inSnake(int x, int y);  //判断(x, y)是否在蛇上,1表示在,0表示不在 
void snakeMove();  //蛇的移动 
int getDirection();  //获取移动方向,0、1、2、3分别代表上、下、左、右 

typedef struct Node{
	int x;
	int y;
	Node* next;
}node;

//全局变量
node* head;  //蛇头
node food;  //食物 
int reCreateFood;  //判断食物是否被吃掉
int fail;  //如果蛇头碰到蛇身或边界则失败 
int score, add = 10;  //定义分数和每个食物的分数 
int dx[4] = {0, 0, -1, 1}, dy[4] = {-1, 1, 0, 0};  //(dx[0], dy[0])为(0, 1),即代表“上”
int d = -1;  //表示蛇前进的方向,与上一行对应,0为上,1为下,2为左,3为右
//开局时初始化为-1,表示还未按方向键 

int main(){
	welcome();  //欢迎界面 
	border();  //创建边界 
	initSnake();  //蛇的初始化 
	createFood();  //生成食物 
	
	//fail != 0就一直进行 
	while(1){
		if(fail) break;
		//食物被吃掉需要重新生成 
		if(reCreateFood){
			createFood();
			reCreateFood = 0;
		}
		snakeMove();  //蛇的移动 
		Sleep(500);  //程序暂停500毫秒,注释掉运行一下就懂了
		//获取新的方向 
		d = getDirection(); 
	}
	
	//这个也是注释掉对比一下就懂了 
	Pos(0, 24);
	printf("\n");
	
	return 0;
}

void welcome(){
	system("mode con cols=100 lines=30");
	system("cls");
	
	Pos(38,6);
	printf("welcome come to SnakeGame\n");
	Pos(38,8);
	printf("↑↓←→control direction\n");
	Pos(45,10);
	printf("ESC For Exit\n");
	Pos(42,12);
	printf("Enter For Begin\n");
	getchar();
	system("cls");
}

void border(){  //创建以(0, 0), (59, 25)为顶点的矩形边界
	for(int i = 0; i < 60; i ++ ){
		Pos(i, 0);  //上行 
		printf("▇");
		Pos(i, 25);  //下行 
		printf("▇"); 
	} 
	
	for(int i = 1; i < 25; i ++ ){
		Pos(0, i);  //左列 
		printf("▇");
		Pos(59, i);  //右列 
		printf("▇");
	}
}

void Pos(int x, int y){
	COORD pos;  //位置坐标 
	pos.X = x;
	pos.Y = y;
	
	HANDLE handleOutput = GetStdHandle(STD_OUTPUT_HANDLE);  //获取输出句柄 
	SetConsoleCursorPosition(handleOutput, pos);   //定位 
}

void getRandomPos(int *x, int *y){
	srand((unsigned int)time(NULL));
    *x = rand() % 58 + 1;
    *y = rand() % 24 + 1;
}

void initSnake(){ 
	head = (node*)malloc(sizeof(node));
	//保证在边界内
	head->x = rand() % 58 + 1;   
	head->y = rand() % 24 + 1;
	head->next = NULL;
	
	Pos(head->x, head->y);
	printf("*");
}

void createFood(){
	int x, y;
	getRandomPos(&x, &y);
	if(inSnake(x, y)) createFood();  //重新生成
	food.x = x;
	food.y = y;
	Pos(x, y);
	printf("$");
}

int inSnake(int x, int y){
	node* p = head->next;
	while(p){  //从头遍历蛇身 
		if(x == p->x && y == p->y)
			return 1;
		p = p->next;
	}
	return 0;
} 

void snakeMove(){
	//刚开局未按方向键的情况 
	if(d == -1)
		while(d == -1) d = getDirection();

	node* newHead = (node*)malloc(sizeof(node));
	newHead->x = head->x + dx[d];
	newHead->y = head->y + dy[d];
	newHead->next = head;
	head = newHead;
	
	node* p = head;
	if(inSnake(p->x, p->y) || (p->x == 0 || p->x == 59 || p->y == 0 || p->y == 25))
		fail = 1;
	else if(p->x != food.x || p->y != food.y){
		Pos(p->x, p->y);
		printf("*");
		
		while(p->next->next) p = p->next;
		Pos(p->next->x, p->next->y);
		printf(" ");
		p->next = NULL;
	} 
	else{
		reCreateFood = 1;
		score += add;
		Pos(p->x, p->y);
		printf("*");
	}
	Pos(61, 25);
	printf("您的得分为:%d", score);
}

int getDirection(){
	//不能往反方向走 
	if((GetAsyncKeyState(VK_UP) & 0x8000) && d != 1) d = 0;
	else if((GetAsyncKeyState(VK_DOWN) & 0x8000) && d != 0) d = 1;
	else if((GetAsyncKeyState(VK_LEFT) & 0x8000) && d != 3) d = 2;
	else if((GetAsyncKeyState(VK_RIGHT) & 0x8000) && d != 2) d = 3;	
	return d; 
}

游戏主界面

游戏运行界面

原程序存在的缺点

  1. 原程序无法保存玩家之前的积分记录,缺少游戏的挑战性及成就感;
  2. 游戏界面活动范围过小,游戏画面单调、缺乏设计,游戏过程中不可暂停或重新开始,导致游戏的体验感较差;
  3. “贪吃蛇”的移动速度不可改变,且移动方向不可随意操作,只能上下左右移动,缺乏趣味性。

改进方案

  1. 添加积分排行榜,即记录玩家每次的积分,以及耗时;
void ReadGrade()
{
	FILE* pf = fopen("贪吃蛇最高得分记录.txt", "r"); //以只读的方式打开文件
	if (pf == NULL) //打开文件失败
	{
		pf = fopen("贪吃蛇最高得分记录.txt", "w"); //以只写的方式打开文件
		fwrite(&max, sizeof(int), 1, pf); //将max写入文件(此时max为0),即将最高得分初始化为0
	}
	fseek(pf, 0, SEEK_SET); //使文件指针pf指向文件开头
	fread(&max, sizeof(int), 1, pf); //读取文件当中的最高得分到max当中
	fclose(pf); //关闭文件
	pf = NULL; //文件指针及时置空
}
//更新最高分到文件
void WriteGrade()
{
	FILE* pf = fopen("贪吃蛇最高得分记录.txt", "w"); //以只写的方式打开文件
	if (pf == NULL) //打开文件失败
	{
		printf("保存最高得分记录失败\n");
		exit(0);
	}
	fwrite(&grade, sizeof(int), 1, pf); //将本局游戏得分写入文件当中
	fclose(pf); //关闭文件
	pf = NULL; //文件指针及时置空
}
  1. 界面设计:

扩大“贪吃蛇”的活动范围;

void border(){
    for(int i = 0; i < 80; i ++ ){ // 扩大边界为 80 * 30
        Pos(i, 0);
        printf("■");
        Pos(i, 29);
        printf("■");
    }

    for(int i = 1; i < 29; i ++ ){
        Pos(0, i);
        printf("■");
        Pos(79, i);
        printf("■");
    }
}

美化游戏界面;

struct Snake
{
	int len; //记录蛇身长度
	int x; //蛇头横坐标
	int y; //蛇头纵坐标
}snake;
 
//蛇身
struct Body
{
	int x; //蛇身横坐标
	int y; //蛇身纵坐标
}body[ROW*COL]; //开辟足以存储蛇身的结构体数组
 
int face[ROW][COL]; //标记游戏区各个位置的状态
void InitInterface()
{
	color(6); //颜色设置为土黄色
	for (int i = 0; i < ROW; i++)
	{
		for (int j = 0; j < COL; j++)
		{
			if (j == 0 || j == COL - 1)
			{
				face[i][j] = WALL; //标记该位置为墙
				CursorJump(2 * j, i);
				printf("■");
			}
			else if (i == 0 || i == ROW - 1)
			{
				face[i][j] = WALL; //标记该位置为墙
				printf("■");
			}
			else
			{
				face[i][j] = KONG; //标记该位置为空
			}
		}
	}
	color(7); //颜色设置为白色
	CursorJump(0, ROW);
	printf("当前得分:%d", grade);
	CursorJump(COL, ROW);
	printf("历史最高得分:%d", max);
}
  1. 改善“贪吃蛇”的移动问题;

改进后效果

结语
通过这次对贪吃蛇游戏的二次开发,我收获了更多宝贵的经验和教训。尽管经过一番努力和改进,程序仍存在一些缺陷和不足,但在这个过程中,不仅让我更加熟悉了项目的开发流程,也让我更加自信地面对编程中的挑战与困难。在迭代优化过程中,我逐渐提升了自己的问题分析能力、解决问题的能力以及编程实践能力。
未来,我会继续努力学习,不断提升自己的编程水平,追求更高的技术成就。编程之路漫长而又充满挑战,但正是这种挑战让我不断前行,不断进步。感谢这次作业给我带来的成长与启示!

标签:int,void,Pos,小游戏,pf,printf,二次开发,贪吃蛇
From: https://www.cnblogs.com/ccchenxx/p/18052395

相关文章

  • Python项目 简单计算器的二次开发
    在互联网上找到一个简单计算器的项目源码点击查看代码#计算器#加法defadd(a,b):c=a+bprint(f"结果为:{c:.2f}")#减法defsub(a,b):c=a-bprint(f"结果为:{c:.2f}")#乘法defmul(a,b):c=a*bprint(f"结果为:{c:.2f}......
  • 鲨鱼记账二次开发
    一. 明细方面① 货币仅支持人民币,可以加设多种货币,记录后并自动以当天汇率转化为人民币。② 关于初始的明细方面,设置的分类过于复杂,可精简设置,后续用户自己依据自身需求进行添加。③ 记录支出和收入时,可以分配不同银行卡和不同平台,更好管理资产。二. 图表方面‘① 没有饼状图,可......
  • C++网上购书系统项目的二次开发
    1.来源该项目来自同学以前的期末大作业:网上购书系统项目。2.运行环境及运行结果(1)运行环境:DevC++(2)运行结果:代码如下:点击查看代码#include<iostream>#include<string>#include<fstream>#include<vector>#include"buyer.h"#include"book.h"#include"order.h&q......
  • c语言项目 球球大作战(简易版)小游戏的二次开发
    引言《球球大作战》虽然在玩法上类似于大球吃小球的模式看起来很单薄,但是在游戏过程中会出现无数种意外情况,这就需要玩家运用一系列策略来达到不被吃和吃掉别人球的目的,大大增加了游戏的耐玩性。游戏彻底抛弃了枯燥无味的单机模式,采取全球玩家联网实时对战。当竞技在PC端打的火热......
  • java Flappy Bird小游戏二次开发
    引言FlappyBird是一款广为人知的经典小游戏,以其简单的操作方式和高难度挑战吸引了全球数百万玩家。游戏的核心机制非常直接——玩家通过点击屏幕使小鸟飞翔,避免碰撞到上下移动的管道,同时尽可能地飞行得更远。这种看似简单的游戏设计隐藏了深层的挑战性和上瘾性,让人不禁一试再试......
  • C语言贪吃蛇小游戏
    #include<stdio.h>#include<graphics.h>//里面有easyX图形库函数#include<conio.h>#include<time.h>#include<mmsystem.h>//#pragmacomment(lib,"winmm.lib")/******************************结构体*****************************......
  • 软件开发与创新第一周实验——关于“打怪小游戏”的试玩体验与修改
    一.“打怪小游戏”代码来源http://blog.csdn.net/zjx120307/article/details/126221342?spm=1001.2014.3001.5506二.运行环境及运行结果1.运行环境:Windows11操作系统,C++运行环境2.运行截图:(1)功能6演示(2)功能1演示(3)功能2演示(4)功能3演示(5)功能4演示原代码:点击查看代......
  • C写的贪吃蛇小游戏
    用了三四个小时跟视频写的小游戏,还是优点漏洞,明明加了音乐但是没声音,代码也没报错不知道啥原因;哪位大佬可以帮忙看看环境:win10,vs2017专业版用到的库://里面有easyX图形库函数#include#include//里面有easyX图形库函数#include#include#include//#pragmaco......
  • 微信小游戏开发流程
    微信小游戏开发相对于传统的网页小游戏开发有一些特定的步骤和要求,以下是一个微信小游戏开发的基本流程。1.注册和准备:注册微信开发者账号,并在微信开放平台创建小游戏项目。下载并安装微信开发者工具。2.项目初始化:在微信开发者工具中创建一个新的小游戏项目。选择合适的开......
  • c++小游戏合集
    1.恶魔轮盘赌恶魔轮盘赌代码#include<windows.h>#include<bits/stdc++.h>usingnamespacestd;intYour=6,Other=6;stringdaojuname[]={"放大镜","手铐","小刀","烟","饮料"};doubleYourmoney;intshi,kong;intq[10],......