欢乐球吃球
【问题描述】
用 C 语言编写一个简单的“欢乐球吃球”游戏程序。欢乐球吃球是一款休闲与挑战并
存的游戏。在这个球球的世界里,每个人都成为一颗独特的球球,发展与生存是所有人的目
标,刺激战场极限逃生。程序需实现所要求的基本功能;在完成基本功能后,可以选择实现
数项扩展功能。
【基本功能要求】
1、 游戏初始界面如图 1 所示(示例,可自己设计)。
2、 游戏开始 例如:按下空格键后,“空格开始”消失游戏开始。
图 1 欢乐球吃球游戏开始界面示例
3、 游戏开始后:
1) 载入图片,有一个大球和若干随机运动的小球,例如图 2;
2) 玩家球可以在一定范围左右或上下移动,玩家用键盘(例如: WASD
键)和控制上、下、左、右运行。玩家碰到墙就停下来,需要调转方
向才能继续前进。玩家可吃球。玩家每吃一球加 1 分。;
3)每隔几秒钟(例如 3 秒)就会产生一组球。
4) 游戏时间固定(例如 30 秒),游戏剩余时间在屏幕固定位置显示,
并适时更新游戏剩余时间;
5)游戏时间到(例如 30 秒),玩家游戏结束显示分数。- 3 -
6) 记录游戏得分,显示在游戏界面上。
7) 保存每个用户的最高分成绩,单击“保存成绩”按钮,将当前用户的
用户名和本次得分存入文件。(是否要求输入文件名自己决定。同一个用
户每次成绩都保存)
图 2 欢乐球吃球游戏界面示例
1、优化界面
界面分为 3 个区域:游戏区、控制区、信息显示区。增加游戏的控制和显示信息。
2、显示排行榜
单击“显示排行榜”按钮,在文件中找到当前成绩中的排行榜,显示在信息显示区中。
3、将游戏的当前状态存盘和导入
存盘:按指定文件名,将当前游戏的状态、用户名、得分等存入文件,游戏继续。
导入:删除当前游戏(删除前应提问是否存盘),将文件中存储的游戏状态恢复到屏幕
上,导入的游戏继续运行。导入文件中的游戏后,得分恢复到存盘时的得分。
4、鼠标控制游戏
5、自己添加的其他功能
自己添加的使游戏更加有趣的功能,增加画面内容,或使界面更加美观的功能(例如,
鼠标单击控制区中的按钮时,按钮有被按下去的效果,松开时,有弹回来的效果)

java大球吃小球项目报告 大球吃小球的单机游戏_java大球吃小球项目报告


java大球吃小球项目报告 大球吃小球的单机游戏_#include_02


java大球吃小球项目报告 大球吃小球的单机游戏_java大球吃小球项目报告_03

// 大球吃小球游戏.cpp
//
#include<graphics.h>
#include<ctime>
#include<iostream>
#include<vector>
#include<cstdio>
#include<cstring>
#include<conio.h>
using namespace std;



void intiGame();
void drawGame();
void controlGame();


using namespace std;

#define WIDE 600
#define HEIGHT 800
#define NUM 20
double LIVETIME =60; //存活时间
const int MOVE_DIS = 10;
struct Fx {
	int x;//单位时间x轴移动距离  正:往右 负:往左
	int y;

};
struct Ball {
	int x;
	int y;
	int radius;
	COLORREF color;
	Fx fx;
};

struct User {
	char name[20];
	int score;
};

struct List {
	struct User data;
	struct List* next;
};


COLORREF colors[7] = { GREEN,MAGENTA,BROWN,YELLOW,BLUE,CYAN,LIGHTGRAY };
vector<Ball> Sballs;
Ball BigBall;

HWND hWnd;
bool isLive = true;

void intiGame();
void drawGame();
void controlGame();
void proc();
void setBigBall();
void Welcom();
void Grade();
void sortList(struct List *head);
int lenList(struct List *head);
struct List * loadFile();
void saveFile(struct List *head);
void drawGrade(struct List *head);


int  _tmain(int  argc, _TCHAR* argv[])
{
	Welcom();
	intiGame();
	drawGame();
	Grade();
	return 0;
}

int lenList(struct List *head)
{	
	if (head == NULL)		
		return 0;	
	struct List *p = head;	
	int len = 0;	
	while(p != NULL)	
	{		
		len++;		
		p = p->next;	
	}	
	return len;
} 

struct List * loadFile()
{
	struct List *head=NULL;
	struct List *p;
	struct User temp;
	FILE* fp=fopen("score.data","r+");
	if(fp==NULL)return NULL;
	fread(&temp,sizeof(struct User),1,fp);
	while(!feof(fp))
	{
		p=(struct List*)malloc(sizeof(struct List));
		p->data=temp;
		p->next=head;
		head=p;
		fread(&temp,sizeof(struct User),1,fp);
	}
	fclose(fp);
	return head;
}

void saveFile(struct List *head)
{
	struct List *p=head;
	FILE* fp=fopen("score.data","w+");
	if(fp==NULL)return ;
	while(p)
	{
		fwrite(&p->data,sizeof(struct User),1,fp);
		p=p->next;
	}
	fclose(fp);
}


void sortList(struct List *head)
{	
	int len = lenList(head);	
	if (len == 0)		
		return;	
	struct List *p = head;	
	int i, j;
	struct User temp;
	for (i = 0; i < len - 1; i++)	
	{		
		p = head;		
		for (j = 0; j < len -i -1; j++)		
		{			
			if (p->data.score < p->next->data.score)			
			{	
				temp=p->data;
				p->data=p->next->data;
				p->next->data=temp;
			}			
			p = p->next;		
		}	
	}
}

void drawGrade(struct List *head)
{
	char t[100];
	sortList(head);
	struct List *p=head;
	int i;
	IMAGE img1;
	loadimage(&img1, _T("1.jpg"),150,150);
	
	RECT r = {0, 0, 600, 200};
	setbkcolor(WHITE);
	cleardevice();
	putimage(450, 650, &img1);
	settextstyle(48, 24, _T("Consolas"));
	drawtext(_T("排行榜"), &r, DT_CENTER | DT_VCENTER | DT_SINGLELINE);

	RECT r2 = {0, 0, 700, 300};
	settextstyle(24, 12, _T("Consolas"));
	sprintf(t,"%-8s%-10s%-10s","名次","姓名","得分");
	drawtext(_T(t), &r2, DT_CENTER | DT_VCENTER | DT_SINGLELINE);	
	for(i=0;i<10&&p!=NULL;i++,p=p->next)
	{
		r2.bottom+=100;
		sprintf(t,"%-8d%-10s%-10d",i+1,p->data.name,p->data.score);
		drawtext(_T(t), &r2, DT_CENTER | DT_VCENTER | DT_SINGLELINE);	
	}
	getch();
}

void Grade()
{
	struct List* head;
	head=loadFile();
	char s[100];
	bool flag=InputBox(s, 100, "英雄,请输入大名:");
	if(flag)
	{
		struct List* p=(struct List*)malloc(sizeof(struct List));
		strcpy(p->data.name,s);
		p->data.score=BigBall.radius-20;
		p->next=head;
		head=p;
	}
	saveFile(head);
	drawGrade(head);
}

void Welcom()
{
	char ch;
	hWnd = initgraph(WIDE, HEIGHT);
	RECT r = {0, 0, WIDE, HEIGHT-180};
	IMAGE img1;
	do
	{
		setbkcolor(WHITE);
		cleardevice();
		loadimage(&img1, _T("peiqi.png"),600,400);
		putimage(0, 400, &img1);
		
		settextcolor(BLUE);
		RECT r2 = {0, 0, 600, 400};
		settextstyle(48, 24, _T("Consolas"));
		drawtext(_T("欢乐球吃球"), &r2, DT_CENTER | DT_VCENTER | DT_SINGLELINE);

		settextstyle(36, 18, _T("Consolas"));
		r.bottom=HEIGHT-180;
		drawtext(_T("1:开始游戏"), &r, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
		r.bottom=HEIGHT;
		drawtext(_T("2:排行榜"), &r, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
		ch=getch();
		if(ch=='2')
		{
			struct List* head;
			head=loadFile();
			drawGrade(head);
		}
	}while(ch!='1');
}

void intiGame() {
	Ball* pb = NULL;
	for (int i = 0; i < NUM; i++) {
		pb = new Ball;
		pb->x = rand() % WIDE;
		pb->y = rand() % HEIGHT;
		pb->radius = rand() % 10 + 1;
		pb->color = colors[rand() % 8];
		pb->fx.x = rand() % 5 + 1;
		pb->fx.y = (rand() % 10) - 5;

		Sballs.push_back(*pb);
	}
	BigBall.color = RED;
	BigBall.x = rand()%WIDE;
	BigBall.y = rand()%HEIGHT;
	BigBall.radius = 20;
}

void drawTimeScore(double time)
{
	char t[100];
	RECT r = {0, 0, 60, 60};
	settextstyle(12, 6, _T("Consolas"));
	sprintf(t,"时间:%d",(int)(LIVETIME-time));
	drawtext(_T(t), &r, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
	
	RECT r2 = {0, 0, 60, 100};
	settextstyle(18, 9, _T("Consolas"));
	sprintf(t,"得分:%d",BigBall.radius-20);
	drawtext(_T(t), &r2, DT_CENTER | DT_VCENTER | DT_SINGLELINE);	
}

void setKeyboardBigBall();

void drawGame() {
	clock_t start, finish;
	double time;
	

	SetTimer(hWnd, 10086, 50,(TIMERPROC)proc);
	CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)setBigBall, NULL, NULL, NULL);
	CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)setKeyboardBigBall, NULL, NULL, NULL);
	start = clock();//开始记时
	while (1) {
		controlGame();
		finish = clock();//当前时间
		time = (double)(finish - start) / CLOCKS_PER_SEC;
		if(time>=LIVETIME)isLive=false;
		if (!isLive) break;
		BeginBatchDraw();
		setbkcolor(WHITE);
		cleardevice();
	
		drawTimeScore(time);
		setfillcolor(BigBall.color);
		solidcircle(BigBall.x, BigBall.y, BigBall.radius);
		for (int i = 0; i < Sballs.size(); i++) {
			setfillcolor(Sballs[i].color);
			solidcircle(Sballs[i].x, Sballs[i].y, Sballs[i].radius);
		}
		EndBatchDraw();
	}
	setbkcolor(WHITE);
	cleardevice();
}


void controlGame() {

	int xlen, ylen;
	int score = 0;
	for (int i = 0; i < Sballs.size(); i++) {
		xlen = (Sballs[i].x > BigBall.x) ? (Sballs[i].x - BigBall.x) : (BigBall.x - Sballs[i].x);
		ylen = (Sballs[i].y> BigBall.y) ? (Sballs[i].y - BigBall.y) : (BigBall.y - Sballs[i].y);
		if ((xlen*xlen+ylen*ylen)<(Sballs[i].radius+BigBall.radius)* (Sballs[i].radius + BigBall.radius) ){
			Sballs[i].x = rand() % WIDE;
			Sballs[i].y = rand() % HEIGHT;
			Sballs[i].radius = rand() % 10 + 1;
			Sballs[i].color = colors[rand() % 7];
			Sballs[i].fx.x = rand() % 5 + 1;
			Sballs[i].fx.y = (rand() % 10) - 5;
			BigBall.radius += 1;
		}
		if (Sballs[i].x > WIDE || Sballs[i].x<0 || Sballs[i].y>HEIGHT || Sballs[i].y < 0) {
			Sballs[i].x = rand() % WIDE;
			Sballs[i].y = rand() % HEIGHT;
			Sballs[i].radius = rand() % 10 + 1;
			Sballs[i].color = colors[rand() % 7];
			Sballs[i].fx.x = rand() % 5 + 1;
			Sballs[i].fx.y = (rand() % 10) - 5;
		}
	}
}

void proc() {
	for (int i = 0; i < Sballs.size(); i++) {
		Sballs[i].x += Sballs[i].fx.x;
		Sballs[i].y += Sballs[i].fx.y;
	}
}
void setBigBall() {
	MOUSEMSG msg;
	while (1) {
		msg= GetMouseMsg();
		if (msg.mkLButton) {
			BigBall.x = msg.x;
			BigBall.y = msg.y;
		}
	}
		

}

void setKeyboardBigBall() {
	char ch;
	while(1)
	{
		if(kbhit())
		{
			ch = getch();
			switch(ch)
			{
			case 'a'://左边
			case 'A':
				if(BigBall.x-MOVE_DIS>0)
				BigBall.x-=MOVE_DIS;
				break;
			case 'w'://向上
			case 'W':
				if(BigBall.y-MOVE_DIS>0)
				BigBall.y-=MOVE_DIS;
				break;
			case 'd'://向右
			case 'D':
				if(BigBall.x+MOVE_DIS<WIDE)
				BigBall.x+=MOVE_DIS;
				break;
			case 's'://向下
			case 'S':
				if(BigBall.y+MOVE_DIS<HEIGHT)
				BigBall.y+=MOVE_DIS;
				break;
			}
		}	
	}
}