⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bullets.cpp

📁 打飞机的过关游戏(linux)
💻 CPP
📖 第 1 页 / 共 2 页
字号:

		return 1;
	}

	return 0;
}

/*
Fill in later...
*/
void fireRay(object *attacker)
{
	SDL_Rect ray;

	if (attacker->face == 0)
	{
		ray.x = (int)(attacker->x + attacker->image[0]->w);
	}
	else
	{
		ray.x = (int)(attacker->x - 800);
	}
	ray.y = (int)(attacker->y + attacker->engineY - 1);
	ray.h = 3;
	ray.w = 800;

	int red = SDL_MapRGB(graphics.screen->format, rand() % 256, 0x00, 0x00);
	SDL_FillRect(graphics.screen, &ray, red);
	graphics.addBuffer(ray.x, ray.y, ray.w, ray.h);

	if (attacker != &player)
	{
		if (player.shield > 0)
		{
			if (Collision::collision(player.x, player.y, player.image[0]->w, player.image[0]->h, ray.x, ray.y, ray.w, ray.h) && (!engine.cheatShield))
			{
				if (player.shield > engine.lowShield)
				{
					if (player.shield - 1 <= engine.lowShield)
					{
						setInfoLine("!!! WARNING: SHIELD LOW !!!", FONT_RED);
					}
				}
				player.shield--;

				addExplosion(player.x, player.y, E_SMALL_EXPLOSION);
				playSound(SFX_HIT);
				if (player.shield < 1)
				{
					playSound(SFX_DEATH);
					playSound(SFX_EXPLOSION);
				}
			}
		}
	}

	object *anEnemy = enemy;

	for (int i = 0 ; i < MAX_ALIENS ; i++)
	{
		if (anEnemy->flags & FL_IMMORTAL)
			continue;

		if ((anEnemy->shield > 0) && (attacker != anEnemy) && (attacker->classDef != anEnemy->classDef))
		{
			if (Collision::collision(anEnemy->x, anEnemy->y, anEnemy->image[0]->w, anEnemy->image[0]->h, ray.x, ray.y, ray.w, ray.h))
			{
				anEnemy->shield--;
				addExplosion(anEnemy->x, anEnemy->y, E_SMALL_EXPLOSION);
				playSound(SFX_HIT);
				if (anEnemy->shield < 1)
				{
					destroyAlien(attacker, anEnemy);
				}
			}
		}

		*anEnemy++;
	}

	attacker->ammo[0]--;
	if (attacker->ammo[0] < 1)
		attacker->flags -= FL_FIRERAY;
}

/*
This handles active bullets in a linked list. The current bullet and
previous bullet pointers are first assigned to the main header bullet
and each successive bullet is pulled out. Bullets are moved in their
delta coordinates, with rockets having fire trails added to them. Seperate
collision checks are done for a bullet that belongs to the enemy and one
that belongs to a player. However rockets can hit anyone. Upon an enemy
being killed, mission requirements are checked and collectables are randomly
spawned.
*/
void doBullets()
{
	object *bullet = engine.bulletHead;
	object *prevBullet = engine.bulletHead;
	engine.bulletTail = engine.bulletHead;

	object *theEnemy, *theCargo;

	signed char okayToHit = 0;
	float homingMissileSpeed = 0;

	while (bullet->next != NULL)
	{
		bullet = bullet->next;

		if (bullet->active == 1)
		{
			if (bullet->flags & WF_HOMING)
			{
			  	if (bullet->target == NULL)
					bullet->target = getRandomEnemy(bullet);

				if (bullet->owner->flags & FL_FRIEND)
					homingMissileSpeed = 0.25;
				else
					homingMissileSpeed = 0.05;
			}

			if (bullet->id == WT_ROCKET)
			{
				addExplosion(bullet->x, bullet->y, E_SMALL_EXPLOSION);
			}
			else if (bullet->id == WT_MICROROCKET)
			{
				addExplosion(bullet->x, bullet->y, E_TINY_EXPLOSION);
			}

			if ((bullet->flags & WF_AIMED) || (bullet->flags & WF_THIN_SPREAD))
			{
				graphics.blit(bullet->image[0], (int)(bullet->x - bullet->dx), (int)(bullet->y - bullet->dy));
			}

			if (bullet->id == WT_CHARGER)
			{
				for (int i = 0 ; i < bullet->damage ; i++)
					graphics.blit(bullet->image[0], (int)(bullet->x - Math::rrand(-(bullet->damage / 3), 0)), (int)(bullet->y + Math::rrand(-3, 3)));
			}

			graphics.blit(bullet->image[0], (int)bullet->x, (int)bullet->y);
			bullet->x += bullet->dx;
			bullet->y += bullet->dy;

			if (bullet->target != NULL)
			{
				if (bullet->x < bullet->target->x)
					Math::limitFloat(&(bullet->dx += homingMissileSpeed), -15, 15);
				if (bullet->x > bullet->target->x)
					Math::limitFloat(&(bullet->dx -= homingMissileSpeed), -15, 15);

				//Rocket is (more or less) inline with target. Fly straight
				if ((bullet->x > bullet->target->x - 1) && (bullet->x < bullet->target->x + 5))
					bullet->dx = 0;

				if (bullet->y < bullet->target->y)
					Math::limitFloat(&(bullet->dy += homingMissileSpeed), -15, 15);
				if (bullet->y > bullet->target->y)
					Math::limitFloat(&(bullet->dy -= homingMissileSpeed), -15, 15);

				//Rocket is (more or less) inline with target. Fly straight
				if ((bullet->y > bullet->target->y - 1) && (bullet->y < bullet->target->y + 5))
					bullet->dy = 0;

				if ((bullet->target->shield < 1) || (bullet->target->flags & FL_ISCLOAKED))
					bullet->target = NULL;
			}

			bullet->x += engine.ssx;
			bullet->y += engine.ssy;

			for (int i = 0 ; i < MAX_ALIENS ; i++)
			{
				theEnemy = &enemy[i];

				if ((theEnemy->shield < 1) || (!theEnemy->active))
					continue;

				okayToHit = 0;

				if ((bullet->flags & WF_FRIEND) && (theEnemy->flags & FL_WEAPCO))
					okayToHit = 1;
				if ((bullet->flags & WF_WEAPCO) && (theEnemy->flags & FL_FRIEND))
					okayToHit = 1;
				if ((bullet->id == WT_ROCKET) || (bullet->id == WT_LASER) || (bullet->id == WT_CHARGER))
					okayToHit = 1;

				if (bullet->owner == theEnemy->owner)
					okayToHit = 0;

				if (okayToHit)
				{
					if ((bullet->active == 1) && (Collision::collision(bullet, theEnemy)))
					{
						if (bullet->owner == &player)
						{
							currentGame.hits++;
							if ((theEnemy->classDef == CD_PHOEBE) || (theEnemy->classDef == CD_URSULA))
								getMissFireMessage(theEnemy);
						}

						if (!(theEnemy->flags & FL_IMMORTAL))
						{
							if (!(bullet->flags & WF_DISABLE))
								theEnemy->shield -= bullet->damage;
							else
								theEnemy->systemPower -= bullet->damage;

							theEnemy->hit = 5;
						}

						if (theEnemy->flags & FL_CANNOTDIE)
						{
							Math::limitInt(&theEnemy->shield, 1, theEnemy->maxShield);
							if (theEnemy->shield == 1)
							{
								if (currentGame.area != 26)
								{
									if (!(theEnemy->flags & FL_LEAVESECTOR))
									{
										theEnemy->flags += FL_LEAVESECTOR;
										if (theEnemy->flags & FL_CIRCLES)
											theEnemy->flags -= FL_CIRCLES;
										if (currentGame.area == 11)
											setRadioMessage(FACE_KLINE, "Seems I underestimated you, Bainfield! We'll meet again!", 1);
										else if (currentGame.area == 25)
											setRadioMessage(FACE_SID, "Chris, Kethlan is getting away!", 1);
									}
								}
								else
								{
									setKlineAttackMethod(theEnemy);
								}
							}
						}

						if ((theEnemy->flags & FL_RUNSAWAY) && ((rand() % 50) == 0))
						{
							if (!(theEnemy->flags & FL_LEAVESECTOR))
								theEnemy->flags += FL_LEAVESECTOR;
						}

						if (bullet->id != WT_CHARGER)
						{
							bullet->active = 0;
							bullet->shield = 0;
						}
						else if (bullet->id == WT_CHARGER)
						{
							bullet->shield -= theEnemy->shield;
							if (bullet->shield < 0)
								bullet->active = 0;
						}

						playSound(SFX_HIT);
						if (theEnemy->AIType == AI_EVASIVE)
							theEnemy->thinktime = 0;

						if (theEnemy->shield < 1)
							destroyAlien(bullet, theEnemy);

						if (theEnemy->systemPower < 1)
						{
							if (!(theEnemy->flags & FL_DISABLED))
							{
								theEnemy->flags += FL_DISABLED;
								updateMissionRequirements(M_DISABLE_TARGET, theEnemy->classDef, 1);
							}

							theEnemy->systemPower = 0;
							if (theEnemy->classDef == CD_KLINE)
								theEnemy->systemPower = theEnemy->maxShield;
						}

						if (bullet->id == WT_ROCKET)
							addExplosion(bullet->x, bullet->y, E_BIG_EXPLOSION);
						else
							addExplosion(bullet->x, bullet->y, E_SMALL_EXPLOSION);
					}
				}
			}

			// Check for bullets hitting player
			if ((bullet->flags & WF_WEAPCO) || (bullet->id == WT_ROCKET) || (bullet->id == WT_LASER) || (bullet->id == WT_CHARGER))
			{
				if ((bullet->active == 1) && (player.shield > 0) && (Collision::collision(bullet, &player)) && (bullet->owner != &player))
				{
					if ((!engine.cheatShield) || (engine.missionCompleteTimer != 0))
					{
						if (player.shield > engine.lowShield)
						{
							if (player.shield - bullet->damage <= engine.lowShield)
							{
								setInfoLine("!!! WARNING: SHIELD LOW !!!", FONT_RED);
							}
						}
						player.shield -= bullet->damage;
						Math::limitInt(&player.shield, 0, player.maxShield);
						player.hit = 5;
					}

					if ((bullet->owner->classDef == CD_PHOEBE) || (bullet->owner->classDef == CD_URSULA))
						getPlayerHitMessage(bullet->owner);

					if (bullet->id != WT_CHARGER)
					{
						bullet->active = 0;
						bullet->shield = 0;
					}
					else if (bullet->id == WT_CHARGER)
					{
						bullet->shield -= theEnemy->shield;
						if (bullet->shield < 0)
							bullet->active = 0;
					}

					playSound(SFX_HIT);

					if (bullet->id == WT_ROCKET)
						addExplosion(bullet->x, bullet->y, E_BIG_EXPLOSION);
					else
						addExplosion(bullet->x, bullet->y, E_SMALL_EXPLOSION);
				}
			}
		}

		if (((bullet->owner == &player)) || (bullet->id == WT_ROCKET))
		{
			for (int j = 0 ; j < 20 ; j++)
			{
				theCargo = &cargo[j];
				if (theCargo->active)
				{
					if (Collision::collision(bullet, theCargo))
					{
						bullet->active = 0;
						addExplosion(bullet->x, bullet->y, E_SMALL_EXPLOSION);
						playSound(SFX_HIT);
						if (theCargo->collectType != P_PHOEBE)
						{
							theCargo->active = 0;
							playSound(SFX_EXPLOSION);
							for (int i = 0 ; i < 10 ; i++)
								addExplosion(theCargo->x + Math::rrand(-15, 15), theCargo->y + Math::rrand(-15, 15), E_BIG_EXPLOSION);
							updateMissionRequirements(M_PROTECT_PICKUP, P_CARGO, 1);
						}
					}
				}
			}
		}

		// check to see if a bullet (on any side) hits a mine
		checkMineBulletCollisions(bullet);

		bullet->shield--;

		if (bullet->shield < 1)
		{
			if ((bullet->flags & WF_TIMEDEXPLOSION) || (bullet->id == WT_CHARGER))
			{
				playSound(SFX_EXPLOSION);
				for (int i = 0 ; i < 10 ; i++)
					addExplosion(bullet->x + Math::rrand(-35, 35), bullet->y + Math::rrand(-35, 35), E_BIG_EXPLOSION);

				if (bullet->flags & WF_TIMEDEXPLOSION)
					if (checkPlayerShockDamage(bullet->x, bullet->y, 75))
						setInfoLine("Warning: Missile Shockwave Damage!!", FONT_RED);
			}
			bullet->active = 0;
		}

		if (bullet->active == 1)
		{
			prevBullet = bullet;
			engine.bulletTail = bullet;
		}
		else
		{
			prevBullet->next = bullet->next;
			delete bullet;
			bullet = prevBullet;
		}
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -