python - pygame,如何让我的游戏中的分数在循环内只添加一次?
问题描述
我几乎完成了我的飞扬小鸟克隆的核心机制,除了我不确定如何添加一次分数,问题在于它在循环中,所以当玩家与物体/隐形墙碰撞时,它实际上会碰撞多次并在分数上增加一个以上,所以我的问题是我如何让它只碰撞一次并在分数上增加一次。
import sys
import pygame
import random
pygame.init()
pygame.display.set_caption("Slivering snake")
window = pygame.display.set_mode((1024, 768))
clock = pygame.time.Clock()
black = 0, 0, 0
red = 255, 0, 0
score = 0
font = pygame.font.SysFont("segoe ui", 34, True)
class Player:
def __init__(self, x, y, w, h, ):
self.x, self.y, self.width, self.height = x, y, w, h
self.colour = 0, 0, 255
self.force = 12.5
self.timer = 0
def movement(self):
self.keys = pygame.key.get_pressed()
if self.keys[pygame.K_w] or self.keys[pygame.K_UP]:
self.force -= 0.2
self.y -= self.force
def gravity(self):
self.y += 4
self.timer += 1
if self.timer >= 32:
self.timer = 0
self.force = 12.5
def draw(self):
pygame.draw.rect(window, self.colour, (self.x, self.y, self.width, self.height))
player = Player(60, 200, 50, 50)
class Pipes:
def __init__(self, x, y, w, h, s):
self.x, self.y = x, y
self.width, self.height = w, h
self.speed = s
self.colour = 0, 255, 0
self.x1, self.y1 = 1450, 0
def movement(self):
self.x -= self.speed
if self.x < -95:
self.x = 1030
location = random.randint(-300, 300)
self.y = location
self.x1 -= self.speed
if self.x1 < -95:
self.x1 = 1030
location = random.randint(-300, 300)
self.y1 = location
def draw(self):
pygame.draw.rect(window, self.colour, (self.x, self.y - 300, self.width, self.height))
pygame.draw.rect(window, self.colour, (self.x, self.y + 490, self.width, self.height))
pygame.draw.rect(window, self.colour, (self.x1, self.y1 - 300, self.width, self.height))
pygame.draw.rect(window, self.colour, (self.x1, self.y1 + 490, self.width, self.height))
pipes = Pipes(900, 0, 70, 600, 3.5)
running = True
while running:
window.fill(black)
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
pipe_list = [
pygame.Rect(pipes.x, pipes.y - 300, pipes.width, pipes.height),
pygame.Rect(pipes.x, pipes.y + 490, pipes.width, pipes.height),
pygame.Rect(pipes.x1, pipes.y1 - 300, pipes.width, pipes.height),
pygame.Rect(pipes.x1, pipes.y1 + 490, pipes.width, pipes.height)
]
score_rect = [
pygame.Rect(pipes.x, 0, 1, 1024),
pygame.Rect(pipes.x1, 0, 1, 1024)
]
player.gravity()
player.movement()
pipes.movement()
player_rect = pygame.Rect(player.x, player.y, player.width, player.height)
for collision in pipe_list:
if player_rect.colliderect(collision):
running = False
for points in score_rect:
if player_rect.colliderect(points):
score = score + 1
text = font.render("Score " + str(score), True, red)
print(score)
pipes.draw()
player.draw()
window.blit(text, (30, 20))
clock.tick(60)
pygame.display.flip()
解决方案
一个Pipes
对象不应包含 2 个或更多管道,它仅包含 1 个管道,并且如果管道已通过则具有状态 ( self.passed
)
class Pipes:
def __init__(self, x, y, w, h, s):
self.x, self.y = x, y
self.width, self.height = w, h
self.speed = s
self.colour = 0, 255, 0
self.passed = False
在开始重新创建管道时,必须重置状态通道:
class Pipes:
# [...]
def movement(self):
self.x -= self.speed
if self.x < -95:
self.x = 1030
location = random.randint(-300, 300)
self.y = location
self.passed = False
该类有一个方法score
,它评估对象是否被传递,并在传递管道时返回 true:
class Pipes:
# [...]
def score(self, player_rect):
if not self.passed and player_rect.colliderect(pygame.Rect(self.x, 0, 1, 1024)):
self.passed = True
return True
return False
此外,还有一种方法可以评估玩家是否与管道发生碰撞:
```py
class Pipes:
# [...]
def collide(self, player_rect):
rect1 = pygame.Rect(self.x, self.y - 300, self.width, self.height)
rect2 = pygame.Rect(self.x, self.y + 490, self.width, self.height)
return player_rect.colliderect(rect1) or player_rect.colliderect(rect2)
创建 2 个管道的列表
pipe_list = [
Pipes(900, 0, 70, 600, 3.5),
Pipes(1450, 0, 70, 600, 3.5)]
移动、绘制、点碰撞测试并循环评估分数:
while running:
# [...]
for pipe in pipe_list:
pipe.movement()
player_rect = pygame.Rect(player.x, player.y, player.width, player.height)
for pipe in pipe_list:
if pipe.collide(player_rect):
running = False
for pipe in pipe_list:
if pipe.score(player_rect):
score += 1
# [...]
for pipe in pipe_list:
pipe.draw()
请参阅示例:
import sys
import pygame
import random
pygame.init()
pygame.display.set_caption("Slivering snake")
window = pygame.display.set_mode((1024, 768))
clock = pygame.time.Clock()
black = 0, 0, 0
red = 255, 0, 0
score = 0
font = pygame.font.SysFont("segoe ui", 34, True)
class Player:
def __init__(self, x, y, w, h, ):
self.x, self.y, self.width, self.height = x, y, w, h
self.colour = 0, 0, 255
self.force = 12.5
self.timer = 0
def movement(self):
self.keys = pygame.key.get_pressed()
if self.keys[pygame.K_w] or self.keys[pygame.K_UP]:
self.force -= 0.2
self.y -= self.force
def gravity(self):
self.y += 4
self.timer += 1
if self.timer >= 32:
self.timer = 0
self.force = 12.5
def draw(self):
pygame.draw.rect(window, self.colour, (self.x, self.y, self.width, self.height))
player = Player(60, 200, 50, 50)
class Pipes:
def __init__(self, x, y, w, h, s):
self.x, self.y = x, y
self.width, self.height = w, h
self.speed = s
self.colour = 0, 255, 0
self.passed = False
def movement(self):
self.x -= self.speed
if self.x < -95:
self.x = 1030
location = random.randint(-300, 300)
self.y = location
self.passed = False
def score(self, player_rect):
if not self.passed and player_rect.colliderect(pygame.Rect(self.x, 0, 1, 1024)):
self.passed = True
return True
return False
def collide(self, player_rect):
rect1 = pygame.Rect(self.x, self.y - 300, self.width, self.height)
rect2 = pygame.Rect(self.x, self.y + 490, self.width, self.height)
return player_rect.colliderect(rect1) or player_rect.colliderect(rect2)
def draw(self):
pygame.draw.rect(window, self.colour, (self.x, self.y - 300, self.width, self.height))
pygame.draw.rect(window, self.colour, (self.x, self.y + 490, self.width, self.height))
pipe_list = [
Pipes(900, 0, 70, 600, 3.5),
Pipes(1450, 0, 70, 600, 3.5)]
running = True
while running:
window.fill(black)
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
player.gravity()
player.movement()
for pipe in pipe_list:
pipe.movement()
player_rect = pygame.Rect(player.x, player.y, player.width, player.height)
for pipe in pipe_list:
if pipe.collide(player_rect):
running = False
for pipe in pipe_list:
if pipe.score(player_rect):
score += 1
text = font.render("Score " + str(score), True, red)
print(score)
for pipe in pipe_list:
pipe.draw()
player.draw()
window.blit(text, (30, 20))
clock.tick(60)
pygame.display.flip()
推荐阅读
- php - 如何在右表中的特定行上进行左连接?
- javascript - 如何解决“CKEditor 错误:“无法将 null 转换为对象””错误
- reactjs - React useEffect() localhost API 获取不起作用
- spark-ar-studio - How to change the default person in the inbuilt simulator in Spark AR Studio?
- android - 为不同的主题配置不同的颜色
- laravel - Mockery 中的 Laravel 依赖注入
- reactjs - 在另一个组件中调用一个方法,该方法在 React 中返回一些值
- flutter - “ValueNotifier”+“ValueListenableBuilder”是否适用于 Flutter 中的“许多”小部件?
- sharepoint - Sharepoint:无法添加新的应用程序目录
- python - 如何在特定类别中创建 Discord 频道?