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

📄 collectable.cpp

📁 打飞机的过关游戏(linux)
💻 CPP
字号:
#include "collectable.h"

/*
Create a new collectable item based on supplied arguments.
*/
void addCollectable(float x, float y, int type, int value, int life)
{
	if (type == P_ANYTHING)
	{
		type = P_CASH;

		int r = rand() % 9;

		switch (r)
		{
			case 0:
				type = P_PLASMA_AMMO;
				break;
			case 1:
				type = P_SHIELD;
				break;
			case 2:
				type = P_ROCKET;
				value /= 10;
				break;
		}
	}
	else if (type == P_WEAPONS)
	{
		type = P_PLASMA_RATE;

		int r = rand() % 61;

		if (r <= 19)
			type = P_PLASMA_DAMAGE;
		else if (r <= 39)
			type = P_PLASMA_SHOT;
		else if (r <= 59)
			type = P_PLASMA_RATE;
		else
			type = P_SUPER;
	}

	if (type == P_SUPER)
		value = 1;

	/*
	Cash is rare on interceptions. Stops people from point leeching(!)
	*/
	if ((currentGame.area == MAX_MISSIONS - 1) && (type == P_CASH))
	{
		if (rand() % 10 > 0)
			return;
	}

	if (value == 0)
		return; // don't bother!

	// If the player has a charge cannon or a laser cannon, don't give them
	// rockets. Causes problems otherwise :)
	if (type == P_ROCKET)
	{
		if ((player.weaponType[1] == W_CHARGER) || (player.weaponType[1] == W_LASER))
		{
			type = P_CASH;
		}
	}

	collectables *collectable = new collectables;

	collectable->next = NULL;
	collectable->active = 1;
	collectable->x = x;
	collectable->y = y;

	collectable->dx = Math::rrand(-100, 100);
	if (collectable->dx != 0)
		collectable->dx /= 100;

	collectable->dy = Math::rrand(-100, 100);
	if (collectable->dy != 0)
		collectable->dy /= 100;

	collectable->type = type;
	collectable->value = value;
	collectable->life = life;

	switch(type)
	{
		case P_CASH:
			collectable->image = graphics.shape[24];
			break;

		case P_ROCKET:
			collectable->image = graphics.shape[49];
			break;

		case P_PLASMA_AMMO:
			collectable->image = graphics.shape[25];
			break;

		case P_SHIELD:
			collectable->image = graphics.shape[26];
			break;

		case P_PLASMA_SHOT:
			collectable->image = graphics.shape[27];
			break;

		case P_PLASMA_RATE:
			collectable->image = graphics.shape[28];
			break;

		case P_PLASMA_DAMAGE:
			collectable->image = graphics.shape[29];
			break;

		case P_CARGO:
			collectable->image = graphics.shape[32];
			break;

		case P_SUPER:
			collectable->image = graphics.shape[50];
			break;

		case P_MINE:
			collectable->image = graphics.shape[31];
			break;

		case P_SLAVES:
		case P_ESCAPEPOD:
			collectable->image = graphics.shape[45];
			break;

		case P_ORE:
			collectable->image = graphics.shape[46 + rand() % 3];
			break;
	}

	engine.collectableTail->next = collectable;
	engine.collectableTail = collectable;
}

void explodeMine(collectables *collectable)
{
	if ((collectable->x >= 0) && (collectable->x <= 800) && (collectable->y >= 0) && (collectable->y <= 600))
		playSound(SFX_EXPLOSION);

	for (int i = 0 ; i < 10 ; i++)
		addExplosion(collectable->x + rand() % 25 - rand() % 25, collectable->y + rand() % 25 - rand() % 25, E_BIG_EXPLOSION);

	if (checkPlayerShockDamage(collectable->x, collectable->y, 50))
		setInfoLine("Warning: Mine damage to shield!!", FONT_RED);
}

void checkMineBulletCollisions(object *bullet)
{
	collectables *collectable = engine.collectableHead;
	collectables *prevCollectable = engine.collectableHead;
	engine.collectableTail = engine.collectableHead;

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

		if (collectable->type == P_MINE)
		{
			if (Collision::collision(collectable, bullet))
			{
				collectable->active = 0;
				bullet->active = 0;
				if (bullet->owner == &player)
				{
					currentGame.minesKilled++;
					currentGame.hits++;
				}
			}
		}

		if (collectable->active == 1)
		{
			prevCollectable = collectable;
			engine.collectableTail = collectable;
		}
		else
		{
			explodeMine(collectable);
			prevCollectable->next = collectable->next;
			delete collectable;
			collectable = prevCollectable;
		}
	}
}

/*
Loops through the currently active collectables (in a linked list). The collectable
will travel in the direction that was defined when it was made. Its life will decreased
whilst it remains active. It will be removed if the player touches it or if its life
reaches 0. When it is picked up, depending on the type of collectable it is, mission requirements
will be updated. Information will be displayed and appropriate player variables altered.
*/
void doCollectables()
{
	collectables *collectable = engine.collectableHead;
	collectables *prevCollectable = engine.collectableHead;
	engine.collectableTail = engine.collectableHead;

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

		if (collectable->active == 1)
		{
			if ((collectable->x + collectable->image->w > 0) && (collectable->x < 800) && (collectable->y + collectable->image->h > 0) && (collectable->y < 600))
				graphics.blit(collectable->image, (int)collectable->x, (int)collectable->y);

			collectable->x += engine.ssx;
			collectable->y += engine.ssy;
			collectable->x += collectable->dx;
			collectable->y += collectable->dy;

			collectable->life--;

			if ((player.shield > 0) && (Collision::collision(collectable, &player)))
			{
				char temp[40];
				switch(collectable->type)
				{
					case P_CASH:
						currentGame.cash += collectable->value;
						currentGame.cashEarned += collectable->value;
						sprintf(temp, "Got $%d ", collectable->value);
						break;

					case P_ROCKET:
						Math::limitChar(&(player.ammo[1] += collectable->value), 0, currentGame.maxRocketAmmo);
						if (player.ammo[1] == currentGame.maxRocketAmmo)
							sprintf(temp, "Rocket Ammo at Maximum");
						else
						{
							if (collectable->value > 1)
								sprintf(temp, "Got %d rockets", collectable->value);
							else
								sprintf(temp, "Got a rocket");
						}
						currentGame.rocketPickups += collectable->value;
						break;

					case P_SHIELD:
						Math::limitInt(&(player.shield += 10), 0, player.maxShield);
						currentGame.shieldPickups ++;
						sprintf(temp, "Restored 10 shield points");
						break;

					case P_PLASMA_RATE:
						Math::limitChar(&(weapon[1].reload[0] -= 2), currentGame.maxPlasmaRate, 15);
						player.weaponType[0] = 1;
						if (player.ammo[0] < 50)
							player.ammo[0] = 50;
						Math::limitChar(&(player.ammo[0]), 0, currentGame.maxPlasmaAmmo);
						if (weapon[1].reload[0] == currentGame.maxPlasmaRate)
							sprintf(temp, "Firing Rate at Maximum");
						else
							sprintf(temp, "Firing rate increased");
						currentGame.powerups++;
						break;

					case P_PLASMA_SHOT:
						Math::limitChar(&(weapon[1].ammo[0] += 1), 1, currentGame.maxPlasmaOutput);
						if (player.ammo[0] < 50)
							player.ammo[0] = 50;
						Math::limitChar(&(player.ammo[0]), 0, currentGame.maxPlasmaAmmo);
						if (weapon[1].ammo[0] == currentGame.maxPlasmaOutput)
							sprintf(temp, "Plasma output at Maximum");
						else
							sprintf(temp, "Plasma output increased");
						player.weaponType[0] = 1;
						currentGame.powerups++;
						break;

					case P_PLASMA_DAMAGE:
						Math::limitChar(&(weapon[1].damage += 1), 1, currentGame.maxPlasmaDamage);
						if (player.ammo[0] < 50)
							player.ammo[0] = 50;
						Math::limitChar(&(player.ammo[0]), 0, currentGame.maxPlasmaAmmo);
						if (weapon[1].damage == currentGame.maxPlasmaDamage)
							sprintf(temp, "Plasma damage at Maximum");
						else
							sprintf(temp, "Plasma damage increased");
						player.weaponType[0] = 1;
						currentGame.powerups++;
						break;

					case P_SUPER:
						weapon[1].ammo[0] = 5;
						weapon[1].damage = 5;
						weapon[1].reload[0] = 7;

						if (weapon[1].flags & WF_STRAIGHT)
							weapon[1].flags -= WF_STRAIGHT;

						if (weapon[1].flags & WF_THIN_SPREAD)
							weapon[1].flags -= WF_THIN_SPREAD;

						if (!(weapon[1].flags & WF_WIDE_SPREAD))
							weapon[1].flags += WF_WIDE_SPREAD;
							
						sprintf(temp, "Picked up a Super Charge!!");

						if (player.ammo[0] < 50)
							player.ammo[0] = 50;
						player.weaponType[0] = 1;
						currentGame.powerups++;
						break;

					case P_PLASMA_AMMO:
						Math::limitChar(&(player.ammo[0] += collectable->value), 0, currentGame.maxPlasmaAmmo);
						if (player.ammo[0] == currentGame.maxPlasmaAmmo)
							sprintf(temp, "Plasma cells at Maximum");
						else
						{
							if (collectable->value > 1)
							{
								sprintf(temp, "Got %d plasma cells", collectable->value);
							}
							else
							{
								sprintf(temp, "Got a plasma cell");
								if ((rand() % 25) == 0)
									sprintf(temp, "Got one whole plasma cell (wahoo!)");
							}
						}
						player.weaponType[0] = 1;
						currentGame.cellPickups += collectable->value;
						break;

					case P_CARGO:
						strcpy(temp, "Picked up some Cargo");
						currentGame.cargoPickups++;
						break;

					case P_SLAVES:
						sprintf(temp, "Rescued %d slaves", collectable->value);
						currentGame.slavesRescued += collectable->value;
						break;

					case P_ESCAPEPOD:
						sprintf(temp, "Picked up an Escape Pod");
						break;

					case P_ORE:
						sprintf(temp, "Picked up some Ore");
						break;
				}

				updateMissionRequirements(M_COLLECT, collectable->type, collectable->value);

				collectable->active = 0;
				if (collectable->type != P_MINE)
				{
					setInfoLine(temp, FONT_WHITE);
					if (collectable->type == P_SHIELD)
						playSound(SFX_SHIELDUP);
					else
						playSound(SFX_PICKUP);
				}
			}

			// stop people from exploiting a weapon check condition
			if (player.ammo[0] == 0)
			{
				player.weaponType[0] = 0;
				weapon[1] = weapon[0]; // reset to weapon 1 defaults
			}
		}

		if (collectable->life < 1)
		{
			collectable->active = 0;
			if ((collectable->type == P_CARGO) || (collectable->type == P_ESCAPEPOD) || (collectable->type == P_SLAVES))
				updateMissionRequirements(M_PROTECT_PICKUP, collectable->type, 1);
		}

		if (collectable->active == 1)
		{
			prevCollectable = collectable;
			engine.collectableTail = collectable;
		}
		else
		{
			if (collectable->type == P_MINE)
				explodeMine(collectable);
			prevCollectable->next = collectable->next;
			delete collectable;
			collectable = prevCollectable;
		}
	}
}

⌨️ 快捷键说明

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