void Tux::tryStartWalking() { if (moving) return; if (input_direction == D_NONE) return; auto level = worldmap->at_level(); // We got a new direction, so lets start walking when possible Vector next_tile; if ((!level || level->solved || level->perfect) && 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 (ghost_mode || (input_direction == back_direction)) { moving = true; direction = input_direction; tile_pos = worldmap->get_next_tile(tile_pos, direction); back_direction = reverse_dir(direction); } }
void Tux::try_start_walking() { if (m_moving) return; if (m_input_direction == Direction::NONE) return; auto level = m_worldmap->at_level(); // We got a new direction, so lets start walking when possible Vector next_tile; if ((!level || level->is_solved() || level->is_perfect() || (Editor::current() && Editor::current()->is_testing_level())) && m_worldmap->path_ok(m_input_direction, m_tile_pos, &next_tile)) { m_tile_pos = next_tile; m_moving = true; m_direction = m_input_direction; m_back_direction = reverse_dir(m_direction); } else if (m_ghost_mode || (m_input_direction == m_back_direction)) { m_moving = true; m_direction = m_input_direction; m_tile_pos = m_worldmap->get_next_tile(m_tile_pos, m_direction); m_back_direction = reverse_dir(m_direction); } }
/* * retrace steps on map, optionally walk them back */ void map_retrace(int steps, int walk_back) { char cmd[2]; cmd[1] = '\0'; if (!steps && !walk_back) mapend = mapstart; else { if (!steps) steps = -1; if (walk_back && opt_echo) { status(1); tty_putc('['); } while (mapstart != mapend && steps--) { mapend = MAPINDEX(mapend - 1); if (walk_back) { cmd[0] = reverse_dir(mappath[mapend]); if (opt_echo) tty_putc(cmd[0]); tcp_write(tcp_fd, cmd); } } if (walk_back && opt_echo) tty_puts("]\n"); } }
void gameloop(int nrow, int ncol) { timeout(1000 / SAMPLING_RATE); const clock_t checkpoint = (clock_t) (CLOCKS_PER_SEC/GAME_SPEED); clock_t last_update = clock(); struct snake * snake = new_snake(ncol/2, nrow/2); struct point food_pos = generate_food(nrow, ncol, snake); redraw(snake, food_pos); for (;;) { struct point tail_pos = snake->tail->pos; int ch; if ((ch = getch()) != ERR) { switch (ch) { case KEY_UP: case KEY_DOWN: case KEY_LEFT: case KEY_RIGHT: if (to_dir(ch) == reverse_dir(snake->heading)) { break; } else { snake->heading = to_dir(ch); step_snake(snake); tail_pos = snake->tail->pos; redraw(snake, food_pos); } break; default: break; } } if (clock() - last_update >= checkpoint) { step_snake(snake); tail_pos = snake->tail->pos; redraw(snake, food_pos); last_update = clock(); } if (point_equal(snake->head->pos, food_pos)) { grow_snake(snake, tail_pos); food_pos = generate_food(nrow, ncol, snake); redraw(snake, food_pos); } if (out_of_border(snake->head->pos, nrow, ncol) || eat_self(snake)) { display_lose(nrow, ncol); return; } if (snake->length == (nrow-2)*(ncol-2)) { display_win(nrow, ncol); return; } } }
/* * add direction to automap */ void map_add_dir(char dir) { #ifdef NOMAZEMAPPING if (mapend != mapstart && dir == reverse_dir(MAPENTRY(mapend - 1))) { mapend = MAPINDEX(mapend - 1); /* retrace one step */ } else #endif { MAPENTRY(mapend) = dir; mapend = MAPINDEX(mapend + 1); if(mapend == mapstart) mapstart = MAPINDEX(mapstart + 1); } }
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; auto sprite_change = worldmap->at_sprite_change(tile_pos); ChangeSprite(sprite_change); // if this is a special_tile with passive_message, display it auto special_tile = worldmap->at_special_tile(); if(special_tile) { // 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)) { process_special_tile(special_tile); } } // check if we are at a Teleporter auto teleporter = worldmap->at_teleporter(tile_pos); // stop if we reached a level, a WORLDMAP_STOP tile, a teleporter or a special tile without a passive_message if ((worldmap->at_level()) || (worldmap->tile_data_at(tile_pos) & Tile::WORLDMAP_STOP) || (special_tile && !special_tile->passive_message && special_tile->script.empty()) || (teleporter) || ghost_mode) { 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 int tile_data = worldmap->tile_data_at(tile_pos); if ((direction != input_direction) && canWalk(tile_data, input_direction)) { direction = input_direction; back_direction = reverse_dir(direction); } else { Direction dir = D_NONE; if (tile_data & Tile::WORLDMAP_NORTH && back_direction != D_NORTH) dir = D_NORTH; else if (tile_data & Tile::WORLDMAP_SOUTH && back_direction != D_SOUTH) dir = D_SOUTH; else if (tile_data & Tile::WORLDMAP_EAST && back_direction != D_EAST) dir = D_EAST; else if (tile_data & Tile::WORLDMAP_WEST && back_direction != D_WEST) dir = D_WEST; if (dir == D_NONE) { // Should never be reached if tiledata is good log_warning << "Could not determine where to walk next" << std::endl; stop(); return; } direction = dir; input_direction = direction; back_direction = reverse_dir(direction); } // Walk automatically to the next tile if(direction == D_NONE) return; Vector next_tile; if (!ghost_mode && !worldmap->path_ok(direction, tile_pos, &next_tile)) { log_debug << "Tilemap data is buggy" << std::endl; stop(); return; } auto next_sprite = worldmap->at_sprite_change(next_tile); if(next_sprite != NULL && next_sprite->change_on_touch) { ChangeSprite(next_sprite); } //SpriteChange* last_sprite = worldmap->at_sprite_change(tile_pos); if(sprite_change != NULL && next_sprite != NULL) { log_debug << "Old: " << tile_pos << " New: " << next_tile << std::endl; sprite_change->set_stay_action(); } tile_pos = next_tile; }
void Tux::try_continue_walking(float dt_sec) { if (!m_moving) return; // Let tux walk m_offset += TUXSPEED * dt_sec; // Do nothing if we have not yet reached the next tile if (m_offset <= 32) return; m_offset -= 32; auto sprite_change = m_worldmap->at_sprite_change(m_tile_pos); change_sprite(sprite_change); // if this is a special_tile with passive_message, display it auto special_tile = m_worldmap->at_special_tile(); if (special_tile) { // direction and the apply_action_ are opposites, since they "see" // directions in a different way if ((m_direction == Direction::NORTH && special_tile->get_apply_action_south()) || (m_direction == Direction::SOUTH && special_tile->get_apply_action_north()) || (m_direction == Direction::WEST && special_tile->get_apply_action_east()) || (m_direction == Direction::EAST && special_tile->get_apply_action_west())) { process_special_tile(special_tile); } } // check if we are at a Teleporter auto teleporter = m_worldmap->at_teleporter(m_tile_pos); // stop if we reached a level, a WORLDMAP_STOP tile, a teleporter or a special tile without a passive_message if ((m_worldmap->at_level()) || (m_worldmap->tile_data_at(m_tile_pos) & Tile::WORLDMAP_STOP) || (special_tile && !special_tile->is_passive_message() && special_tile->get_script().empty()) || (teleporter) || m_ghost_mode) { if (special_tile && !special_tile->get_map_message().empty() && !special_tile->is_passive_message()) { m_worldmap->set_passive_message({}, 0.0f); } stop(); return; } // if user wants to change direction, try changing, else guess the direction in which to walk next const int tile_data = m_worldmap->tile_data_at(m_tile_pos); if ((m_direction != m_input_direction) && can_walk(tile_data, m_input_direction)) { m_direction = m_input_direction; m_back_direction = reverse_dir(m_direction); } else { Direction dir = Direction::NONE; if (tile_data & Tile::WORLDMAP_NORTH && m_back_direction != Direction::NORTH) dir = Direction::NORTH; else if (tile_data & Tile::WORLDMAP_SOUTH && m_back_direction != Direction::SOUTH) dir = Direction::SOUTH; else if (tile_data & Tile::WORLDMAP_EAST && m_back_direction != Direction::EAST) dir = Direction::EAST; else if (tile_data & Tile::WORLDMAP_WEST && m_back_direction != Direction::WEST) dir = Direction::WEST; if (dir == Direction::NONE) { // Should never be reached if tiledata is good log_warning << "Could not determine where to walk next" << std::endl; stop(); return; } m_direction = dir; m_input_direction = m_direction; m_back_direction = reverse_dir(m_direction); } // Walk automatically to the next tile if (m_direction == Direction::NONE) return; Vector next_tile; if (!m_ghost_mode && !m_worldmap->path_ok(m_direction, m_tile_pos, &next_tile)) { log_debug << "Tilemap data is buggy" << std::endl; stop(); return; } auto next_sprite = m_worldmap->at_sprite_change(next_tile); if (next_sprite != nullptr && next_sprite->m_change_on_touch) { change_sprite(next_sprite); } //SpriteChange* last_sprite = m_worldmap->at_sprite_change(tile_pos); if (sprite_change != nullptr && next_sprite != nullptr) { log_debug << "Old: " << m_tile_pos << " New: " << next_tile << std::endl; sprite_change->set_stay_action(); } m_tile_pos = next_tile; }