问题描述
我正在制作一款类似于 Space Invaders 的游戏.有没有办法检查像不那么频繁地拍摄这样的事件?现在,如果你足够快地按下空格键,顶部镜头会在它击中屏幕顶部之前消失.我想知道你是否可以检查像 2/(到达顶部需要多长时间)这样的击球事件.
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).
这是我的代码:
#-----!!!!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()
推荐答案
您可以使用 counter 来计算自上次拍摄以来主循环中的循环 - 如果它大于(例如)10 比您清除计数器并拍摄 - 在更多复杂的游戏你可以使用 pygame.time.get_ticks() 以毫秒为单位计算自上次拍摄以来的时间
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
另一种方法是仅当屏幕上的镜头少于 2 个时才开火.
Another method is to fire shot only if you have less than 2 shot on screen.
您的代码将如下所示 - 简单示例.使用键:LEFT、RIGHT、SPACE、P(暂停).
Your code would look like this - simple example. Use keys: LEFT, RIGHT, SPACE, P (for pause).
还有很多事情要做.例如更好的碰撞检测 - pygame.sprite.collide_rect()
There is still much to do. For example better collision detect - pygame.sprite.collide_rect()
(我在最后附上了我的位图)
#-----!!!!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球2.png球3.png
ball1.pngball2.pngball3.png
截图
这篇关于太空侵略者计划的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!