首页 > 编程 > Python > 正文

pygame实现雷电游戏雏形开发

2020-01-04 14:01:26
字体:
来源:转载
供稿:网友

本文实例为大家分享了pygame实现雷电游戏开发代码,供大家参考,具体内容如下

源代码:

stars.py

 

#-*- coding=utf-8 -*-#!/usr/bin/python import pygamefrom pygame.locals import *from random import randintimport math class Star(object):  def __init__(self, x, y, speed, color=(255,255,255)):     self.x = x    self.y = y    self.speed = speed    self.color = color class Stars(object):  '''    用于绘制星星背景  '''  def __init__(self, num = 0, SCREEN_SIZE=(800,600), color=(255,255,255)):    self.stars = []    self.MIN_SPEED = 10    self.MAX_SPEED = 300    self.SCREEN_SIZE = SCREEN_SIZE    if num > 0:      self.create_star(num, color)   def set_min_speed(self,speed):    self.MIN_SPEED = speed  def set_max_speed(self,speed):    self.MAX_SPEED = speed   def create_star(self,num = 1, color = (255,255,255)):    '''创建一个或多个星星,颜色可选'''    for i in xrange(0,num):      x = float(randint(0, self.SCREEN_SIZE[0]))      y = float(randint(0, self.SCREEN_SIZE[1]))      speed = float(randint(self.MIN_SPEED, self.MAX_SPEED))      self.stars.append( Star(x, y, speed, color) )   def move(self,time_passed_seconds):    '''移动星星并过滤'''    for star in self.stars:      star.y = star.y + time_passed_seconds * star.speed    #过滤跑出画面的星星    self.stars = filter(lambda one: one.y<=self.SCREEN_SIZE[1], self.stars)   def draw(self, surface):    '''将星星画到指定图像对象'''    for star in self.stars:      #pygame.draw.aaline(surface, star.color,/      #    (star.x, star.y), (star.x+1., star.y))      surface.set_at((int(star.x),int(star.y)),star.color)  def test():   pygame.init()  screen = pygame.display.set_mode((800, 600)) #, FULLSCREEN)   stars = Stars()  #stars.set_max_speed(1000)  #stars.set_min_speed(300)   # 在第一帧,画上一些星星  stars.create_star(200)     clock = pygame.time.Clock()   white = (255, 255, 255)     while True:     for event in pygame.event.get():      if event.type == QUIT:        return      if event.type == KEYDOWN:        return     time_passed = clock.tick(30)    time_passed_seconds = time_passed / 1000.     #update_background(stars, screen, time_passed_seconds)    # 增加一颗新的星星    stars.create_star(1)    stars.move(time_passed_seconds)     screen.fill((0, 0, 0))     # 绘制所有的星    stars.draw(screen)     pygame.display.update() if __name__ == "__main__":  test()

game.py

#-*- coding=utf-8 -*-#!/usr/bin/python import pygamefrom pygame.locals import *from random import randint#from gameobjects import vector2import mathimport time SCREEN_RECT = pygame.Rect(0,0,800,600) class Player(pygame.sprite.Sprite):  '''玩家类'''  speed = 10  images = []  def __init__(self):    pygame.sprite.Sprite.__init__(self, self.containers)    self.image = Player.images[0]    self.rect = self.image.get_rect(midbottom=SCREEN_RECT.midbottom)    self.health= 4    #self.time = 0    #self.reloading = False   #def update(self, time_passed_seconds=0.0): if not self.reloading: super(Player,self).update(time_passed_seconds) else: self.time += time_passed_seconds if self.time > 1.5: print self.time self.time = 0.0 self.reloading = False self.groups()[0].remove(self)   def move(self, directions):    '''移动,direction == 'up' or 'down' or 'left' or 'right' '''    for direction in directions:      if direction == 'up':        self.rect.move_ip(0, -1 * Player.speed)      elif direction == 'down':        self.rect.move_ip(0, 1 * Player.speed)      elif direction == 'left':        self.rect.move_ip(-1 * Player.speed, 0)      elif direction == 'right':        self.rect.move_ip(1 * Player.speed, 0)      else:        print 'argument error'        return None    self.rect.clamp_ip(SCREEN_RECT)   def shoted_and_live(self, harm):    '''被攻击处理,依然存活返回True,否则返回False'''    self.health -= harm    if self.health <= 0:      return False    else:      return True   def attack_pos(self):    return self.rect.x + self.rect.width / 2, self.rect.y class Shot(pygame.sprite.Sprite):  '''通用子弹类'''  speed_tab = [ 13, 13, 26, 30 ]  #子弹攻击力表  harm_tab = [ 1, 2 , 3, 12]  images  = []  #子弹大小表  shot_size = []  def __init__(self, pos, angle, id=1 ):    '''pos为射出位置      angle参数为子弹射出的方向角度,以12点钟方向为0度,逆时针增大'''    pygame.sprite.Sprite.__init__(self, self.containers)    self.id  = id    self.angle = angle    self.speed = Shot.speed_tab[id-1]    self.harm = Shot.harm_tab[id-1]    self.image = pygame.transform.scale(Shot.images[id-1], Shot.shot_size[id-1])    self.image = pygame.transform.rotate(self.image, angle)    self.rect = self.image.get_rect(midbottom=pos)   def update(self,time_passed_seconds=0.0):    radian = self.angle / 180.0 * math.pi    self.rect.move_ip(math.sin(radian) * -self.speed,/        -self.speed * math.cos(radian) )    if self.rect.x+self.rect.width < 0 or/        self.rect.x > SCREEN_RECT.width or/        self.rect.y+self.rect.height < 0 or/        self.rect.y > SCREEN_RECT.height:      self.kill() class AlienShot(Shot):  '''    敌方子弹类    为了对象分组专为敌人的子弹使用一个新类,并定制子弹射速  '''  def __init__(self, pos, angle, id=1, speed=20 ):    Shot.__init__(self, pos, angle, id)    self.speed = speed def SectorShot(pos, shot_id):  '''扇形子弹的封装'''  Shot(pos, 0, shot_id)  Shot(pos, 15, shot_id)  Shot(pos, 30, shot_id)  Shot(pos, 45, shot_id)  Shot(pos, 315,shot_id)  Shot(pos, 330,shot_id)  Shot(pos, 345,shot_id)  def CommonShot(pos, shot_id):  '''常规子弹'''  Shot(pos, 0, shot_id) class Alien(pygame.sprite.Sprite):  '''通用敌人类'''  #默认速度表,速度为像素/秒  speed_tab = [ 400, 200, 200 ]  images= []  #用于射击间隔  times = [0.15, 0.3, 0.4]    def __init__(self, id=1, health=5):    pygame.sprite.Sprite.__init__(self, self.containers)    self.id   = id    self.speed = Alien.speed_tab[id-1]    self.health = health    self.image = Alien.images[id-1]    self.rect  = self.image.get_rect()    self.rect.topleft = (randint(0, SCREEN_RECT.width-self.rect.width),0)     self.move_tab = [ self.move_line, self.move_circle, self.move_curve ]    #用于射击的时间计算    self.time  = 0.0   def update(self, time_passed_seconds=0.0):    self.move_tab[self.id-1](time_passed_seconds)    if self.rect.x < 0 or self.rect.x > SCREEN_RECT.width or self.rect.y < 0 or self.rect.y > SCREEN_RECT.height:      self.kill()    self.time += time_passed_seconds    if self.time > Alien.times[self.id-1]:      self.time = 0.0      if self.id == 1:        AlienShot(self.attack_pos(), 180, 1, 30)      elif self.id == 2:        AlienShot(self.attack_pos(), 120, 1, 10)        AlienShot(self.attack_pos(), 150, 1, 10)        AlienShot(self.attack_pos(), 180, 1, 10)        AlienShot(self.attack_pos(), 210, 1, 10)        AlienShot(self.attack_pos(), 240, 1, 10)      elif self.id == 3:        AlienShot(self.attack_pos(), 180, 2, 10)    def shoted_and_live(self, harm):    '''被攻击处理,依然存活返回True,否则返回False'''    self.health -= harm    if self.health <= 0:      return False    else:      return True   def move_line(self, time_passed_seconds):    self.rect.move_ip(0, self.speed * time_passed_seconds)   def move_circle(self, time_passed_seconds):    if not hasattr(self, 'angle'):      self.angle = 180    else:      self.angle = self.angle+time_passed_seconds*360    if not hasattr(self, 'radius'):      self.radius = 60    if not hasattr(self, 'center'):      x = self.rect.x+self.radius if self.rect.x < self.radius else self.rect.x-self.radius      self.center = [ x, 0+self.radius]    self.center[1] += 2    new_pos = self.__circle_next( self.center, self.radius, self.angle)     #self.rect.move_ip(new_pos[0], new_pos[1])    self.rect.x, self.rect.y = new_pos[0], new_pos[1]   def __circle_next(self, center, radius, angle):    x = math.sin(angle/180.0*math.pi) * radius + center[0]    y = math.cos(angle/180.0*math.pi) * radius + center[1]    return x, y   def move_curve(self, time_passed_seconds):    if not hasattr(self, 'ray'):      self.ray = self.rect.x    if not hasattr(self, 'angle'):      self.angle = 0    else:      self.angle = self.angle + time_passed_seconds * 360    if not hasattr(self, 'curve_width'):      self.curve_width = 50    x = math.sin(self.angle/180*math.pi) * self.curve_width + self.ray    y = self.rect.y + self.speed * time_passed_seconds    self.rect.x, self.rect.y = x, y   def attack_pos(self):    return self.rect.x + self.rect.width / 2, self.rect.y + self.rect.height  class Explosion(pygame.sprite.Sprite):  '''爆炸类'''  #用于存储爆炸图像每帧的坐标  areas = [/(0,0,104,135), (104,0,104,135), (208,0,104,135),(312,0,104,135),(416,0,94,135),/(0,135,102,112),(102,135,102,112),(204,135,102,112),(306,135,102,112),(408,135,102,112),/(0,247,108,144),(108,247,100,144),(208,247,102,144),(310,247,100,144),(412,247,98,144),/(0,400,95,100) ]  images = []    def __init__(self, pos, id=1, areas=None):    pygame.sprite.Sprite.__init__(self, self.containers)    self.pos = pos    self.fps = 0    self.image_data = Explosion.images[id-1]    if areas is not None:      self.areas = areas     self.update()    def update(self, time_passed_seconds=0.0):    self.rect = pygame.Rect(self.areas[self.fps])    self.image = self.image_data.subsurface(Rect(self.areas[self.fps]))    self.rect.topleft = self.pos    self.fps += 1    if self.fps >= len(self.areas):      self.kill() class Score(pygame.sprite.Sprite):   score = 0  health= 0  life = 0  def __init__(self, font_type = "文泉驿点阵正黑"):    pygame.sprite.Sprite.__init__(self)    self.font = pygame.font.SysFont(font_type, 20)    self.color= (255,255,255)    self.msg = u"得分:%d/n生命:%d"    self.update()    self.rect = self.image.get_rect()    self.rect.topleft = (10,10)   def update(self, time_passed_seconds=0.0):    self.msg = u"生命:%d  得分:%d"% (Score.life, Score.score)    self.image = self.font.render(self.msg, True, self.color)

main.py

#-*- coding=utf-8 -*-#!/usr/bin/python import osimport timeimport pygamefrom pygame.locals import *from random import randint import stars from game import * #默认星空的速度default_stars_speed = (50, 300)#子弹种数和当前子弹ID,以及对应的子弹大小、发射频率(个/秒)SHOT_NUM = 4shot_id = 1shot_size= [(2,9), (16, 16), (19,14), (99,120)]shot_rate= [ 0.15, 0.3, 0.10, 0.7 ] dest_area = [/(0,0,104,135), (104,0,104,135), (208,0,104,135),(312,0,104,135),(416,0,104,135),/(0,135,102,112),(102,135,102,112),(204,135,102,112),(306,135,102,112),(408,135,102,112),/(0,247,108,144),(108,247,100,144),(208,247,102,144),(310,247,100,144),(412,247,98,144),/(0,400,95,100) ] star_bmg = []def update_background(stars, screen, time_passed_seconds):  '''在指定图像上生成一些星星并移动,绘制'''  stars.create_star(2,(randint(0,255),randint(0,255),randint(0,255)))  #stars.create_star(1,(255,255,255))  stars.move(time_passed_seconds)  screen.fill((0, 0, 0))  stars.draw(screen)   #screen.blit(star_bmg[0],(100,100))  #screen.blit(star_bmg[1],(100,100)) def load_image(file, alpha=False):  '''加载一张图片,可指定是否为alpha转换'''  file = 'data/image/' + file  try:    surface = pygame.image.load(file)  except pygame.error:    raise SystemExit('加载图像 "%s" 失败 %s' % (file, pygame.get_error()) )  if alpha:    return surface.convert_alpha()  return surface.convert() def load_sound(file):  file = 'data/music/' + file  try:    sound = pygame.mixer.Sound(file)    return sound  except pygame.error:    print ('加载音乐 "%s" 失败' % file)  return None def main():  global shot_id   global star_bmg   pygame.mixer.pre_init(44100, -16, 2, 4096)  pygame.init()  screen = pygame.display.set_mode((800, 600)) #, FULLSCREEN)   #加载各种资源数据  image_list    = os.listdir('data/image')  image_list.sort()  Player.images   = [ load_image(file,True) for file in image_list if 'player' in file ]  Alien.images   = [ pygame.transform.rotate(load_image(file,True),180)/              for file in image_list if 'alien' in file ]  Shot.images    = [ load_image(file,True) for file in image_list if 'shot'  in file ]  star_bmg     = [ load_image(file,True) for file in image_list if 'star' in file ]   Shot.shot_size  = shot_size  shot_sound    = load_sound('shot2.wav')  Explosion.images = [ load_image(file,True) for file in image_list if 'explosion' in file ]  explosion_sound1 = load_sound('explosion1.wav')  explosion_sound2 = load_sound('explosion2.wav')  change_shot_sound = load_sound('change_shot.wav')  alarm_sound    = load_sound('alarm.wav')  #加载并播放BGM  pygame.mixer.music.load('data/music/bgm01.ogg')  pygame.mixer.music.play(-1)   # 初始化并生成一些星星  world = stars.Stars(200)  world.set_min_speed(default_stars_speed[0])  world.set_max_speed(default_stars_speed[1])   #为各种游戏对象分组,all组存储了所有游戏对象  shots = pygame.sprite.Group() #玩家的子弹和敌人的子弹分成2组  alien_shots = pygame.sprite.Group()   aliens= pygame.sprite.Group()  explosions = pygame.sprite.Group()  all  = pygame.sprite.Group()   Player.containers = all  Alien.containers = aliens, all  Shot.containers  = shots, all  AlienShot.containers = alien_shots, all  Explosion.containers = explosions, all   player = Player()   #玩家生命数,重载标志和重载时间  life  = 3  reloading = False  reloading_time = 1.5   Score.score = 0  Score.life = life  score = Score()  all.add(score)  #无敌标志,重生后需要进入一段无敌时间  iamyourdaddy = False   clock = pygame.time.Clock()  prev_time = 0.0     while life or len(explosions.sprites())>0:    allkill=None     for event in pygame.event.get():      if event.type == QUIT:        return      if event.type == KEYDOWN and event.key == K_ESCAPE:        return      if event.type == KEYDOWN:        #处理子弹切换        if event.key == K_TAB:          shot_id = shot_id % SHOT_NUM + 1          change_shot_sound.play()        elif event.key == K_x:          for alien in aliens:            alien.kill()            explosion_sound2.play()            Explosion(alien.rect.topleft)          for shot in alien_shots:            shot.kill()            explosion_sound2.play()            Explosion(shot.rect.topleft)     keystate = pygame.key.get_pressed()    time_passed = clock.tick(30)    time_passed_seconds = time_passed / 1000.     update_background(world, screen, time_passed_seconds)    #all.clear(screen, screen)    all.update(time_passed_seconds)     #处理方向控制    direct = []    if keystate[K_UP]:      direct.append('up')      #模拟加速星空      world.set_min_speed(default_stars_speed[0] * 10)      world.set_max_speed(default_stars_speed[1] * 2)    if keystate[K_DOWN]:      direct.append('down')      #模拟减速星空      world.set_min_speed(10)      world.set_max_speed(default_stars_speed[1] / 2)    if keystate[K_LEFT]:      direct.append('left')    if keystate[K_RIGHT]:      direct.append('right')    player.move(direct)    #若不是上下则恢复默认速度    if not (keystate[K_UP] or keystate[K_DOWN]):      world.set_min_speed(default_stars_speed[0])      world.set_max_speed(default_stars_speed[1])     #处理攻击行为,用攻击间隔控制频率    if not reloading and keystate[K_SPACE]:      if time.time()-prev_time > shot_rate[shot_id-1]:        #第二个参数为射出角度,以12点钟方向为0度逆时针变大        #Shot(player.attack_pos(), 45, shot_id)        if shot_id==1:          SectorShot(player.attack_pos(), shot_id)        else:          CommonShot(player.attack_pos(), shot_id)        shot_sound.play()        #Explosion(player.attack_pos())        prev_time = time.time()     #随机生成敌人,不同敌人血量不同    n = randint(0,100)    if n==1:       Alien(1,3)    elif n==2:      Alien(2,5)    elif n==3:      Alien(3,5)     #处理玩家子弹与敌方的碰撞,碰撞字典键为第一个组的对象,值为第二个组的对象列表    collide_dict = pygame.sprite.groupcollide(aliens,shots,False,False)    for alien in collide_dict:      for shot in collide_dict[alien]:        if shot_id!=4:          shot.kill()        explosion_sound1.play()        harm = shot.harm        if not alien.shoted_and_live(harm):          Score.score += 1          alien.kill()          explosion_sound2.play()          Explosion(alien.rect.topleft)     #检测无敌时间是否结束    if iamyourdaddy:      wait += time_passed_seconds      if wait > 1.5:        iamyourdaddy = False        wait = 0.0     #如果玩家处于重生中则不检测玩家碰撞    if not reloading:      #处理玩家与敌人的碰撞      for alien in pygame.sprite.spritecollide(player, aliens,True):        explosion_sound2.play()        Explosion(alien.rect.topleft)        if iamyourdaddy:          pass        else:          alarm_sound.play(2)           Explosion(player.rect.topleft)          Score.score += 1          Score.life -= 1          player.kill()          reloading = True          wait = 0.0          life -= 1     if not reloading:      #处理玩家与敌方子弹的碰撞      for shot in pygame.sprite.spritecollide(player, alien_shots, True):        explosion_sound1.play()        harm = shot.harm        if iamyourdaddy:          pass        elif not player.shoted_and_live(harm):          alarm_sound.play(2)           explosion_sound2.play()          Explosion(player.rect.topleft)          Score.life -= 1          player.kill()          reloading = True          wait = 0.0          life -= 1     #处理子弹与子弹的碰撞    if shot_id==4:      collide_dict = pygame.sprite.groupcollide(alien_shots,shots,True,False)      for alien_shot in collide_dict:        explosion_sound2.play()        Explosion(alien_shot.rect.topleft)     #死亡后重置玩家,生命数-1    if reloading:       wait += time_passed_seconds       if wait > reloading_time:         reloading = False         player = Player()        wait = 0.0        #进入无敌模式        iamyourdaddy = True     # 增加一颗新的星星    #stars.create_star(1)    #stars.move(time_passed_seconds)    #screen.fill((0, 0, 0))    # 绘制所有的星    #stars.draw(screen)    #screen.blit(image,(300,300))    all.draw(screen)    pygame.display.update()   #绘制结束画面  #设置字体  font = pygame.font.SysFont("文泉驿点阵正黑", 80)  end = font.render(u"YOU LOST!!!", True, (255,0,0))  screen.blit(end, (180, 270))  pygame.display.update()  time.sleep(2.5) if __name__ == "__main__":  main()

测试画面:

pygame,雷电游戏,开发

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持VEVB武林网。


注:相关教程知识阅读请移步到python教程频道。
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表