您好,登錄后才能下訂單哦!
本文實例為大家分享了pygame實現雷電游戲開發代碼,供大家參考,具體內容如下
源代碼:
stars.py
#-*- coding=utf-8 -*- #!/usr/bin/python import pygame from pygame.locals import * from random import randint import 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 pygame from pygame.locals import * from random import randint #from gameobjects import vector2 import math import 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 os import time import pygame from pygame.locals import * from random import randint import stars from game import * #默認星空的速度 default_stars_speed = (50, 300) #子彈種數和當前子彈ID,以及對應的子彈大小、發射頻率(個/秒) SHOT_NUM = 4 shot_id = 1 shot_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()
測試畫面:
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持億速云。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。