简体   繁体   English

2D Python 游戏 map 移动后更新

[英]2D Python game map update after movement

I am currently working on 2D game which is using text as a textures in python.我目前正在开发使用文本作为 python 中的纹理的 2D 游戏。 The main idea for this game is to collect the treasure and try to escape the ghost aka monster.这个游戏的主要思想是收集宝藏并试图逃离幽灵又名怪物。 After lots of struggle I finally added movement system for player and monster.经过一番努力,我终于为玩家和怪物添加了移动系统。 Everything is working like it should as coordinates are changing properly (function info() will show them), however my map does not update and i have no idea how can i update it.一切都在正常工作,因为坐标正在正确更改(函数 info() 将显示它们),但是我的 map 没有更新,我不知道如何更新它。

Map is 12x12 Map 为 12x12

#map generation

map_width = 12
map_height = 12
player_view = 1
map = [([1] * map_width)] + ([([1] + ([0] * (map_width - 2)) + [1]) for _ in range(map_height - 2)]) + [([1] * map_width)]
def print_map():
  for row in map:
    print(*row, sep='\t')
    print("\n")

Generation of “objects” like player, monster and treasure.生成玩家、怪物和宝藏等“对象”。 During the player generation there will be generation of the vision along.在玩家一代期间,将会有一代人的愿景。

#player generation + vision
    
  player = {
      "x_p":random.randint(1,map_width  - 2),
      "y_p":random.randint(1,map_height - 2),
      
  }
  map[player["y_p"]][player["x_p"]] = ‘😑’
  for i,row in enumerate(map[player["y_p"]- player_view :player["y_p"]+1 + player_view]):
    for j,element in enumerate(row[player["x_p"]- player_view :player["x_p"]+1 + player_view]):
      if (element == 0):
        map[player["y_p"] - player_view + i][player["x_p"] - player_view +j]='🕯'

#monster generation

  monster = {
      'y_m':random.randint(1, map_width - 2),
  }
  possible_x = []
  for i,e in enumerate(map[monster['y_m']]):
    if e == 0:
      possible_x.append(i)
  monster['x_m'] = random.choice(possible_x)
  map[monster["y_m"]][monster["x_m"]]='👻'

#treasure generation

  treasure = {
      'y_t':random.randint(1, map_width - 2),
  }
  possible_x = []
  for i,e in enumerate(map[treasure['y_t']]):
    if e == 0:
      possible_x.append(i)
  treasure['x_t'] = random.choice(possible_x)
  map[treasure["y_t"]][treasure["x_t"]]='💰'

All of the functions which are used in program程序中使用的所有函数


#printing info about characters, map dimensions and icons used

def info():
    print('\n')
    #print_map()
    #print('\n')
    print('Map dimentions are',map_width, 'x', map_height, '(including walls!)\n')
    print('Player -',player, 'Icon used:',player_character, '\n')
    print('Monster -',monster, 'Icon used: 👻.\n')
    print('Treasure -',treasure, 'Icon used: 💰.\n')
    print('Player vision value is', player_view,', and is represented with icon: 🕯.\n')
    print('Other icons used, 0 as empty area and 1 as walls. \n')

#generating number 1 or -1 randomly in order to select direction of monster movement

def monster_random_values():
  exclude = [0]
  movement_value = random.randint(-1,1)
  return my_custom_random() if movement_value in exclude else movement_value

And finally the movement system for player and monster最后是玩家和怪物的移动系统


loop = True
while loop:

    # movment system
    movment_choice = input('Please select your movment choice - [W,A,S,D]\nIf you want to exit press [Q]\n')
    if movment_choice == 'W' or movment_choice == 'w':
        print_map()
        player['y_p'] = (player['y_p'] + 1)
        #print(map[player['y_p']])
        info()
    elif movment_choice == 'A' or movment_choice == 'a':
        player['x_p'] = (player['x_p'] - 1)
        #print(map[player['x_p']])
        info()
    elif movment_choice == 'S' or movment_choice == 's':
        player['y_p'] = (player['y_p'] - 1)
        #print(map[player['y_p']])
        info()
    elif movment_choice == 'D' or movment_choice == 'd':
        player['x_p'] = (player['x_p'] + 1)
        #print(player['x_p'])
        info()
    elif movment_choice == 'Q':
      print('Thank you for playing the game!\n See you soon!')
      loop = False
    else:
        print('ERROR! Please select one of the options in the question')

    #monster movment
    possible_movment = random.randint(1, 3)
    if possible_movment == 1:
      monster['y_m'] = (monster['y_m'] + monster_random_values())
      monster['x_m'] = (monster['x_m'] + monster_random_values())
    elif possible_movment == 2:
      monster['y_m'] = (monster['y_m'] + monster_random_values())
    elif possible_movment == 3:
      monster['x_m'] = (monster['x_m'] + monster_random_values())
      info()

I hope that it is clear.我希望这很清楚。 If it will not work properly i will sent a full version of a code.如果它不能正常工作,我将发送一个完整版本的代码。

Thank you for help!谢谢你的帮助!

First, map is a python builtin.首先, map是内置的 python。 It is advised not to use it as a variable name.建议不要将其用作变量名。

Second, I'd make the map creation a function and use the object returned by it.其次,我会让 map 创建一个 function 并使用它返回的 object。

Here's a sample code using set and procedural generation of the game map.这是使用游戏 map 的set和程序生成的示例代码。 Using operations of sets we will keep them from overlapping objects in the map.使用集合操作,我们将防止它们与 map 中的对象重叠。 I will be using a tuple for positions.我将使用tuple作为职位。

import random
BORDER = '1'

def create_map(map_width, map_height, num_treasures=1):
    locations = set((i, j) for i in range(map_height) for j in range(map_width))  # All available board coordinates
    player = (random.randint(1, map_width - 2), random.randint(1, map_height - 2))  # Player position
    locations = locations.difference({player})  # Remove player position from available positions
    border = ({(0, i) for i in range(map_width)}.union({(map_height - 1, i) for i in range(map_width)})).union(
        {(i, 0) for i in range(map_height)}.union({(i, map_height - 1) for i in range(map_height)}))  # All borders
    locations = locations.difference(border)  # Remove border from available locations
    vision = {(player[0] + dx, player[1] + dy) for dx in [-1, 0, 1] for dy in [-1, 0, 1]}.intersection(
        locations)  # 3 x 3 vision box. Player is not used since its location is not available in locations
    monster = random.choice(list(locations))  # Monster location selected randomly from available locations
    locations = locations.difference({monster})  # Remove monster from available locations
    treasures = set([])  # Do the same thing as monster with treasures in a loop
    for i in range(num_treasures):
        treasure = random.choice(list(locations))
        treasures.add(treasure)
        locations.remove(treasure)
    my_map = list(list([0] * map_width) for _ in range(map_height))  # Empty map
    my_map[player[0]][player[1]] = '😑'  # Set player
    my_map[monster[0]][monster[1]] = '👻'  # Set monster
    for x, y in border:  # Set border
        my_map[x][y] = BORDER
    for x, y in vision:  # Set vision
        my_map[x][y] = '🕯'
    for x, y in treasures:  # Set treasures
        my_map[x][y] = '💰'
    return my_map, player, monster, treasures

Lastly, I don't see any updates happening in the game while loop.最后,我没有看到游戏while循环中发生任何更新。 You can do this using another function.您可以使用另一个 function 来执行此操作。

def move(my_map, player, player_move):
    # Legal move inputs
    if player_move in ['a', 'A']:  
        player_move = (0, -1)
        vision_remove = [(-1, 1), (0, 1), (1, 1)]
    elif player_move in ['w', 'W']:
        player_move = (-1, 0)
        vision_remove = [(1, -1), (1, 0), (1, 1)]
    elif player_move in ['d', 'D']:
        player_move = (0, 1)
        vision_remove = [(-1, -1), (0, -1), (1, -1)]
    elif player_move in ['s', 'S']:
        player_move = (1, 0)
        vision_remove = [(-1, -1), (-1, 0), (-1, 1)]
    else:
        return False, my_map, player
    neighbors = [(-1, -1), (-1, 0), (-1, 1), (0, -1), (0, 1), (1, -1), (1, 0), (1, 1)]
    # New position
    x = player[0] + player_move[0]
    y = player[1] + player_move[1]
    if my_map[x][y] != BORDER:  # Can't move into borders
        my_map[player[0]][player[1]] = 0
        my_map[x][y] = '😑'
        # Update vision while keeping treasure, ghost, border icons
        for dx, dy in vision_remove:  # Remove old vision
            value = my_map[player[0] + dx][player[1] + dy]
            my_map[player[0] + dx][player[1] + dy] = 0 if value == '🕯' else value
        for dx, dy in neighbors:  # Add new vision
            value = my_map[x + dx][y + dy]
            my_map[x + dx][y + dy] = '🕯' if value == 0 else value
        return True, my_map, (x, y)
    return False, my_map, player

Some of the helper functions:一些辅助函数:

def to_string(my_map):
    return '\n'.join('\t'.join(str(x) for x in y) for y in my_map)


def print_map(my_map):
    print(to_string(my_map))

The move function doesn't detect picking up treasure, walking into ghosts as it is. function这一招没有检测到捡宝,照样走鬼。 Those need to be added.这些需要添加。

The main loop would look something like this:主循环看起来像这样:

my_map, player, monster, treasures = create_map(12, 12, 3)
updated = True
while True:
    # movement system
    if updated:
        updated = False
        print_map(my_map)
    movement_choice = input('Please select your movment choice - [W,A,S,D]\nIf you want to exit press [Q]\n')
    if movement_choice in ['q', 'Q']:
        print('Thank you for playing the game!\n See you soon!')
        break
    if movement_choice not in ['w', 'W', 'a', 'A', 's', 'S', 'd', 'D']:
        print('ERROR! Please select one of the options in the question')
    updated, my_map, player = move(my_map, player, movement_choice)
    hit, my_map, monster = move_monster(my_map, monster)
    if hit:
        print('Oh no! The monster got you.')
        print_map(my_map)
        break

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM