Saya baru mengenal pygame dan python, dan saya baru saja membuat game "Dodger" sederhana. Saya telah membuat menu utama dengan beberapa tombol.

Menu utama saya:

# show the start screen
done=False
while not done:
    screen.fill(black)
    text_width,text_height=font.size("Dodger")
    #a function for drawing text
    drawText('Dodger', font, screen, (screen_width / 2-(text_width/2)), (screen_height / 2-200))
    font = pygame.font.SysFont(None, 45)
    start_button=button(screen_width/2-125,175,250,50,white,black,'Start')
    start_button.draw()
    instructions_button=button(screen_width/2-125,250,250,50,white,black,'Instructions')
    instructions_button.draw()
    back_button=button(screen_width/2-125,325,250,50,white,black,'Back')
    back_button.draw()
    pygame.display.flip()

Saya juga memiliki kelas tombol:

class button(object):
    def __init__(self,x,y,width,height,text_color,background_color,text):
        self.rect=pygame.Rect(x,y,width,height)
        self.image=pygame.draw.rect(screen, background_color,(self.rect),)
        self.x=x
        self.y=y
        self.width=width
        self.height=height
        self.text=text
        self.text_color=text_color

    def check(self):
        return self.rect.collidepoint(pygame.mouse.get_pos())

    def draw(self):
        drawText(self.text,font,screen,self.x+self.width/2,self.y+self.height/2,self.text_color)  
        pygame.draw.rect(screen,self.text_color,self.rect,3) 

Dua tombol berfungsi, tetapi yang ketiga tidak merespons.

Kode saya terlihat seperti ini:

#show start screen
done=False
while not done:
    screen.fill(black)
    text_width,text_height=font.size("Dodger")
    drawText('Dodger', font, screen, (screen_width / 2-(text_width/2)), (screen_height / 2-200))
    font = pygame.font.SysFont(None, 45)
    #the start button starts the game
    start_button=button(screen_width/2-125,175,250,50,white,black,'Start')
    start_button.draw()
    #my button that is not working
    instructions_button=button(screen_width/2-125,250,250,50,white,black,'Instructions')
    instructions_button.draw()
    #go back to game selection
    back_button=button(screen_width/2-125,325,250,50,white,black,'Back')
    back_button.draw()
    pygame.display.flip()
    while not done:
        for event in pygame.event.get():
                if event.type==QUIT:
                    terminate()
                elif event.type == pygame.MOUSEBUTTONDOWN:
                    if start_button.check()==True:
                            #main game code
                    if instructions_button.check()==True:
                            #show instructions
                    if back_button.check()==True:
                            #go back to game selection

Namun, tombol "instruksi" saya tidak berfungsi, meskipun dua lainnya berfungsi.

Kode:

elif instructions_button.check()==True:
screen.fill(black)
drawText('some instructions',font,screen,screen_width/2-127.5, 185)
back_button.draw()
done=False
while not done:
for event in pygame.event.get():
    if event.type==QUIT:
        terminate()
    elif back_button.check()==True:
        done=True     

Masalahnya adalah ketika saya mengklik tombol, layar tidak mengisi (screen.fill(black) atau menggambar teks saya (drawText('some instructions',font,screen,screen_width/2-127.5, 185)).

Dalam upaya saya untuk men-debugnya, saya menempatkan berbagai print('hello') untuk melihat mengapa itu tidak berfungsi:

elif instructions_button.check()==True:
    print('hello')
    screen.fill(black)
    print('hello')
    drawText('some instructions',font,screen,screen_width/2-127.5, 185)
    back_button.draw()
    done=False
    while not done:
    for event in pygame.event.get():
        if event.type==QUIT:
            terminate()
        elif back_button.check()==True:
            done=True 

Itu dicetak tetapi tidak mengisi layar dengan warna hitam.

Semua bantuan dihargai!

Kode lengkap:

import pygame,sys,os,random
from pygame.locals import *
from cPickle import load
from asyncore import write

#initalize pygame
pygame.init()

#define colors
black=(0,0,0)
white=(255,255,255)

def terminate():
    pygame.quit()
    sys.exit()

def drawText(text,font,screen,x,y,color):
    textobj=font.render(text,True,color)
    textrect=textobj.get_rect(center=(x,y))
    screen.blit(textobj,textrect)

class button(object):
    def __init__(self,x,y,width,height,text_color,background_color,text):
        self.rect=pygame.Rect(x,y,width,height)
        self.image=pygame.draw.rect(screen, background_color,(self.rect),)
        self.x=x
        self.y=y
        self.width=width
        self.height=height
        self.text=text
        self.text_color=text_color

    def check(self):
        return self.rect.collidepoint(pygame.mouse.get_pos())

    def draw(self):
        drawText(self.text,font,screen,self.x+self.width/2,self.y+self.height/2,self.text_color)  
        pygame.draw.rect(screen,self.text_color,self.rect,3) 

def dodger(screen,clock):
    global button
    #define variables
    white=(255,255,255)
    black=(0,0,0)
    fps=40
    baddieminsize=10
    baddiemaxsize=40
    baddieminspeed=1
    baddiemaxspeed=8
    addnewbaddierate=6
    player_speed=5

    def terminate():
        pygame.quit()
        sys.exit()

    def waitForPlayerToPressKey():
        while True:
            for event in pygame.event.get():
                if event.type==QUIT:
                    terminate()
                if event.type==KEYDOWN:
                    if event.key==K_ESCAPE: # pressing escape quits
                        terminate()
                    return

    def playerHasHitBaddie(playerRect, baddies):
        for b in baddies:
            if playerRect.colliderect(b['rect']):
                return True
        return False

    def drawText(text, font, surface, x, y):
        textobj = font.render(text, 1, white)
        textrect = textobj.get_rect()
        textrect.topleft = (x, y)
        surface.blit(textobj, textrect)

    def load_hs():
        try:
            f = open("dodger_hs.txt","rb")
            hs = int(f.read())
            f.close()
            return hs
        except:
            return 0
    def write_hs(hs):
        f = open("dodger_hs.txt","wb")
        f.write(str(hs).encode())
        f.close()

    # set up fonts
    font = pygame.font.SysFont(None, 90)

    # set up images
    playerImage = pygame.image.load('player.png')
    playerRect = playerImage.get_rect()
    baddieImage = pygame.image.load('baddie.png')

    # show the start screen
    done=False
    while not done:
        screen.fill(black)
        text_width,text_height=font.size("Dodger")
        drawText('Dodger', font, screen, (screen_width / 2-(text_width/2)), (screen_height / 2-200))
        font = pygame.font.SysFont(None, 45)
        start_button=button(screen_width/2-125,175,250,50,white,black,'Start')
        start_button.draw()
        instructions_button=button(screen_width/2-125,250,250,50,white,black,'Instructions')
        instructions_button.draw()
        back_button=button(screen_width/2-125,325,250,50,white,black,'Back')
        back_button.draw()
        pygame.display.flip()
        while not done:
            for event in pygame.event.get():
                    if event.type==QUIT:
                        terminate()
                    elif event.type == pygame.MOUSEBUTTONDOWN:
                        if start_button.check()==True:
                                while not done:
                                    # set up the start of the game
                                    baddies = []
                                    score = 0
                                    playerRect.topleft = (screen_width / 2, screen_height- 50)
                                    moveLeft = moveRight = moveUp = moveDown = False
                                    reverseCheat = slowCheat = False
                                    baddieAddCounter = 0
                                    high_score=load_hs()

                                    while True: # the game loop runs while the game part is playing
                                        score += 1 # increase score

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

                                            if event.type == KEYDOWN:
                                                if event.key == ord('z'):
                                                    reverseCheat = True
                                                if event.key == ord('x'):
                                                    slowCheat = True
                                                if event.key == K_LEFT or event.key == ord('a'):
                                                    moveRight = False
                                                    moveLeft = True
                                                if event.key == K_RIGHT or event.key == ord('d'):
                                                    moveLeft = False
                                                    moveRight = True
                                                if event.key == K_UP or event.key == ord('w'):
                                                    moveDown = False
                                                    moveUp = True
                                                if event.key == K_DOWN or event.key == ord('s'):
                                                    moveUp = False
                                                    moveDown = True

                                            if event.type == KEYUP:
                                                if event.key == ord('z'):
                                                    reverseCheat = False
                                                if event.key == ord('x'):
                                                    slowCheat = False
                                                if event.key == K_ESCAPE:
                                                        terminate()

                                                if event.key == K_LEFT or event.key == ord('a'):
                                                    moveLeft = False
                                                if event.key == K_RIGHT or event.key == ord('d'):
                                                    moveRight = False
                                                if event.key == K_UP or event.key == ord('w'):
                                                    moveUp = False
                                                if event.key == K_DOWN or event.key == ord('s'):
                                                    moveDown = False

                                        # Add new baddies at the top of the screen, if needed.
                                        if not reverseCheat and not slowCheat:
                                            baddieAddCounter += 1
                                        if baddieAddCounter == addnewbaddierate:
                                            baddieAddCounter = 0
                                            baddieSize = random.randint(baddieminsize, baddiemaxsize)
                                            newBaddie = {'rect': pygame.Rect(random.randint(0, screen_width-baddieSize), 0 - baddieSize, baddieSize, baddieSize),
                                                        'speed': random.randint(baddieminspeed, baddiemaxspeed),
                                                        'surface':pygame.transform.scale(baddieImage, (baddieSize, baddieSize)),
                                                        }

                                            baddies.append(newBaddie)

                                        # Move the player around.
                                        if moveLeft and playerRect.left > 0:
                                            playerRect.move_ip(-1 * player_speed, 0)
                                        if moveRight and playerRect.right < screen_width:
                                            playerRect.move_ip(player_speed, 0)
                                        if moveUp and playerRect.top > 0:
                                            playerRect.move_ip(0, -1 * player_speed)
                                        if moveDown and playerRect.bottom < screen_height:
                                            playerRect.move_ip(0, player_speed)

                                        # Move the baddies down.
                                        for b in baddies:
                                            if not reverseCheat and not slowCheat:
                                                b['rect'].move_ip(0, b['speed'])
                                            elif reverseCheat:
                                                b['rect'].move_ip(0, -5)
                                            elif slowCheat:
                                                b['rect'].move_ip(0, 1)

                                        # Delete baddies that have fallen past the bottom.
                                        for b in baddies[:]:
                                            if b['rect'].top > screen_height:
                                                baddies.remove(b)

                                        if score>=high_score:
                                            high_score=score

                                        # Draw the game world on the window.
                                        screen.fill(black)

                                        # Draw the player's rectangle
                                        screen.blit(playerImage, playerRect)

                                        # Draw each baddie
                                        for b in baddies:
                                            screen.blit(b['surface'], b['rect'])

                                        # Draw the score
                                        drawText('Score: %s' % (score), font, screen, 10, 0)
                                        drawText('High Score: %s' % (high_score), font, screen, 10, 30)

                                        pygame.display.update()

                                        # Check if any of the baddies have hit the player.
                                        if playerHasHitBaddie(playerRect, baddies):
                                            break

                                        clock.tick(fps)

                                    write_hs(high_score)
                                    screen.fill(black)
                                    if score<100:   
                                        drawText('Your Score: %s' % (score), font,screen,screen_width/2-107.5, 185)
                                    if score<1000 and score>99:
                                        drawText('Your Score: %s' % (score), font,screen,screen_width/2-117.5, 185)
                                    if score<10000 and score>999:
                                        drawText('Your Score: %s' % (score), font,screen,screen_width/2-127.5, 185)
                                    if score<100000 and score>9999:
                                        drawText('Your Score: %s' % (score), font,screen,screen_width/2-127.5, 185)
                                    font = pygame.font.SysFont(None, 90)
                                    text_width,text_height=font.size("Game Over")
                                    drawText('Game Over', font, screen, (screen_width / 2-(text_width/2)), (screen_height / 2-200))
                                    font = pygame.font.SysFont(None, 45)
                                    retry_button=button(screen_width/2-125,250,250,50,white,black,'Retry')
                                    retry_button.draw()
                                    back_button.draw()
                                    pygame.display.flip()
                                    back=False 
                                    while not back:
                                        for event in pygame.event.get():
                                                if event.type==QUIT:
                                                    terminate()
                                                elif event.type == pygame.MOUSEBUTTONDOWN:
                                                    if retry_button.check()==True:
                                                        back=True
                                                    if back_button.check()==True:
                                                        back=True
                                                        done=True
                        elif instructions_button.check()==True:
                            screen.fill(black)
                            drawText('Your Score:', font,screen,screen_width/2-127.5, 185)
                            back_button.draw()
                            done=False
                            while not done:
                                for event in pygame.event.get():
                                        if event.type==QUIT:
                                            terminate()
                                        elif back_button.check()==True:
                                            done=True                               
                        elif back_button.check()==True:
                            done=True


#define other varibles           
clock=pygame.time.Clock()
font=pygame.font.SysFont(None,40)
done=False

#set up screen
screen_width=600
screen_height=600
screen=pygame.display.set_mode([screen_width,screen_height])
pygame.display.set_caption('The Arcade')

#set up buttons
dodger_button=button(25,75,125,50,white,black,'Dodger')

#main loop
while not done:
    for event in pygame.event.get():
            if event.type==QUIT:
                terminate()
            elif event.type == pygame.MOUSEBUTTONDOWN:
                if dodger_button.check():
                    dodger(screen, clock)

    #fill screen with background
    screen.fill(black)

    #draw buttons
    dodger_button.draw()

    #draw text
    drawText('The Arcade', font, screen, screen_width/2, 25, white)

    #change display
    pygame.display.flip()
    clock.tick(15)

terminate()
2
gnawydna 2 Januari 2018, 19:59

1 menjawab

Jawaban Terbaik

Masalahnya adalah karena Anda tidak menggunakan pygame.display.update()

Semua fungsi menarik buffer di memori RAM dan update()/flip() mengirimkan data dari buffer di memori ke buffer di kartu video yang menampilkannya di layar. Ini disebut "Double Buffering" dan digunakan sebagai solusi untuk gambar berkedip/sobek.

enter image description here


BTW: Anda juga lupa MOUSEBUTTONDOWN jadi tombol Back "diklik" saat mouse menyentuh tombol tanpa menggunakan tombol mouse.

Masalah lain - Anda menggunakan variabel done untuk keluar dari "instruksi" tetapi variabel yang sama mengontrol loop while eksternal sehingga keluar dari permainan. Anda harus menggunakan variabel yang berbeda. Jika Anda akan menggunakan fungsi di dalam ini maka itu tidak akan membuat masalah dan kode akan lebih terorganisir.

Anda tidak perlu menggunakan ==True untuk memeriksanya.

Tapi Anda bisa menggunakan spasi di sekitar == dan setelah , untuk membuat kode lebih mudah dibaca.
Lihat: PEP 8 -- Panduan Gaya untuk Kode Python

 elif instructions_button.check():
      screen.fill(black)
      drawText('Your Score:', font, screen, screen_width/2-127.5, 185)
      back_button.draw()
      pygame.display.update() # <-- send to video card
      doneX = False # <-- use different variable
      while not doneX:
           for event in pygame.event.get():
               if event.type == QUIT:
                   terminate()
               elif event.type == pygame.MOUSEBUTTONDOWN: # <-- check mouse click
                   if back_button.check():
                       doneX = True 

Anda tidak perlu membuat dua fungsi drawText() dan terminate().

4
furas 2 Januari 2018, 19:27