Enemy movement

Started by
3 comments, last by Mybowlcut 15 years, 10 months ago
Hey. I've got a bunch of enemies that are being moved around in an extremely primitive manner... so primitive that they all end up going to the top right corner of the screen for some reason... just wondering if anyone can tell me why this would be? This is my level class that updates each enemy.
void Rudey_Level::Update(const SDL_Event* event_)
{
	using namespace SDL_Tools;

	SDL_Rect new_pos, old_pos;
	bool found_valid_move = false;
	
	/*std::copy(moves_shuffled.begin(), moves_shuffled.end(),
				std::ostream_iterator<DIRECTION>(std::cout, " "));*/

	if(Screen_Event_Manager::Empty())
	{ // No need to update yet.
		return;
	}

	for(enemy_it it = enemies.begin(); it != enemies.end(); ++it)
	{
		/* Move enemy. */
		if(Screen_Event_Manager::Find_First_Of("", TIMER))
		{ // Time to update.
			found_valid_move = false;
			old_pos = it->Get_Position();

			// shuffle array to randomise movement
			std::random_shuffle(moves_shuffled.begin(), moves_shuffled.end());

			for(int i = 0; i < QTY_DIRECTIONS && !found_valid_move; ++i)
			{ // Try to find a valid move.			
				new_pos = move_by(old_pos, distance_from_direction(
					DIRECTION_ARRAY, TILE_WIDTH, TILE_HEIGHT));

				if(Can_Move_To(*it, new_pos))
				{ // New position is inside level_boundary and
				  // not already taken by someone other than it..
					it->Move(DIRECTION_ARRAY);
					found_valid_move = true;
				}
			}
			// If we couldn't move anywhere... we stay where we are!
		}
	}
}
This is the main game loop. The enemies always end up going to the top right corner of the screen...
void Rudey_Game::Run()
{
	Rudey_Clock::Start(game_speed);

	while(!exit)
	{ // While the user hasn't exit
		if(SDL_PollEvent(&sdl_event) != 0)
		{ // There's an event to handle.
			if(sdl_event.type == SDL_QUIT)
			{ // If the user has Xed out
				exit = true;
				break;
			}
			else
			{
				rudey.Update(&sdl_event);
			}
		}

		Rudey_Clock::Update();

		game_screen.Update(&sdl_event);
		game_screen.Draw();

		level.Update(&sdl_event);
		level.Draw();
		rudey.Draw();

		Draw_Engine::Write(0,0,Conversions::to_string(Rudey_Clock::Get_Ticks()));

		Draw_Engine::Draw_Screen();
		
		// Handle events that control the game/app.
		Handle_Events();
	}
	// Exit.
}

namespace Direction
{
	// (n,e,s,w)
	const unsigned short QTY_DIRECTIONS = 4;

	typedef enum DIRECTION
	{
		NO_DIRECTION, START, NORTH, EAST, SOUTH, WEST
	};

	// Using an array prevents code from breaking if the element order of DIRECTION changes.
	const DIRECTION DIRECTION_ARRAY[QTY_DIRECTIONS] = {NORTH, EAST, SOUTH, WEST};

Cheers!

Advertisement
without really delving into the code i'd hazzard a guess that it has something to do with the fact that you declare that the number of options are 4... however the first 2 in the array you create are nodirection and start, which leaves only north and east as valid directions. so if you randomly pick the first 4 out of the array you will get 2 bogus ones then either north or east which would make them go up and right.

or then again maybe someone who actually really reads your code will have a better answer.

[slight edit]
Quote:Original post by nb
without really delving into the code i'd hazzard a guess that it has something to do with the fact that you declare that the number of options are 4... however the first 2 in the array you create are nodirection and start, which leaves only north and east as valid directions. so if you randomly pick the first 4 out of the array you will get 2 bogus ones then either north or east which would make them go up and right.

or then again maybe someone who actually really reads your code will have a better answer.

[slight edit]
Yeah... I thought that wasn't the problem, but now that I think about it you're most likely right haha.
Rudey_Level::Rudey_Level()	:	rudey(NULL),	difficulty(0),	level_boundary(DEFAULT_LEVEL_BOUNDARY),	moves_shuffled(DIRECTION_ARRAY, DIRECTION_ARRAY + sizeof(*DIRECTION_ARRAY)){}Rudey_Level::Rudey_Level(	const std::string& directory,	const Rudey* rudey,	ushort difficulty,	const SDL_Rect& level_boundary)	:	directory(directory),	rudey(rudey),	difficulty(difficulty),	level_boundary(level_boundary),	moves_shuffled(DIRECTION_ARRAY, DIRECTION_ARRAY + sizeof(*DIRECTION_ARRAY)){	if(NULL == rudey)	{ // bad rudey!		throw std::runtime_error("Rudey was NULL in Rudey_Level::Rudey_Level.");	}	Create_Enemies();}I also just realised that I'm using DIRECTION_ARRAY not the moves_shuffled vector...new_pos = move_by(old_pos, distance_from_direction(					DIRECTION_ARRAY, TILE_WIDTH, TILE_HEIGHT));
That was retarded. :s

I don't know why you don't make this a simple case statement instead of trying to shuffle things, or perhaps do something like

xmove = random(3)-1;
ymove = random(3)-1;

just a thought.

Because I think
std::random_shuffle(moves_shuffled.begin(), moves_shuffled.end());
is a lot neater than a switch statement.

This topic is closed to new replies.

Advertisement