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

📄 enemy.cpp

📁 蕃茄炸弹超人[ACT]I ve no Tomatoes 开放原始码
💻 CPP
📖 第 1 页 / 共 2 页
字号:

	// Check the traps
	if(traplist.size() > 0) {
		list<TRAP>::iterator t;
		for(t = traplist.begin(); t != traplist.end(); ++t) {
			if(x == (*t).x && y == (*t).y) {
				die();
				return;
			}
		}
	}


	// Handle the burning, that is run around aimlessly
	if(burning) {
		if(!kicked) {
			// Reduce the burning time
			burn_time--;
			if(burn_time == 0) {
				die();
				return;
			}

			// Choose a random direction
			if(RAND(0,100) > 50 && offset == 0.0f) {
				if(RAND(0,100) > 50)
					dir++;
				else
					dir--;
				if(dir > DIR_W)
					dir = DIR_N;
				else if(dir < DIR_N)
					dir = DIR_W;
			}

			// Move one step
			if(tx == x && ty == y) {
				offset = 0.0f;

				// Don't stop until there's a wall.
				switch(dir) {
					default:
					case DIR_N: tx = x; ty = y - 1; break;
					case DIR_E: tx = x + 1; ty = y; break;
					case DIR_S: tx = x; ty = y + 1; break;
					case DIR_W: tx = x - 1; ty = y; break;
				}

				// Check if the target is passable?
				if(map_solid(tx, ty)) {
					// Stop and choose a new dir
					tx = x;
					ty = y;

					dir += RAND(-1,1);
					if(dir < DIR_N)
						dir = DIR_W;
					else if(dir > DIR_W)
						dir = DIR_N;
					return;
				}

			}

			// Move towards the target tile
			if(offset < 1.0f && (tx != x || ty != y)) {
				offset += speed;

				// Check the collision between the player #1
				if(p1.alive && !p1.jumping && !(using_special_power == 1 && which_special_power == BLUE_POWER_TELEPORT)) {
					float dx = get_real_x() - p1.get_real_x();
					float dy = get_real_y() - p1.get_real_y();
					if(dx*dx + dy*dy <= 0.9f) {
						// Collision happened!

						// Turn around and run
						tx = x;
						ty = y;
						offset = 0.0f;
						dir += 2;
						if(dir > DIR_W)
							dir -= 4;
					}
				}

				// Check the collision between the player #2
				if(two_players && p2.alive && !p2.jumping && !(using_special_power == 2 && which_special_power == BLUE_POWER_TELEPORT)) {
					float dx = get_real_x() - p2.get_real_x();
					float dy = get_real_y() - p2.get_real_y();
					if(dx*dx + dy*dy <= 0.9f) {
						// Collision happened!

						// Turn around and run
						tx = x;
						ty = y;
						offset = 0.0f;
						dir += 2;
						if(dir > DIR_W)
							dir -= 4;
					}
				}

				// Check the collision between the potato men
				if(potatoman.collide_with(this) && !kicked) {
					// Potatoman "kicked" us
					potatoman.kick(this);
				}


				// If we're reached the target tile, move again
				if(offset >= 1.0f) {
					x = tx;
					y = ty;
					offset = 0.0f;
				}
			}
		}

		// Check collisions with other enemies and spread the fire
		bool burnt_somebody = false;
		list<ENEMY>::iterator e;
		for(e = enemylist.begin(); e != enemylist.end(); ++e) {
			if(this != &(*e) && !(*e).burning) {
				// Check the distance
				float dx = get_real_x() - (*e).get_real_x();
				float dy = get_real_y() - (*e).get_real_y();
				if(dx*dx + dy*dy <= 0.9f) {
					// Burn the other enemy
					(*e).burning = true;
					(*e).burn_time = enemy_burn_time;
					(*e).speed += 0.06f;
					burnt_somebody = true;
				}
			}
		}

		// Play the burning sound
		if(burnt_somebody)
			play_sound(SND_WILDFIRE, false);

		if(!kicked)
			return;
	}


	// Not burning below here

	// Choose a random destination
	if(path_pos == -1) {
		// Choose a valid target
		int dx = RAND(0, MAP_W-1);
		int dy = RAND(0, MAP_H-1);
		while(map_solid(dx, dy) || dx == x || dy == y) {
			dx = RAND(0, MAP_W-1);
			dy = RAND(0, MAP_H-1);
		}

		// Calculate the path
		if(pf.find_path(x, y, dx, dy) == PATH_FAILED) {
			// Well, tough luck. We'll just wait and try again later.
			return;
		}

		// Now we've got a nice path for us!
		path_pos = 0;
		offset = 0.0f;
		tx = pf.path[0].x;
		ty = pf.path[0].y;
		dir = get_dir(tx - x, ty - y);
		look_player();
	}

	// Move one step
	if(tx == x && ty == y && path_pos > -1) {
		offset = 0.0f;

		// Follow the path if we're not chasing
		if(chase == 0 && !kicked) {
			path_pos++;
			tx = pf.path[path_pos].x;
			ty = pf.path[path_pos].y;
			dir = get_dir(tx - x, ty - y);
			look_player();
		}
		else if(chase && !kicked) {
			// We are chasing. Don't stop until there's a wall.
			switch(dir) {
				default:
				case DIR_N: tx = x; ty = y - 1; break;
				case DIR_E: tx = x + 1; ty = y; break;
				case DIR_S: tx = x; ty = y + 1; break;
				case DIR_W: tx = x - 1; ty = y; break;
			}

			// Check if the target is passable?
			if(map_solid(tx, ty)) {
				// Stop and choose a new path
				tx = x;
				ty = y;

				path_pos = -1;
				chase = 0;
				speed -= 0.03f;
			}
		}
		else if(kicked) {
			// Potatoman has kicked us. "Fly" straight until we hit a wall.
			switch(dir) {
				default:
				case DIR_N: tx = x; ty = y - 1; break;
				case DIR_E: tx = x + 1; ty = y; break;
				case DIR_S: tx = x; ty = y + 1; break;
				case DIR_W: tx = x - 1; ty = y; break;
			}

			// Check for the wall
			if(map_solid(tx, ty)) {
				die();
				return;
			}
		}
	}

	// Move towards the target tile
	if(offset < 1.0f && (tx != x || ty != y) && path_pos > -1) {
		offset += speed;

		// Check the collision between the player #1
		if(p1.alive && !p1.jumping && !(using_special_power == 1 && which_special_power == BLUE_POWER_TELEPORT)) {
			float dx = get_real_x() - p1.get_real_x();
			float dy = get_real_y() - p1.get_real_y();
			if(dx*dx + dy*dy <= 0.9f) {
				// Collision happened!

				// Kill the player and die
				p1.die();
				die();
			}
		}

		// Check the collision between the player #2
		if(alive && two_players && p2.alive && !p2.jumping && !(using_special_power == 2 && which_special_power == BLUE_POWER_TELEPORT)) {
			float dx = get_real_x() - p2.get_real_x();
			float dy = get_real_y() - p2.get_real_y();
			if(dx*dx + dy*dy <= 0.9f) {
				// Collision happened!

				// Kill the player and die
				p2.die();
				die();
			}
		}


		// Check the collision between the potato men
		if(potatoman.collide_with(this) && !kicked) {
			// Potatoman "kicked" us
			potatoman.kick(this);
		}


		// If we're reached the target tile, move again
		if(offset >= 1.0f) {
			x = tx;
			y = ty;
			offset = 0.0f;

			// If this is the final destination, stay put and choose a new path
			// on the next cycle
			if(x == pf.dx && y == pf.dy && !chase && !kicked)
				path_pos = -1;
		}
	}

}


// Kill the enemy
void ENEMY::die() {
	if(dying)
		return;		// Hey, don't you die twice, man! ;)
	dying = true;
	kill_count++;
	die_anim = 1.0f;

	// Create a bonus
	add_bonus((int)get_real_x(), (int)get_real_y(), type);

	// Play the sound
	static int last_sound = -1;
	int sound = last_sound;
	while(sound == last_sound)
		sound = RAND(SND_DIE1, SND_DIE6);
	play_sound(sound, false);
	last_sound = sound;
}


// Get current x with offset
float ENEMY::get_real_x() {
	// Calculate the offset
	float offx = 0;
	if(dir == DIR_E)
		offx = offset;
	else if(dir == DIR_W)
		offx = -offset;

	return (float)x + offx + 0.5f;
}


// Get current y with offset
float ENEMY::get_real_y() {
	// Calculate the offset
	float offy = 0;
	if(dir == DIR_N)
		offy = -offset;
	else if(dir == DIR_S)
		offy = offset;

	return (float)y + offy + 0.5f;
}


// Draw the enemy
void ENEMY::draw() {
	// Calculate the offset
	float offx = 0, offz = 0;
	switch(dir) {
		default:
		case DIR_N: offz = -offset; break;
		case DIR_E: offx = offset; break;
		case DIR_S: offz = offset; break;
		case DIR_W: offx = -offset; break;
	}

	// Translate to the position
	glPushMatrix();
	glTranslatef(x + offx + 0.5f, size - 0.20f, y + offz + 0.5f);

	// Draw the shadow
	glDepthMask(GL_FALSE);
	glColor3f(1,1,1);
	BIND_TEXTURE(sprite_shadow);
	float sh = -(size - 0.21f);
	glBegin(GL_TRIANGLE_STRIP);
		glTexCoord2f(1,1); glVertex3f( 0.6f, sh, -0.6f);
		glTexCoord2f(0,1); glVertex3f(-0.6f, sh, -0.6f);
		glTexCoord2f(1,0); glVertex3f( 0.6f, sh,  0.6f);
		glTexCoord2f(0,0); glVertex3f(-0.6f, sh,  0.6f);
	glEnd();
	glDepthMask(GL_TRUE);

	// Raise up if we're turning
	if(turning)
		glTranslatef(0, turning_raise * 0.85f, 0);


	// Negate the camera rotation
	glMultMatrixf(cam_neg_matrix);
//	glRotatef(45.0f, 0,1,0);
//	glRotatef(-30.0f, 1,0,0);

	// Draw the sprite
	if(burning)
		glColor3f(.5f,.5f,.5f);

	// Compute the texture coords according the animation frame and direction
	BIND_TEXTURE(enemy_anim[type]);
	int f = anim_frames[(int)anim];
	float textx = 0.25f * f;
	float texty = 0.25f * (3-dir);

	if(!dying) {
		glBegin(GL_TRIANGLE_STRIP);
			glTexCoord2f(textx + 0.25f, texty + 0.25f); glVertex3f( size,  size,  size);
			glTexCoord2f(textx, texty + 0.25f); glVertex3f(-size,  size,  size);
			glTexCoord2f(textx + 0.25f, texty); glVertex3f( size, -size, -size);
			glTexCoord2f(textx, texty); glVertex3f(-size, -size, -size);
		glEnd();
	}
	else {
		// Draw the dying animation
		float z = size - (2*size*(1-die_anim));
		glBegin(GL_TRIANGLE_STRIP);
			glTexCoord2f(textx + 0.25f, texty + (die_anim*0.25f)); glVertex3f( size,  z,  z);
			glTexCoord2f(textx, texty + (die_anim*0.25f)); glVertex3f(-size,  z,  z);
			glTexCoord2f(textx + 0.25f, texty); glVertex3f( size, -size, -size);
			glTexCoord2f(textx, texty); glVertex3f(-size, -size, -size);
		glEnd();

	}

	glPopMatrix();
}


// Clear the enemy
void ENEMY::clear() {
	x = y = 0;
	tx = ty = 0;
	offset = 0.0f;
	speed = 0.05f;
	dir = RAND(DIR_N, DIR_W);
	nextdir = dir;
	size = 0.85f;
	anim = 0.0f;
	type = 0;
	alive = false;
	dying = false;
	die_anim = 1.0f;
	path_pos = -1;
	chase = 0;
	burning = false;
	burn_time = 0;
	turning = 0;
	turning_counter = 0;
	turning_raise = 0.0f;
	kicked = false;
}


⌨️ 快捷键说明

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