pygame - 添加滚动背景时失去功能

时间:2013-11-27 23:46:09

标签: pygame

好的,对于我们来说,我们几乎已经抛出了很多代码并被告知制作它的项目......整个星期都在修复bug。现在我终于有了滚动背景工作,但是当我添加它时。拍摄功能停止工作,以及控制...我需要帮助,为什么会发生这种情况?该项目将在一周内完成,我的选项已经用完了......

""" Import al the necessary classes/sprites and pygame libs """

import pygame
from sys import exit
from LaserSprite import Laser
from PlayerShipSprite import PlayerShip
from EnenySprite import Asteroid
from Vector_Calc import Vector
from CursorSprite import Cursor
from ScoreBoardSprite import ScoreBoard
import math

""" Set up the screen size and sound mixer """
pygame.init()
screen = pygame.display.set_mode((640, 480)) 
pygame.mixer.init()



""" This function updates the score board with 
    information retrieved from the player class """
def updateScoreBoard(RefreshScore):  
    (ship, scoreBoard) = RefreshScore
    scoreBoard.text = ("Score: %d    Fired: %d    Shield: %d" %(ship.Get_Score(),ship.Get_Ammo(),ship.Get_Shield()))

""" This function updates the position of the ship on the
    screen based on what keys are pressed """
def checkKeys(myData):
    (event, ship) = myData
    if event.key == pygame.K_LEFT:
        print 'LEFT'
        ship.MoveLeft()
    if event.key == pygame.K_RIGHT:
        print 'RIGHT'
        ship.MoveRight()
    if event.key == pygame.K_UP:
        ship.MoveUp()
        print 'UP'
    if event.key == pygame.K_DOWN:
        print 'DOWN'
        ship.MoveDown()

""" This is the main game loop, when the game is over the player will
    be returned to the introduction screen """
def game():
    """ Set up the title of the game, the background size, color and then 
        blit to the screen """
    pygame.display.set_caption("Asteroids Version 2.0")
    background = pygame.Surface(screen.get_size())
    background.fill((0, 0, 0))
    screen.blit(background, (0, 0))

    """ Set the mouse cursor to be hidden """
    pygame.mouse.set_visible(False)

    """ Create a new instance of a player and cursor, here 
        I have set up the cursor as a class the will be updated during the game """
    ship = PlayerShip(screen)
    cursor = Cursor()   

    """ Create a new instance of the ScoreBoard class, this is then
        given a text value and a position on the screen.  Pay note 
        as to how the score, ammo and shield are retrieved from the PlayerShip class"""
    scoreBoard = ScoreBoard()
    scoreBoard.text = ("Score: %d   Fired: %d   Shield: %d" %(ship.Get_Score(),ship.Get_Ammo(),ship.Get_Shield()))
    scoreBoard.center = (320,470)

    """ Create empty sprite groups as shown below """
    all_sprites_list = pygame.sprite.Group()    
    laser_list = pygame.sprite.Group()
    asteroid_list = pygame.sprite.Group()

    """ Create 20 asteroids and add them to the asteroid list group """
    for i in range(10):
        asteroid = Asteroid()
        asteroid_list.add(asteroid)

    """ Add the ship, cursor, asteroid list group and the scoreBoard to the
        all sprites list.  In doing this we can have the transparent effect some
        were looking for """
    all_sprites_list.add(ship)
    all_sprites_list.add(cursor)
    all_sprites_list.add(asteroid_list)
    all_sprites_list.add(scoreBoard)

    """ Set up the refresh rate and key repeat for the game"""
    clock = pygame.time.Clock()
    pygame.key.set_repeat(10,10)

    keepGoing = True

    while keepGoing:
        b1 = "ocean1.gif"
        back = pygame.image.load(b1)
        back2 = pygame.image.load(b1)
        h = 0
        screenWidth = 600
        clock.tick(30)
        """ Check for any events - keyboard, mouse etc. """
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                keepGoing = False




        screen.blit(back, (h,0))
        screen.blit(back2, (h-screenWidth,0))

        h = h + 0.5
        if h == screenWidth:
            h = 0
            if event.type == pygame.KEYDOWN:
                """ If a key is pressed, bundle the event and the ship
                    and pass it to the function that handles events """
                myData =  (event, ship)
                checkKeys(myData)
            if event.type == pygame.MOUSEBUTTONDOWN:
                """ If a mouse event occurs check to see if it is the left click """
                if event.button==1: 
                    """ reduce the ammo of the ship
                        get the center of the ship sprite
                        get where the mouse was clicked on the screen
                        bundle the (x,y) position for the above
                        pass them to PlotVector function and have the 
                        angle and vector returned
                        create a new instance a laser
                        pass to it the start position, angle and vector it must travel
                        add the laser to the laser_list group and the all sprites group """ 
                    ship.Set_Ammo();     
                    shipCenter = ship.returnPosition() 
                    mousePos = pygame.mouse.get_pos()
                    print "Ship: %s, Mouse: %s " %(shipCenter, mousePos)
                    data= (shipCenter, mousePos)          
                    angle, vect = PlotVector(data)
                    laser = Laser()
                    laser.fire.play()
                    laser.AnglePoints(shipCenter, angle, vect)
                    laser_list.add(laser)
                    all_sprites_list.add(laser)

        """ update all sprites """
        all_sprites_list.update()
        """ For every laser that was fired we are going to do the following: """
        for laser in laser_list:
            """ Create a list of asteroids that were hit by the laser """
            asteroid_hit_list = pygame.sprite.spritecollide(laser, asteroid_list, False)            

            """ For each asteroid hit,
                Update the ship score
                play a bang sound
                reset the asteroid to the top of the screen again
                remove the laser from the laser list and all sprites """
            for asteroid in asteroid_hit_list:
                ship.Set_Score()
                asteroid.bang.play()
                asteroid.reset()
                laser_list.remove(laser)
                all_sprites_list.remove(laser)

            """ Remove the laser if it flies up off the screen """
            if laser.rect.y < -10 or laser.rect.y > screen.get_height():
                laser_list.remove(laser)
                all_sprites_list.remove(laser)
            if laser.rect.x < -10 or laser.rect.x > screen.get_width():
                laser_list.remove(laser)
                all_sprites_list.remove(laser)

        """ Now we are going to create a list of asteroids that hit the ship """
        asteroid_hit_Ship = pygame.sprite.spritecollide(ship, asteroid_list, False)
        """ For each asteroid that hits the ship,
                Update the ship shields
                play a bang sound
                reset the asteroid to the top of the screen again """
        for asteroid in asteroid_hit_Ship:
            asteroid.bang.play()
            ship.Set_Shield()
            asteroid.reset()


        """ if the ship's shields are less than 0 then the game will finish """     
        if ship.Get_Shield()<0:
            keepGoung=False
            break
        """ Update the score and refresh the scoreboard using the updateScoreBoard function """
        RefreshScore  = (ship, scoreBoard)       
        updateScoreBoard(RefreshScore) 

        """ The last part refreshes the sprites """
        asteroid_list.clear(screen, background)
        asteroid_list.update()
        asteroid_list.draw(screen)  

        all_sprites_list.clear(screen, background)
        all_sprites_list.update()
        all_sprites_list.draw(screen) 

        pygame.display.flip()
    return ship.Get_Score()

def PlotVector(PlotVect):
    """
        This PlotVector function handles the calculation of the new
        vector and also the calculation of the angle the arrow/bullet/projectile 
        will be transformed and travel to.  
        REFER TO YOUR NOTES FROM LECTURE 5
    """
    """ Un-bundle the data that is passed into this function """
    (start, dest) = PlotVect
    """ Create a new Vector object and call it vect """
    vect = Vector()
    """ Pass the start and dest coordinates and get back a new vector which the arrow must travel """
    vect = Vector.from_points(start, dest)
    """ Calculate the magnitude (Distance) between the two points """
    mag = vect.get_magnitude()
    """ Get the values for the vector, i.e. the change in x and change in y """
    x = vect.x
    y = vect.y
    """ This variable will be used to calculate and store the angle between points """
    angDEG = (math.atan2(y, x)*(180/math.pi))*-1
    """ Print the coordinates and angle to the screen for testing """
    print "Start: %s \nEnd: %s\nVector: %s\nMagnitude: %d" %(start, dest, vect, mag) 
    print "Angle : %d" %(angDEG)    
    """ Bundle and return the angle and vector which will be used in the TheArrow Sprite """
    return (angDEG, vect)
"""
   The next if statement runs the main function as it is in the primary program scope.  
   This was covered in lecture 5 available on Moodle 
"""


def instructions(score):

    shipIntro = PlayerShip(screen)
    allSprites = pygame.sprite.Group(shipIntro)
    insFont = pygame.font.SysFont(None, 30)

    instructions = (
    "Asteroids Version 2.0" ,
    "Previous Score: %d" %score,
    "Instructions:  You must clear the asteroid",
    "field so that you can reach your home-world",
    "",
    "Fly around the field and fire to hit the ",
    "asteroids but be careful not to fly too close",    
    "to any asteroids. Your ship has a limited amount of ",
    "off shielding and if your shielding drops below ",
    "0 your done for",
    "good luck!",
    "",
    "click to start, escape to quit..."
    )

    insLabels = []    
    for line in instructions:
        tempLabel = insFont.render(line, 1, (255, 255, 0))
        insLabels.append(tempLabel)

    keepGoing = True
    clock = pygame.time.Clock()
    pygame.mouse.set_visible(False)
    while keepGoing:
        clock.tick(60)
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                keepGoing = False
                donePlaying = True
            if event.type == pygame.MOUSEBUTTONDOWN:
                keepGoing = False
                donePlaying = False
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    keepGoing = False
                    donePlaying = True

        allSprites.update()
        allSprites.draw(screen)

        for i in range(len(insLabels)):
            screen.blit(insLabels[i], (50, 30*i))

        pygame.display.flip()

    pygame.mouse.set_visible(True)
    return donePlaying

def main():
    donePlaying = False
    score = 0
    while not donePlaying:
        donePlaying = instructions(score)
        if not donePlaying:
            score = game()

if __name__ == "__main__":
    main()

1 个答案:

答案 0 :(得分:1)

检查缩进 - 您在if event.type == pygame.KEYDOWN:之外有if event.type == pygame.MOUSEBUTTONDOWN:for event in pygame.event.get():。您有一些screen.blit() betwin forif具有较小的缩进。

也许你把它放错了地方:

    screen.blit(back, (h,0))
    screen.blit(back2, (h-screenWidth,0))

    h = h + 0.5
    if h == screenWidth:
        h = 0

修改

您的代码可能如下所示:

while keepGoing:
    b1 = "ocean1.gif"
    back = pygame.image.load(b1)
    back2 = pygame.image.load(b1)
    h = 0
    screenWidth = 600
    clock.tick(30)
    """ Check for any events - keyboard, mouse etc. """
    for event in pygame.event.get():

        if event.type == pygame.QUIT:
            keepGoing = False

        elif event.type == pygame.KEYDOWN:
            """ If a key is pressed, bundle the event and the ship
                and pass it to the function that handles events """
            myData =  (event, ship)
            checkKeys(myData)

        elif event.type == pygame.MOUSEBUTTONDOWN:
            """ If a mouse event occurs check to see if it is the left click """
            if event.button == 1: 
                """ reduce the ammo of the ship
                    get the center of the ship sprite
                    get where the mouse was clicked on the screen
                    bundle the (x,y) position for the above
                    pass them to PlotVector function and have the 
                    angle and vector returned
                    create a new instance a laser
                    pass to it the start position, angle and vector it must travel
                    add the laser to the laser_list group and the all sprites group """ 
                ship.Set_Ammo();     
                shipCenter = ship.returnPosition() 
                mousePos = pygame.mouse.get_pos()
                print "Ship: %s, Mouse: %s " %(shipCenter, mousePos)
                data= (shipCenter, mousePos)          
                angle, vect = PlotVector(data)
                laser = Laser()
                laser.fire.play()
                laser.AnglePoints(shipCenter, angle, vect)
                laser_list.add(laser)
                all_sprites_list.add(laser)

    screen.blit(back, (h,0))
    screen.blit(back2, (h-screenWidth,0))

    h = h + 0.5
    if h == screenWidth:
        h = 0

    # rest of main loop

btw:我使用elif,因为event.type在一次活动中不能是pygame.QUITpygame.KEYDOWNpygame.MOUSEBUTTONDOWN