Как вызвать событие, если хотя бы один раунд в цикле for равен «True» - PullRequest
0 голосов
/ 31 октября 2018

Я делаю игру про космических захватчиков и уворачиваясь в пигмеях. У меня есть вещи, к которым вы можете прикоснуться, например, увеличить здоровье. Когда спрайт касается предмета здоровья, я хочу, чтобы фон на мгновение стал зеленым. Ниже то, что у меня есть на данный момент. Поскольку на экране одновременно отображается более 1 элемента, я проверяю каждый раз с помощью (строка 1). Вы можете видеть, что при касании зелья цвет заливки устанавливается на зеленый

Проблема в том, что если спрайт касается только 1 из 2 элементов на экране, фон будет установлен черным при проверке второго.

Как сделать так, чтобы при касании хотя бы 1 из 2 элементов фон становился зеленым?

EDIT: Я сделал вопрос слишком расплывчатым, боясь сделать его слишком длинным, поэтому здесь есть более подробная информация.

fillcolor - это переменная, которая устанавливает цвет фона окна. Существует три типа элементов, к которым можно прикоснуться, и одновременно может отображаться максимум 2 элемента независимо от типа элемента.

Это может быть немного длинно, но что идет не так: Используя цикл for, я проверяю 2 элемента на экране и проверяю, является ли предмет, который вы ударили, зельем, боеприпасом или «режимом лихорадки» (пункт усиления). Как вы видите, если это «зелье», ваше здоровье увеличивается, а если это «боеприпасы», то увеличивается количество боеприпасов. Например, если на экране есть два элемента, и вы касаетесь одного из них, который является зельем. Затем фон становится зеленым, однако в следующем раунде цикла for при проверке второго элемента цвет заливки мгновенно становится черным, потому что вы не касаетесь обоих элементов, только одного из них. Что нужно сделать, так это сделать фон зеленым, если вы касаетесь одного из них, даже если второй не касается.

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 голосов
/ 31 октября 2018

Это происходит, когда вы изобретаете свою собственную функцию обнаружения столкновений вместо использования методов обнаружения столкновений в 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)

Прямоугольник также необходимо перемещать при обновлении позиций.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...