python - 使用 pygame 或任何其他工具在 python 中形成二维数组后绘制一条线
问题描述
我正在使用 python 和 pygame 创建游戏。首先,我尝试使用 pygame.draw 工具创建游戏,但后来我意识到使用这种方法很难调用点和训练数据集。我第一次尝试的代码是
import pygame
import sys
WINDOW_WIDTH = 800
WINDOW_HEIGHT= 600
#define colour
white = (255,255,255)
black = (0,0,0)
red = (255,0,0)
green = (0,255,0)
blue = (121,202,255)
yellow= (255,255,0)
def lineRectIntersectionPoints( line, rect ):
""" Get the list of points where the line and rect
intersect, The result may be zero, one or two points.
BUG: This function fails when the line and the side
of the rectangle overlap """
def linesAreParallel( x1,y1, x2,y2, x3,y3, x4,y4 ):
""" Return True if the given lines (x1,y1)-(x2,y2) and
(x3,y3)-(x4,y4) are parallel """
return (((x1-x2)*(y3-y4)) - ((y1-y2)*(x3-x4)) == 0)
def intersectionPoint( x1,y1, x2,y2, x3,y3, x4,y4 ):
""" Return the point where the lines through (x1,y1)-(x2,y2)
and (x3,y3)-(x4,y4) cross. This may not be on-screen """
#Use determinant method, as per
#Ref: https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection
Px = ((((x1*y2)-(y1*x2))*(x3 - x4)) - ((x1-x2)*((x3*y4)-(y3*x4)))) / (((x1-x2)*(y3-y4)) - ((y1-y2)*(x3-x4)))
Py = ((((x1*y2)-(y1*x2))*(y3 - y4)) - ((y1-y2)*((x3*y4)-(y3*x4)))) / (((x1-x2)*(y3-y4)) - ((y1-y2)*(x3-x4)))
return Px,Py
### Begin the intersection tests
result = []
line_x1, line_y1, line_x2, line_y2 = line # split into components
pos_x, pos_y, width, height = rect
### Convert the rectangle into 4 lines
rect_lines = [ ( pos_x, pos_y, pos_x+width, pos_y ), ( pos_x, pos_y+height, pos_x+width, pos_y+height ), # top & bottom
( pos_x, pos_y, pos_x, pos_y+height ), ( pos_x+width, pos_y, pos_x+width, pos_y+height ) ] # left & right
### intersect each rect-side with the line
for r in rect_lines:
rx1,ry1, rx2,ry2 = r
if ( not linesAreParallel( line_x1,line_y1, line_x2,line_y2, rx1,ry1, rx2,ry2 ) ): # not parallel
pX, pY = intersectionPoint( line_x1,line_y1, line_x2,line_y2, rx1,ry1, rx2,ry2 ) # so intersecting somewhere
# Lines intersect, but is it on-screen?
if ( pX >= 0 and pY >= 0 and pX < WINDOW_WIDTH and pY < WINDOW_HEIGHT ): # yes! on-screen
result.append( ( round(pX), round(pY) ) ) # keep it
if ( len( result ) == 2 ):
break # Once we've found 2 intersection points, that's it
return result
#opening window
pygame.init()
screen = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
#pygame.draw.rect(screen, red, (200,100,250,250), 2)
#pygame.draw.rect(screen, green, (150,75,350,300), 2)
#pygame.draw.rect(screen, red, (100,50,450,350), 2)
##draw lines
##upper line
#pygame.draw.line(screen,white,(325,50),(325,100),3)
##lower line
#pygame.draw.line(screen,white,(325,350),(325,400),3)
##left line
#pygame.draw.line(screen,white,(100,200),(200,200),3)
##right line
#pygame.draw.line(screen,white,(450,200),(550,200),3)
#@kingsley correction of the code
board_rects = [ ( 200,100,250,250, red ), ( 150,75,350,300, green ), ( 100,50,450,350, red ) ]
for rect in board_rects:
x_pos, y_pos = rect[0], rect[1]
width, height = rect[2], rect[3]
colour = rect[4]
pygame.draw.rect( screen, colour, ( x_pos, y_pos, width, height ), 2 )
board_lines = [ ( 325,50,325,100 ), ( 325,350,325,400 ), ( 100,200,200,200 ), ( 450,200,550,200 ) ]
for line in board_lines:
line_from = ( line[0], line[1] )
line_to = ( line[2], line[3] )
pygame.draw.line( screen, white, line_from, line_to, 3)
for line in board_lines:
for rect in board_rects:
rect = rect[ 0: -1 ] # trim off the colour
intersection_points = lineRectIntersectionPoints( line, rect )
for p in intersection_points:
pygame.draw.circle( screen, blue, p, 10 ) # Draw a circle at the intersection point
#updating window
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
pygame.display.update()
之后我尝试使用二维数组创建板。在这个我只想在特定的高亮框上画线,我想删除/删除所有其他框。我使用了以下代码:
import pygame
# Define some colors
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
GREEN = (0, 255, 0)
RED = (255, 0, 0)
WIDTH = 20
HEIGHT = 20
MARGIN = 5
#set the array
grid = []
for row in range(19):
grid.append([])
for column in range(19):
grid[row].append(0)
# Set row 1, cell 5 to one. (Remember rows and
# column numbers start at zero.)
grid[0][0] = 1
pygame.init()
# Set the width and height of the screen [width, height]
size = [600, 600]
screen = pygame.display.set_mode(size)
#set the tittle of the game
pygame.display.set_caption("My Array Game")
# Loop until the user clicks the close button.
done = False
# Used to manage how fast the screen updates
clock = pygame.time.Clock()
# -------- Main Program Loop -----------
#while not done:
# --- Main event loop
while not done:
for event in pygame.event.get(): # User did something
if event.type == pygame.QUIT: # If user clicked close
done = True # Flag that we are done so we exit this loop
elif event.type == pygame.MOUSEBUTTONDOWN:
# User clicks the mouse. Get the position
pos = pygame.mouse.get_pos()
# Change the x/y screen coordinates to grid coordinates
column = pos[0] // (WIDTH + MARGIN)
row = pos[1] // (HEIGHT + MARGIN)
# Set that location to one
grid[row][column] = 1
print("Click ", pos, "Grid coordinates: ", row, column)
# --- Game logic should go here
# --- Screen-clearing code goes here
# Here, we clear the screen to white. Don't put other drawing commands
# above this, or they will be erased with this command.
# If you want a background image, replace this clear with blit'ing the
# background image.
screen.fill(BLACK)
# --- Drawing code should go here
# Draw the grid
for row in range(19):
for column in range(19):
color = WHITE
if grid[row][column] == 1:
color = GREEN
pygame.draw.rect(screen,
color,
[(MARGIN + WIDTH) * column + MARGIN,
(MARGIN + HEIGHT) * row + MARGIN,
WIDTH,
HEIGHT])
# --- Go ahead and update the screen with what we've drawn.
pygame.display.flip()
# --- Limit to 60 frames per second
clock.tick(60)
# Close the window and quit.
pygame.quit()
我想保留的盒子
我想在选定的框上画线
盒子的坐标
解决方案
您不能“删除”在显示表面上绘制的框,不要绘制它们:
while not done:
# [...]
for row in range(19):
for column in range(19):
if grid[row][column] == 1:
color = GREEN
box_rect = [(MARGIN + WIDTH) * column + MARGIN,
(MARGIN + HEIGHT) * row + MARGIN,
WIDTH,
HEIGHT]
pygame.draw.rect(screen, color, box_rect)
要绘制线条,您必须找到框的中心。使用一个pygame.Rect
对象来找到一个盒子的中心点。row
具有索引 ( , )的框的中心点column
可以通过以下方式计算:
box_rect = pygame.Rect((MARGIN + WIDTH) * column + MARGIN,
(MARGIN + HEIGHT) * row + MARGIN,
WIDTH,
HEIGHT)
box_center = box_rect.center
推荐阅读
- angular - 未找到 UserCommonModalComponent 的组件工厂。你把它添加到@NgModule.entryComponents 了吗?
- integration-testing - 即使执行了测试,Jacoco 报告聚合显示 0 覆盖率
- javascript - 执行业力测试用例时浏览器断开连接
- unity3d - 寻找一种为异步任务添加进度条的方法(Unity,C#)
- uwp - 如何在 uwp 中隐藏 NavigationView 的 PaneToggleButton
- python - 当我们想要实现交叉验证时如何使用 flow_from_directory 函数
- python - 如何拆分数字值?
- javascript - React 中的 env-vars 使用 Dotenv 和 Webpack
- r - 如何用 R 中的一个 case_when 表达式改变两列?
- amazon-web-services - 在 Glue Dev Endpoint 上为 Sagemaker 设置 Spark 版本