.colliderect无法正常工作;为什么x和y不更新?

时间:2019-07-13 04:46:00

标签: python python-3.x pygame

我目前正在制作一款游戏,您可以像熊一样跑来跑去,收集鱼,并获得积分。但是,当熊碰到鱼时,它不会捡起它,因为熊碰到了鱼。

我试图让函数在制作鱼的某些循环中运行,甚至使其成为一个函数,但似乎不起作用。

global screen, grasspic, bearImg, fishpic, screen_width, screen_height, score_number, bearRect
import random
import pygame
import sys
import time
import math
pygame.init()

screen_width = 640
screen_height = 480
sw2 = screen_width/2
sh2 = screen_height/2

bearImg = pygame.image.load('bear.png')
bearImg = pygame.transform.scale(bearImg, (150,150))

green = (24, 255, 0)

bearImg_width = 150

def text_objects(text, font):
    textSurface = font.render(text, True, (0,0,0))
    return textSurface, textSurface.get_rect()

def message_display(text):
    clocktxt = pygame.font.Font('freesans.ttf', 20)
    TextSurf, TextRect = text_objects(text, clocktxt)
    TextRect.center = (55, 15)
    screen.blit(TextSurf, TextRect)
    pygame.display.update()

white = (255, 255, 255)
black = (0,0,0)
#NOTE: DOWNLOAD FISH, BEAR, AND GRASS PICTURES|| IT WILL NOT WORK WITHOUT IT
grasspic = []
for i in range(1, 5):
    grasspic.append(pygame.image.load('grass%s.png' % i))
fishpic = []
for i in range(1, 3):
    fishpic.append(pygame.image.load('fish%s.png' % i))

fishpic[0] = pygame.transform.scale(fishpic[0], (50,50))
fishpic[1] = pygame.transform.scale(fishpic[1], (50,50))

screen = pygame.display.set_mode((screen_width,screen_height))
pygame.display.set_caption('Hungry Boi') 
clock = pygame.time.Clock()

camerax = 0
cameray = 0

def getRandomOffCameraPos(camerax, cameray, objWidth, objHeight):
    cameraRect = pygame.Rect(camerax, cameray, screen_width, screen_height)
    while True:
        x = random.randint(camerax - screen_width, camerax + (2*screen_width))
        y = random.randint(cameray - screen_height, cameray + (2*screen_height))
        objRect = pygame.Rect(x, y, objWidth, objHeight)
        if not objRect.colliderect(cameraRect):
            return x, y

def makeNewGrass(camerax, cameray):
    gr = {}
    gr['grassImage'] = random.randint(0, len(grasspic) - 1)
    gr['width'] = 80
    gr['height'] = 80
    gr['x'], gr['y'] = getRandomOffCameraPos(camerax, cameray, gr['width'], gr['height'])
    gr['rect'] = pygame.Rect((gr['x'], gr['y'], gr['width'], gr['height']))
    return gr

def makeNewFish(camerax, cameray):
    fi = {}
    fi['fishImage'] = random.randint(0, len(fishpic) - 1)
    fi['width'] = 150
    fi['height'] = 150
    fi['x'], fi['y'] = getRandomOffCameraPos(camerax, cameray, fi['width'], fi['height'])
    fi['rect'] = pygame.Rect((fi['x'], fi['y'], fi['width'], fi['height']))
    return fi

def bear(x,y):
    screen.blit(bearImg,(x,y))

allgrass = []
def makegrass():    
    for i in range(15):
                    allgrass.append(makeNewGrass(camerax, cameray))
                    allgrass[i]['x'] = random.randint(0, screen_width)
                    allgrass[i]['y'] = random.randint(0, screen_height)
makegrass()

allfish = []
def makefish():
    for i in range(2):
            allfish.append(makeNewFish(camerax, cameray))
            allfish[i]['x'] = random.randint(0, screen_width)
            allfish[i]['y'] = random.randint(0, screen_height)

makefish()

def game_loop():
    x = (screen_width * 0.4)
    y = (screen_height * 0.4)

    STARTINGX = (screen_width * 0.4)
    STARTINGY = (screen_height * 0.4)

    x_change = 0
    y_change = 0
    vel = 5

    gameExit = False

    while not gameExit:

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                gameExit = True

            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_LEFT:
                    x_change -= vel
                    STARTINGX -= vel
                elif event.key == pygame.K_RIGHT:
                    x_change += vel
                    STARTINGX += vel
                elif event.key == pygame.K_UP:
                    y_change -= vel
                    STARTINGY -= vel
                elif event.key == pygame.K_DOWN:
                    y_change += vel
                    STARTINGY += vel


            if event.type == pygame.KEYUP:
                if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
                    x_change = 0
                elif event.key == pygame.K_UP or event.key == pygame.K_DOWN:
                    y_change = 0


            #print (event) #see events, basically a console, makes a mess
        x += x_change
        y += y_change

        screen.fill(green)

        bearRect = pygame.Rect((STARTINGX, STARTINGY, STARTINGX+150, STARTINGY+150))


        for grass in allgrass:
                    gRect = pygame.Rect((grass['x'] - camerax,
                                grass['y'] - cameray,
                                grass['width'],
                                grass['height']))
                    screen.blit(grasspic[grass['grassImage']], gRect)
        for fish in allfish:
            fRect = pygame.Rect((fish['x'] - camerax,
                        fish['y'] - cameray,
                        fish['width'],
                        fish['height']))
            screen.blit(fishpic[fish['fishImage']], fRect)

        bear(x,y)
        score_count()

        if bearRect.colliderect(fRect):
            makefish()
            makegrass()

        pygame.display.update()
        clock.tick(30) #fps//may not be safe to run really fast

def score_count():
    score_number = 0
    message_display("Score is: " + str(score_number))

game_loop()
pygame.quit()
quit

代码不会发生碰撞并使草和鱼的图像再次随机出现在屏幕上,而是将忽略整个碰撞。有没有办法修复它,让它知道熊和鱼在哪里正确?

谢谢

1 个答案:

答案 0 :(得分:0)

现在它可以正常工作,但是我进行了很多更改,以至于难以描述。

代码没有删除鱼肉,也没有改变得分,因此很难说是否检查了碰撞。现在,它删除了鱼(并在新位置添加了新鱼)并更改了分数。

代码将位置和大小保留在Rect中,并且每个项目仅使用一个Rect。我的旧代码Bear有两个矩形-一个用于检查碰撞,另一个用于碰撞。

在某些函数中,我更改了名称以表明它们非常相似,并且可能是一个函数。

每个对象都有imagerect。阅读pygame.sprite.Sprite的文档时,您会发现它也使用imagerect

import random
import pygame
import sys
import time
import math

# --- constants --- (UPPER_CASE_NAMES)

GREEN = (24, 255, 0)
WHITE = (255, 255, 255)
BLACK = (0,0,0)

SCREEN_WIDTH = 640
SCREEN_HEIGHT = 480
SW2 = SCREEN_WIDTH/2
SH2 = SCREEN_HEIGHT/2

# --- functions ---

def text_objects(text, font):
    surface = font.render(text, True, BLACK)
    return surface, surface.get_rect()

def message_display(text):
    surface, rect = text_objects(text, CLOCKTXT)
    rect.center = (55, 15)
    screen.blit(surface, rect)
    #pygame.display.update() # use update() olny in one place

def getRandomOffCameraPos(camerax, cameray, objWidth, objHeight):
    camera_rect = pygame.Rect(camerax, cameray, SCREEN_WIDTH, SCREEN_HEIGHT)
    x1 = camerax - SCREEN_WIDTH
    x2 = camerax + (2*SCREEN_WIDTH)
    y1 = cameray - SCREEN_HEIGHT
    y2 = cameray + (2*SCREEN_HEIGHT)
    while True:
        x = random.randint(x1, x2)
        y = random.randint(y1, y2)
        obj_rect = pygame.Rect(x, y, objWidth, objHeight)
        if not obj_rect.colliderect(camera_rect):
            return x, y

def makeNewGrass(camerax, cameray):
    w, h = 80, 80
    x, y = getRandomOffCameraPos(camerax, cameray, w, h)
    images = grasspic
    item = {
        'image': random.choice(images),
        'rect': pygame.Rect(x, y, w, h),
    }
    return item

def makeNewFish(camerax, cameray):
    w, h = 50, 50
    x, y = getRandomOffCameraPos(camerax, cameray, w, h)
    images = fishpic
    item = {
        'image': random.choice(images),
        'rect': pygame.Rect(x, y, w, h),
    }
    return item

def makegrass(number=15):    
    for i in range(number):
        item = makeNewGrass(camerax, cameray)
        item['rect'].x = random.randint(0, SCREEN_WIDTH-item['rect'].width)
        item['rect'].y = random.randint(0, SCREEN_HEIGHT-item['rect'].height)
        allgrass.append(item)

def makefish(number=2):
    for i in range(number):
        item = makeNewFish(camerax, cameray)
        item['rect'].x = random.randint(0, SCREEN_WIDTH-item['rect'].width)
        item['rect'].y = random.randint(0, SCREEN_HEIGHT-item['rect'].height)
        allfish.append(item)

def score_draw(score):
    message_display("Score is: " + str(score))

#--- main ---

pygame.init()

screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption('Hungry Boi') 

CLOCKTXT = pygame.font.Font('freesans.ttf', 20)

# ---

bear_img = pygame.image.load('bear.png').convert()
bear_img = pygame.transform.scale(bear_img, (150, 150)).convert()
bear_rect = bear_img.get_rect()
bear_rect.x = SCREEN_WIDTH * 0.4
bear_rect.y = SCREEN_HEIGHT * 0.4
bear_vel = 5

grasspic = []
for i in range(1, 5):
    image = pygame.image.load('grass%s.png' % i).convert()
    grasspic.append(image)

fishpic = []
for i in range(1, 3):
    image = pygame.image.load('fish%s.png' % i).convert()
    image = pygame.transform.scale(image, (50, 50)).convert()
    fishpic.append(image)

# ---

allgrass = []
makegrass()

allfish = []
makefish()

x_change = 0
y_change = 0

camerax = 0
cameray = 0

score = 0

# --- mainloop ---

gameExit = False
clock = pygame.time.Clock()

while not gameExit:

    # --- events ---

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            gameExit = True

        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT:
                x_change -= bear_vel
            elif event.key == pygame.K_RIGHT:
                x_change += bear_vel
            elif event.key == pygame.K_UP:
                y_change -= bear_vel
            elif event.key == pygame.K_DOWN:
                y_change += bear_vel

        if event.type == pygame.KEYUP:
            if event.key == pygame.K_LEFT:
                x_change += bear_vel
            elif event.key == pygame.K_RIGHT:
                x_change -= bear_vel
            elif event.key == pygame.K_UP:
                y_change += bear_vel
            elif event.key == pygame.K_DOWN:
                y_change -= bear_vel

    # --- updates ---

    bear_rect.x += x_change
    bear_rect.y += y_change

    keep_fish = []
    for fish in allfish:
        if not bear_rect.colliderect(fish['rect']):
            keep_fish.append(fish)
        else:
            makefish(1)
            #makegrass()
            score += 1
    allfish = keep_fish

    # --- draws ---

    screen.fill(GREEN)

    for grass in allgrass:
        screen.blit(grass['image'], grass['rect'].move(camerax, cameray))

    for fish in allfish:
        screen.blit(fish['image'], fish['rect'].move(camerax, cameray))

    screen.blit(bear_img, bear_rect.move(camerax, cameray))
    score_draw(score)


    pygame.display.update()

    # --- FPS ---

    clock.tick(30) #fps//may not be safe to run really fast

# --- end ---

pygame.quit()