pygame实现雷电游戏雏形开发
程序员文章站
2022-05-25 21:24:33
本文实例为大家分享了pygame实现雷电游戏开发代码,供大家参考,具体内容如下
源代码:
stars.py
#-*- coding=utf-8 -*-...
本文实例为大家分享了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()
测试画面:
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
上一篇: Vue2.0子同级组件之间数据交互方法
下一篇: PHP在字符断点处截断文字的实现代码