当for循环中至少有一个回合为“ True”时,如何触发事件

时间:2018-10-30 21:27:23

标签: python pygame

我正在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()

1 个答案:

答案 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)

更新位置时也需要移动矩形。