Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
138 views
in Technique[技术] by (71.8m points)

python - Space Invaders project

I'm making a game similar to Space Invaders. Is there a way to check for an event like shooting less frequently? Right now, if you press space bar fast enough the top shot will disappear before it hits the top of the screen. I was wondering if you could check for the shot event like 2/(how long it takes to get the the top).

Here is my code:

#-----!!!!SPACE INVADERS!!!!-----
import pygame, sys
from pygame.locals import *
#-----MAIN FUNCTIONS-----
def movement(move_x):
    if event.type == KEYDOWN:
        if event.key == K_LEFT:
            move_x = -5
        if event.key == K_RIGHT:
            move_x = 5
    if event.type == KEYUP:
        if event.key == K_LEFT:
            move_x = 0
        if event.key == K_RIGHT:
            move_x = 0
    return move_x


#-----FFRAME RAEE / SCREEN SIZE-----
clock = pygame.time.Clock()
w,h = 800,800
screen = pygame.display.set_mode((w,h))

#-----SETTING IMAGES-----
pygame.mouse.set_visible(0)

ship = pygame.image.load("spaceship.png")
ship = pygame.transform.scale(ship,(100,50))
ship_top = screen.get_height() - ship.get_height()
ship_left = screen.get_width()/2 - ship.get_width()/2

screen.blit(ship, (ship_left,ship_top))

shot1 = pygame.image.load("SingleBullet.png")
shot1 = pygame.transform.scale(shot1,(25,25))
shot2 = shot1
shot_count = 0
shot_y = 0
shot_y_2 = 0

#-----GLOBAL VARIABLES-----
x = 0
resetShot = 0
move_x = 0
#-----MAIN GAME LOOP-----
while True:
    clock.tick(60)
    screen.fill((0,0,0))
    #x,y = pygame.mouse.get_pos()
    screen.blit(ship, (x-ship.get_width()/2,ship_top))

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

        move_x = movement(move_x)

        if event.type == KEYDOWN:
            if event.key == K_SPACE and shot_count == 0:
                shot_y = h-50
                shot_x = x
            elif event.type == K_SPACE and shot_count == 1:
                shot_y_2 = h-50
                shot_x_2 = x
            print(h, ' ', shot_y, shot_count)
        if event.type == KEYUP:
            if event.key == K_SPACE and shot_count == 0:
                resetShot = 0 
            elif event.type == K_SPACE and shot_count == 1:
                resetShot = 0


    if shot_y > 0:
        screen.blit(shot1, (shot_x-shot1.get_width()/2,shot_y))
        shot_y -= 15
    if shot_y_2 > 0:
        screen.blit(shot2, (shot_x_2-shot1.get_width()/2,shot_y_2))
        shot_y_2 -= 15

    x+=move_x
    pygame.display.update()
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You could use counter to count loops in main loop since last shot - if it is bigger than (for example) 10 than you clear counter and shoot - in more complicated game you could use pygame.time.get_ticks() to count time in milliseconds since last shot

Another method is to fire shot only if you have less than 2 shot on screen.

EDIT:

Your code would look like this - simple example. Use keys: LEFT, RIGHT, SPACE, P (for pause).

There is still much to do. For example better collision detect - pygame.sprite.collide_rect()

(I attached my bitmaps at the end)

#-----!!!!SPACE INVADERS!!!!-----

import pygame
from pygame.locals import *

#----------------------------------------------------------------------

class Ship():

    def __init__(self, screen_rect):

        #self.image = pygame.image.load("spaceship.png")
        self.image = pygame.image.load("ball1.png")
        self.image = pygame.transform.scale(self.image, (100,50))

        self.rect = self.image.get_rect()

        # put ship bottom, center x 
        self.rect.bottom = screen_rect.bottom 
        self.rect.centerx = screen_rect.centerx

        self.move_x = 0

        self.shots = []
        self.shots_count = 0

        self.max_shots = 2

    #--------------------

    def event_handler(self, event):

        #print "debug: Ship.event_handler"

        if event.type == KEYDOWN:
            if event.key == K_LEFT:
                self.move_x = -5
            elif event.key == K_RIGHT:
                self.move_x = 5
            elif event.key == K_SPACE:
                if len(self.shots) < self.max_shots:
                    self.shots.append(Bullet(self.rect.centerx, self.rect.top))

        if event.type == KEYUP:
            if event.key in (K_LEFT, K_RIGHT):
                self.move_x = 0

    def update(self):

        #print "debug: Ship.update: move_x", self.move_x
        self.rect.x += self.move_x

        for s in self.shots:
            s.update()

        for i in range(len(self.shots)-1, -1, -1):
            print "debug: Ship.update: testing bullet ", i
            if not self.shots[i].is_alive:
                print "debug: Ship.update: removing bullet ", i
                del self.shots[i]

    #--------------------

    def draw(self, screen):

        #print "debug: Ship.draw"

        screen.blit(self.image, self.rect.topleft)

        for s in self.shots:
            s.draw(screen)

    def bullet_detect_collison(self, enemy_list):

        for s in self.shots:
            for e in enemy_list:
                if pygame.sprite.collide_circle(s, e):
                    s.is_alive = False
                    e.is_alive = False

#----------------------------------------------------------------------

class Bullet():

    def __init__(self, x, y):

        #self.image = pygame.image.load("SingleBullet.png")
        self.image = pygame.image.load("ball2.png")
        self.image = pygame.transform.scale(self.image, (25,25))

        self.rect = self.image.get_rect()
        self.rect.centerx = x
        self.rect.centery = y

        self.is_alive = True

    #--------------------

    def update(self):

        self.rect.y -= 15

        if self.rect.y < 0:
            self.is_alive = False

    #--------------------

    def draw(self, screen):

        screen.blit(self.image, self.rect.topleft)

#----------------------------------------------------------------------

class Enemy():

    def __init__(self, x, y):

        self.image = pygame.image.load("ball3.png")

        self.rect = self.image.get_rect()
        self.rect.centerx = x
        self.rect.centery = y

        self.is_alive = True

    #--------------------

    def update(self):

        self.rect.y += 1

        #~ if self.rect.y < 0:
            #~ self.is_alive = False

    #--------------------

    def draw(self, screen):

        screen.blit(self.image, self.rect.topleft)

#----------------------------------------------------------------------

class Game():

    def __init__(self):

        pygame.init()

        w, h = 800, 800
        self.screen = pygame.display.set_mode((w,h))

        pygame.mouse.set_visible(False)

        self.ship = Ship(self.screen.get_rect())

        self.enemies = []

        for i in range(100, 800, 100):
            self.enemies.append(Enemy(i, 100))

        font = pygame.font.SysFont("", 72)
        self.text_paused = font.render("PAUSED", True, (255, 0, 0))
        self.text_paused_rect = self.text_paused.get_rect(center=self.screen.get_rect().center)

    #-----MAIN GAME LOOP-----

    def run(self):

        clock = pygame.time.Clock()

        RUNNING = True
        PAUSED = False

        while RUNNING:

            clock.tick(30)

            #--- events ---

            for event in pygame.event.get():

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

                if event.type == KEYDOWN:
                    if event.key == K_ESCAPE:
                        RUNNING = False

                    if event.key == K_p:
                        PAUSED = not PAUSED

                if not PAUSED:
                    self.ship.event_handler(event)

            #--- changes ---
            if not PAUSED:

                self.ship.update()

                for e in self.enemies:
                    e.update()

                self.ship.bullet_detect_collison(self.enemies)

                for i in range(len(self.enemies)-1, -1, -1):
                    print "debug: Ship.update: testing bullet ", i
                    if not self.enemies[i].is_alive:
                        print "debug: Ship.update: removing bullet ", i
                        del self.enemies[i]

            #--- draws ---

            self.screen.fill((0,0,0))

            self.ship.draw(self.screen)

            for e in self.enemies:
                e.draw(self.screen)

            if PAUSED:
                self.screen.blit(self.text_paused, self.text_paused_rect)

            pygame.display.update()

        #--- quit ---

        pygame.quit()

#---------------------------------------------------------------------

Game().run()

ball1.png enter image description here ball2.png enter image description here ball3.png enter image description here

Screenshot enter image description here


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...