簡體   English   中英

在初學者基於網格的游戲中,並非所有對象都從一個列表轉移到另一個列表

[英]Not all objects transferring from one list to another in beginner grid-based game

這讓我發瘋。

我正在為游戲開發基於網格的運動引擎。 角色實例使用“移動”功能移動,每次將其內部move_left變量減小1。

def move(self, direction):      #how characters move around
        if self.collision_check(direction) == True:
            print("Collision")
            return
        if self.moves_left == 0:
            print("No more moves left")
            Map.update()
            return

        elif direction == "UP":                    
                self.internal_row -= 1            
        elif direction == "LEFT":
                self.internal_column -= 1
        elif direction == "RIGHT":
                self.internal_column += 1
        elif direction == "DOWN":
                self.internal_row += 1

        self.moves_left = self.moves_left -1 
        Map.update()

當此變量達到0時,它們應該停止移動,並從“可以移動”字符列表轉移到“不移動”字符列表。 此檢查在Map.update()函數中。

for characterobject in range(0, len(Map.no_moves)-1):    #This moves any characters with moves to the can move list 
    if len(Map.no_moves) > 0:
        if Map.no_moves[characterobject].moves_left > 0:
            print("character moved from no moves to moves")
            Map.can_move.append(Map.no_moves[characterobject])
            Map.no_moves.remove(Map.no_moves[characterobject])

for characterobject in range(0, len(Map.can_move)-1):
    if len(Map.can_move) == 0:
        break
    elif Map.can_move[characterobject].moves_left == 0:     #This moves any characters with 0 moves from the can't move list to the can move list
        print("character moved from moves to no moves")
        Map.no_moves.append(Map.can_move[characterobject])
        Map.can_move.remove(Map.can_move[characterobject])

我遇到的問題是沒有進行檢查。 當移動的角色達到moves_left = 0時,移動函數將打印“ no left left”,並調用Map.update(),但角色對象保留在列表中,並且不會傳輸到no_moves列表中。

這是完整的代碼:

import random 
import pygame 
import math 

pygame.init()                                 
Clock = pygame.time.Clock()                   
Screen = pygame.display.set_mode([650, 650])  
DONE = False                                  
MAPSIZE = 50    #how many tiles


TILEWIDTH  = 10     #pixel size of tile                               
TILEHEIGHT = 10
TILEMARGIN = 2

BLACK = (0, 0, 0)                             
WHITE = (255, 255, 255)
GREEN = (0, 255, 0)
RED = (255, 0, 0)
BLUE = (0, 0, 255)
BROWN = (123, 123, 0)
MOVECOLOR = (150, 250, 150)

ITEMS = ["Sword", "Helmet", "Shield", "Coin"]   #just a test

KeyLookup = {
    pygame.K_LEFT: "LEFT",
    pygame.K_RIGHT: "RIGHT",
    pygame.K_DOWN: "DOWN",
    pygame.K_UP: "UP"
}


class MapTile(object):                       #The main class for stationary things that inhabit the grid ... grass, trees, rocks and stuff.
    def __init__(self, name, internal_column, internal_row):
        self.name = name
        self.internal_column = internal_column
        self.internal_row = internal_row


class Item(object):
    def __init__(self, name, weight):
        self.name = name
        self.weight = weight


class Character(object):                    #can_move can move around and do cool stuff
    def __init__(self, name, HP, internal_column, internal_row):
        self.name = name
        self.HP = HP
        self.internal_column = internal_column
        self.internal_row = internal_row

    inventory = []
    moves_left = 25

    def move(self, direction):      #how characters move around
        if self.collision_check(direction) == True:
            print("Collision")
            return
        if self.moves_left == 0:
            print("No more moves left")
            Map.update()
            return

        elif direction == "UP":                    
                self.internal_row -= 1            
        elif direction == "LEFT":
                self.internal_column -= 1
        elif direction == "RIGHT":
                self.internal_column += 1
        elif direction == "DOWN":
                self.internal_row += 1

        self.moves_left = self.moves_left - 1 
        Map.update()

    def collision_check(self, direction):       
        if direction == "UP":
            if self.internal_row == 0:
                return True
            if len(Map.Grid[self.internal_column][(self.internal_row)-1]) > 1:
                return True
        elif direction == "LEFT":
            if self.internal_column == 0:
                return True
            if len(Map.Grid[self.internal_column-1][(self.internal_row)]) > 1:
                return True
        elif direction == "RIGHT":
            if self.internal_column == MAPSIZE-1:
                return True
            if len(Map.Grid[self.internal_column+1][(self.internal_row)]) > 1:
                return True
        elif direction == "DOWN":
            if self.internal_row == MAPSIZE-1:
                return True
            if len(Map.Grid[self.internal_column][(self.internal_row)+1]) > 1:
                return True

        return False

    def location(self):
        print("Coordinates:" + str(self.internal_column) + ", " + str(self.internal_row))

    def check_inventory(self):
        weight = 0
        for item in self.inventory:
            print(item)
            weight = weight + item.weight
        print(weight)



class Map(object):              #The main class; where the action happens
    global MAPSIZE
    can_move = []
    no_moves = []
    Grid = []

    for row in range(MAPSIZE):     # Creating grid
        Grid.append([])
        for column in range(MAPSIZE):
            Grid[row].append([])

    for row in range(MAPSIZE):     #Filling grid with grass
        for column in range(MAPSIZE):
            TempTile = MapTile("Grass", column, row)
            Grid[column][row].append(TempTile)

    for row in range(MAPSIZE):     #Putting some rocks near the top
        for column in range(MAPSIZE):
            TempTile = MapTile("Rock", column, row)
            if row == 1:
                Grid[column][row].append(TempTile)

    for i in range(10):         #Trees in random places
        random_row = random.randint(0, MAPSIZE - 1)
        random_column = random.randint(0, MAPSIZE - 1)
        TempTile = MapTile("Tree", random_column, random_row)
        Grid[random_column][random_row].append(TempTile)

    def generate_hero(self):            #Generate a character and place it randomly
        random_row = random.randint(0, MAPSIZE - 1)      
        random_column = random.randint(0, MAPSIZE - 1)
        id_number = len(Map.can_move)
        temp_hero = Character(str(id_number), 10, random_column, random_row)
        i = random.randint(0, len(ITEMS)-1)
        temp_hero.inventory.append(ITEMS[i])

        self.Grid[random_column][random_row].append(temp_hero)
        self.can_move.append(temp_hero)
        Map.update()


    def update(self):           #Important function
        for column in range(MAPSIZE):                           #These nested loops go through entire grid 
            for row in range(MAPSIZE):                          #They check if any objects internal coordinates
                for i in range(len(Map.Grid[column][row])):     #disagree with its place on the grid and update it accordingly

                    if Map.Grid[column][row][i].internal_column != column:
                        TempChar = Map.Grid[column][row][i]
                        Map.Grid[column][row].remove(Map.Grid[column][row][i])
                        Map.Grid[int(TempChar.internal_column)][int(TempChar.internal_row)].append(TempChar)

                    elif Map.Grid[column][row][i].internal_row != row:
                        TempChar = Map.Grid[column][row][i]
                        Map.Grid[column][row].remove(Map.Grid[column][row][i])
                        Map.Grid[int(TempChar.internal_column)][int(TempChar.internal_row)].append(TempChar)

        for characterobject in range(0, len(Map.no_moves)-1):    #This moves any characters with moves to the can move list 
            if len(Map.no_moves) > 0:
                if Map.no_moves[characterobject].moves_left > 0:
                    print("character moved from no moves to moves")
                    Map.can_move.append(Map.no_moves[characterobject])
                    Map.no_moves.remove(Map.no_moves[characterobject])

        for characterobject in range(0, len(Map.can_move)-1):
            print(str(characterobject))
            if len(Map.can_move) == 0:
                break
            elif Map.can_move[characterobject].moves_left == 0:     #This moves any characters with 0 moves from the can't move list to the can move list
                print("character moved from moves to no moves")
                Map.no_moves.append(Map.can_move[characterobject])
                Map.can_move.remove(Map.can_move[characterobject])



Map = Map()
Map.generate_hero()

while not DONE:     #Main pygame loop

    for event in pygame.event.get():         #catching events
        if event.type == pygame.QUIT:
            DONE = True       

        elif event.type == pygame.MOUSEBUTTONDOWN:
            Pos = pygame.mouse.get_pos()
            column = Pos[0] // (TILEWIDTH + TILEMARGIN)  #Translating the position of the mouse into rows and columns
            row = Pos[1] // (TILEHEIGHT + TILEMARGIN)
            print(str(row) + ", " + str(column))

            for i in range(len(Map.Grid[column][row])):
                print(str(Map.Grid[column][row][i].name))  #print stuff that inhabits that square

        elif event.type == pygame.KEYDOWN:
            if event.key == 97:      # Keypress: a
                print("new turn")
                for characterobject in range(0, len(Map.no_moves)-1):
                    Map.no_moves[characterobject].moves_left = 25
                Map.update()

            elif event.key == 115:    # Keypress: s
                print("boop")
                Map.generate_hero()
                Map.update()

            elif len(Map.can_move) > 0:
                Map.can_move[0].move(KeyLookup[event.key])

            else:
                print("invalid")

    Screen.fill(BLACK)



    for row in range(MAPSIZE):           # Drawing grid
        for column in range(MAPSIZE):
            for i in range(0, len(Map.Grid[column][row])):
                Color = WHITE

                if len(Map.can_move) > 0:   # Creating colored area around character showing his move range
                    if (math.sqrt((Map.can_move[0].internal_column - column)**2 + (Map.can_move[0].internal_row - row)**2)) <= Map.can_move[0].moves_left:
                        Color = MOVECOLOR

                if len(Map.Grid[column][row]) > 1:
                    Color = RED
                if Map.Grid[column][row][i].name == "Tree":
                    Color = GREEN
                if str(Map.Grid[column][row][i].__class__.__name__) == "Character":
                    Color = BROWN



            pygame.draw.rect(Screen, Color, [(TILEMARGIN + TILEWIDTH) * column + TILEMARGIN,
                                             (TILEMARGIN + TILEHEIGHT) * row + TILEMARGIN,
                                             TILEWIDTH,
                                             TILEHEIGHT])

    Clock.tick(30)      
    pygame.display.flip()     


pygame.quit()

試一試,看看我的意思。 您可以按“ s”添加新字符。 注意當角色無法移動記錄器時,外殼程序會發生什么情況。 您應該可以按“ a”為no_moves列表中的字符提供更多的移動,但這也不起作用。

謝謝

您不應該遍歷正在變異的數組,這會導致此問題。 代替:

arr = Map.no_moves[:] # copy
for item in arr:
    if item.moves_left == 0:
        Map.no_moves.remove(item)
        Map.can_move.append(item)

請注意,這個概念幾乎適用於每種語言,因此最好將此模式保留在工具箱中。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM