c语言实现飞机大战小游戏

目录

引言

游戏代码 

基本思路 


引言

最近刚学了一点easyx库的知识,写了一个飞机大战的小游戏

WASD键控制上下左右,IJKL控制子弹从上下左右方向发射

敌机会从屏幕左右边缘随机出现,并会发射不同轨迹的子弹

同时也有敌机坠毁或玩家被攻击的动画和背景

下面是游戏截屏:

游戏代码 

下面是游戏代码(需提前下载easyx库)

#include<graphics.h>
#include<time.h>
#include<conio.h>
#include<stdlib.h>
#include<stdio.h>


int v = 4, enemy_v = 3, enemy_bullet_v = 4;
int bullet_count = 0, enemy_count = 0, enemy_bullet_count = 0,damage_hero_count=0;
unsigned long gametime = 0, bullettime = 0;
short bullet_frequency = 10, enenmy_frequency = 20, enenmy_bullet_frequency = 100;
int HP = 9;
int BULLETLEFT = 450;
int SCORE = 0;
#define LENTH 750
#define WIDTH 500
#define MAXBULLET 80
#define MAXSTAR 60
#define MAXENEMY 50
#define MAXDAMAGE 50
#define MAXENEMY_BULLET 80
#define hero_size 10
#define enemy_size 18
#define bullet_size 3
#define enemy_bullet_size 7
#define damage_size 20
int x = LENTH / 2, y = WIDTH / 2;


int absolute_value(int a, int b)
{
	int c;
	if (a > b)
	{
		c = a - b;
	}
	else
	{
		c = b - a;
	}
	return c;
}


struct STAR
{
	double x;
	int y;
	double step;
	int color;
};
STAR star[MAXSTAR];
void initstar(int i)
{
	star[i].x = 0;
	star[i].y = rand() % WIDTH;
	star[i].step = (rand() % 5000) / 1000.0 + 1;
	star[i].color = (int)(star[i].step * 255 / 6.0 + 0.5);
	star[i].color = RGB(star[i].color, star[i].color, star[i].color);
}
void initallstar()
{
	for (int i = 0; i < MAXSTAR; i++)
	{
		initstar(i);
		star[i].x = rand() % LENTH;
	}
}
void MoveStar(int i)
{
	fillcircle((int)star[i].x, star[i].y, 1);
	star[i].x += star[i].step;
	if (star[i].x > LENTH)
	{
		initstar(i);
	}
	setfillcolor(star[i].color);
	fillcircle((int)star[i].x, star[i].y, 1);
}


struct BULLET
{
	int po_x;
	int po_y;
	short direction;
};
struct BULLET bullet[MAXBULLET];
void initbullet(int m)
{
	bullet[m].po_x = 0;
	bullet[m].po_y = 0;
	bullet[m].direction = 5;
}
void initallbullet()
{
	for (int i = 0; i < MAXBULLET; i++)
	{
		initbullet(i);
	}
}


struct ENEMY
{
	int enemy_x;
	int enemy_y;
	short direction;
};
struct ENEMY enemy[MAXENEMY];
void initenemy(int n)
{
	enemy[n].enemy_x = enemy_size;
	enemy[n].enemy_y = 0;
	enemy[n].direction = 2;
}
void initallenemy()
{
	for (int i = 0; i < MAXENEMY; i++)
	{
		initenemy(i);
	}
}
void create_enemy()
{
	if (gametime % enenmy_frequency == 0)
	{
		enemy_count = enemy_count % MAXENEMY;
		enemy[enemy_count].enemy_y = enemy_size + rand() % (WIDTH - 2 * enemy_size);
		enemy[enemy_count].direction = rand() % 2;
		if (enemy[enemy_count].direction == 1)
		{
			enemy[enemy_count].enemy_x = LENTH - enemy_size;
		}
		enemy_count = enemy_count + 1;
	}
}


struct ENEMY_BULLET
{
	int posi_x;
	int posi_y;
	int direction;
};
struct ENEMY_BULLET enemy_bullet[MAXENEMY_BULLET];
void init_enemy_bullet(int mn)
{
	enemy_bullet[mn].posi_x = 0;
	enemy_bullet[mn].posi_y = 0;
	enemy_bullet[mn].direction = 2;
}
void init_all_enemy_bullet()
{
	for (int i = 0; i < MAXENEMY_BULLET; i++)
	{
		init_enemy_bullet(i);
	}
}

struct DAMAGE
{
	int damage_x;
	int damage_y;
	int damage_r;
	bool damage_test;
};
struct DAMAGE damage[MAXDAMAGE];
void initdamage(int da)
{
	damage[da].damage_test = 0;
	damage[da].damage_r = 0;
	damage[da].damage_x = 0;
	damage[da].damage_y = 0;
}
void init_all_damage()
{
	for (int i = 0; i < MAXDAMAGE; i++)
	{
		initdamage(i);
	}
}
void create_damage(int op)
{
	damage[op].damage_x = enemy[op].enemy_x;
	damage[op].damage_y = enemy[op].enemy_y;
	damage[op].damage_test = 1;
	damage[op].damage_r = 5;
}

struct DAMAGE_HERO
{
	int damage_x;
	int damage_y;
	int damage_r;
	bool damage_test;
};
struct DAMAGE_HERO damage_hero[10];
void create_hero_damage()
{
	damage_hero_count = damage_hero_count % 10;
	damage_hero[damage_hero_count].damage_x = x;
	damage_hero[damage_hero_count].damage_y = y;
	damage_hero[damage_hero_count].damage_test = 1;
	damage_hero[damage_hero_count].damage_r = 10;
	damage_hero_count++;
}
void init_damage_hero(int i)
{
	damage_hero[i].damage_r = 0;
	damage_hero[i].damage_test = 0;
	damage_hero[i].damage_x = 0;
	damage_hero[i].damage_y = 0;
}

void init_all_damage_hero()
{
	for (int i = 0; i < 10; i++)
	{
		init_damage_hero(i);
	}
}
void create_enemy_bullet()
{
	if (gametime % enenmy_bullet_frequency == 0)
	{
		for (int i = 0; i < MAXENEMY; i++)
		{
			if (enemy[i].direction != 2)
			{
				enemy_bullet_count = enemy_bullet_count % MAXENEMY_BULLET;
				if (enemy[i].direction == 1 && enemy[i].enemy_x < LENTH && enemy[i].enemy_x>0)
				{
					enemy_bullet[enemy_bullet_count].posi_x = enemy[i].enemy_x;
					enemy_bullet[enemy_bullet_count].posi_y = enemy[i].enemy_y;
					enemy_bullet[enemy_bullet_count].direction = 0;
					enemy_bullet_count = enemy_bullet_count + 1;
				}
				if (enemy[i].direction == 0 && enemy[i].enemy_x < LENTH && enemy[i].enemy_x>0)
				{
					enemy_bullet[enemy_bullet_count].posi_x = enemy[i].enemy_x;
					enemy_bullet[enemy_bullet_count].posi_y = enemy[i].enemy_y;
					enemy_bullet[enemy_bullet_count].direction = 1;
					enemy_bullet_count = enemy_bullet_count + 1;
				}
			}
		}
	}
}


void keyboard()
{

	if (GetAsyncKeyState('W'))
	{
		y = y - v;
	}
	if (GetAsyncKeyState('S'))
	{
		y = y + v;
	}
	if (GetAsyncKeyState('A'))
	{
		x = x - v;
	}
	if (GetAsyncKeyState('D'))
	{
		x = x + v;
	}
	if (x < 0)
	{
		x = 0;
	}
	if (x > LENTH)
	{
		x = LENTH;
	}
	if (y < 0)
	{
		y = 0;
	}
	if (y > WIDTH)
	{
		y = WIDTH;
	}
	if (BULLETLEFT > 0)
	{
		if (GetAsyncKeyState('I'))
		{
			if ((gametime - bullettime) % bullet_frequency == 0)
			{
				bullettime = gametime;
				bullet_count = bullet_count % MAXBULLET;
				bullet[bullet_count].po_x = x;
				bullet[bullet_count].po_y = y - 3;
				bullet[bullet_count].direction = 1;
				bullet_count = bullet_count + 1;
				BULLETLEFT = BULLETLEFT - 1;
			}
		}
		if (GetAsyncKeyState('K'))
		{
			if ((gametime - bullettime) % bullet_frequency == 0)
			{
				bullettime = gametime;
				bullet_count = bullet_count % MAXBULLET;
				bullet[bullet_count].po_x = x;
				bullet[bullet_count].po_y = y + 3;
				bullet[bullet_count].direction = 2;
				bullet_count = bullet_count + 1;
				BULLETLEFT = BULLETLEFT - 1;
			}
		}
		if (GetAsyncKeyState('J'))
		{
			if ((gametime - bullettime) % bullet_frequency == 0)
			{
				bullettime = gametime;
				bullet_count = bullet_count % MAXBULLET;
				bullet[bullet_count].po_x = x - 3;
				bullet[bullet_count].po_y = y;
				bullet[bullet_count].direction = 3;
				bullet_count = bullet_count + 1;
				BULLETLEFT = BULLETLEFT - 1;
			}
		}
		if (GetAsyncKeyState('L'))
		{
			if ((gametime - bullettime) % bullet_frequency == 0)
			{
				bullettime = gametime;
				bullet_count = bullet_count % MAXBULLET;
				bullet[bullet_count].po_x = x + 3;
				bullet[bullet_count].po_y = y;
				bullet[bullet_count].direction = 4;
				bullet_count = bullet_count + 1;
				BULLETLEFT = BULLETLEFT - 1;
			}
		}
	}
}


void drawhero()
{
	setfillcolor(RED);
	solidcircle(x, y, hero_size);
	POINT pts_1[] = { {x + 3 * hero_size / 2,y},{x + 3 * hero_size,y + hero_size / 2},{x + 5 * hero_size,y},{x + 3 * hero_size,y - hero_size / 2} };
	solidpolygon(pts_1, 4);
	POINT pts_2[] = { {x - 3 * hero_size / 2,y},{x - 3 * hero_size,y + hero_size / 2},{x - 5 * hero_size,y},{x - 3 * hero_size,y - hero_size / 2} };
	solidpolygon(pts_2, 4);
	POINT pts_3[] = { {x,y + 3 * hero_size / 2},{x + hero_size / 2,y + 3 * hero_size},{x,y + 5 * hero_size},{x - hero_size / 2,y + 3 * hero_size} };
	solidpolygon(pts_3, 4);
	POINT pts_4[] = { {x,y - 3 * hero_size / 2},{x + hero_size / 2,y - 3 * hero_size},{x,y - 5 * hero_size},{x - hero_size / 2,y - 3 * hero_size} };
	solidpolygon(pts_4, 4);
}


void drawbullet()
{
	for (int i = 0; i < MAXBULLET; i++)
	{
		if (bullet[i].direction < 5)
		{
			setfillcolor(WHITE);
			if (bullet[i].direction == 3 || bullet[i].direction == 4)
			{
				solidroundrect(bullet[i].po_x - 2 * bullet_size, bullet[i].po_y + bullet_size, bullet[i].po_x + 2 * bullet_size, bullet[i].po_y - bullet_size, 2, 2);
			}
			if (bullet[i].direction == 1 || bullet[i].direction == 2)
			{
				solidroundrect(bullet[i].po_x - bullet_size, bullet[i].po_y + 2 * bullet_size, bullet[i].po_x + bullet_size, bullet[i].po_y - 2 * bullet_size, 2, 2);
			}
			if (bullet[i].direction == 1)
			{
				bullet[i].po_y = bullet[i].po_y - 8;
			}
			if (bullet[i].direction == 2)
			{
				bullet[i].po_y = bullet[i].po_y + 8;
			}
			if (bullet[i].direction == 3)
			{
				bullet[i].po_x = bullet[i].po_x - 8;
			}
			if (bullet[i].direction == 4)
			{
				bullet[i].po_x = bullet[i].po_x + 8;
			}
			if (bullet[i].po_x < 0 || bullet[i].po_x > LENTH || bullet[i].po_y < 0 || bullet[i].po_y > WIDTH)
			{
				initbullet(i);
			}
		}
	}
}


void drawstar()
{
	for (int i = 0; i < MAXSTAR; i++)
	{
		MoveStar(i);
	}
}


void drawenemy()
{
	for (int i = 0; i < MAXENEMY; i++)
	{
		if (enemy[i].direction != 2)
		{
			setfillcolor(YELLOW);
			solidellipse(enemy[i].enemy_x - enemy_size, enemy[i].enemy_y - enemy_size / 2, enemy[i].enemy_x + enemy_size, enemy[i].enemy_y + enemy_size / 2);
			solidrectangle(enemy[i].enemy_x - enemy_size / 3, enemy[i].enemy_y - enemy_size, enemy[i].enemy_x + enemy_size / 3, enemy[i].enemy_y + enemy_size);
			if (enemy[i].direction == 0)
			{
				enemy[i].enemy_x = enemy[i].enemy_x + enemy_v;
			}
			if (enemy[i].direction == 1)
			{
				enemy[i].enemy_x = enemy[i].enemy_x - enemy_v;
			}
			if (enemy[i].enemy_x < 0 || enemy[i].enemy_x > LENTH || enemy[i].enemy_y < 0 || enemy[i].enemy_y > WIDTH)
			{
				initenemy(i);
			}
		}
	}
}


void draw_enemy_bullet()
{
	for (int i = 0; i < MAXENEMY_BULLET; i++)
	{
		if (enemy_bullet[i].direction != 2)
		{
			setfillcolor(BLUE);
			solidcircle(enemy_bullet[i].posi_x, enemy_bullet[i].posi_y, enemy_bullet_size);
			if (enemy_bullet[i].direction == 0)
			{
				enemy_bullet[i].posi_x = enemy_bullet[i].posi_x + enemy_bullet_v;
				enemy_bullet[i].posi_y = enemy_bullet[i].posi_y + enemy_bullet_v;
			}
			if (enemy_bullet[i].direction == 1)
			{
				enemy_bullet[i].posi_x = enemy_bullet[i].posi_x - enemy_bullet_v;
			}
			if (enemy_bullet[i].posi_x < 0 || enemy_bullet[i].posi_x > LENTH || enemy_bullet[i].posi_y < 0 || enemy_bullet[i].posi_y > WIDTH)
			{
				init_enemy_bullet(i);
			}
		}
	}
}


void drawhp_and_bullet()
{
	settextcolor(RGB(111, 222, 147));
	settextstyle(20, 0, _T("Courier"));
	outtextxy(10, 10, _T("Your Hp is:"));
	char str_hp[10];
	sprintf_s(str_hp, "%d", HP);
	outtextxy(150, 10, *str_hp);
	if (BULLETLEFT > 450)
	{
		BULLETLEFT = 450;
	}
	outtextxy(10, 30, _T("Your Bullet is:"));
	char str_bulletleft[10];
	sprintf_s(str_bulletleft, "%d", BULLETLEFT / 50);
	outtextxy(190, 30, *str_bulletleft);
	char str_score[10];
	sprintf_s(str_score, "%d", SCORE / 10);
	outtextxy(10, 50, _T("Your Score is:"));
	outtextxy(180, 50, *str_score);
}


void drawdamage()
{
	for (int k = 0; k < MAXDAMAGE; k++)
	{
		if (damage[k].damage_test == 1)
		{
			if (damage[k].damage_r < damage_size)
			{
				setfillcolor(WHITE);
				fillcircle(damage[k].damage_x, damage[k].damage_y, damage[k].damage_r);
				damage[k].damage_r++;
			}
			if (damage[k].damage_r == damage_size)
			{
				initdamage(k);
			}
		}
	}
}
void draw_hero_damage()
{
	for (int i = 0; i < 10; i++)
	{
		if (damage_hero[i].damage_test == 1)
		{
			if (damage_hero[i].damage_r < 30)
			{
				setfillcolor(RGB(111, 222, 147));
				fillcircle(damage_hero[i].damage_x, damage_hero[i].damage_y, damage_hero[i].damage_r);
				damage_hero[i].damage_r++;
			}
			if (damage_hero[i].damage_r == 30)
			{
				init_damage_hero(i);
			}
		}
	}
}
void draw()
{
	drawhero();
	drawbullet();
	drawstar();
	drawenemy();
	drawdamage();
	draw_hero_damage();
	draw_enemy_bullet();
	drawhp_and_bullet();
}


void collide()
{
	int direction_x, direction_y;
	for (int i = 0; i < MAXENEMY_BULLET; i++)
	{
		direction_x = absolute_value(enemy_bullet[i].posi_x, x);
		direction_y = absolute_value(enemy_bullet[i].posi_y, y);
		if (direction_x < enemy_bullet_size + hero_size / 2 && direction_y < 2 * enemy_bullet_size + hero_size / 2)
		{
			init_enemy_bullet(i);
			HP = HP - 1;
			create_hero_damage();
		}
	}
	for (int i = 0; i < MAXENEMY; i++)
	{
		if (enemy[i].direction != 2)
		{
			direction_x = absolute_value(enemy[i].enemy_x, x);
			direction_y = absolute_value(enemy[i].enemy_y, y);
			if (direction_x < enemy_size + hero_size / 2 && direction_y < 2 * enemy_size + hero_size / 2)
			{
				initenemy(i);
				HP = HP - 1;
				create_hero_damage();
			}
			for (int j = 0; j < MAXBULLET; j++)
			{
				if (bullet[j].direction < 5)
				{
					direction_x = absolute_value(enemy[i].enemy_x, bullet[j].po_x);
					direction_y = absolute_value(enemy[i].enemy_y, bullet[j].po_y);
					if (direction_x < enemy_size + bullet_size / 2 && direction_y < enemy_size + bullet_size / 2)
					{
						create_damage(i);
						initenemy(i);
						initbullet(j);
						BULLETLEFT = BULLETLEFT + 5;
						SCORE = SCORE + 1;
					}
				}
			}
		}
	}
}



void init_all_things()
{
	initgraph(LENTH, WIDTH);
	setbkcolor(BLACK);
	initallstar();
	initallbullet();
	initallenemy();
	init_all_enemy_bullet();
	init_all_damage();
	init_all_damage_hero();
}


int main()
{
	init_all_things();
	while (HP > 0)
	{
		Sleep(5);
		gametime++;
		BeginBatchDraw();
		cleardevice();
		create_enemy();
		create_enemy_bullet();
		keyboard();
		collide();
		draw();
		FlushBatchDraw();
		if (GetAsyncKeyState('M'))
		{
			break;
		}
		if (GetAsyncKeyState('N'))
		{
			Sleep(500);
			while (!GetAsyncKeyState('N'))
			{
				Sleep(500);
			}
		}
		if (gametime > 4294967290)
		{
			break;
		}
	}
	closegraph();
	return 0;
}

基本思路 

每5ms刷新一次屏幕,用draw函数绘制英雄,英雄子弹,敌机,敌机子弹,和背景星星,同时用collide函数计算子弹和敌机之间距离,如果过近则销毁并绘制爆炸图像。

类型数组
背景移动的星星star[ ]
爆炸画面

 damage[ ]

英雄子弹bullet[ ]
敌机enemy[ ]
敌机子弹enemy_bullet[ ]

监视键盘GetAsyncKeyState函数
绘制图像solidcircle,solidrectangle函数(easyx有详细介绍)
创建/关闭窗口initgraph,closegraph函数

注1:easyx库只能用c++语言,不能用c语言,但本人感觉两者还是挺相似的,大多数基础的c语言代码c++也能跑 

注2:如果没有BeginBatchDraw和FlushBatchDraw函数,这个屏幕会一直闪烁,影响游戏体验,因此一定要加上

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值