前言
发现很多朋友都想要一些小项目来练手,却找不到从哪里寻找,给大家整理了游戏项目开发源代码汇总。
一、最经典游戏之俄罗斯方块
#include
#include
#include
#include
#include
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 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||boss1hpx, 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 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)y - p_AP->y)>-ph && (p_MP->y - p_AP->y)x - p_AP2->x) > -pw && (p_MP->x - p_AP2->x)y - p_AP2->y)>-ph && (p_MP->y - p_AP2->y)boss1h&&(p_MP->x-(WINDOW_WIDTH / 2 - boss1w / 2)) >-pw && (p_MP->x-(WINDOW_WIDTH / 2 + boss1w / 2))yy -= 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->xx = (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->yy = 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
#include
#include
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
#include
#include
#include
#include
#include
// 定义标记上下左右的明示常量
#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 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 = 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
|