python - 如何在 pygame 程序中获得分数功能?
问题描述
我一直在尝试在一个我一直在尝试制作的简单游戏中记录一个变量中的分数。当子弹与外星人(代码中的敌人)之间的距离小于某个值(此处为 20 个单位)时,分数会增加。
然而,当我用子弹击中外星人时,分数并没有增加。我该怎么办?
import pygame
import random
import math
# for initialising pygame (req for every pygame app)
pygame.init()
# making the basic window (dimensions must be written inside a tuple )
screen = pygame.display.set_mode((500, 500))
# background
background = pygame.image.load('C:/Users/aryan/Downloads/background.jpg')
# load and set the logo
logo = pygame.image.load('C:/Users/aryan/Downloads/bp.png') # directory of logo
pygame.display.set_icon(logo)
pygame.display.set_caption("space wars") # program name
# define a variable to control the main loop
running = True
# player
playerimg = pygame.image.load('C:/Users/aryan/Downloads/spaceship.png')
playerX = 218 # x and y coordinates of image
playerY = 350
playerxchange = 0 # this will be the change in movement in x direction of our image
playerychange = 0 # this will be the change in movement in y direction of our image
def player(x, y):
screen.blit(playerimg, (x, y)) # blit draws our image on the surface(basically the background)
# syntax for blit(imagename, (xcoordinate,ycoordinate))
# enemy
enemyimg = pygame.image.load('C:/Users/aryan/Downloads/enemy.png')
enemyX = random.randint(0, 476)
enemyY = 20
enemyxchange = 0.2
enemyychange = 40
# game over
overimg = pygame.image.load('C:/Users/aryan/Downloads/gameover.png')
# bullet
bulletimg = pygame.image.load('C:/Users/aryan/Downloads/bullet.png')
bulletX = 0
bulletY = 350
bulletxchange = 0
bulletychange = 1
bullet_state = "ready" # "ready" you cant see bullet on screen
# "fire" you can see bullet firing
bullets = [] # Array to store the position of the bullets
score = 0
def enemy(x, y):
screen.blit(enemyimg, (x, y)) # blit draws our image on the surface(basically the background)
# syntax for blit(imagename, (xcoordinate,ycoordinate))
def firebullet(x, y):
global bullet_state
bullet_state = "ready"
bullets.append([x + 12, y + 6]) # Creating a new bullet
def iscollision(enemyX, enemyY, bulletX, bulletY):
distance = math.sqrt(math.pow(enemyX-bulletX, 2)+ math.pow(enemyY-bulletY,2)) # distance formula
if distance <= 20:
return True
else:
return False
# main loop
while running:
screen.fill((120, 120, 120)) # in order (r, g, b) . (0, 0, 0) is black (255, 0, 0) is red...
screen.blit(background, (0, 0))
# event handling, gets all event from the event queue
for event in pygame.event.get():
# only do something if the event is of type QUIT
if event.type == pygame.QUIT:
# change the value to False, to exit the main loop
running = False
# checking keystroke
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RIGHT:
playerxchange += 0.2 # change in movement will be 0.2 towards the right
if event.key == pygame.K_LEFT:
playerxchange -= 0.2 # change in movement will be 0.2 towards the right
if event.key == pygame.K_UP:
playerychange -= 0.2
if event.key == pygame.K_DOWN:
playerychange += 0.2
if event.key == pygame.K_SPACE:
bullet_state = "fire"
firebullet(playerX, playerY)
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT or event.key == pygame.K_DOWN or event.key == pygame.K_UP:
playerxchange = 0
playerychange = 0
playerY += playerychange
playerX += playerxchange # the value of playerx changes by +- 0.1 depending on keystroke
if playerX <= -64: # this teleports the spaceship from left end to right end
playerX = 564
elif playerX >= 564: # this teleports spaceship from right end to left
playerX = -64
if playerY >= 436: # this prevents spaceship from leaving vertically
playerY = 436
if playerY <= 0:
playerY = 0
# enemy movement
enemyX += enemyxchange
if enemyY >= 476:
enemyY = 476
enemyYchange = 0
enemyXchange = 0
if enemyX <= 0:
enemyxchange = 0.1
enemyY += enemyychange
elif enemyX >= 465:
enemyxchange = -0.1
enemyY += enemyychange
# bullet movement
if bullet_state is "fire":
firebullet(playerX, playerY)
for bullet in bullets:
screen.blit(bulletimg, (bullet[0], bullet[1])) # Print a bullet
bullet[0] -= bulletxchange # Updates its position
bullet[1] -= bulletychange
if bullet[1] < 0:
bullets.remove(bullet)
# collision
collision = iscollision(enemyX, enemyY, bulletX, bulletY)
if collision:
score += 1
player(playerX, playerY) # player method is called AFTER screen.fill otherwise the screen will fill after image has been blitted
enemy(enemyX, enemyY)
pygame.display.update() # necessary for events to keep updating
解决方案
您需要测试子弹的实际位置。使用 for 循环遍历列表中的所有项目符号。测试单个子弹是否与循环内的敌人相撞。当子弹与敌人发生碰撞时,将其从列表中删除。bullets[:]
出于这个原因,必须遍历列表 ( ) 的副本(请参阅如何在迭代时从列表中删除项目?):
while running:
# [...]
# collision
#collision = iscollision(enemyX, enemyY, bulletX, bulletY) DELETE
#if collision: DELETE
# score += 1 DELETE
# ADD
for bullet in bullets[:]:
collision = iscollision(enemyX, enemyY, bullet[0], bullet[1])
if collision:
score += 1
print(score)
bullets.remove(bullet)
如果你不移除子弹,它会在连续帧中多次击中敌人,分数会增加数倍。或者,您可以删除敌人或敌人和子弹。
使用pygame.Rect
对象和colliderect()
检测 2 个对象或 2 个图像的边界矩形之间的碰撞:(
请参阅如何在 pygame 中检测两个矩形对象或图像之间的碰撞)
def iscollision(enemyX, enemyY, bulletX, bulletY):
bullet_rect = bulletimg.get_rect(topleft = (bulletX, bulletY))
enemy_rect = enemyimg.get_rect(topleft = (enemyX, enemyY))
return bullet_rect.colliderect(enemy_rect)
推荐阅读
- typescript - TS:如何获取常量数组元素类型
- javascript - Mediawiki Hyperswitch:如果响应正文中的某个值等于变量,则返回
- javascript - 动态 Kendo UI Grid 可编辑日期时间列不使用值
- spring - 不支持GET方式,登录成功后显示,如何解决?
- html - 如何制作响应式水平尺
- python - 在python中添加简单的菜单
- c++ - Arduino 我如何存储最后一个 IR 代码以检查它是否需要重复?
- c# - 发布列表中缺少编号的列表
- reactjs - 使用打字稿时如何在props函数中声明一个react ref
- scipy - 为什么我无法成功扩展 scipy rv_discrete 类?