前言

发现很多朋友都想要一些小项目来练手,却找不到从哪里寻找,给大家整理了游戏项目开发源代码汇总。

一、最经典游戏之俄罗斯方块

#include<iostream>
#include<math.h>
#include<Windows.h>
#include<conio.h>
#include<ctime>
using namespace std;

enum DIR
{
	UP,
	RIGHT,
	DOWN,
	LEFT
};

time_t start = 0, finish = 0;

int _x = 6, _y = 1;//图形生成位置

int map[30][16] = { 0 };

int sharp[20][8] = {
	{0,0,0,0,0,0,0,0},
	//I形
	{0,0,0,1,0,2,0,3},
	{0,0,1,0,2,0,3,0},
	//■形
	{0,0,1,0,0,1,1,1},
	//L形
	{0,0,0,1,0,2,1,2},
	{0,0,0,1,1,0,2,0},
	{0,0,1,0,1,1,1,2},
	{0,1,1,1,2,0,2,1},
	//J形
	{0,2,1,0,1,1,1,2},
	{0,0,0,1,1,1,2,1},
	{0,0,0,1,0,2,1,0},
	{0,0,1,0,2,0,2,1},
	//Z形
	{0,0,1,0,1,1,2,1},
	{0,1,0,2,1,0,1,1},
	//S形
	{0,1,1,0,1,1,2,0},
	{0,0,0,1,1,1,1,2},
	//T形
	{0,1,1,0,1,1,2,1},
	{0,0,0,1,0,2,1,1},
	{0,0,1,0,1,1,2,0},
	{0,1,1,0,1,1,1,2}
};


class Game
{
public:
	int score;//游戏分数
	int _id;//图形编号
	int top;//最高点高度
	int speed;//下落速度

	Game();
	void showMenu();//显示菜单
	void showGround();//显示游戏界面
	void gameOver();//游戏结束界面
	void Run();//运行游戏
	void sharpDraw(int id, bool show = false);//绘制图形
	void keyControl();//键盘控制
	bool move(int dir, int id);//移动判断
	bool downSet(int id);//下落
	void Turn(int id);//旋转
	void clean();//消行
};

void SetPos(int i, int j)//控制光标位置, 列, 行
{
	COORD pos = { i,j };
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
}

int main()
{
	CONSOLE_CURSOR_INFO cursor;
	GetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor);
	cursor.bVisible = 0;	//这四行用来设置光标不显示
	SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor);

	srand((unsigned)time(NULL));

	Game game;
	game.showMenu();
	return 0;
}

Game::Game()
{
	score = 0;
	_id = 0;
	top = 58;
	speed = 1000;
}

void Game::showMenu()
{
	for (int i = 0; i < 30; i++)
	{
		for (int j = 0; j < 26; j++)
		{
			if ((i == 0 || i == 29) || (j == 0 || j == 25))
			{
				cout << "■";
			}
			else
			{
				cout << "  ";
			}
		}
		cout << endl;
	}

	SetPos(17, 8);
	cout << "俄 罗 斯 方 块" << endl;
	SetPos(13, 12);
	cout << "↑旋转方块  ↓加速下滑" << endl;
	SetPos(12, 14);
	cout << "← →左右移动  空格  暂停" << endl;
	SetPos(15, 20);
	cout << "0 退出  Enter 开始" << endl;

	while (1)
	{
		int select = _getch();
		if (select == 13)
		{
			system("cls");
			this->Run();
		}
		else if (select = 48)
		{
			system("cls");
			exit(0);
		}
	}
}

void Game::showGround()
{
	for (int i = 0; i < 30; i++)
	{
		for (int j = 0; j < 26; j++)
		{
			if ((i == 0 || i == 29) || (j == 0 || j == 25 || j == 15))
			{
				cout << "■";
			}
			else if (i == 15 && j > 15)
			{
				cout << "■";
			}
			else
			{
				cout << "  ";
			}
		}
		cout << endl;
	}

	SetPos(31, 2);
	cout << "下 个图形" << endl;
	SetPos(31, 17);
	cout << "当 前得分" << endl;

	for (int i = 0; i < 30; i++)
	{
		for (int j = 0; j < 16; j++)
		{
			if ((i == 0 || i == 29) || (j == 0 || j == 15))
			{
				map[i][j] = 1;
			}
			else
			{
				map[i][j] = 0;
			}
		}
	}
}

void Game::gameOver()
{
	for (int i = 5; i < 15; i++)
	{
		SetPos(1, i);
		cout << "                            " << endl;
	}

	SetPos(8, 7);
	cout << "G a m e   O v e r" << endl;

	SetPos(3, 10);
	cout << "0 退出   Enter 重新开始" << endl;

	while (1)
	{
		int select = _getch();
		if (select == 13)
		{
			system("cls");
			this->Run();
		}
		else if (select == 48)
		{
			system("cls");
			exit(0);
		}
	}

}

void Game::Run()
{
	score = 0;
	_id = 0;
	top = 58;
	_x = 6;
	_y = 1;
	showGround();
	start = clock();
	int new_id = rand() % 19 + 1;

	while (1)
	{
		sharpDraw(_id);
		keyControl();

		if (downSet(_id))
		{
			sharpDraw(-new_id, 1);
			_id = new_id;
			new_id = rand() % 19 + 1;
			sharpDraw(new_id, 1);
			clean();
		}

		SetPos(34, 20);
		cout << score << endl;
	}
}

void Game::sharpDraw(int id, bool show)
{
	int x, y;

	if (show == true)
	{
		if (id > 0)
		{
			for (int i = 0; i < 4; i++)
			{
				x = 19 + sharp[id][2 * i];
				y = 6 + sharp[id][2 * i + 1];
				SetPos(2 * x, y);
				cout << "■";
			}
		}
		else
		{
			for (int i = 0; i < 4; i++)
			{
				x = 19 + sharp[-id][2 * i];
				y = 6 + sharp[-id][2 * i + 1];
				SetPos(2 * x, y);
				cout << "  ";
			}
		}
		return;
	}


	if (id > 0)
	{
		for (int i = 0; i < 4; i++)
		{
			x = _x + sharp[id][2 * i];
			y = _y + sharp[id][2 * i + 1];
			SetPos(2 * x, y);
			cout << "■";
		}
	}
	else
	{
		for (int i = 0; i < 4; i++)
		{
			x = _x + sharp[-id][2 * i];
			y = _y + sharp[-id][2 * i + 1];
			SetPos(2 * x, y);
			cout << "  ";
		}
	}
	return;

}

bool Game::downSet(int id)
{
	if (id == 0)
		return true;

	finish = clock();

	if (finish - start < speed)
	{
		return false;
	}

	start = clock();

	if (!move(DOWN, _id))
	{
		int x, y;
		for (int i = 0; i < 4; i++)
		{
			x = _x + sharp[id][2 * i];
			y = _y + sharp[id][2 * i + 1];
			map[y][x] = 1;

			if (y < top)
			{
				top = y;
			}
			if (top <= 1)
			{
				gameOver();
			}
		}
		_x = 6;
		_y = 1;
		return true;
	}

	sharpDraw(-id);
	_y++;
	sharpDraw(id);
	return false;
}

bool Game::move(int dir, int id)
{
	int x, y;
	switch (dir)
	{
	case UP:
		for (int i = 0; i < 4; i++)
		{
			x = _x + sharp[id][2 * i];
			y = _y + sharp[id][2 * i + 1];
			if (map[y][x] == 1)
			{
				return false;
			}
		}
		break;
	case DOWN:
	{
		for (int i = 0; i < 4; i++)
		{
			x = _x + sharp[id][2 * i];
			y = _y + sharp[id][2 * i + 1];
			if (map[y + 1][x] == 1)
			{
				return false;
			}
		}
	}
	break;
	case RIGHT:
	{
		for (int i = 0; i < 4; i++)
		{
			x = _x + sharp[id][2 * i];
			y = _y + sharp[id][2 * i + 1];
			if (map[y][x + 1] == 1)
			{
				return false;
			}
		}
	}
	break;
	case LEFT:
	{
		for (int i = 0; i < 4; i++)
		{
			x = _x + sharp[id][2 * i];
			y = _y + sharp[id][2 * i + 1];
			if (map[y][x - 1] == 1)
			{
				return false;
			}
		}
	}
	break;
	default:
		break;
	}
	return true;
}

void Game::Turn(int id)
{
	switch (id)
	{
	case 1:id++; break;
	case 2:id--; break;

	case 3: break;

	case 4:id++; break;
	case 5:id++; break;
	case 6:id++; break;
	case 7:id -= 3; break;

	case 8:id++; break;
	case 9:id++; break;
	case 10:id++; break;
	case 11:id -= 3; break;

	case 12:id++; break;
	case 13:id--; break;

	case 14:id++; break;
	case 15:id--; break;

	case 16:id++; break;
	case 17:id++; break;
	case 18:id++; break;
	case 19:id -= 3; break;

	default:
		break;
	}

	if (!move(UP, id))
	{
		return;
	}

	sharpDraw(-_id);
	_id = id;
}

void Game::keyControl()
{
	if (!_kbhit())
		return;

	int key = _getch();

	switch (key)
	{
	case 72:
		Turn(_id);
		break;
	case 80:
		if (move(DOWN, _id))
		{
			sharpDraw(-_id);
			_y++;
		}
		break;
	case 75:
		if (move(LEFT, _id))
		{
			sharpDraw(-_id);
			_x--;
		}
		break;
	case 77:
		if (move(RIGHT, _id))
		{
			sharpDraw(-_id);
			_x++;
		}
		break;
	case 32:
	{
		for (int i = 5; i < 15; i++)
		{
			SetPos(1, i);
			cout << "                            " << endl;
		}

		SetPos(10, 7);
		cout << "游 戏 暂 停" << endl;

		SetPos(3, 10);
		cout << "0 返回菜单  回车 继续游戏" << endl;

		while (1)
		{
			int select = _getch();

			if (select == 13)
			{
				for (int i = 5; i < 15; i++)
				{
					SetPos(1, i);
					cout << "                            " << endl;
				}
				break;
			}
			else if (select == 48)
			{
				system("cls");
				showMenu();
			}
		}

	}
	default:
		break;
	}
}

void Game::clean()
{
	int n = -1;
	int line = -1;
	while (1)
	{
		for (int i = 28; i > 0; i--)
		{
			for (int j = 1; j < 15; j++)
			{
				line = i;
				if (map[i][j] == 0)
				{
					line = -1;
					break;
				}
			}
			if (line != -1)
				break;
		}

		if (line == -1)
			break;

		for (int i = line; i > 0; i--)
		{
			for (int j = 1; j < 15; j++)
			{
				if (i == 1)
					map[i][j] = 0;
				else
				{
					map[i][j] = map[i - 1][j];
					SetPos(2 * j, i);
					if (map[i][j] == 1)
						cout << "■";
					else
						cout << "  ";
				}
			}
		}
		top++;
		n++;
	}

	if (n >= 0)
	{
		score += n * n * 100 + 100;
		if (speed > 100)
			speed = 1000 - score / 10;
	}
}

二、雷霆战机游戏源代码

#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<graphics.h>
#include<conio.h>
#include<time.h>
#include<mmsystem.h>
#pragma comment(lib,"winmm.lib")
 
 
 
 
typedef struct Node
{
	int x;
	int y;
	struct Node *pnext;
}NODE;
 
#define WINDOW_WIDTH 1024
#define WINDOW_HEIGHT 680
#define WIDTH 480
 
//我机图片尺寸
#define pw 86
#define ph 82
 
//敌机图片尺寸
#define aw 70
#define ah 70
 
#define boss1w 192
#define boss1h 290
 
 
//敌机重出现的y坐标
#define APStart -ah-20
 
 
 
 
 
NODE *p_bullet = NULL;
//MyPlane
NODE *p_MP = NULL;
//AttackPlane
NODE* p_AP = NULL;
//子弹时间差
NODE* p_AP2 = NULL;
DWORD b1, b2, b3, b4, b5, b6;
 
IMAGE i_MP,i_MPS,i_AP,i_APS;
IMAGE i_backeve, i_backxing, i_backduicheng, i_backguan,i_backcontrol,i_backgo;
IMAGE i_boss1_1, i_boss1_1S, i_boss1_2, i_boss1_2S;
 
//backxing的左右移动
int left = (WINDOW_WIDTH / 2 - WIDTH / 2);
//分数
int score = 0;
//击毁敌机的数量
int kill = 0;
//boss是否出现
int boss1show = 0;
//boss1贴图开关
int boss1image = 0;
int boss1hp = 20;
 
int line1_x = WINDOW_WIDTH / 2 - 20;
int line1_y = boss1h;
int line2_x = WINDOW_WIDTH / 2 + 20;
int line2_y = boss1h;
 
//Beam只播放一次
int test = 1;
int MP_HP = 1;
 
 
 
void CreateList()
{
	p_MP = (NODE*)malloc(sizeof(NODE));
	p_MP->x = WINDOW_WIDTH / 2 - pw / 2;
	p_MP->y = WINDOW_HEIGHT-100;
	p_MP->pnext = NULL;
 
 
	p_bullet = (NODE*)malloc(sizeof(NODE));
	p_bullet->pnext = NULL;
	b1 = GetTickCount();
 
 
	p_AP = (NODE*)malloc(sizeof(NODE));
	srand((unsigned)time(NULL));
	p_AP->x = rand() % (WIDTH - aw) + (WINDOW_WIDTH / 2 - WIDTH / 2);
	p_AP->y = APStart;
	p_AP->pnext = NULL;
	b3 = GetTickCount();
 
	p_AP2 = (NODE*)malloc(sizeof(NODE));
	p_AP2->x = rand() % (WIDTH - aw) + (WINDOW_WIDTH / 2 - WIDTH / 2);
	p_AP2->y = -350;
	p_AP2->pnext = NULL;
	b5 = GetTickCount();
}
 
void GameBackInit()
{
	loadimage(&i_MP, L"mp.jpg");
	loadimage(&i_MPS, L"mpbit.jpg");
	loadimage(&i_backeve, L"backeve.jpg");
	loadimage(&i_backxing, L"backtaikong.jpg");
	loadimage(&i_AP, L"AP.jpg", aw, ah);
	loadimage(&i_APS, L"APS.jpg", aw, ah);
	loadimage(&i_backduicheng, L"backduicheng.jpg");
	loadimage(&i_backguan, L"backguan.jpg", WIDTH, WINDOW_HEIGHT);
	loadimage(&i_backcontrol, L"backcontrol.jpg",WINDOW_WIDTH,WINDOW_HEIGHT);
	loadimage(&i_boss1_1, L"boss1_1.jpg");
	loadimage(&i_boss1_1S, L"boss1_1S.jpg");
	loadimage(&i_boss1_2, L"boss1_2.jpg");
	loadimage(&i_boss1_2S, L"boss1_1S.jpg");
	loadimage(&i_backgo, L"Gameover.jpg", WINDOW_WIDTH, WINDOW_HEIGHT);
 
 
	putimage(0, 30, &i_backeve);
	Sleep(1000);
	PlaySound(L"baozou.wav", NULL, SND_FILENAME | SND_ASYNC);
 
	putimage(0, 0, &i_backcontrol);
	outtextxy(600, 540, L"【PRESS】 按任意键进入游戏");
	system("pause");
 
	mciSendString(L"open bgmusic.mp3 alias bg", NULL, 0, NULL);
	mciSendString(L"play bg repeat", NULL, 0, NULL);
 
	putimage((WINDOW_WIDTH / 2 - WIDTH / 2), 0, WIDTH, WINDOW_HEIGHT, &i_backguan, 0, 0, SRCCOPY);
	putimage(0, 0, (WINDOW_WIDTH / 2 - WIDTH / 2), WINDOW_HEIGHT, &i_backduicheng, 0, 100, SRCCOPY);
	putimage((WINDOW_WIDTH / 2 + WIDTH / 2), 0, (WINDOW_WIDTH / 2 - WIDTH / 2), WINDOW_HEIGHT, &i_backduicheng, 1200 - (WINDOW_WIDTH / 2 - WIDTH / 2), 100, SRCCOPY);
	//字体出现的高度
	int text_h = WINDOW_HEIGHT/2;
	Sleep(300);
	BeginBatchDraw();
	for (int i = 0; i < text_h; i++)
	{
		clearrectangle((WINDOW_WIDTH / 2 - WIDTH / 2), 0, (WINDOW_WIDTH / 2 + WIDTH / 2), WINDOW_HEIGHT);
		putimage((WINDOW_WIDTH / 2 - WIDTH / 2), 0-i, WIDTH, text_h , &i_backguan, 0, 0, SRCCOPY);
		putimage((WINDOW_WIDTH / 2 - WIDTH / 2), text_h + i, WIDTH, WINDOW_HEIGHT - (text_h + i), &i_backguan, 0, text_h, SRCCOPY);
		putimage((WINDOW_WIDTH / 2 - WIDTH / 2), text_h - i, WIDTH, 2*i, &i_backxing, left, text_h-i, SRCCOPY);
		FlushBatchDraw();
		Sleep(5);
	}
	EndBatchDraw();
 
	
	Sleep(100);
 
 
}
 
 
void Boss1show()
{
	
	p_AP->y = WINDOW_HEIGHT + 100;
	p_AP2->y = WINDOW_HEIGHT + 100;
 
	if (boss1hp >14)
	{
		putimage(WINDOW_WIDTH / 2 - boss1w / 2, -boss1h + boss1image, &i_boss1_1S, NOTSRCERASE);
		putimage(WINDOW_WIDTH / 2 - boss1w / 2, -boss1h + boss1image, &i_boss1_1, SRCINVERT);
	}
	else if(boss1hp >= 9 && boss1hp <=14)
	{
		
		if (boss1hp % 2 == 0)
		{
			setlinecolor(0x996666);
			setlinestyle(PS_DOT, 3);
			line(line1_x, line1_y, line1_x, WINDOW_HEIGHT);
			line(line2_x, line2_y, line2_x, WINDOW_HEIGHT);
 
			putimage(WINDOW_WIDTH / 2 - boss1w / 2, -boss1h + boss1image, &i_boss1_2S, NOTSRCERASE);
			putimage(WINDOW_WIDTH / 2 - boss1w / 2, -boss1h + boss1image, &i_boss1_2, SRCINVERT);
			
		}
		else
		{
			setlinecolor(0xCC6666);
			setlinestyle(PS_DOT, 3);
			line(line1_x, line1_y, line1_x, WINDOW_HEIGHT);
			line(line2_x, line2_y, line2_x, WINDOW_HEIGHT);
 
			
			putimage(WINDOW_WIDTH / 2 - boss1w / 2, -boss1h + boss1image, &i_boss1_1S, NOTSRCERASE);
			putimage(WINDOW_WIDTH / 2 - boss1w / 2, -boss1h + boss1image, &i_boss1_1, SRCINVERT);
		}
		
		
	}
	else
	{
		
		if (test == 1)
		{
			PlaySound(L"Beam.wav", NULL, SND_FILENAME | SND_ASYNC);
			test++;
		}
		setlinecolor(0xFF6666);
		setlinestyle(PS_DASH, 5);
		line(line1_x, line1_y, line1_x, WINDOW_HEIGHT);
		line(line2_x, line2_y, line2_x, WINDOW_HEIGHT);
		line(WINDOW_WIDTH / 2 - boss1w / 2, boss1h -90, 482, boss1h + 50);
		line(WINDOW_WIDTH / 2 + boss1w / 2, boss1h - 90, 542, boss1h + 50);
		putimage(WINDOW_WIDTH / 2 - boss1w / 2, -boss1h + boss1image, &i_boss1_2S, NOTSRCERASE);
		putimage(WINDOW_WIDTH / 2 - boss1w / 2, -boss1h + boss1image, &i_boss1_2, SRCINVERT);
		if ((boss1hp!=8)&&(p_MP->x - line1_x) > -pw && (p_MP->x - line2_x)<0&& (p_MP->y - line1_y)>-ph)			MP_HP = 0;
	}
 
	
	if(boss1image<=boss1h )	boss1image+=2;
 
}
 
void AddNode(int flag)
{
	//后插法,更新第二个位置
	if (flag == 0)
	{
		NODE* p_new = (NODE*)malloc(sizeof(NODE));
 
		p_new->x = p_MP->x + 35;
		p_new->y = p_MP->y - 45;
 
		p_new->pnext = p_bullet->pnext;
		p_bullet->pnext = p_new;
	}
}
 
 
 
int main()
{
	//create a window
	initgraph(WINDOW_WIDTH, WINDOW_HEIGHT);
 
	setfillcolor(0xFF9999);
 
	GameBackInit();
 
	char key;
	CreateList();
	//批量绘图
	
	BeginBatchDraw();
	while (1)
	{	
		
		//清画板,要不然就成重叠的残影了
		cleardevice();
 
 
 
		putimage((WINDOW_WIDTH / 2 - WIDTH / 2), 0, WIDTH, WINDOW_HEIGHT, &i_backxing, left, 0, SRCCOPY);
		putimage(0, 0, (WINDOW_WIDTH / 2 - WIDTH / 2), WINDOW_HEIGHT, &i_backduicheng, 0, 100, SRCCOPY);
		putimage((WINDOW_WIDTH / 2 + WIDTH / 2), 0, (WINDOW_WIDTH / 2 - WIDTH / 2), WINDOW_HEIGHT, &i_backduicheng, 1200 - (WINDOW_WIDTH / 2 - WIDTH / 2), 100, SRCCOPY);
 
 
		putimage(p_MP->x, p_MP->y, &i_MPS, NOTSRCERASE);
		putimage(p_MP->x, p_MP->y, &i_MP, SRCINVERT);
		putimage(p_AP->x, p_AP->y, &i_APS, NOTSRCERASE);
		putimage(p_AP->x, p_AP->y, &i_AP, SRCINVERT);
		putimage(p_AP2->x, p_AP2->y, &i_APS, NOTSRCERASE);
		putimage(p_AP2->x, p_AP2->y, &i_AP, SRCINVERT);
		
		
 
		//MP单位时间发射子弹的数量
		b2 = GetTickCount();
		//不能等于,有偏差
		if (b2 - b1 >= 600)
		{
			AddNode(0);
			b1 = b2;
		}
 
 
 
 
		//我方战机子弹递增
		NODE* P = p_bullet->pnext;
 
 
		while (P != NULL)
		{
			if (boss1show == 0)
			{
 
				//确定敌机重生位置不是在原位置
				int mid;
				//10是子弹宽度,但半个子弹打中也算,要不然太难了,就右边是-3,左边是-7
				if ((P->y - p_AP->y) < ah && (P->y - p_AP->y) >= 0 && (P->x - p_AP->x) < aw -3 && (P->x - p_AP->x) >= -7)
				{
					P->y = APStart -100;
					P = P->pnext;
					p_AP->y = APStart;
					kill++;
 
					PlaySound(L"Bomb.wav", NULL, SND_FILENAME | SND_ASYNC);
					while (1)
					{
						mid = rand() % (WIDTH - aw) + (WINDOW_WIDTH / 2 - WIDTH / 2);
						if (abs(mid - p_AP->x) > aw)
						{
							p_AP->x = mid;
							break;
						}
					}
					
 
				}
				else if((P->y - p_AP2->y) < ah && (P->y - p_AP2->y) >= 0 && (P->x - p_AP2->x) < aw - 3 && (P->x - p_AP2->x) >= -7)
				{
					P->y = APStart -100;
					P = P->pnext;
					p_AP2->y = APStart;
					kill++;
 
					while (1)
					{
						mid = rand() % (WIDTH - aw) + (WINDOW_WIDTH / 2 - WIDTH / 2);
						if (abs(mid - p_AP2->x) > aw)
						{
							p_AP2->x = mid;
							break;
						}
					}
					PlaySound(L"Bomb.wav", NULL, SND_FILENAME | SND_ASYNC);
				}
				else
				{
					fillroundrect(P->x, P->y, P->x + 10, P->y + 35, 10, 30);
					P->y -= 5;
					P = P->pnext;
				}
			}
			else if (boss1show == 1)
			{
				if (boss1image > boss1h)
				{
					if ((P->y) < boss1h && (P->y) >= 0 && (P->x - (WINDOW_WIDTH / 2 - boss1w / 2)) < boss1w - 3 && (P->x - (WINDOW_WIDTH / 2 - boss1w / 2)) >= -7)
					{
						P->y = APStart -100;
						P = P->pnext;
						boss1hp--;
						if (boss1hp>9||boss1hp<7)	PlaySound(L"Bomb.wav", NULL, SND_FILENAME | SND_ASYNC);
					}
					else
					{
						fillroundrect(P->x, P->y, P->x + 10, P->y - 35, 10, 30);
						P->y -= 10;
						P = P->pnext;
					}
 
					TCHAR s_boss1hp[100];
					_stprintf(s_boss1hp, _T("【Boss】HP:%d"), boss1hp);
					outtextxy((WINDOW_WIDTH / 2 + WIDTH / 2) + 45, 200, s_boss1hp);
 
					if (boss1hp <= 0)
					{
						boss1show = 0;
						kill += 50;
					}
				}
				else
				{
					fillroundrect(P->x, P->y, P->x + 10, P->y + 35, 10, 30);
					P->y -= 5;
					P = P->pnext;
				}
			}
		}
 
 
 
 
 
		//AP飞行的速度
		b4 = GetTickCount();
		//不能等于,有偏差
		if (b4- b3 >= 50)
		{
			if (p_AP->y < WINDOW_HEIGHT)
			{
				p_AP->y += 3;
			}
			else
			{
				p_AP->y = 0;
				p_AP->x = rand() % (WIDTH - aw) + (WINDOW_WIDTH / 2 - WIDTH / 2);
			}
			b3 = b4;
		}
 
 
 
 
		//AP2飞行的速度
		b6 = GetTickCount();
		//不能等于,有偏差
		if (b6 - b5 >= 50)
		{
			if (p_AP2->y < WINDOW_HEIGHT)
			{
				p_AP2->y += 3;
			}
			else
			{
				p_AP2->y = 0;
				p_AP2->x = rand() % (WIDTH - aw) + (WINDOW_WIDTH / 2 - WIDTH / 2);
			}
			b5 = b6;
		}
		
		
 
 
 
		if (kill==10&& boss1hp > 0) boss1show = 1;
 
 
 
 
		if (boss1show==1)
		{
			Boss1show();
		}
 
 
 
 
		if ((p_MP->x - p_AP->x) > -pw && (p_MP->x - p_AP->x)<pw && (p_MP->y - p_AP->y)>-ph && (p_MP->y - p_AP->y)<ph )			MP_HP = 0;
		else if ((p_MP->x - p_AP2->x) > -pw && (p_MP->x - p_AP2->x)<pw && (p_MP->y - p_AP2->y)>-ph && (p_MP->y - p_AP2->y)<ph)	MP_HP = 0;
		else if (boss1show==1&&boss1image>boss1h&&(p_MP->x-(WINDOW_WIDTH / 2 - boss1w / 2)) >-pw && (p_MP->x-(WINDOW_WIDTH / 2 + boss1w / 2))<pw && p_MP->y<boss1h)		MP_HP = 0;
		
		if (MP_HP == 0)
		{
			mciSendString(L"close bg", NULL, 0, NULL);
			mciSendString(L"open bggo.mp3 alias bg", NULL, 0, NULL);
			mciSendString(L"play bg repeat", NULL, 0, NULL);
			putimage(0, 0, &i_backgo, SRCCOPY);
			outtextxy(430, 540, L"3秒后自动退出");
			EndBatchDraw();
			Sleep(3000);
			closegraph();
			return 0;
		}
 
		
		TCHAR s_score[100];
		_stprintf(s_score, _T("你的分数:%d"), kill);
		outtextxy((WINDOW_WIDTH / 2 + WIDTH / 2) + 50, WINDOW_HEIGHT/2, s_score);
		
		
		
 
 
		FlushBatchDraw();
 
		
		//子弹飞行速度以及按键延迟等
		Sleep(15);
 
 
 
		if (kbhit())
		{
			key = getch();
			switch (key)
			{
			case 72://上
				p_MP->y -= 5;
				break;
			case 80://下
				p_MP->y += 5;
				break;
			case 75://左
				p_MP->x -= 5;
				left -= 5;
				break;
			case 77://右
				p_MP->x += 5;
				left += 5;
				break;
			}
		}
 
 
 
		if (p_MP->x<(WINDOW_WIDTH / 2 - WIDTH / 2)) 
			p_MP->x = (WINDOW_WIDTH / 2 - WIDTH / 2);
		if (p_MP->x>(WINDOW_WIDTH / 2 + WIDTH / 2 - pw))
			p_MP->x = (WINDOW_WIDTH / 2 + WIDTH / 2 - pw);
		if (p_MP->y<0 ) 
			p_MP->y = 0;
		if (p_MP->y>WINDOW_HEIGHT - ph) 
			p_MP->y = WINDOW_HEIGHT - ph;
 
 
		if (left < 0)
			left = 0;
		if (left>1280 - WIDTH)
			left = 1280 - WIDTH;
 
	}
	
	EndBatchDraw();
	closegraph();
	return 0;
}

三、五子棋经典游戏源代码

#define _CRT_SECURE_NO_WARNINGS
#define MAX_ROW 3
#define MAX_COL 3
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void init(char chessBoard[MAX_ROW][MAX_COL]) {
	for (int row = 0; row < MAX_ROW; row++) {
		for (int col = 0; col < MAX_COL; col++) {
			chessBoard[row][col] = ' ';
		}
	}
}
void print_chessBoard(char chessBoard[MAX_ROW][MAX_COL]) {
	printf("+---+---+---+\n");
	for (int row = 0; row < MAX_ROW; row++) {
		printf("| %c | %c | %c |\n", chessBoard[row][0],
			chessBoard[row][1], chessBoard[row][2]);
		printf("+---+---+---+\n");
	}
}
void playerMove(char chessBoard[MAX_ROW][MAX_COL]) {
	while (1) {
		int row = 0;
		int col = 0;
		printf("请输入坐标(row col):");
		scanf("%d %d", &row, &col);
		if (row < 0 || row >= MAX_ROW || col < 0 || col >= MAX_COL) {
			printf("您的坐标不在合法范围内 [0, 2],请重新输入:\n");
			continue;
		}
		if (chessBoard[row][col] != ' ') {
			printf("您的坐标位置已经有子了!\n");
			continue;
		}
		chessBoard[row][col] = 'x';
		break;
	}
}
void computerMove(char chessBoard[MAX_ROW][MAX_COL]) {
	while (1) {
		int row = rand() % MAX_ROW;
		int col = rand() % MAX_COL;
		if (chessBoard[row][col] != ' ') {
			continue;
		}
		chessBoard[row][col] = 'o';
		break;
	}
}
int isFull(char chessBoard[MAX_ROW][MAX_COL]) {
	for (int row = 0; row < MAX_ROW; row++) {
		for (int col = 0; col < MAX_COL; col++) {
			if (chessBoard[row][col] == ' ') {
				return 0;
			}

		}
	}
	return 1;
}
char isWin(char chessBoard[MAX_ROW][MAX_COL]) {
	for (int row = 0; row < MAX_ROW; row++) {
		if (chessBoard[row][0] != ' '
			&& chessBoard[row][0] == chessBoard[row][1]
			&& chessBoard[row][0] == chessBoard[row][2]) {
			return chessBoard[row][0];
		}
	}
	for (int col = 0; col < MAX_COL; col++) {
		if (chessBoard[0][col] != ' '
			&& chessBoard[0][col] == chessBoard[1][col]
			&& chessBoard[0][col] == chessBoard[2][col]) {
			return chessBoard[0][col];
		}
	}
	if (chessBoard[0][0] != ' '
		&& chessBoard[0][0] == chessBoard[1][1]
		&& chessBoard[0][0] == chessBoard[2][2]) {
		return chessBoard[0][0];
	}
	if (chessBoard[2][0] != ' '
		&& chessBoard[2][0] == chessBoard[1][1]
		&& chessBoard[2][0] == chessBoard[0][2]) {
		return chessBoard[2][0];
	}
	if (isFull(chessBoard)) {
		return 'q';
	}
	return ' ';
}
void game() {
	char chessBoard[MAX_ROW][MAX_COL] = { 0 };
	init(chessBoard);
	char winner = ' ';
	while (1) {
		system("cls");
		print_chessBoard(chessBoard);
		playerMove(chessBoard);
		winner = isWin(chessBoard);
		if (winner != ' ') {
			break;
		}
		computerMove(chessBoard);
		winner = isWin(chessBoard);
		if (winner != ' ') {
			break;
		}
	}
	print_chessBoard(chessBoard);
	if (winner == 'x') {
		printf("恭喜您, 您赢了!\n");
	}
	else if (winner == 'o') {
		printf("哈哈,您连人工智障都下不过!\n");
	}
	else {
		printf("您只能和人工智障打平手!!\n");
	}
}

int menu() {
	printf("--------------------------\n");
	printf("--------1.开始游戏--------\n");
	printf("--------0.退出游戏--------\n");
	printf("--------------------------\n");
	int choice = 0;
	printf("请输入你的选择:");
	scanf("%d", &choice);
	return choice;
}
int main()
{
	srand((unsigned int)time(0));
	while (1) {
		int choice = menu();
		if (choice == 1) {
			game();
		}
		else if (choice == 0) {
			printf("退出游戏,GOODBYE!!!!!\n");
			break;
		}
		else {
			printf("输入错误!请重新输入!\n");
			continue;
		}
	}
	system("pause");
	return 0;
}

四、贪吃蛇完整版EN

// 必要的头文件 
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <time.h>
#include <windows.h>
#include <string.h>


// 定义标记上下左右的明示常量 
#define UP 1
#define DOWN 2
#define LEFT 3
#define RIGHT 4
#define ESC 5 
#define FOOD 10
// 定义表示位置的结构体类型
typedef struct snake{
	int x;
	int y;
	struct snake *next;
}snake;
// 定义全局变量 
int score = 0; // 当前得分
int speed = 200; // 存储当前速度
int status;
snake *tail, *head; // 存储蛇头蛇尾 
snake *food, *q;// q用于遍历链表 

HANDLE hOUT;
void gotoxy(int x, int y); // 设置光标位置 
int choice(void); // 载入游戏界面
int color(int c); // 设置字体颜色 
void printGame(void); // 打印游戏界面 
void printSnake(void); // 打印蛇身
void printFood(void); // 打印食物
void printTips(void); // 打印提示
void snakeMove(void); // 主操作函数 
int biteSelf(void); // 判断是否咬到了自己
int encounterWall(void); // 判断是否撞墙 
void keyboardControl(void); // 获取击键 
void speedUp(void); // 加速
void speedDown(void); // 减速
int endGame(void); // 结束函数; 
char *s_gets(char *st, int n); // 读取字符
void frees(snake *); // 释放内存 

int main(int argc, char *argv[]){
	while (1)
	{
		if (choice() == 1)
			keyboardControl();
		else
		{
			gotoxy(5, 15);
			printf("按任意键返回");
			getchar(); // 去除前一个前导换行 
			while (1)
			{
				if (getchar())
				{
					system("cls");
					break;
				}
			}
		}
	}
	frees(head);

	return 0;
}

void gotoxy(int x, int y)
{
	COORD c;
	c.X = x;
	c.Y = y;
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), c);
}

int choice(void)
{
	int yourchoice;
	// 画出界面 
	gotoxy(35, 5);
	color(11);
	printf("\t贪吃蛇大作战\n");
	printf("\n\n");
	color(13);
	printf("\t\t★★★★★★★★  Snake!");
	printf("\t\t★★★★★★★★  Snake!");
	gotoxy(25, 15);
	color(12);
	printf("1.进入游戏\t2.查看说明\t3.退出游戏\n");
	color(11);
	printf("请选择:");
	scanf("%d", &yourchoice);
	switch (yourchoice)
	{
	case 1:
		system("cls");
		// 初始化 
		printGame();
		printSnake();
		printFood();
		break;
	case 2:
		system("cls");
		printTips();
		break;
	case 3:
		system("cls");
		gotoxy(30, 10);
		color(11);
		printf("Bye!");
		exit(0);
	default:
		system("cls");
		printf("没有此序号,请输入1,2或3\n");
		Sleep(2000);
		system("cls");
	}
	return yourchoice;
}
int color(int c)
{
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), c);        //更改文字颜色
	return 0;
}
void printGame()
{
	int i, j;
	gotoxy(5, 5);
	printf("游戏载入中...请稍后");
	Sleep(2000);
	system("cls");

	// 打印上下界面
	for (i = 0; i <= 50; i += 2)
	{
		gotoxy(i, 0);
		printf("□");
		gotoxy(i, 25);
		printf("□");
	}
	// 打印左右界面
	for (i = 0; i <= 25; i += 1)
	{
		gotoxy(0, i);
		printf("□");
		gotoxy(50, i);
		printf("□");
	}
	// 打印中间网格
	for (i = 1; i <= 24; i += 1)
	{
		for (j = 2; j <= 48; j += 2)
		{
			gotoxy(j, i);
			color(11);
			printf("■");
		}
	}
	// 打印右侧的规则和计分栏
	gotoxy(60, 13);
	printf("当前分数:%d分,当前速度%d", score, speed);
	gotoxy(60, 15);
	printf("用↑ ↓ ← →分别控制蛇的移动\n");
	gotoxy(60, 18);
	printf("每次获取食物加10分  按下F1加速,F2减速,空格暂停\n");
	gotoxy(60, 20);
	printf("不能撞墙和咬到自己!");
	gotoxy(60, 22);
	printf("速度不低于100,不高于300");
}
void printSnake(void)
{
	int i;
	// 设定蛇尾(16,13),头插入,初始向右 
	tail = (snake*)malloc(sizeof(snake));
	tail->x = 16;
	tail->y = 13;
	tail->next = NULL;
	// 设定初始蛇长是4
	for (i = 1; i <= 4; i++)
	{
		head = (snake*)malloc(sizeof(snake));
		head->next = tail;
		head->x = 16 + 2 * i;
		head->y = 13;
		tail = head; // 头成为尾
	}
	// 输出蛇身
	while (tail->next)
	{
		gotoxy(tail->x, tail->y);
		color(14);
		printf("★");
		tail = tail->next;
	}
}
void printFood(void)
{
	srand((unsigned)time(NULL)); // 利用时钟修改种子 
	food = (snake*)malloc(sizeof(snake));
	food->x = 1; // 初始化x坐标 
	while (food->x % 2 && food->x)
	{
		food->x = rand() % 46 + 2;// 2-48 
	}
	food->y = rand() % 23 + 1; // 1-24 
	q = head; // 不改变头遍历链表 
	while (q->next)
	{
		if (q->x == food->x && q->y == food->y)
		{
			free(food);
			printFood();
		}
		else
		{
			gotoxy(food->x, food->y);
			color(12);
			printf("●");
			break;
		}
	}
}
void printTips(void)
{
	color(11);
	printf("***********Tips************\n");
	printf("1.采用合理的速度可以获得更高的分数哦!\n");
	printf("2.一定不要撞到自己或者两边的墙!\n");
	printf("3.游戏过程中按ESC退出游戏!\n");
}
void snakeMove(void)
{
	snake *snakenext;
	snakenext = (snake*)malloc(sizeof(snake));
	if (biteSelf())
	{
		gotoxy(60, 11);
		printf("咬到自己啦!");
		free(snakenext);
		Sleep(1500);
		system("cls");
		exit(0);
	}
	else if (encounterWall())
	{
		gotoxy(60, 11);
		printf("撞到墙啦!");
		free(snakenext);
		Sleep(1500);
		system("cls");
		exit(0);
	}
	else
	{
		// 前两个条件判断完成才开始移动 
		Sleep(350 - speed);
		if (status == UP)
		{
			snakenext->x = head->x;
			snakenext->y = head->y - 1;
			snakenext->next = head;
			head = snakenext;
			q = head;
			if (snakenext->x == food->x && snakenext->y == food->y)
			{
				while (q)
				{
					gotoxy(q->x, q->y);
					color(14);
					printf("★");
					q = q->next;
				}
				score += FOOD;
				gotoxy(60, 13);
				printf("当前分数:%d分,当前速度%d", score, speed);
				printFood();
			}
			else
			{
				while (q->next->next)
				{
					gotoxy(q->x, q->y);
					color(14);
					printf("★");
					q = q->next;
				}
				gotoxy(q->next->x, q->next->y);
				color(11);
				printf("■");
				free(q->next);
				q->next = NULL;
			}
		}
		else if (status == DOWN)
		{
			snakenext->x = head->x;
			snakenext->y = head->y + 1;
			snakenext->next = head;
			head = snakenext;
			q = head;
			if (snakenext->x == food->x && snakenext->y == food->y)
			{
				while (q)
				{
					gotoxy(q->x, q->y);
					color(14);
					printf("★");
					q = q->next;
				}
				score += FOOD;
				gotoxy(60, 13);
				printf("当前分数:%d分,当前速度%d", score, speed);
				printFood();
			}
			else
			{
				while (q->next->next)
				{
					gotoxy(q->x, q->y);
					color(14);
					printf("★");
					q = q->next;
				}
				gotoxy(q->next->x, q->next->y);
				color(11);
				printf("■");
				free(q->next);
				q->next = NULL;
			}
		}
		else if (status == LEFT)
		{
			snakenext->x = head->x - 2;
			snakenext->y = head->y;
			snakenext->next = head;
			head = snakenext;
			q = head;
			if (snakenext->x == food->x && snakenext->y == food->y)
			{
				while (q)
				{
					gotoxy(q->x, q->y);
					color(14);
					printf("★");
					q = q->next;
				}
				score += FOOD;
				gotoxy(60, 13);
				printf("当前分数:%d分,当前速度%d", score, speed);
				printFood();
			}
			else
			{
				while (q->next->next)
				{
					gotoxy(q->x, q->y);
					color(14);
					printf("★");
					q = q->next;
				}
				gotoxy(q->next->x, q->next->y);
				color(11);
				printf("■");
				free(q->next);
				q->next = NULL;
			}
		}
		else if (status == RIGHT)
		{
			snakenext->x = head->x + 2;
			snakenext->y = head->y;
			snakenext->next = head;
			head = snakenext;
			q = head;
			if (snakenext->x == food->x && snakenext->y == food->y)
			{
				while (q)
				{
					gotoxy(q->x, q->y);
					color(14);
					printf("★");
					q = q->next;
				}
				score += FOOD;
				gotoxy(60, 13);
				printf("当前分数:%d分,当前速度%d", score, speed);
				printFood();
			}
			else
			{
				while (q->next->next)
				{
					gotoxy(q->x, q->y);
					color(14);
					printf("★");
					q = q->next;
				}
				gotoxy(q->next->x, q->next->y);
				color(11);
				printf("■");
				free(q->next);
				q->next = NULL;
			}
		}
	}
}
int biteSelf(void)
{
	int x = 0; // 默认未咬到自己
	q = head->next;
	// 遍历蛇身 
	while (q->next)
	{
		if (q->x == head->x && q->y == head->y)
		{
			x = 1;
		}
		q = q->next;
	}

	return x;
}
int encounterWall(void)
{
	int x = 0; // 默认未撞到墙

	if (head->x == 0 || head->x == 50 || head->y == 0 || head->y == 25)
		x = 1;

	return x;
}
void keyboardControl(void)
{
	status = RIGHT; // 初始蛇向右移动
	while (1)
	{
		if (GetAsyncKeyState(VK_UP) && status != DOWN) // GetAsyncKeyState函数用来判断函数调用时指定虚拟键的状态
		{
			status = UP;           //如果蛇不是向下前进的时候,按上键,执行向上前进操作
		}
		else if (GetAsyncKeyState(VK_DOWN) && status != UP) // 如果蛇不是向上前进的时候,按下键,执行向下前进操作
		{
			status = DOWN;
		}
		else if (GetAsyncKeyState(VK_LEFT) && status != RIGHT) // 如果蛇不是向右前进的时候,按左键,执行向左前进
		{
			status = LEFT;
		}
		else if (GetAsyncKeyState(VK_RIGHT) && status != LEFT) // 如果蛇不是向左前进的时候,按右键,执行向右前进
		{
			status = RIGHT;
		}
		if (GetAsyncKeyState(VK_SPACE))// 空格暂停 
		{
			while (1)
			{
				Sleep(300);
				if (GetAsyncKeyState(VK_SPACE)) // 再次按空格改变状态 
				{
					break;
				}

			}
		}
		else if (GetAsyncKeyState(VK_ESCAPE))
		{
			status = ESC; // 按esc键,直接到结束界面
			if (endGame())
			{
				Sleep(500);
				system("cls");
				break;
			}
		}
		else if (GetAsyncKeyState(VK_F1)) // 按F1键,加速
		{
			speedUp();
			gotoxy(60, 13);
			printf("当前分数:%d分,当前速度%d", score, speed);
		}
		else if (GetAsyncKeyState(VK_F2)) // 按F2键,减速
		{
			speedDown();
			gotoxy(60, 13);
			printf("当前分数:%d分,当前速度%d", score, speed);
		}
		snakeMove();
	}
}
void speedUp(void)
{
	if (speed <= 280)
		speed += 20;
}
void speedDown(void)
{
	if (speed >= 120)
		speed -= 20;
}
int endGame(void)
{
	char x = 0;
	char judge[5];

	getchar();
	gotoxy(60, 9);
	printf("确定退出吗?(Yes/No)");
	gotoxy(60, 11);
	s_gets(judge, 5);

	if (strcmp(judge, "Yes") == 0)
	{
		Sleep(250);
		system("cls");
		gotoxy(40, 11);
		printf("\tBye!");
		x = 1;
	}
	else
		x = 0;

	return x;
}
char *s_gets(char *st, int n)
{
	char *ret_val;
	char *find;

	gotoxy(60, 11);
	ret_val = fgets(st, n, stdin);
	if (ret_val)
	{
		find = strchr(st, '\n');
		if (find)
			*find = '\0';
		else
		while (getchar() != '\n')
			continue;
	}

	return ret_val;
}
void frees(snake *s)
{
	snake *current = s;

	while (current)
	{
		current = s;
		s = current->next;
		free(current);
	}
}

END

源代码比较长只能先放上去这么多,还有更多的小项目 加一下我的c/c++编程资料交流Q群:214574728

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐