我正在pygame中制作一款太空入侵者/躲避游戏。我有一些您可以触摸的项目,例如增加健康。当精灵接触到健康项目时,我希望背景暂时变为绿色。 以下是我目前所拥有的。由于我一次在屏幕上有多个项目,因此我每次使用(第1行)进行检查。您会看到,在触摸药水时,fillcolor设置为绿色
问题是,如果精灵仅触摸屏幕上2个项目中的1个,则在检查第二个项目时背景将设置为黑色。
如何做到这一点,如果至少触摸了2个项目中的1个,背景就会变成绿色?
编辑: 由于担心时间过长,我使这个问题过于含糊,所以这里有更多详细信息。
fillcolor
是设置窗口背景颜色的变量。您可以触摸三种类型的项目,无论哪种类型,一次最多可以显示2个项目。
这可能有点长,但是出了什么问题: 通过使用for循环,我正在检查屏幕上的2个项目,并检查您击中的项目是药水,弹药还是“发烧模式”(加电项目)。如您所见,如果它是“药水”,则您的健康状况得到了提高;如果是“弹药”,则您的弹药数正在增加。例如,如果屏幕上有两项,而您正在触摸其中一项,那是一种药水。然后背景变成绿色,但是在检查第二个项目时,在for循环的下一轮中,fillcolor会立即变为黑色,因为您没有同时触摸两个项目,只有其中一个项目。要做的是,即使您未触摸第二个背景,也要使其变成绿色。
for e in items:
ship.checkItemCollision(e, ship)
if ship.checkItemCollision(e, ship) == 'potion':
print('potion')
ship.health += 0.5
fillcolor = (0, 255, 0)
touchDatItem = True
elif ship.checkItemCollision(e, ship) == 'ammo':
print('ammo')
ammoCount += 1
fillcolor = (255, 255, 0)
touchDatItem = True
elif ship.checkItemCollision(e, ship) == 'fever':
print('fever')
feverMode = True
fillcolor = (255, 0, 0)
touchDatItem = True
elif not touchDatItem:
fillcolor = black
这是整个代码:
import pygame as pg
import time
import random
import math
pg.init()
display_width = 800
display_height = 600
black = (0, 0, 0)
white = (255, 255, 255)
red = (200, 0, 0)
bllue = (0, 0, 255)
green = (0, 200, 0)
bright_red =(255, 0, 20)
bright_green = (0, 255, 0)
yellow = (255,255,0)
dark_yellow = (150, 150, 0)
clock = pg.time.Clock()
potion = pg.image.load('revive.png')
ammo = pg.image.load('ammo.png')
fever = pg.image.load('fever.png')
gameDisplay = pg.display.set_mode((display_width, display_height))
pg.display.set_caption('Object Oriented')
class Item:
def __init__(self):
self.items = [potion, potion, potion, ammo, ammo,ammo, ammo, ammo, fever, fever, fever, fever, fever, fever, fever, fever, fever, fever, fever, fever, fever, ]
self.images = potion
self.speed = 3
self.width = 30
self.height = 30
self.x = 30
self.y = random.randrange(-1000, -300)
def move(self):
self.y += self.speed
if self.y > display_height:
self.x = random.randrange(0, (display_width - self.width))
self.y = random.randrange(-5000, -1000)
self.images = random.choice(self.items)
def draw(self):
gameDisplay.blit(self.images, (self.x, self.y))
class Thing:
def __init__(self):
self.width = 20
self.height = 20
self.x = random.randrange(0, (display_width - self.width))
self.y = random.randrange(-500, 0)
self.speedY = 3
self.speedX = 3
self.color = bright_red
self.ratio = random.randrange(-3, 3)
def move(self, count):
if self.ratio == 0:
self.y += self.speedY
else:
self.y += self.speedY
## self.x += random.randint(-5, 5)
self.x += self.ratio
if self.y > display_height:
self.x = random.randrange(0, (display_width - self.width))
self.y = random.randrange(-500, 0)
self.ratio = random.randrange(-3, 3)
return True
def draw(self):
pg.draw.rect(gameDisplay, self.color, [self.x, self.y, self.height, self.width])
## def randomizeX(self):
## self.x = random.randrange(0, (display_width - self.width))
## def resetY(self):
## self.y = 05
##def checkQuit():
## for event in pg.event.get():
## if event.type == pg.QUIT:
## pg.quit()
## quit()
class Ship:
def __init__(self):
self.x = display_width / 2
self.y = display_height / 2
self.speed = 10
self.height = 20
self.width = 20
self.color = yellow
self.changeX = 0
self.changeY = 0
self.health = 100
## def move(self, event):
##
## if event.type == pg.KEYDOWN:
## print(event.key)
## if event.key == pg.K_LEFT:
## self.change = -(self.speed)
## if event.key == pg.K_RIGHT:
## self.change = self.speed
## if event.type == pg.KEYUP:
## if event.key == pg.K_LEFT or event.key == pg.K_RIGHT:
## self.change = 0
## self.x += self.change
def draw(self):
pg.draw.rect(gameDisplay, self.color, [self.x, self.y, self.height, self.width])
def moveShip(self, event):
if event.type == pg.KEYDOWN:
## print(self.changeY)
## print(self.changeX)
if event.key == pg.K_LEFT:
self.changeX = -(self.speed)
if event.key == pg.K_RIGHT:
self.changeX = self.speed
if event.key == pg.K_UP:
self.changeY = -(self.speed)
if event.key == pg.K_DOWN:
self.changeY = self.speed
if event.type == pg.KEYUP:
if event.key == pg.K_LEFT or event.key == pg.K_RIGHT or event.key == pg.K_UP or event.key == pg.K_DOWN:
self.changeX = 0
self.changeY = 0
def testWallCollision(self):
if self.x > (display_width - self.width) or self.x < 0:
self.health = self.health/2
def checkThingCollision(self, t, ship, fillcolor, red, count):
# if thing_starty < (y + car_height) and y < (thing_starty+thing_height):
if (t.y - (t.height/2)) < (ship.y + ship.height) and ship.y < ((t.y - (t.height/2)) + t.height):
if (self.x > t.x and self.x < (t.x + t.width) or ((self.x + t.width) > t.x and (self.x + t.width) < t.x + t.width)):
self.health -= 0.5
t.x = random.randrange(0, (display_width - t.width))
t.y = random.randrange(-500, 0)
t.ratio = random.randrange(-10, 10)
def checkItemCollision(self, e, ship):
if e.y < (ship.y + ship.height) and ship.y < (e.y + e.height):
if (self.x > e.x and self.x < (e.x + e.width) or ((self.x + e.width) > e.x and (self.x + e.width) < e.x + e.width)):
if e.images == potion:
return 'potion'
elif e.images == ammo:
return 'ammo'
elif e.images == fever:
return 'fever'
class Bullet:
def __init__(self, ship):
self.speed = 20
self.color = white
self.x = ship.x + (ship.width / 2)
self.y = ship.y + (ship.width / 2)
self.height = 5
self.width = 5
def draw(self):
## print('IN DRAAAAAW')
## if event.key == pg.K_SPACE:
pg.draw.rect(gameDisplay, self.color, [self.x, self.y, self.height, self.width])
def move(self, ship):
self.y -= self.speed
## if self.y < 0:
## self.x = ship.x + (ship.width / 2)
## self.y = ship.y + (ship.width / 2)
def checkCollision(self, t, ship, count):
if t.y < (self.y + self.height) and self.y < (t.y + t.height):
if (self.x > t.x and self.x < (t.x + t.width) or ((self.x + t.width) > t.x and (self.x + t.width) < t.x + t.width)):
t.x = random.randrange(0, (display_width - t.width))
t.y = random.randrange(-500, 0)
t.ratio = random.randrange(-10, 10)
self.y = -self.height
return True
def healthNum(health, color):
font = pg.font.SysFont(None, 25)
text = font.render('health:' + str(health) + '/100', True, color)
gameDisplay.blit(text, (500, 0))
def ammoNum(ammoCount, color):
font = pg.font.SysFont(None, 25)
text = font.render('ammo:' + str(ammoCount), True, color)
gameDisplay.blit(text, (300, 0))
def things_dodged(count):
font = pg.font.SysFont(None, 25)
text = font.render('score: ' + str(count), True, white)
gameDisplay.blit(text, (0, 0))
def main_loop():
touchDatItem = False
feverTimer = 0
gameExit = False
allItems = [potion, ammo]
things = []
ship = Ship()
bullets = []
fillcolor = black
count = 0
items = []
ammoCount = 20
FEVER = False
LIST = []
feverMode = False
for t in range (30):
things.append(Thing())
for e in range(2):
items.append(Item())
while not gameExit:
print(fillcolor)
for event in pg.event.get():
if event.type == pg.QUIT:
pg.quit()
quit()
ship.moveShip(event)
if event.type == pg.KEYDOWN:
if event.key == pg.K_SPACE:
## FEVER = True
if ammoCount > 0:
bullets.append(Bullet(ship))
if not feverMode:
ammoCount -= 1
if feverMode:
FEVER = True
else:
FEVER = False
if event.type == pg.KEYUP:
if event.key == pg.K_SPACE:
FEVER = False
if FEVER == True:
feverTimer += 1
if not feverTimer > 100:
if ammoCount > 0:
bullets.append(Bullet(ship))
else:
print('STAAAAAAAAAP')
FEVER = False
feverTimer = 0
feverMode = False
ship.x += ship.changeX
ship.y += ship.changeY
ship.testWallCollision()
gameDisplay.fill(fillcolor)
LIST = []
healthNum(ship.health, white)
ammoNum(ammoCount, white)
for t in things:
ship.checkThingCollision(t, ship, fillcolor, red, count)
if ship.checkThingCollision(t, ship, fillcolor, red, count) == True:
print('###########################')
ship.color = red
else:
ship.color = yellow
t.draw()
ship.draw()
t.move(count)
if t.move(count) == True:
count+= 1
for b in bullets:
b.draw()
for t in things:
b.checkCollision(t, ship, count)
if b.checkCollision(t, ship, count) == True:
count += 10
b.move(ship)
for e in items:
ship.checkItemCollision(e, ship)
if ship.checkItemCollision(e, ship) == 'potion':
LIST.append('potion')
print('potion')
ship.health += 0.5
touchDatItem = True
elif ship.checkItemCollision(e, ship) == 'ammo':
LIST.append('ammo')
print('ammo')
ammoCount += 1
touchDatItem = True
elif ship.checkItemCollision(e, ship) == 'fever':
LIST.append('fever')
print('fever')
feverMode = True
touchDatItem = True
if 'potion' in LIST:
fillcolor = (0, 255, 0)
elif 'ammo' in LIST:
fillcolor = (255, 255, 0)
elif 'fever' in LIST:
fillcolor = (255, 0, 0)
else:
fillcolor = black
e.draw()
e.move()
print('fillcolor = ' + str(fillcolor))
if ship.health < 1:
ship.health = 0
pg.quit()
quit()
things_dodged(count)
pg.display.update()
clock.tick(60)
pg.quit()
quit()
main_loop()
答案 0 :(得分:0)
当您发明自己的碰撞检测功能而不是使用pygame的碰撞检测方法时,就会发生这种情况。 ;)您的checkItemCollision
方法不正确。
更改此行...
if (self.x > e.x and self.x < (e.x + e.width) or ((self.x + e.width) > e.x and (self.x + e.width) < e.x + e.width)):
对此:
if (self.x > e.x and self.x < e.x + e.width or self.x + self.width > e.x and self.x + self.width < e.x + e.width):
我现在还不确定100%是否正确。我会给您的对象一个self.rect
属性,并将其用于碰撞检测,例如:
# In __init__:
self.rect = pg.Rect(self.x, self.y, self.width, self.height)
# Then check if they collide with the `colliderect` method.
self.rect.colliderect(e.rect)
更新位置时也需要移动矩形。