简体   繁体   English

使用pygame在矩形上方绘制Ascii字符

[英]Draw Ascii character above rectangle with pygame

I'm trying to make a rogue like using pygame. 我试图像使用pygame一样制造流氓。

在此输入图像描述

Actually i have no problem to draw the first grid which represent the background of game (using mapLoaded which contain the original map and drawMap() function which return a list of Case Object). 其实我已经没有问题,提请代表游戏的背景,第一格(使用mapLoaded包含原始地图和drawMap()函数返回一个列表Case对象)。

I love rectangle but for future i want to draw on top of this rectangle the ascii Character stored into Case object. 我喜欢矩形但是为了将来我想要在这个矩形的顶部绘制ascii字符存储到Case对象中。

Using this method for overriding rect by char, i can create later Object like player "@" which is also draw on top of this background rectangle or character. 使用此方法通过char覆盖rect,我可以创建稍后的Object如播放器“@”,它也可以在此背景矩形或字符的顶部绘制。

上面的矩形

My question is related in this image, how can i draw (and later move) an ascii character (here the player @ ) on top center of the pygame.draw.rect() function used to draw each cell of the background (using character attribute defined in Case ). 我的问题与此图像有关,我如何在用于绘制背景的每个单元格的pygame.draw.rect()函数的顶部中心绘制(以及稍后移动)ascii字符(此处为player @ )(使用字符) Case定义的属性)。

My init code : 我的初始代码:

import os
import drawRogue as draw

mapLoaded = [[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
             [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1],
             [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1],
             [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,0,0,1,1,1,1,1,1,1,1],
             [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,0,1,1,1,1,1,1,1,1],
             [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,0,0,0,1,1,1,1,1,1,1],
             [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1],
             [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,0,0,0,0,1,1,1,1,1],
             [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,0,0,1,1,1,1,1],
             [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1,1],
             [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,0,0,1,1,1,1,1,1],
             [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1],
             [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1],
             [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1],
             [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,0,0,0,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1],
             [1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1],
             [1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
             [1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
             [1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1],
             [1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1],
             [1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,0,0,0,1,1,0,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1],
             [1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,0,0,0,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1],
             [1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1],
             [1,1,1,1,1,1,1,1,1,1,0,0,0,1,0,0,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1],
             [1,1,1,1,1,1,1,1,1,1,0,0,1,1,0,0,0,1,1,1,1,1,0,0,0,0,0,0,1,1,1,0,0,1,0,0,0,1,1,1,1,1],
             [1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,1,1,1,1],
             [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,1,1,1,1,1],
             [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,1,1,1,1],
             [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1],
             [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1],
             [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1],
             [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1],
             [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1],
             [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1],
             [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1],
             [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1],
             [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
             [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
             [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
             [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
             [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
             [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]]

class Object:
    def __init__(self,x,y,char,color):
        self.x = x
        self.y = y
        self.char = char
        self.color = color

        def move(self,dx,dy):
            if not map[self.x + dx][self.y + dy].blocked:
                self.x = self.x + dx
                self.y = self.y + dy

class Case:
    #a tile of the map and its properties
    def __init__(self, char, blocked):
        self.blocked = blocked
        self.char =  char


#Afficher seulement une partie du monde... tres vaste comme vous le voyez...        
def drawMap(mymap):
    tileMap = []
    for line in mymap:
        tileLine = []
        for value in line:
            if value == 1:
                tileLine.append(Case("#",False))
            else:
                tileLine.append(Case(".",True))
        tileMap.append(tileLine)
    return tileMap

clear = lambda: os.system('clear')

if __name__ == "__main__":

    clear()
    tileMap = drawMap(mapLoaded)
    draw.drawInit()
    draw.addColorRules("#",(255,255,255))
    draw.addColorRules(".",(0,0,0))
    draw.drawScreen(tileMap,40)
    while True:
        draw.drawScreen(tileMap, 40)
        draw.events()

My actual code for drawing background into drawRogue.py : 我将绘制背景的实际代码转换为drawRogue.py

import sys, pygame

colorRules = {}

def drawInit():
    pygame.init()

def drawScreen(t_view,speed):

    grid_size = grid_rows, grid_cols = len(t_view), len(t_view)
    square_pixels = 15
    base_offset = 30
    size = width, height = (2*base_offset)+(grid_cols*square_pixels), (2*base_offset)+(grid_rows*square_pixels)

    screen = pygame.display.set_mode(size)
    clock = pygame.time.Clock()

    render_steps = True
    screen.fill((0,0,0))

    for event in pygame.event.get():
        if event.type == pygame.QUIT: sys.exit()

    for row in xrange(grid_rows):
        for col in xrange(grid_cols):
            for char in colorRules.keys():
                if (t_view[row][col].char == char):
                    FillSquare(screen, base_offset, square_pixels,(row, col), colorRules[char])

    #draw the outer border
    border_rect = (base_offset, base_offset, (grid_cols*square_pixels), (grid_rows*square_pixels))
    pygame.draw.rect(screen, (150,150,0), border_rect, 2)
    pygame.display.flip()
    clock.tick(speed)

def FillSquare(screen, base_offset, square_pixels, loc, color):
    row = loc[0]
    col = loc[1]
    off_x = base_offset + col * square_pixels
    off_y = base_offset + row * square_pixels
    rect = (off_x+4, off_y+4,  square_pixels - 6, square_pixels - 6)
    pygame.draw.rect(screen, color, rect)

def addColorRules(char, color):
    colorRules[char] = color

def events():
    for event in pygame.event.get():
        if event.type == pygame.QUIT: sys.exit()

You can dowload and test the two python files here : 你可以在这里下载并测试两个python文件:

File1 文件1

File2 文件2

As was mentioned already, pygame.font.Font contains methods to draw ASCII characters. 如前所述, pygame.font.Font包含绘制ASCII字符的方法。 Here is an example of render being used to draw a character in a maze. 这是一个用于在迷宫中绘制角色的render示例。

import pygame
from pygame.locals import *

grid = [[0, 0, 0, 0, 0],
        [1, 1, 0, 0, 0],
        [0, 1, 0, 1, 1],
        [0, 1, 0, 1, 0],
        [0, 1, 1, 1, 0]]
resolution = (160, 160)
cell_margin = 14
cell_colors = (255, 255, 255), (0, 0, 0)
player_character = "@"
player_color = (255, 0, 0)
player_size = 20
current_position = [0, 1]

def main():
    pygame.init()
    screen = pygame.display.set_mode(resolution)
    screen.fill(cell_colors[1])
    player = pygame.font.Font(None, player_size).render(player_character,
                                                        False, player_color)
    while True:
        for event in pygame.event.get():
            if event.type == KEYDOWN:
                key = event.key
                if key == K_UP:
                    move(0, -1)
                elif key == K_RIGHT:
                    move(1, 0)
                elif key == K_DOWN:
                    move(0, 1)
                elif key == K_LEFT:
                    move(-1, 0)
            elif event.type == QUIT:
                return
        draw_maze(screen)
        draw_player(player, screen)
        pygame.display.update()

def draw_maze(screen):
    for row in xrange(len(grid)):
        for column in xrange(len(grid[0])):
            screen.fill(cell_colors[grid[column][row]],
                        get_cell_rect((row, column), screen))

def get_cell_rect(coordinates, screen):
    row, column = coordinates
    cell_width = screen.get_width() / len(grid)
    adjusted_width = cell_width - cell_margin
    return pygame.Rect(row * cell_width + cell_margin / 2,
                       column * cell_width + cell_margin / 2,
                       adjusted_width, adjusted_width)

def draw_player(player, screen):
    rect = player.get_rect()
    rect.center = get_cell_rect(current_position, screen).center
    screen.blit(player, rect)

def move(dx, dy):
    x, y = current_position
    nx, ny = x + dx, y + dy
    if nx >= 0 and nx < len(grid) and ny >= 0 and ny < len(grid[0]) and \
       grid[ny][nx]:
        current_position[0] = nx
        current_position[1] = ny

if __name__ == "__main__":
    main()
    pygame.quit()

I tried to limit the example to the bare essentials of what you're interested in learning. 我试图将这个例子限制在你有兴趣学习的基本要素上。 Basically, what's happening is the entire grid and the character are being redrawn every frame. 基本上,正在发生的是整个网格,每个帧都重新绘制角色。 The character's position is being modified by the direction keys. 方向键正在修改角色的位置。 The cells and the character are being drawn according to the rects being returned by get_cell_rect . 根据get_cell_rect返回的rects绘制单元格和字符。 The character is an ordinary Surface created by pygame.font.Font at the initialization of the program. 该字符是由pygame.font.Font在程序初始化时创建的普通Surface

The global variables can be redefined to change the layout, color, sizes, etc. There is also a downloadable version of the example. 可以重新定义全局变量以更改布局,颜色,大小等。还有一个可下载的示例版本

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

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