使用矩阵作为精灵
Using a matrix as a sprite
现在,我有一个球在屏幕上沿随机对角线方向移动,并在与它碰撞时从墙上反弹。
所述程序的图像
我的最终目标是让球成为一个矩阵,并让它在 30x30 的网格周围表现相同。
我已经尝试过 enumerate() 函数,但想不出如何让它像我在本文末尾引用的图片和代码中那样执行 post。
通过执行,我的意思是在屏幕上沿对角线方向随机移动
这是矩阵球:
Ball = [[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],
[0, 1, 1, 1, 0]]
这是我的网格:
class Grid():
grid = []
for row in range(36):
# An empty array that will hold each cell in this row
grid.append([])
for column in range(91):
grid[row].append(0) # Append cells
这是我的枚举循环:
# coordinates for where the ball will reside
offset = (3, 3)
# enumerate the matrices to form one object
for x, row in enumerate(Ball):
for y, e in enumerate(row):
Grid[x + offset[0]][y + offset[1]] = e
我希望有人能提供帮助。如果需要,我可以提供任何其他信息。这是我的完整代码供参考:
import sys
import math
from random import randrange
import pygame as pg
# Define some colors
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
GREEN = (0, 255, 0)
RED = (255, 0, 0)
# This sets the WIDTH and HEIGHT of each grid location
WIDTH = 10
HEIGHT = 10
# This sets the margin between each cell
MARGIN = 1
# Create a ball, add movement (diagonally for now)
class Ball(pg.sprite.Sprite):
def __init__(self, pos, *groups):
super().__init__(groups)
self.image = pg.Surface((100,100), pg.SRCALPHA) # creates a surface
col = randrange(256), randrange(256), randrange(256) # random colors
pg.draw.circle(self.image, col, (50, 50), 50) # draws a circle
self.rect = self.image.get_rect(center=pos)
self.vel = pg.math.Vector2(8, 0).rotate(randrange(360)) # defines a velocity
self.pos = pg.math.Vector2(pos) # defines position
self.overlap = False
def update(self): # moves balls
self.pos += self.vel
self.rect.center = self.pos
if self.rect.left < 0 or self.rect.right > 990:
self.vel.x *= -1 # makes ball bounce off walls
if self.rect.top < 0 or self.rect.bottom > 385:
self.vel.y *= -1
class Grid():
grid = []
for row in range(36):
# An empty array that will hold each cell in this row
grid.append([])
for column in range(91):
grid[row].append(0) # Append cells
def main():
#self.overlap = False
screen = pg.display.set_mode((1000, 395))
# Set title of screen
pg.display.set_caption("Ball With Grid")
clock = pg.time.Clock()
sprite_group = pg.sprite.Group()
ball = Ball((495, 193), sprite_group)
done = False
while not done:
for event in pg.event.get():
if event.type == pg.QUIT:
done = True
# Used to track the grid coordinates
if event.type == pg.MOUSEBUTTONDOWN:
# Get the position is screen is clicked
pos = pg.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)
if event.type == pg.KEYDOWN:
if event.key == pg.K_SPACE:
sprite_group.add(Ball((320, 240)))
# Draw the grid and add values to the cells
for row in range(36):
for column in range(91):
count = { (row,column):0 for row in range(36) for column in range(90) }
color= WHITE
"""
while self.overlap == False:
for i in range(0, 36):
for j in range(0, 91):
if self.pos == row[i] and self.pos == column[j]:
self.overlap = True
if self.overlap == True:
color = RED
"""
pg.draw.rect(screen,
color,
[(MARGIN + WIDTH) * column + MARGIN,
(MARGIN + HEIGHT) * row + MARGIN,
WIDTH,
HEIGHT])
sprite_group.update()
sprite_group.draw(screen)
pg.display.flip()
clock.tick(30)
if __name__ == '__main__':
pg.init()
main()
pg.quit()
sys.exit()
我不知道这是 obvious/right 在我眼皮底下发生的事情还是太复杂的事情。无论如何,如果你能提供帮助,你会建议我如何实现我的最终目标?
创建一个可以从网格生成 .image
属性的精灵 class:
class GridObject(pg.sprite.Sprite):
def __init__(self, pos, grid, *groups):
super().__init__(groups)
# create image from grid
self.grid = grid
self.gridsize = (len(grid[0]), len(grid))
imgsize = self.gridsize[0]*(WIDTH+MARGIN), self.gridsize[1]*(HEIGHT+MARGIN)
self.image = pg.Surface(imgsize, flags=pg.SRCALPHA)
self.image.fill((0, 0, 0, 0))
col = randrange(256), randrange(256), randrange(256)
for c in range(self.gridsize[0]):
for r in range(self.gridsize[1]):
if self.grid[r][c] == 1:
rect = [(MARGIN + WIDTH) * c + MARGIN, (MARGIN + HEIGHT) * r + MARGIN, WIDTH, HEIGHT]
pg.draw.rect(self.image, col, rect)
self.rect = self.image.get_rect(center=pos)
self.vel = pg.math.Vector2(8, 0).rotate(randrange(360))
self.pos = pg.math.Vector2(pos)
更新 Sprite 的位置时,.rect
属性必须与网格对齐:
class GridObject(pg.sprite.Sprite):
# [...]
def update(self, boundrect):
self.pos += self.vel
self.rect.center = self.pos
if self.rect.left <= boundrect.left or self.rect.right >= boundrect.right:
self.vel.x *= -1
if self.rect.top <= boundrect.top or self.rect.bottom >= boundrect.bottom:
self.vel.y *= -1
# align rect to grid
gridpos = round(self.rect.x / (WIDTH+MARGIN)), round(self.rect.y / (HEIGHT+MARGIN))
self.rect.topleft = gridpos[0] * (WIDTH+MARGIN), gridpos[1] * (HEIGHT+MARGIN)
创建一个 "gridball" 精灵:
ballGrid = [[0, 1, 1, 1, 0],
[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1],
[0, 1, 1, 1, 0]]
ball = GridObject((495, 193), ballGrid, sprite_group)
看例子:
import sys
import math
from random import randrange
import pygame as pg
# Define some colors
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
GREEN = (0, 255, 0)
RED = (255, 0, 0)
WIDTH, HEIGHT, MARGIN = 10, 10, 1
GRIDX, GRIDY = 91, 36
class GridObject(pg.sprite.Sprite):
def __init__(self, pos, grid, *groups):
super().__init__(groups)
# create image from grid
self.grid = grid
self.gridsize = (len(grid[0]), len(grid))
imgsize = self.gridsize[0]*(WIDTH+MARGIN), self.gridsize[1]*(HEIGHT+MARGIN)
self.image = pg.Surface(imgsize, flags=pg.SRCALPHA)
self.image.fill((0, 0, 0, 0))
col = randrange(256), randrange(256), randrange(256)
for c in range(self.gridsize[0]):
for r in range(self.gridsize[1]):
if self.grid[r][c] == 1:
rect = [(MARGIN + WIDTH) * c + MARGIN, (MARGIN + HEIGHT) * r + MARGIN, WIDTH, HEIGHT]
pg.draw.rect(self.image, col, rect)
self.rect = self.image.get_rect(center=pos)
self.vel = pg.math.Vector2(8, 0).rotate(randrange(360))
self.pos = pg.math.Vector2(pos)
def update(self, boundrect):
self.pos += self.vel
self.rect.center = self.pos
if self.rect.left <= boundrect.left or self.rect.right >= boundrect.right:
self.vel.x *= -1
if self.rect.top <= boundrect.top or self.rect.bottom >= boundrect.bottom:
self.vel.y *= -1
# align rect to grid
gridpos = round(self.rect.x / (WIDTH+MARGIN)), round(self.rect.y / (HEIGHT+MARGIN))
self.rect.topleft = gridpos[0] * (WIDTH+MARGIN), gridpos[1] * (HEIGHT+MARGIN)
ballGrid = [[0, 1, 1, 1, 0],
[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1],
[0, 1, 1, 1, 0]]
def main():
#self.overlap = False
screen = pg.display.set_mode((GRIDX * (WIDTH+MARGIN) + MARGIN, GRIDY * (HEIGHT+MARGIN)))
# Set title of screen
pg.display.set_caption("Ball With Grid")
clock = pg.time.Clock()
sprite_group = pg.sprite.Group()
ball = GridObject((495, 193), ballGrid, sprite_group)
done = False
while not done:
for event in pg.event.get():
if event.type == pg.QUIT:
done = True
screen.fill((0, 0, 0))
# Draw the grid and add values to the cells
for row in range(GRIDY):
for column in range(GRIDX):
rect = [(MARGIN + WIDTH) * column + MARGIN, (MARGIN + HEIGHT) * row + MARGIN, WIDTH, HEIGHT]
pg.draw.rect(screen, WHITE, rect)
sprite_group.update(screen.get_rect())
sprite_group.draw(screen)
pg.display.flip()
clock.tick(30)
if __name__ == '__main__':
pg.init()
main()
pg.quit()
sys.exit()
现在,我有一个球在屏幕上沿随机对角线方向移动,并在与它碰撞时从墙上反弹。
所述程序的图像
我的最终目标是让球成为一个矩阵,并让它在 30x30 的网格周围表现相同。
我已经尝试过 enumerate() 函数,但想不出如何让它像我在本文末尾引用的图片和代码中那样执行 post。
通过执行,我的意思是在屏幕上沿对角线方向随机移动
这是矩阵球:
Ball = [[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],
[0, 1, 1, 1, 0]]
这是我的网格:
class Grid():
grid = []
for row in range(36):
# An empty array that will hold each cell in this row
grid.append([])
for column in range(91):
grid[row].append(0) # Append cells
这是我的枚举循环:
# coordinates for where the ball will reside
offset = (3, 3)
# enumerate the matrices to form one object
for x, row in enumerate(Ball):
for y, e in enumerate(row):
Grid[x + offset[0]][y + offset[1]] = e
我希望有人能提供帮助。如果需要,我可以提供任何其他信息。这是我的完整代码供参考:
import sys
import math
from random import randrange
import pygame as pg
# Define some colors
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
GREEN = (0, 255, 0)
RED = (255, 0, 0)
# This sets the WIDTH and HEIGHT of each grid location
WIDTH = 10
HEIGHT = 10
# This sets the margin between each cell
MARGIN = 1
# Create a ball, add movement (diagonally for now)
class Ball(pg.sprite.Sprite):
def __init__(self, pos, *groups):
super().__init__(groups)
self.image = pg.Surface((100,100), pg.SRCALPHA) # creates a surface
col = randrange(256), randrange(256), randrange(256) # random colors
pg.draw.circle(self.image, col, (50, 50), 50) # draws a circle
self.rect = self.image.get_rect(center=pos)
self.vel = pg.math.Vector2(8, 0).rotate(randrange(360)) # defines a velocity
self.pos = pg.math.Vector2(pos) # defines position
self.overlap = False
def update(self): # moves balls
self.pos += self.vel
self.rect.center = self.pos
if self.rect.left < 0 or self.rect.right > 990:
self.vel.x *= -1 # makes ball bounce off walls
if self.rect.top < 0 or self.rect.bottom > 385:
self.vel.y *= -1
class Grid():
grid = []
for row in range(36):
# An empty array that will hold each cell in this row
grid.append([])
for column in range(91):
grid[row].append(0) # Append cells
def main():
#self.overlap = False
screen = pg.display.set_mode((1000, 395))
# Set title of screen
pg.display.set_caption("Ball With Grid")
clock = pg.time.Clock()
sprite_group = pg.sprite.Group()
ball = Ball((495, 193), sprite_group)
done = False
while not done:
for event in pg.event.get():
if event.type == pg.QUIT:
done = True
# Used to track the grid coordinates
if event.type == pg.MOUSEBUTTONDOWN:
# Get the position is screen is clicked
pos = pg.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)
if event.type == pg.KEYDOWN:
if event.key == pg.K_SPACE:
sprite_group.add(Ball((320, 240)))
# Draw the grid and add values to the cells
for row in range(36):
for column in range(91):
count = { (row,column):0 for row in range(36) for column in range(90) }
color= WHITE
"""
while self.overlap == False:
for i in range(0, 36):
for j in range(0, 91):
if self.pos == row[i] and self.pos == column[j]:
self.overlap = True
if self.overlap == True:
color = RED
"""
pg.draw.rect(screen,
color,
[(MARGIN + WIDTH) * column + MARGIN,
(MARGIN + HEIGHT) * row + MARGIN,
WIDTH,
HEIGHT])
sprite_group.update()
sprite_group.draw(screen)
pg.display.flip()
clock.tick(30)
if __name__ == '__main__':
pg.init()
main()
pg.quit()
sys.exit()
我不知道这是 obvious/right 在我眼皮底下发生的事情还是太复杂的事情。无论如何,如果你能提供帮助,你会建议我如何实现我的最终目标?
创建一个可以从网格生成 .image
属性的精灵 class:
class GridObject(pg.sprite.Sprite):
def __init__(self, pos, grid, *groups):
super().__init__(groups)
# create image from grid
self.grid = grid
self.gridsize = (len(grid[0]), len(grid))
imgsize = self.gridsize[0]*(WIDTH+MARGIN), self.gridsize[1]*(HEIGHT+MARGIN)
self.image = pg.Surface(imgsize, flags=pg.SRCALPHA)
self.image.fill((0, 0, 0, 0))
col = randrange(256), randrange(256), randrange(256)
for c in range(self.gridsize[0]):
for r in range(self.gridsize[1]):
if self.grid[r][c] == 1:
rect = [(MARGIN + WIDTH) * c + MARGIN, (MARGIN + HEIGHT) * r + MARGIN, WIDTH, HEIGHT]
pg.draw.rect(self.image, col, rect)
self.rect = self.image.get_rect(center=pos)
self.vel = pg.math.Vector2(8, 0).rotate(randrange(360))
self.pos = pg.math.Vector2(pos)
更新 Sprite 的位置时,.rect
属性必须与网格对齐:
class GridObject(pg.sprite.Sprite):
# [...]
def update(self, boundrect):
self.pos += self.vel
self.rect.center = self.pos
if self.rect.left <= boundrect.left or self.rect.right >= boundrect.right:
self.vel.x *= -1
if self.rect.top <= boundrect.top or self.rect.bottom >= boundrect.bottom:
self.vel.y *= -1
# align rect to grid
gridpos = round(self.rect.x / (WIDTH+MARGIN)), round(self.rect.y / (HEIGHT+MARGIN))
self.rect.topleft = gridpos[0] * (WIDTH+MARGIN), gridpos[1] * (HEIGHT+MARGIN)
创建一个 "gridball" 精灵:
ballGrid = [[0, 1, 1, 1, 0],
[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1],
[0, 1, 1, 1, 0]]
ball = GridObject((495, 193), ballGrid, sprite_group)
看例子:
import sys
import math
from random import randrange
import pygame as pg
# Define some colors
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
GREEN = (0, 255, 0)
RED = (255, 0, 0)
WIDTH, HEIGHT, MARGIN = 10, 10, 1
GRIDX, GRIDY = 91, 36
class GridObject(pg.sprite.Sprite):
def __init__(self, pos, grid, *groups):
super().__init__(groups)
# create image from grid
self.grid = grid
self.gridsize = (len(grid[0]), len(grid))
imgsize = self.gridsize[0]*(WIDTH+MARGIN), self.gridsize[1]*(HEIGHT+MARGIN)
self.image = pg.Surface(imgsize, flags=pg.SRCALPHA)
self.image.fill((0, 0, 0, 0))
col = randrange(256), randrange(256), randrange(256)
for c in range(self.gridsize[0]):
for r in range(self.gridsize[1]):
if self.grid[r][c] == 1:
rect = [(MARGIN + WIDTH) * c + MARGIN, (MARGIN + HEIGHT) * r + MARGIN, WIDTH, HEIGHT]
pg.draw.rect(self.image, col, rect)
self.rect = self.image.get_rect(center=pos)
self.vel = pg.math.Vector2(8, 0).rotate(randrange(360))
self.pos = pg.math.Vector2(pos)
def update(self, boundrect):
self.pos += self.vel
self.rect.center = self.pos
if self.rect.left <= boundrect.left or self.rect.right >= boundrect.right:
self.vel.x *= -1
if self.rect.top <= boundrect.top or self.rect.bottom >= boundrect.bottom:
self.vel.y *= -1
# align rect to grid
gridpos = round(self.rect.x / (WIDTH+MARGIN)), round(self.rect.y / (HEIGHT+MARGIN))
self.rect.topleft = gridpos[0] * (WIDTH+MARGIN), gridpos[1] * (HEIGHT+MARGIN)
ballGrid = [[0, 1, 1, 1, 0],
[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1],
[0, 1, 1, 1, 0]]
def main():
#self.overlap = False
screen = pg.display.set_mode((GRIDX * (WIDTH+MARGIN) + MARGIN, GRIDY * (HEIGHT+MARGIN)))
# Set title of screen
pg.display.set_caption("Ball With Grid")
clock = pg.time.Clock()
sprite_group = pg.sprite.Group()
ball = GridObject((495, 193), ballGrid, sprite_group)
done = False
while not done:
for event in pg.event.get():
if event.type == pg.QUIT:
done = True
screen.fill((0, 0, 0))
# Draw the grid and add values to the cells
for row in range(GRIDY):
for column in range(GRIDX):
rect = [(MARGIN + WIDTH) * column + MARGIN, (MARGIN + HEIGHT) * row + MARGIN, WIDTH, HEIGHT]
pg.draw.rect(screen, WHITE, rect)
sprite_group.update(screen.get_rect())
sprite_group.draw(screen)
pg.display.flip()
clock.tick(30)
if __name__ == '__main__':
pg.init()
main()
pg.quit()
sys.exit()