PyGame在一个正方形内画一个正方形

时间:2016-08-26 00:47:46

标签: python python-3.x oop pygame game-engine

我正在编写一个基于网格的游戏,其中Character类的实例可以使用其移动(方向)方法移动。

class Character(object):                    #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

    moves_left = 15
    direction = "N"

    def move(self, direction):      #how characters move around

        if self.moves_left == 0:
            print("No more moves left")
            return

        elif direction == "N":                    
                self.internal_row -= 1
                self.direction = "N"
        elif direction == "W":
                self.internal_column -= 1
                self.direction = "W"
        elif direction == "E":
                self.internal_column += 1
                self.direction = "E"
        elif direction == "S":
                self.internal_row += 1
                self.direction = "S"

        self.moves_left = self.moves_left - 1

方向变量跟踪角色指向的位置。我使用PyGame绘制图形:

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])

以下是完整代码,其中定义了常量和Map类:

import random   
import pygame
import math

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

TILEWIDTH  = 20    #pixel size of tile                               
TILEHEIGHT = 20
TILEMARGIN = 4

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)


KeyLookup = {
    pygame.K_LEFT: "W",
    pygame.K_RIGHT: "E",
    pygame.K_DOWN: "S",
    pygame.K_UP: "N"
}

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 Character(object):                    #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

    moves_left = 15
    direction = "N"

    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")
            return

        elif direction == "N":                    
                self.internal_row -= 1
                self.direction = "N"
        elif direction == "W":
                self.internal_column -= 1
                self.direction = "W"
        elif direction == "E":
                self.internal_column += 1
                self.direction = "E"
        elif direction == "S":
                self.internal_row += 1
                self.direction = "S"

        self.moves_left = self.moves_left - 1


    def collision_check(self, direction):       
        if direction == "N":
            if self.internal_row == 0:
                return True
            if len(Map.Grid[self.internal_column][(self.internal_row)-1]) > 1:
                return True
        elif direction == "W":
            if self.internal_column == 0:
                return True
            if len(Map.Grid[self.internal_column-1][(self.internal_row)]) > 1:
                return True
        elif direction == "E":
            if self.internal_column == MAPSIZE-1:
                return True
            if len(Map.Grid[self.internal_column+1][(self.internal_row)]) > 1:
                return True
        elif direction == "S":
            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 attack(self, direction):
        if self.collision_check(direction) == True:
            print("attacked")


class Goblin(Character):
    def __init__(self):
        Character.__init__(self, "Goblin", random.randint(15,20), random.randint(0,MAPSIZE-1), random.randint(0,MAPSIZE-1))

    def random_move(self):
        i = random.randint(0,3)
        if i == 0:
            self.move("N")
        elif i == 1:
            self.move("S")
        elif i == 2:
            self.move("W")
        elif i == 3:
            self.move("E")

        self.moves_left = 10


class Archer(Character):
    def __init__(self):
        Character.__init__(self, "Archer", random.randint(15,20), random.randint(0,MAPSIZE-1), random.randint(0,MAPSIZE-1))


class Warrior(Character):
    def __init__(self):
        Character.__init__(self, "Warrior", random.randint(15,20), random.randint(0,MAPSIZE-1), random.randint(0,MAPSIZE-1))


class Scout(Character):
    def __init__(self):
        Character.__init__(self, "Scout", random.randint(15,20), random.randint(0,MAPSIZE-1), random.randint(0,MAPSIZE-1))


class Rogue(Character):
    def __init__(self):
        Character.__init__(self, "Rogue", random.randint(15,20), random.randint(0,MAPSIZE-1), random.randint(0,MAPSIZE-1))


class Wizard(Character):
    def __init__(self):
        Character.__init__(self, "Wizard", random.randint(15,20), random.randint(0,MAPSIZE-1), random.randint(0,MAPSIZE-1))



class Map(object):              #The main class; where the action happens
    global MAPSIZE
    wild_characters = []
    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) + random.randint(0,100)
        temp_hero = Character(str("Hero " + str(id_number)), 10, random_column, random_row)
        self.Grid[random_column][random_row].append(temp_hero)
        self.can_move.append(temp_hero)


    def generate_goblin(self):            #Generate a character and place it randomly
        random_row = random.randint(0, MAPSIZE - 1)

        random_column = random.randint(0, MAPSIZE - 1)
        temp_goblin = Goblin()
        self.Grid[random_column][random_row].append(temp_goblin)
        Map.wild_characters.append(temp_goblin)

    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)


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

        arr = Map.can_move[:] # copy
        for item in arr:
            if item.moves_left == 0:
                print("character moved from moves to no moves")
                Map.can_move.remove(item)
                Map.no_moves.append(item)


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:

            wild_char_arr = Map.wild_characters[:]
            for wildcharacter in wild_char_arr:
                if wildcharacter.name == "Goblin":
                    print("Goblin moved")
                    wildcharacter.random_move() 

            if event.key == 97:      # Keypress: a
                print("New turn.")
                temparr = Map.no_moves[:]
                for item in temparr:
                    if item.moves_left == 0:
                        item.moves_left = 15

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

            elif event.key == 100:  # Keypress: d
                Map.generate_goblin()
                print("Generated goblin.")

            elif event.key == 102:  # Keypress: f
                Map.can_move[0].attack("N") 

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

            else:
                print("invalid")

            Map.update()

    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(60)      
    pygame.display.flip()     


pygame.quit()

我遇到的问题是以图形方式显示角色的方向。我想要做的就是在他们面对的角色的网格瓷砖内画一个小的红色方块。例如,如果它们面向北方,则小红色方块将位于角色方格的顶部。

我该怎么做?

1 个答案:

答案 0 :(得分:0)

结束这样做:

    if str(Map.Grid[column][row][i].__class__.__name__) == "Character":     #Drawing the little red square showing character direction
        if Map.Grid[column][row][i].direction == "N":
                Color = RED
            pygame.draw.rect(Screen, Color, [(TILEMARGIN + TILEWIDTH) * column + TILEMARGIN + 8,
                                     (TILEMARGIN + TILEHEIGHT) * row + TILEMARGIN,
                                     TILEWIDTH/4,
                                     TILEHEIGHT/4])
    if str(Map.Grid[column][row][i].__class__.__name__) == "Character": #Drawing the little red square showing character directio
        if Map.Grid[column][row][i].direction == "S":
            Color = RED
            pygame.draw.rect(Screen, Color, [(TILEMARGIN + TILEWIDTH) * column + TILEMARGIN + 8,
                                     (TILEMARGIN + TILEHEIGHT) * row + TILEMARGIN*5 - 1 ,
                                     TILEWIDTH/4,
                                     TILEHEIGHT/4])
    if str(Map.Grid[column][row][i].__class__.__name__) == "Character": #Drawing the little red square showing character directio
        if Map.Grid[column][row][i].direction == "E":
            Color = RED
            pygame.draw.rect(Screen, Color, [(TILEMARGIN + TILEWIDTH) * column + TILEMARGIN + 15,
                                     (TILEMARGIN + TILEHEIGHT) * row + TILEMARGIN*5 - 8,
                                     TILEWIDTH/4,
                                     TILEHEIGHT/4])
    if str(Map.Grid[column][row][i].__class__.__name__) == "Character": #Drawing the little red square showing character directio
        if Map.Grid[column][row][i].direction == "W":
            Color = RED
            pygame.draw.rect(Screen, Color, [(TILEMARGIN + TILEWIDTH) * column + TILEMARGIN
                                             ,
                                     (TILEMARGIN + TILEHEIGHT) * row + TILEMARGIN*5 - 8 ,
                                     TILEWIDTH/4,
                                     TILEHEIGHT/4])