From: Christoph Sommer Date: Sun, 2 Apr 2006 21:50:31 +0000 (+0000) Subject: Tux can no longer stop on arbitrary positions / Can hold directional buttons pressed... X-Git-Url: https://git.verplant.org/?a=commitdiff_plain;h=992a822d1be4ff178ee558c94ca30bb01e2e45ae;p=supertux.git Tux can no longer stop on arbitrary positions / Can hold directional buttons pressed down / Split mutant if-block from hell into smaller functions SVN-Revision: 3207 --- diff --git a/src/worldmap.cpp b/src/worldmap.cpp index 20b1355f6..ac9fdf32e 100644 --- a/src/worldmap.cpp +++ b/src/worldmap.cpp @@ -197,150 +197,141 @@ Tux::set_direction(Direction dir) input_direction = dir; } -void -Tux::update(float delta) +void +Tux::tryStartWalking() { - // check controller - if(main_controller->pressed(Controller::UP)) - input_direction = D_NORTH; - else if(main_controller->pressed(Controller::DOWN)) - input_direction = D_SOUTH; - else if(main_controller->pressed(Controller::LEFT)) - input_direction = D_WEST; - else if(main_controller->pressed(Controller::RIGHT)) - input_direction = D_EAST; - - if(!moving) + if (moving) return; + if (input_direction == D_NONE) return; + + WorldMap::Level* level = worldmap->at_level(); + + // We got a new direction, so lets start walking when possible + Vector next_tile; + if ((!level || level->solved) && worldmap->path_ok(input_direction, tile_pos, &next_tile)) + { + tile_pos = next_tile; + moving = true; + direction = input_direction; + back_direction = reverse_dir(direction); + } + else if (input_direction == back_direction) + { + moving = true; + direction = input_direction; + tile_pos = worldmap->get_next_tile(tile_pos, direction); + back_direction = reverse_dir(direction); + } + +} + +bool +Tux::canWalk(const Tile* tile, Direction dir) +{ + return ((tile->getData() & Tile::WORLDMAP_NORTH && dir == D_NORTH) || + (tile->getData() & Tile::WORLDMAP_SOUTH && dir == D_SOUTH) || + (tile->getData() & Tile::WORLDMAP_EAST && dir == D_EAST) || + (tile->getData() & Tile::WORLDMAP_WEST && dir == D_WEST)); +} + +void +Tux::tryContinueWalking(float elapsed_time) +{ + if (!moving) return; + + // Let tux walk + offset += TUXSPEED * elapsed_time; + + // Do nothing if we have not yet reached the next tile + if (offset <= 32) return; + + offset -= 32; + + // if this is a special_tile with passive_message, display it + WorldMap::SpecialTile* special_tile = worldmap->at_special_tile(); + if(special_tile && special_tile->passive_message) + { + // direction and the apply_action_ are opposites, since they "see" + // directions in a different way + if((direction == D_NORTH && special_tile->apply_action_south) || + (direction == D_SOUTH && special_tile->apply_action_north) || + (direction == D_WEST && special_tile->apply_action_east) || + (direction == D_EAST && special_tile->apply_action_west)) { - if (input_direction != D_NONE) - { - WorldMap::Level* level = worldmap->at_level(); - - // We got a new direction, so lets start walking when possible - Vector next_tile; - if ((!level || level->solved) - && worldmap->path_ok(input_direction, tile_pos, &next_tile)) - { - tile_pos = next_tile; - moving = true; - direction = input_direction; - back_direction = reverse_dir(direction); - } - else if (input_direction == back_direction) - { - moving = true; - direction = input_direction; - tile_pos = worldmap->get_next_tile(tile_pos, direction); - back_direction = reverse_dir(direction); - } - } + worldmap->passive_message = special_tile->map_message; + worldmap->passive_message_timer.start(map_message_TIME); } + } + + // stop if we reached a level, a WORLDMAP_STOP tile or a special tile without a passive_message + if ((worldmap->at_level()) || (worldmap->at(tile_pos)->getData() & Tile::WORLDMAP_STOP) || (special_tile && !special_tile->passive_message)) + { + if(special_tile && !special_tile->map_message.empty() && !special_tile->passive_message) worldmap->passive_message_timer.start(0); + stop(); + return; + } + + // if user wants to change direction, try changing, else guess the direction in which to walk next + const Tile* tile = worldmap->at(tile_pos); + if (direction != input_direction) + { + if(canWalk(tile, input_direction)) + { + direction = input_direction; + back_direction = reverse_dir(direction); + } + } else + { + Direction dir = D_NONE; + if (tile->getData() & Tile::WORLDMAP_NORTH && back_direction != D_NORTH) dir = D_NORTH; + else if (tile->getData() & Tile::WORLDMAP_SOUTH && back_direction != D_SOUTH) dir = D_SOUTH; + else if (tile->getData() & Tile::WORLDMAP_EAST && back_direction != D_EAST) dir = D_EAST; + else if (tile->getData() & Tile::WORLDMAP_WEST && back_direction != D_WEST) dir = D_WEST; + + if (dir == D_NONE) { - // Let tux walk - offset += TUXSPEED * delta; - - if (offset > 32) - { // We reached the next tile, so we check what to do now - offset -= 32; - - WorldMap::SpecialTile* special_tile = worldmap->at_special_tile(); - if(special_tile && special_tile->passive_message) - { // direction and the apply_action_ are opposites, since they "see" - // directions in a different way - if((direction == D_NORTH && special_tile->apply_action_south) || - (direction == D_SOUTH && special_tile->apply_action_north) || - (direction == D_WEST && special_tile->apply_action_east) || - (direction == D_EAST && special_tile->apply_action_west)) - { - worldmap->passive_message = special_tile->map_message; - worldmap->passive_message_timer.start(map_message_TIME); - } - } + // Should never be reached if tiledata is good + msg_warning("Could not determine where to walk next"); + stop(); + return; + } - if (worldmap->at(tile_pos)->getData() & Tile::WORLDMAP_STOP || - (special_tile && !special_tile->passive_message) || - worldmap->at_level()) - { - if(special_tile && !special_tile->map_message.empty() && - !special_tile->passive_message) - worldmap->passive_message_timer.start(0); - stop(); - } - else - { - const Tile* tile = worldmap->at(tile_pos); - if (direction != input_direction) - { - // Turn to a new direction - const Tile* tile = worldmap->at(tile_pos); - - if((tile->getData() & Tile::WORLDMAP_NORTH - && input_direction == D_NORTH) || - (tile->getData() & Tile::WORLDMAP_SOUTH - && input_direction == D_SOUTH) || - (tile->getData() & Tile::WORLDMAP_EAST - && input_direction == D_EAST) || - (tile->getData() & Tile::WORLDMAP_WEST - && input_direction == D_WEST)) - { // player has changed direction during auto-movement - direction = input_direction; - back_direction = reverse_dir(direction); - } - else - { // player has changed to impossible tile - back_direction = reverse_dir(direction); - stop(); - } - } - else - { - Direction dir = D_NONE; - - if (tile->getData() & Tile::WORLDMAP_NORTH - && back_direction != D_NORTH) - dir = D_NORTH; - else if (tile->getData() & Tile::WORLDMAP_SOUTH - && back_direction != D_SOUTH) - dir = D_SOUTH; - else if (tile->getData() & Tile::WORLDMAP_EAST - && back_direction != D_EAST) - dir = D_EAST; - else if (tile->getData() & Tile::WORLDMAP_WEST - && back_direction != D_WEST) - dir = D_WEST; - - if (dir != D_NONE) - { - direction = dir; - input_direction = direction; - back_direction = reverse_dir(direction); - } - else - { - // Should never be reached if tiledata is good - stop(); - return; - } - } - - // Walk automatically to the next tile - if(direction != D_NONE) - { - Vector next_tile; - if (worldmap->path_ok(direction, tile_pos, &next_tile)) - { - tile_pos = next_tile; - } - else - { - puts("Tilemap data is buggy"); - stop(); - } - } - } - } + direction = dir; + input_direction = direction; + back_direction = reverse_dir(direction); + } + + // Walk automatically to the next tile + if(direction != D_NONE) + { + Vector next_tile; + if (worldmap->path_ok(direction, tile_pos, &next_tile)) + { + tile_pos = next_tile; + } + else + { + msg_warning("Tilemap data is buggy"); + stop(); } + } +} + +void +Tux::updateInputDirection() +{ + if(main_controller->hold(Controller::UP)) input_direction = D_NORTH; + else if(main_controller->hold(Controller::DOWN)) input_direction = D_SOUTH; + else if(main_controller->hold(Controller::LEFT)) input_direction = D_WEST; + else if(main_controller->hold(Controller::RIGHT)) input_direction = D_EAST; +} + + +void +Tux::update(float elapsed_time) +{ + updateInputDirection(); + if (moving) tryContinueWalking(elapsed_time); else tryStartWalking(); } //--------------------------------------------------------------------------- diff --git a/src/worldmap.hpp b/src/worldmap.hpp index 6333d34d4..1256d6ce6 100644 --- a/src/worldmap.hpp +++ b/src/worldmap.hpp @@ -80,6 +80,12 @@ private: bool moving; void stop(); + + bool canWalk(const Tile* tile, Direction dir); /**< check if we can leave "tile" in direction "dir" */ + void updateInputDirection(); /**< if controller was pressed, update input_direction */ + void tryStartWalking(); /**< try starting to walk in input_direction */ + void tryContinueWalking(float elapsed_time); /**< try to continue walking in current direction */ + public: Tux(WorldMap* worldmap_); ~Tux();