screen = pygame.display.set_mode((width, height))
...
# Let's create a board
board = screen.copy()
board.fill((40, 40, 40))
# We connect all dots with lines
prev = None
for pos in POSITIONS:
if prev:
pygame.draw.line(board, (0,0,0), prev, pos, 4)
prev = pos
# Then we draw the good and bad connections
for pos in CONNECTIONS:
target = CONNECTIONS[pos]
pygame.draw.line(board, (0,200,0) if pos < target else (200,0,0), POSITIONS[pos], POSITIONS[target], 4)
# Last we create all fields
for pos in POSITIONS:
pygame.draw.circle(board, (0,0,0), pos, 40)
pygame.draw.circle(board, (200,200,200), pos, 36)
import pygame
import random
CONNECTIONS = {
2: 4,
1: 7,
5: 3,
8: 0,
}
POSITIONS = [
(93, 394),
(244, 338),
(368, 391),
(457, 317),
(579, 348),
(572, 181),
(458, 108),
(379, 203),
(231, 115),
(89, 197)
]
class Player(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.image = pygame.Surface((30, 50))
self.image.fill((200,100,0))
self.rect = self.image.get_rect()
# The player has a state.
# Either it is WAITING, so it reacts to the move() command
# Or it is already MOVING, and pressing a key does nothing
self.state = 'WAITING'
# It's important to have a distinction between the logical position
# on the board, and the actual position of the sprite on the screen
# We start on board position 0
self.board_pos = 0
# We set the current position of the sprite to the position
# of the tile we're standing on
self.rect.center = POSITIONS[self.board_pos]
# We use an additional vector to store the position of the
# sprite so we can let pygame handle all the vector math
self.pos = pygame.Vector2(self.rect.center)
def move(self):
if self.state == 'WAITING':
# If we are waiting and a key is pressed, we start moving
eyes = random.randint(1, 6)
print(f"rolled a {eyes}")
# Keep track of how many tiles we move forward
self.eyes = eyes
self.state = 'MOVING'
# Since we move forward, increase our board position
self.board_pos += 1
# We want a smooth movement, so we store the position
# of the next tile in a vector, too
self.target = pygame.Vector2(POSITIONS[self.board_pos])
def update(self, dt, events):
if self.state == 'MOVING':
# When we're moving, create a movement vector
# so we know in which direction we have to move
movement = self.target - self.pos
length = movement.length()
if length < 5:
# We arrived at out target tile
# If we still have some tiles to go, decrease the number
# since we arrived at one
if self.eyes > 0:
self.eyes -= 1
self.pos = self.target
if self.eyes == 0:
# We moved all tiles, so let's see if there's a
# connection to another tile
con = CONNECTIONS.get(self.board_pos, None)
if con:
# If there is, we have a new target to move to
self.board_pos = con
self.target = pygame.Vector2(POSITIONS[self.board_pos])
else:
# If not, our turn is over
self.state = 'WAITING'
else:
# We have still some tiles to go
self.board_pos += 1
self.target = pygame.Vector2(POSITIONS[self.board_pos])
else:
# Just keep moving
movement.normalize_ip()
# Some math to keep the movement smooth and nice
self.pos += movement * dt/10 * max(length/40., 0.7)
# Pygame uses the rect attribute to position the sprite
# so let's update it with the position of our vector
self.rect.center = int(self.pos.x), int(self.pos.y)
def main():
width, height = 640, 480
pygame.init()
screen = pygame.display.set_mode((width, height))
clock = pygame.time.Clock()
player = Player()
sprites = pygame.sprite.Group(player)
# Let's create a board
board = screen.copy()
board.fill((40, 40, 40))
# We connect all dots with lines
prev = None
for pos in POSITIONS:
if prev:
pygame.draw.line(board, (0,0,0), prev, pos, 4)
prev = pos
# Then we draw the good and bad connections
for pos in CONNECTIONS:
target = CONNECTIONS[pos]
pygame.draw.line(board, (0,200,0) if pos < target else (200,0,0), POSITIONS[pos], POSITIONS[target], 4)
# Last we create all fields
for pos in POSITIONS:
pygame.draw.circle(board, (0,0,0), pos, 40)
pygame.draw.circle(board, (200,200,200), pos, 36)
dt = 0
while True:
events = pygame.event.get()
for e in events:
if e.type == pygame.QUIT:
return
if e.type == pygame.KEYDOWN:
player.move()
screen.blit(board, (0,0))
sprites.update(dt, events)
sprites.draw(screen)
pygame.display.flip()
dt = clock.tick(60)
if __name__ == '__main__':
main()
你首先应该考虑的是如何将你的游戏逻辑从你的绘图逻辑中分离出来,以及在考虑如何绘制一个10*10的网格之前如何表示你的游戏状态。你知道吗
这实际上是最重要的事情之一,所以让我重复一遍:首先考虑如何表示你的游戏状态,然后再考虑如何绘制它。你知道吗
假设我们有一个由10个图块组成的板(为了保持这个示例的简单性),那么让我们从创建一个连接这些图块的地图开始:
这意味着如果一个玩家在地砖2上着陆,他们将移动到地砖4。如果它们落在8号牌上,它们会移回0,等等。所以
CONNECTIONS
已经是游戏的重要部分了。你知道吗既然我们想要一个好的棋盘,让我们定义每个磁贴在屏幕上的位置。我们可以使用一个简单的列表:
这意味着tile 0位于屏幕位置
(93, 394)
等,并且已经允许我们使用pygame的draw
模块绘制一个漂亮的游戏板然后再重用
CONNECTIONS
和POSITIONS
(绿色是好的,红色是坏的)。你知道吗当然,如果你想要一个简单的网格而不是一个不对称的电路板,你可以使用一个嵌套的循环或者一些简单的数学来动态地创建每个图块的位置。你知道吗
但是正如你所看到的,我们已经在游戏坐标(1D:棋盘是线性的)和屏幕坐标(2D:x和y)之间有了某种关系,这些东西是不同的。你知道吗
这意味着如果我们使用一些数据结构来表示玩家,那么这个数据结构(我们将使用pygame的
Sprite
的子类)也应该有两个位置:一个代表玩家在棋盘上的位置,另一个代表精灵在场地上的位置。你知道吗当玩家移动时,我们改变它的棋盘位置,如果他们落在一个有连接的场地上(我们将他们的棋盘位置与
CONNECTIONS
中的值进行比较),我们就知道玩家必须继续移动。你知道吗所以这里有一个我一起破解的例子(按任意键滚动模具并移动):
相关问题 更多 >
编程相关推荐