# pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pygame import pygame, sys, time, random, math from pygame.locals import * FPS = 60 winwidth = 1200 winheight = 800 maxhealth = 8 basicspeed = 6 createenemytime = 2 createbullettime = 0.3 enemybreadth = 30 enemywidth = 40 enemyheight = 40 playerwidth = 40 playerheight = 40 enemymaxhealth = 2 enemybulletspeed = 4 enemybulletsize = 6 enemybulletgailv = 10 # 每一秒产生一个子弹的概率 boss1creategailv = 100 bossexistflag = False wudiflag = False wuditimeflag = True wuditime = 0 wudistarttime = 0 # R G B red = (255, 0, 0) green = (0, 255, 0) blue = (0, 0, 255) white = (255, 255, 255) black = (0, 0, 0) yellow = (255, 255, 0) bgcolor = white enemybulletcolor = black def main(): global moveright, moveleft, moveup, movedown, dissurf, bulletlist, enemybulletlist, enemylist, basicfont, \ bigfont, biggerfont, biggestfont, score, level, clock, playerobj, bossexistflag, wudiflag, wuditimeflag, wudistarttime, \ wuditime, boss1, player pygame.init() dissurf = pygame.display.set_mode((winwidth, winheight)) clock = pygame.time.Clock() playerobj = {'surf': pygame.image.load('玩家飞船.png'), 'x': winwidth / 2 - playerwidth / 2, 'y': winheight - playerheight, 'health': maxhealth, 'speed': basicspeed, 'width': playerwidth, 'height': playerheight, } playerobj['surf'] = pygame.transform.scale(playerobj['surf'], (playerwidth, playerheight)) jindutiao = JinzhiJindutiao(110, 20, 200, 15, green, yellow, playerobj['health'], maxhealth) playerobj['healthjindutiao'] = jindutiao player = player() basicfont = pygame.font.Font('freesansbold.ttf', 8) bigfont = pygame.font.Font('freesansbold.ttf', 16) biggerfont = pygame.font.Font('freesansbold.ttf', 24) biggestfont = pygame.font.Font('freesansbold.ttf', 64) moveright = False moveleft = False moveup = False movedown = False attackflag = False enemylist = [] bulletlist = [] enemybulletlist = [] attackstarttime = time.time() bulletcreatecishu = 0 score = 0 level = 0 while True: for event in pygame.event.get(): if event.type == QUIT: terminate() elif event.type == KEYDOWN: if event.key in (K_LEFT, K_a): moveleft = True elif event.key in (K_RIGHT, K_d): moveright = True elif event.key in (K_UP, K_w): moveup = True elif event.key in (K_DOWN, K_s): movedown = True elif event.key == K_SPACE: attackflag = True attackstarttime = time.time() elif event.type == KEYUP: if event.key in (K_LEFT, K_a): moveleft = False elif event.key in (K_RIGHT, K_d): moveright = False playerobj['x'] += playerobj['speed'] elif event.key in (K_UP, K_w): moveup = False elif event.key in (K_DOWN, K_s): movedown = False elif event.key == K_SPACE: attackflag = False bulletcreatecishu = 0 dissurf.fill(bgcolor) updateplayerlocation(playerobj) updatebulletlocation(bulletlist) playerrect = (playerobj['x'], playerobj['y'], playerobj['width'], playerobj['height']) dealxiaoshi(bulletlist, enemylist) dissurf.blit(playerobj['surf'], playerrect) if wudiflag: drawwudi(0.3, 1.5) if time.time() - wudistarttime > 3: wudiflag = False wuditimeflag = True if attackflag: if time.time() - attackstarttime > createbullettime * bulletcreatecishu: updatebulletlist(bulletlist, createbullet(playerobj['x'] + playerobj['width'] / 2 - 3, playerobj['y'] - playerobj['height'] / 2, 6, 6, 8, cishu=1), number=1) bulletcreatecishu += 1 if not enemylist: if random.randint(1, 100) <= boss1creategailv and not bossexistflag: bossexistflag = True boss1 = Boss1() n = random.randint(1, 3) w = random.choice((-1, 1)) * random.uniform(0.1, 0.5) elif not bossexistflag: n = random.randint(1, 5) guanqia = Guanqia(20) enemybulletlist.clear() if not bossexistflag: eval(f'guanqia.guanqia{n}')(0.7, 10) else: if not boss1.bossoverflag: if time.time() - boss1.chuzhaoovertime > boss1.chuzhaobreadth and not boss1.chuzhaoflag: # 该出招了! boss1.chuzhaoflag = True boss1.bubianstarttime = time.time() n = random.randint(1, 3) w = random.choice((-1, 1)) * random.uniform(0.1, 0.5) eval(f'boss1.skill{n}chushi')(0.4, 10) eval(f'boss1.skill{n}change')(10) # boss1.jiguang3(2,5, w) boss1.drawjiguang() boss1.chuchang() boss1.allattack() boss1.bossmove() boss1.dealxiaoshi() boss1.drawbossandbullet() boss1.createdevice() boss1.updatedevice() boss1.updatebullet() else: bossexistflag = False enemylistfu = enemylist[:] for enemy in enemylistfu: enemyrect = pygame.Rect(enemy['x'], enemy['y'], enemy['width'], enemy['height']) for enemy1 in enemylistfu: enemy1rect = pygame.Rect(enemy1['x'], enemy1['y'], enemy1['width'], enemy1['height']) if enemyrect.colliderect(enemy1rect): flipmovelr(enemy) flipmovelr(enemy1) break updatefleet(enemy) allattack(enemy, bulletlist, playerobj) drawenemyhealth(enemy) if random.randint(1, 6000) <= enemybulletgailv: appendenemybullet(enemy, playerobj) if enemybulletlist: updateenemybulletlocation() drawenemybullet() beibulletattack(playerobj) if playerobj['health'] <= 0: showgameover() drawplayerhealth(playerobj) drawscore() drawenemyfleet(enemylist) drawbullets(bulletlist) pygame.display.update() clock.tick(FPS) def drawwudi(jiangetime, alltime): global wuditime, wuditimeflag, wudiflag, wudistarttime # 时隐时现 if wuditimeflag and time.time() - wuditime <= jiangetime: # 隐 dissurf.fill(bgcolor, (playerobj['x'], playerobj['y'], playerobj['width'], playerobj['height'])) elif time.time() - wuditime > jiangetime and wuditimeflag: wuditime = time.time() wuditimeflag = False elif not wuditimeflag and time.time() - wuditime > jiangetime: wuditimeflag = True wuditime = time.time() class Jiguang(pygame.sprite.Sprite): def __init__(self, boss, warnlasttime,width, x = 'boss1发射', y = 'boss1发射'): super().__init__() self.starttime = time.time() self.warnlasttime = warnlasttime self.warnflag = True self.width = width self.height = 1000 self.color = red self.image0 = pygame.Surface((self.width, self.height)).convert() self.image0.fill(black) self.image0.set_colorkey(black) self.image0.fill(self.color) self.mask = pygame.mask.from_surface(self.image0) self.rect = self.image0.get_rect() if x == 'boss1发射' and y == 'boss1发射': self.rect.x, self.rect.y = boss.x + boss.width / 2 - self.width / 2, boss.y + boss.height * 5 / 4 else: self.rect.x, self.rect.y = x, y self.startx, self.starty = x, y self.warnwidth, self.warnheight = 1, 1200 self.warnrect = pygame.Rect(self.rect.x + (self.width / 2 - self.warnwidth / 2), self.rect.y, self.warnwidth, self.warnheight) self.warncolor = self.color self.warnimage = pygame.Surface((self.warnwidth, self.warnheight)) self.warnimage.fill(self.warncolor) self.warnimage.set_colorkey(black) self.angle = 0 self.boss = boss def update(self,x,y): if time.time() - self.starttime >= self.warnlasttime: self.warnflag = False else: self.warnflag = True if self.warnflag: if x == 'boss1发射' and y == 'boss1发射': warnrectx = self.boss.x + self.boss.width / 2 - self.width / 2 + (self.width / 2 - self.warnwidth / 2) warnrecty = self.boss.y + self.boss.height * 5 / 4 else: warnrectx, warnrecty = x, y self.startx, self.starty = x, y if 0 <= self.angle <= 90: self.warnrect.x = warnrectx + self.warnwidth / 2 - self.warnwidth / 2 * math.cos( self.angle * math.pi / 180) self.warnrect.y = warnrecty - self.warnwidth / 2 * math.sin(self.angle * math.pi / 180) elif 90 < self.angle <= 180: self.warnrect.x = warnrectx + self.warnwidth / 2 + self.warnwidth / 2 * math.cos( self.angle * math.pi / 180) self.warnrect.y = warnrecty - self.warnwidth / 2 * math.sin(self.angle * math.pi / 180) \ + self.warnheight * math.cos(self.angle * math.pi / 180) elif 180 < self.angle <= 270: self.warnrect.x = warnrectx + self.warnwidth / 2 + self.warnwidth / 2 * math.cos( self.angle * math.pi / 180) + self.warnheight * math.sin(self.angle * math.pi / 180) self.warnrect.y = warnrecty + self.warnwidth / 2 * math.sin( self.angle * math.pi / 180) + self.warnheight * math.cos(self.angle * math.pi / 180) elif 270 < self.angle <= 360: self.warnrect.x = warnrectx + self.warnwidth / 2 - self.warnwidth / 2 * math.cos( self.angle * math.pi / 180) + self.warnheight * math.sin(self.angle * math.pi / 180) self.warnrect.y = warnrecty + self.warnwidth / 2 * math.sin(self.angle * math.pi / 180) def rotate(self, angle, x = 'boss1发射', y = 'boss1发射'): self.image1 = pygame.transform.rotate(self.image0, angle).convert() if x == 'boss1发射' and y == 'boss1发射': self.rect.x, self.rect.y = self.boss.x + self.boss.width / 2 - self.width / 2, self.boss.y + self.boss.height * 5 / 4 else: self.rect.x, self.rect.y = x, y self.startx, self.starty = x, y self.mask = pygame.mask.from_surface(self.image1) if self.warnflag: self.warnimage = pygame.transform.rotate(self.warnimage, angle).convert() self.angle = angle if 0 <= angle <= 90: if not self.warnflag: self.rect.x = self.rect.x + self.width / 2 - self.width / 2 * math.cos(angle * math.pi / 180) self.rect.y = self.rect.y - self.width / 2 * math.sin(angle * math.pi / 180) elif self.warnflag: self.warnrect.x = self.warnrect.x + self.warnwidth / 2 - self.warnwidth / 2 * math.cos( angle * math.pi / 180) self.warnrect.y = self.warnrect.y - self.warnwidth / 2 * math.sin(angle * math.pi / 180) elif 90 < angle <= 180: if not self.warnflag: self.rect.x = self.rect.x + self.width / 2 + self.width / 2 * math.cos(angle * math.pi / 180) self.rect.y = self.rect.y - self.width / 2 * math.sin(angle * math.pi / 180) + self.height * math.cos( angle * math.pi / 180) elif self.warnflag: self.warnrect.x = self.warnrect.x + self.warnwidth / 2 + self.warnwidth / 2 * math.cos( angle * math.pi / 180) self.warnrect.y = (self.warnrect.y - self.warnwidth / 2 * math.sin(angle * math.pi / 180) + self.warnheight * math.cos(angle * math.pi / 180)) elif 180 < angle <= 270: if not self.warnflag: self.rect.x = self.rect.x + self.width / 2 + self.width / 2 * math.cos(angle * math.pi / 180) \ + self.height * math.sin(angle * math.pi / 180) self.rect.y = self.rect.y + self.width / 2 * math.sin(angle * math.pi / 180) + self.height * math.cos( angle * math.pi / 180) elif self.warnflag: self.warnrect.x = self.warnrect.x + self.warnwidth / 2 + self.warnwidth / 2 * math.cos( angle * math.pi / 180) \ + self.warnheight * math.sin(angle * math.pi / 180) self.warnrect.y = self.warnrect.y + self.warnwidth / 2 * math.sin( angle * math.pi / 180) + self.warnheight * math.cos( angle * math.pi / 180) elif 270 < angle <= 360: if not self.warnflag: self.rect.x = self.rect.x + self.width / 2 - self.width / 2 * math.cos( angle * math.pi / 180) + self.height * math.sin(angle * math.pi / 180) self.rect.y = self.rect.y + self.width / 2 * math.sin(angle * math.pi / 180) elif self.warnflag: self.warnrect.x = self.warnrect.x + self.warnwidth / 2 - self.warnwidth / 2 * math.cos( angle * math.pi / 180) + self.warnheight * math.sin(angle * math.pi / 180) self.warnrect.y = self.warnrect.y + self.warnwidth / 2 * math.sin(angle * math.pi / 180) def draw(self): if not self.warnflag: dissurf.blit(self.image1, (self.rect.x, self.rect.y)) else: dissurf.blit(self.warnimage, (self.warnrect.x, self.warnrect.y)) class Boss1: def __init__(self): self.maxhealth = 100 self.health = self.maxhealth self.bulletbasicspeed = 5 self.width = 100 self.height = 100 self.surf = pygame.image.load('boss1.jpg') self.surf = pygame.transform.scale(self.surf, (self.width, self.height)) self.moveleft = False self.moveright = False self.moveup = False self.movedown = False self.score = 10000 self.x = winwidth / 2 - self.width / 2 self.y = -self.height self.ybreadth = 30 self.bulletsize = 5 self.bulletlist = [] self.bubianstarttime = time.time() self.starttime = 0 self.movestarttime = time.time() self.movelastmaxtime = 5 self.movelastmintime = 1 self.movexlength = winwidth / 2 self.moveylength = winheight / 5 self.moveflag = False self.movelasttime = 4 self.xminspeed = 0.5 self.xmaxspeed = 4 self.yminspeed = 0.5 self.ymaxspeed = 3 self.bossoverflag = False self.chuzhaoflag = True self.chuzhaoovertime = 0 self.chuzhaobreadth = 3 self.chuchangover = False self.jindutiao = JinzhiJindutiao(winwidth / 2, 20, 450, 15, green, red, self.health, self.maxhealth) self.jiguanggroup = pygame.sprite.Group() self.player = player self.jiguangexistflag = False self.jiguangwarnlist = [] self.devicegailv = 100 self.device = None self.deviceexistflag = False def chuchang(self): if self.y <= self.ybreadth + 1: self.y += 1 else: if not self.chuchangover: self.bubianstarttime = time.time() self.chuchangover = True def skill1chushi(self, jiangetime, lasttime): # 三连发弹幕流,夹角45° if time.time() - self.bubianstarttime <= lasttime and self.chuchangover and self.chuzhaoflag: if time.time() - self.starttime > jiangetime: skill1bullet1 = createenemybullet(self.x + self.width / 2 - 6, self.y + self.height / 4 * 5, self.bulletsize, self.bulletsize, self.bulletbasicspeed, black) skill1bullet2 = createenemybullet(self.x + self.width / 2, self.y + self.height / 4 * 5, self.bulletsize, self.bulletsize, self.bulletbasicspeed, black) skill1bullet3 = createenemybullet(self.x + self.width / 2 + 6, self.y + self.height / 4 * 5, self.bulletsize, self.bulletsize, self.bulletbasicspeed, black) skill1bullet1['xspeed'] = - skill1bullet1['speed'] * (2 ** (1 / 2) / 2) skill1bullet1['yspeed'] = skill1bullet1['speed'] * (2 ** (1 / 2) / 2) skill1bullet2['xspeed'] = 0 skill1bullet2['yspeed'] = skill1bullet2['speed'] skill1bullet3['xspeed'] = - skill1bullet1['xspeed'] skill1bullet3['yspeed'] = skill1bullet1['yspeed'] self.bulletlist.append(skill1bullet1) self.bulletlist.append(skill1bullet2) self.bulletlist.append(skill1bullet3) self.starttime = time.time() elif self.chuzhaoflag and self.chuchangover: # 招式结束 self.chuzhaoflag = False self.chuzhaoovertime = time.time() def skill1change(self, lasttime): for bullet in self.bulletlist: bullet['x'] += bullet['xspeed'] bullet['y'] += bullet['yspeed'] def skill2chushi(self, jiangetime, lasttime): # 五连发弹幕流30° if time.time() - self.bubianstarttime <= lasttime and self.chuchangover and self.chuzhaoflag: if time.time() - self.starttime > jiangetime: skill2bullet1 = createenemybullet(self.x + self.width / 2 - 4, self.y + self.height / 4 * 5, self.bulletsize, self.bulletsize, self.bulletbasicspeed, black) skill2bullet2 = createenemybullet(self.x + self.width / 2 - 2, self.y + self.height / 4 * 5, self.bulletsize, self.bulletsize, self.bulletbasicspeed, black) skill2bullet3 = createenemybullet(self.x + self.width / 2, self.y + self.height / 4 * 5, self.bulletsize, self.bulletsize, self.bulletbasicspeed, black) skill2bullet4 = createenemybullet(self.x + self.width / 2 + 2, self.y + self.height / 4 * 5, self.bulletsize, self.bulletsize, self.bulletbasicspeed, black) skill2bullet5 = createenemybullet(self.x + self.width / 2 + 4, self.y + self.height / 4 * 5, self.bulletsize, self.bulletsize, self.bulletbasicspeed, black) skill2bullet1['xspeed'] = - skill2bullet1['speed'] * (3 ** (1 / 2) / 2) skill2bullet1['yspeed'] = skill2bullet1['speed'] * (1 / 2) skill2bullet2['xspeed'] = - skill2bullet2['speed'] * (1 / 2) skill2bullet2['yspeed'] = skill2bullet2['speed'] * (3 ** (1 / 2) / 2) skill2bullet3['xspeed'] = 0 skill2bullet3['yspeed'] = skill2bullet3['speed'] skill2bullet4['xspeed'] = - skill2bullet1['xspeed'] skill2bullet4['yspeed'] = skill2bullet1['yspeed'] skill2bullet5['xspeed'] = - skill2bullet2['xspeed'] skill2bullet5['yspeed'] = skill2bullet2['yspeed'] self.bulletlist.append(skill2bullet1) self.bulletlist.append(skill2bullet2) self.bulletlist.append(skill2bullet3) self.bulletlist.append(skill2bullet4) self.bulletlist.append(skill2bullet5) self.starttime = time.time() elif self.chuzhaoflag and self.chuchangover: # 招式结束 self.chuzhaoflag = False self.chuzhaoovertime = time.time() def skill2change(self, lasttime): for bullet in self.bulletlist: bullet['x'] += bullet['xspeed'] bullet['y'] += bullet['yspeed'] def skill3chushi(self, jiangetime, lasttime): # 七连发弹幕流15° if time.time() - self.bubianstarttime <= lasttime and self.chuchangover and self.chuzhaoflag: if time.time() - self.starttime > jiangetime: skill3bullet1 = createenemybullet(self.x + self.width / 2 - 3, self.y + self.height / 4 * 5, self.bulletsize, self.bulletsize, self.bulletbasicspeed, black) skill3bullet2 = createenemybullet(self.x + self.width / 2 - 2, self.y + self.height / 4 * 5, self.bulletsize, self.bulletsize, self.bulletbasicspeed, black) skill3bullet3 = createenemybullet(self.x + self.width / 2 - 1, self.y + self.height / 4 * 5, self.bulletsize, self.bulletsize, self.bulletbasicspeed, black) skill3bullet4 = createenemybullet(self.x + self.width / 2, self.y + self.height / 4 * 5, self.bulletsize, self.bulletsize, self.bulletbasicspeed, black) skill3bullet5 = createenemybullet(self.x + self.width / 2 + 1, self.y + self.height / 4 * 5, self.bulletsize, self.bulletsize, self.bulletbasicspeed, black) skill3bullet6 = createenemybullet(self.x + self.width / 2 + 2, self.y + self.height / 4 * 5, self.bulletsize, self.bulletsize, self.bulletbasicspeed, black) skill3bullet7 = createenemybullet(self.x + self.width / 2 + 3, self.y + self.height / 4 * 5, self.bulletsize, self.bulletsize, self.bulletbasicspeed, black) skill3bullet1['xspeed'] = - skill3bullet1['speed'] * math.sin(math.pi / 4) skill3bullet1['yspeed'] = skill3bullet1['speed'] * math.cos(math.pi / 4) skill3bullet2['xspeed'] = - skill3bullet2['speed'] * math.sin(math.pi / 6) skill3bullet2['yspeed'] = skill3bullet2['speed'] * math.cos(math.pi / 6) skill3bullet3['xspeed'] = - skill3bullet3['speed'] * math.sin(math.pi / 12) skill3bullet3['yspeed'] = skill3bullet3['speed'] * math.cos(math.pi / 12) skill3bullet4['xspeed'] = 0 skill3bullet4['yspeed'] = skill3bullet4['speed'] skill3bullet5['xspeed'] = - skill3bullet1['xspeed'] skill3bullet5['yspeed'] = skill3bullet1['yspeed'] skill3bullet6['xspeed'] = - skill3bullet2['xspeed'] skill3bullet6['yspeed'] = skill3bullet2['yspeed'] skill3bullet7['xspeed'] = - skill3bullet3['xspeed'] skill3bullet7['yspeed'] = skill3bullet3['yspeed'] self.bulletlist.append(skill3bullet1) self.bulletlist.append(skill3bullet2) self.bulletlist.append(skill3bullet3) self.bulletlist.append(skill3bullet4) self.bulletlist.append(skill3bullet5) self.bulletlist.append(skill3bullet6) self.bulletlist.append(skill3bullet7) self.starttime = time.time() elif self.chuzhaoflag and self.chuchangover: # 招式结束 self.chuzhaoflag = False self.chuzhaoovertime = time.time() def skill3change(self, lasttime): for bullet in self.bulletlist: bullet['x'] += bullet['xspeed'] bullet['y'] += bullet['yspeed'] def jiguang1(self, jiangetime, lasttime): if time.time() - self.bubianstarttime <= lasttime and self.chuchangover and self.chuzhaoflag: if time.time() - self.starttime > jiangetime: jiguang = Jiguang(self, 1,3) jiguang.rotate(random.choice((random.randint(270, 360), random.randint(0, 90)))) self.jiguanggroup.add(jiguang) self.starttime = time.time() elif time.time() - self.starttime > lasttime and self.chuzhaoflag and self.chuchangover: self.chuzhaoflag = False self.chuzhaoovertime = time.time() self.jiguanggroup.empty() def jiguang2(self, lasttime): # 固定七连激光 if time.time() - self.bubianstarttime <= lasttime and self.chuchangover and self.chuzhaoflag and not self.jiguangexistflag: angle = 300 while angle != 75: jiguang = Jiguang(self, 1,3) jiguang.rotate(angle) self.jiguanggroup.add(jiguang) angle += 15 if angle == 360: angle = 0 self.jiguangexistflag = True self.starttime = time.time() elif time.time() - self.starttime > lasttime and self.chuzhaoflag and self.chuchangover: self.chuzhaoflag = False self.chuzhaoovertime = time.time() self.jiguanggroup.empty() self.jiguangexistflag = False def jiguang3(self, stilltime, lasttime, w): # 逆时针为正方向 if time.time() - self.bubianstarttime <= lasttime and self.chuchangover and self.chuzhaoflag: rotatestartflag = time.time() - self.starttime > stilltime for jiguang in self.jiguanggroup: jiguang.update() if not rotatestartflag and not jiguang.warnflag: jiguang.rotate(jiguang.angle) if not self.jiguangexistflag: angle = 300 while angle != 75: jiguang = Jiguang(self, 1,3) jiguang.rotate(angle) self.jiguanggroup.add(jiguang) angle += 15 if angle == 360: angle = 0 self.jiguangexistflag = True self.starttime = time.time() elif time.time() - self.starttime > stilltime: # 开始旋转 for jiguang in self.jiguanggroup: if jiguang.angle + w > 360: jiguang.angle = jiguang.angle - 360 elif jiguang.angle + w < 0: jiguang.angle = jiguang.angle + 360 if 270 >= jiguang.angle + w >= 90: self.jiguanggroup.remove(jiguang) elif 270 <= jiguang.angle + w <= 360: jiguang.rotate(jiguang.angle + w) elif 0 <= jiguang.angle + w <= 90: jiguang.rotate(jiguang.angle + w) elif time.time() - self.starttime > lasttime and self.chuzhaoflag and self.chuchangover: self.chuzhaoflag = False self.chuzhaoovertime = time.time() self.jiguanggroup.empty() self.jiguangexistflag = False def drawjiguang(self): for jiguang in self.jiguanggroup: jiguang.draw() def createdevice(self): if random.randint(1, 6000) <= self.devicegailv and not self.deviceexistflag: self.device = Device(player, self) self.deviceexistflag = True def updatedevice(self): if self.device: if time.time() - self.device.chuzhaoovertime > self.device.chuzhaobreadth and not self.device.chuzhaoflag: # 该出招了! self.device.chuzhaoflag = True self.device.bubianstarttime = time.time() self.device.chuchang(1) #self.device.danmu(12, 0.6, 8, 10) self.device.jiguang(3, lasttime = 4, stilltime = 1, dw = 1) self.device.draw() def updatebullet(self): for bullet in self.bulletlist: bullet['x'] += bullet['xspeed'] bullet['y'] += bullet['yspeed'] def allattack(self): global score, wudiflag, wudistarttime, wuditime bossrect = pygame.Rect(self.x, self.y, self.width, self.height) # 检测子弹与boss的碰撞 for bullet in bulletlist: # 这个是玩家的子弹库 bulletrect = pygame.Rect(bullet['x'], bullet['y'], bullet['width'], bullet['height']) if bossrect.colliderect(bulletrect): bullet['cishu'] -= 1 self.health -= 1 if bullet['cishu'] <= 0: bulletlist.remove(bullet) if self.health <= 0: self.bossover() score += self.score # 检测boss子弹与玩家的碰撞 playerrect = pygame.Rect(playerobj['x'], playerobj['y'], playerobj['width'], playerobj['height']) for bullet in self.bulletlist: bulletrect = pygame.Rect(bullet['x'], bullet['y'], bullet['size'], bullet['size']) if bulletrect.colliderect(playerrect): self.bulletlist.remove(bullet) if not wudiflag: playerobj['health'] -= 1 wudiflag = True wudistarttime = time.time() wuditime = wudistarttime # 检测boss与玩家碰撞 if bossrect.colliderect(playerrect): if not wudiflag: playerobj['health'] -= 1 wudiflag = True wudistarttime = time.time() wuditime = wudistarttime self.health -= 10 if self.health <= 0: self.bossover() score += self.score # 检测激光和玩家的碰撞 self.player.update() asprite = pygame.sprite.spritecollideany(self.player, self.jiguanggroup, pygame.sprite.collide_mask) if asprite and not asprite.warnflag: # 发生碰撞 if not wudiflag: playerobj['health'] -= 1 wudiflag = True wudistarttime = time.time() wuditime = wudistarttime def bossover(self): # 播放动画 self.bulletlist.clear() self.bossoverflag = True def bossmove(self): if time.time() - self.movestarttime > self.movelasttime and self.moveflag == True: self.moveflag = False elif random.randint(1, 6000) < 200 and self.moveflag == False: self.moveflag = True self.movelasttime = random.uniform(self.movelastmintime, self.movelastmaxtime) self.movestarttime = time.time() self.xspeed = random.uniform(self.xminspeed, self.xmaxspeed) * random.choice((-1, 1)) self.yspeed = random.uniform(self.yminspeed, self.ymaxspeed) * random.choice((-1, 1)) if self.moveflag and self.chuchangover: if self.x + self.xspeed > 0 and self.x + self.xspeed <= winwidth - self.width: self.x += self.xspeed if self.y + self.yspeed <= self.moveylength and self.y + self.yspeed > self.ybreadth: self.y += self.yspeed def dealxiaoshi(self): for bullet in self.bulletlist: if bullet['x'] > winwidth or bullet['x'] < 0 or bullet['y'] - bullet['size'] < 0 or bullet['y'] > winheight: self.bulletlist.remove(bullet) def drawbossandbullet(self): dissurf.blit(self.surf, (self.x, self.y)) for bullet in self.bulletlist: dissurf.blit(bullet['surf'], (bullet['x'], bullet['y'])) if self.chuchangover: self.jindutiao.drawjindutiao(winwidth / 2, 20) self.jindutiao.presentshu = self.health fontsurf = bigfont.render(f"boss : {self.health} / {self.maxhealth}", True, black) dissurf.blit(fontsurf, (winwidth / 2 - 65, 5)) class Device: # 脱手技能,一开始动。停下来就不动了 def __init__(self, player, boss): self.size, self.width, self.height = 40, 40, 40 # self.image = pygame.image.load('脱手技能1.png') # self.image = pygame.transform.scale(self.image,(self.size.self.size)) self.image = pygame.Surface((self.size, self.size)) self.image.fill(red) self.player = player self.boss = boss self.rect = pygame.Rect(boss.x + boss.width / 2 - self.size / 2, boss.y + boss.height * 5 / 4, self.size, self.size) self.x, self.y = self.rect.x, self.rect.y self.chuzhaoflag = True self.chuzhaoovertime = 0 self.starttime = time.time() self.chuzhaobreadth = 3 self.chuchangover = False self.bubianstarttime = time.time() self.begintime = time.time() # self.jindutiao = JinzhiJindutiao(winwidth / 2, 20, 450, 15, green, red, self.health, self.maxhealth) self.jiguanggroup = pygame.sprite.Group() self.jiguangexistflag = False self.jiguangwarnlist = [] self.bulletslist = [] self.xspeed = random.uniform(1, 2) * random.randint(-1, 1) self.yspeed = random.uniform(1, 2) self.bulletspeed = 2 self.centrex = self.rect.x + self.size / 2 # 圆心坐标 self.centrey = self.rect.y + self.size / 2 self.r = self.size * (2 ** (1/2)) / 2 # 半径 self.bulletsize = 5 self.danmucishu = 0 self.jiguangcishu = 0# 用来记数 def chuchang(self, lasttime): if self.rect.x + self.xspeed > 0 and self.rect.x + self.xspeed + self.size < winwidth \ and time.time() - self.begintime < lasttime: # 防止出界,时间限制 self.rect.x += self.xspeed self.rect.y += self.yspeed self.centrex = self.rect.x + self.size / 2 self.centrey = self.rect.y + self.size / 2 self.x ,self.y = self.rect.x, self.rect.y else: if not self.chuchangover: self.bubianstarttime = time.time() self.chuchangover = True def danmu(self, number, jiangetime, lasttime, dw): if time.time() - self.bubianstarttime <= lasttime and self.chuchangover and self.chuzhaoflag: if time.time() - self.starttime > jiangetime: for i in range(number): angle = i * (360 / number) + self.danmucishu * dw x = self.centrex + self.r * math.cos(angle * math.pi / 180) y = self.centrey - self.r * math.sin(angle * math.pi / 180) bullet = createenemybullet(x, y, self.bulletsize, self.bulletsize, 0, black) bullet['xspeed'] = self.bulletspeed * math.cos(angle * math.pi / 180) bullet['yspeed'] = - self.bulletspeed * math.sin(angle * math.pi / 180) self.bulletslist.append(bullet) self.boss.bulletlist.append(bullet) self.starttime = time.time() self.danmucishu += 1 elif self.chuzhaoflag and self.chuchangover: # 招式结束 self.chuzhaoflag = False self.chuzhaoovertime = time.time() self.danmucishu = 0 def draw(self): dissurf.blit(self.image, (self.rect.x, self.rect.y)) def jiguang(self,number, lasttime, stilltime, dw): if time.time() - self.bubianstarttime <= lasttime and self.chuchangover and self.chuzhaoflag: rotatestartflag = time.time() - self.starttime > stilltime for jiguang in self.jiguanggroup: jiguang.update(jiguang.startx, jiguang.starty) if not rotatestartflag and not jiguang.warnflag: jiguang.rotate(jiguang.angle, jiguang.startx, jiguang.starty) if not self.jiguangexistflag: for i in range(number): angle = i * (360 / number) + self.jiguangcishu * dw x = self.centrex + self.r * math.cos(angle * math.pi / 180) y = self.centrey - self.r * math.sin(angle * math.pi / 180) jiguang = Jiguang(self, 1,3) jiguang.rotate(angle+90,x,y) self.jiguanggroup.add(jiguang) self.boss.jiguanggroup.add(jiguang) self.jiguangexistflag = True self.starttime = time.time() elif time.time() - self.starttime > stilltime: # 开始旋转 for jiguang in self.jiguanggroup: if jiguang.angle + dw > 360: jiguang.angle = jiguang.angle - 360 elif jiguang.angle + dw < 0: jiguang.angle = jiguang.angle + 360 jiguang.rotate(jiguang.angle + dw, jiguang.startx, jiguang.starty) elif time.time() - self.starttime > lasttime and self.chuzhaoflag and self.chuchangover: self.chuzhaoflag = False self.chuzhaoovertime = time.time() for jiguang in self.jiguanggroup: if jiguang in self.boss.jiguanggroup: self.boss.jiguanggroup.remove(jiguang) self.jiguanggroup.empty() self.jiguangexistflag = False self.jiguangcishu = 0 class player(pygame.sprite.Sprite): def __init__(self): super().__init__() self.image = playerobj['surf'] self.x = winwidth / 2 - playerwidth / 2 self.y = winheight - playerheight self.health = maxhealth self.speed = basicspeed self.width = playerwidth self.height = playerheight self.image = pygame.transform.scale(self.image, (playerwidth, playerheight)) self.mask = pygame.mask.from_surface(self.image) self.rect = pygame.Rect(self.x, self.y, self.width, self.height) def update(self): self.rect.x = playerobj['x'] self.rect.y = playerobj['y'] class Guanqia: def __init__(self, number): self.allnumber = number self.starttime = 0 self.bubianstarttime = time.time() self.cishu = 0 if random.randint(0, 1) == 0: self.moveflag = 1 # 设置为1或-1,1向右,反之向左 else: self.moveflag = -1 def guanqia1(self, jiangetime, lasttime): # 无规律(x坐标)间隔时间相同出现敌人 if time.time() - self.bubianstarttime <= lasttime: if time.time() - self.starttime > jiangetime: enemy = createenemy() enemy['y'] = enemybreadth enemy['x'] = random.randint(enemybreadth, winwidth - enemy['width'] - enemybreadth) enemylist.append(enemy) self.starttime = time.time() def guanqia2(self, jiangetime, lasttime): # 从左右两边界生成,间隔时间相同 if time.time() - self.bubianstarttime <= lasttime: if time.time() - self.starttime > jiangetime: enemy0, enemy1 = createenemy(), createenemy() enemy0['y'], enemy1['y'] = enemybreadth, enemybreadth enemy0['x'], enemy1['x'] = enemybreadth, winwidth - enemy1['width'] - enemybreadth enemylist.append(enemy0) enemylist.append(enemy1) self.starttime = time.time() def guanqia3(self, jiangetime, lasttime): # 从中间成对出现,间隔时间相同 if time.time() - self.bubianstarttime <= lasttime: if time.time() - self.starttime > jiangetime: enemy0, enemy1 = createenemy(), createenemy() enemy0['y'], enemy1['y'] = enemybreadth, enemybreadth enemy0['x'], enemy1['x'] = winwidth / 2 - enemy0[ 'width'] - enemybreadth / 2, winwidth / 2 + enemybreadth / 2 enemy0['moveleft'], enemy0['moveright'] = True, False enemy1['moveleft'], enemy1['moveright'] = False, True enemylist.append(enemy0) enemylist.append(enemy1) self.starttime = time.time() def guanqia4(self, jiangetime, lasttime): # 不会移动,快速左右生成,形成s形曲线 if time.time() - self.bubianstarttime <= lasttime: breadth = 200 if time.time() - self.starttime > jiangetime: enemy = createenemy() enemy['y'] = enemybreadth enemy['x'] = enemybreadth + self.cishu * breadth enemy['moveleft'] = False enemy['moveright'] = False if enemy['x'] + enemy['width'] + enemybreadth > winwidth: self.moveflag = -1 elif enemy['x'] - enemybreadth < 0: self.moveflag = 1 if self.moveflag == 1: self.cishu += 1 elif self.moveflag == -1: self.cishu -= 1 enemylist.append(enemy) self.starttime = time.time() def guanqia5(self, jiangetime, lasttime): # 一次性创建舰队 if not enemylist: updateenemylist(enemylist, number=self.allnumber) createfleet(enemylist) ''' def controllevel(): if ''' def beibulletattack(playerobj): global wudiflag, wudistarttime, wuditime playerrect = pygame.Rect(playerobj['x'], playerobj['y'], playerobj['width'], playerobj['height']) for bullet in enemybulletlist: bulletrect = pygame.Rect(bullet['x'], bullet['y'], bullet['width'], bullet['height']) if bulletrect.colliderect(playerrect): if not wudiflag: playerobj['health'] -= 1 wudiflag = True wudistarttime = time.time() wuditime = wudistarttime enemybulletlist.remove(bullet) if playerobj['health'] <= 0: showgameover() if bullet['x'] > winwidth or bullet['x'] < 0 or bullet['y'] - bullet['size'] < 0 or bullet['y'] > winheight: enemybulletlist.remove(bullet) def drawenemybullet(): for bullet in enemybulletlist: dissurf.blit(bullet['surf'], (bullet['x'], bullet['y'])) def updateenemybulletlocation(): for bullet in enemybulletlist: bullet['x'] += bullet['xspeed'] bullet['y'] += bullet['yspeed'] def appendenemybullet(enemy, playerobj): lx = playerobj['x'] - enemy['x'] ly = playerobj['y'] - enemy['y'] ls = (lx ** 2 + ly ** 2) ** (1 / 2) xspeed = enemy['bulletspeed'] * lx / ls yspeed = enemy['bulletspeed'] * ly / ls bullet = createenemybullet(enemy['x'] + enemy['width'] / 2 - 3, enemy['y'] + enemy['height'] / 2 * 3, enemy['bulletsize'], enemy['bulletsize'], enemy['bulletspeed'], black) bullet['xspeed'] = xspeed bullet['yspeed'] = yspeed enemybulletlist.append(bullet) def createenemybullet(x, y, width, height, speed, color): bullet = {'x': x, 'y': y, 'width': width, 'height': height, 'size': width, 'speed': speed, 'xspeed': 0, 'yspeed': 0, 'surf': pygame.Surface((width, height)), } bullet['surf'].fill(color) return bullet def reset(): global score, level, moveright, moveleft, moveup, movedown, bossexistflag score = 0 level = 0 bulletlist.clear() enemylist.clear() enemybulletlist.clear() playerobj['x'] = winwidth / 2 - playerwidth / 2 playerobj['y'] = winheight - playerheight playerobj['health'] = maxhealth moveright, moveleft, moveup, movedown = False, False, False, False bossexistflag = False def showgameover(): s = 0 buttonwidth = 150 buttonheight = 50 buttonrect = pygame.Rect(winwidth / 2 - buttonwidth / 2, winheight / 2 + 200, buttonwidth, buttonheight) buttonfont = biggerfont.render('try again', True, black) breakflag = False while True: s += 1 if s <= 80: surf = pygame.font.Font('freesansbold.ttf', s).render('G A M E O V E R !', True, black) dissurf.fill(bgcolor) dissurf.blit(surf, (255, 300)) if s > 80: pygame.draw.rect(dissurf, blue, buttonrect) dissurf.blit(buttonfont, (buttonrect.x + 25, buttonrect.y + 10)) for event in pygame.event.get(): if event.type == QUIT: terminate() if event.type == MOUSEBUTTONUP: x, y = event.pos if buttonrect.collidepoint((x, y)): breakflag = True if breakflag: break pygame.display.update() clock.tick(FPS) reset() def drawplayerhealth(playerobj): playerobj['healthjindutiao'].presentshu = playerobj['health'] playerobj['healthjindutiao'].drawjindutiao(110, 20) fontsurf = bigfont.render(f"health : {playerobj['health']} / {maxhealth}", True, black) dissurf.blit(fontsurf, (62, 5)) def drawscore(): scorestr = "{:0>8}".format(score) lst = list(scorestr) lst.insert(-3, ',') lst.insert(-7, ',') scorestr = ''.join(lst) fontsurf = biggerfont.render(scorestr, True, black) dissurf.blit(fontsurf, (winwidth - 135, 5)) def drawenemyhealth(enemy): enemy['healthjindutiao'].presentshu = enemy['health'] enemy['healthjindutiao'].drawjindutiao(enemy['x'] + enemy['width'] / 2, enemy['y'] - enemy['healthjindutiao'].height - 4) fontsurf = basicfont.render(f"{enemy['health']} / {enemymaxhealth}", True, black) dissurf.blit(fontsurf, (enemy['x'] + enemy['width'] / 3, enemy['y'] - enemy['healthjindutiao'].height * 2 - 4)) class TimeJindutiao: def __init__(self, x, y, width, height, color, outcolor, lasttime, starttime): # x是进度条中点,y是最底边 self.x, self.y = x, y self.shuzhibreadth = 10 self.pointlist = [(self.x - width / 2, self.y - height), (self.x + width / 2, self.y - height), (self.x + width / 2, self.y), (self.x - width / 2, self.y)] self.zongcishu = lasttime * FPS # 运行这么多次绘制完进度条 self.rect = pygame.Rect(self.x - width / 2 + 1, self.y - height + 1, 0, height - 2) self.color = color self.outcolor = outcolor self.width = width self.height = height def drawjindutiao(self, x, y): # x是进度条中点,y是最底边 self.rect.x = x self.rect.y = y self.rect.width += (self.width - 2) / self.zongcishu self.pointlist = [(x - self.width / 2, y - self.height), (x + self.width / 2, y - self.height), (x + self.width / 2, y), (x - self.width / 2, y)] pygame.draw.rect(dissurf, self.color, self.rect) pygame.draw.lines(dissurf, self.outcolor, True, self.pointlist, width=1) class JinzhiJindutiao: def __init__(self, x, y, width, height, color, outcolor, presentshu, allshu): # x是进度条中点,y是最底边 self.x, self.y = x, y self.pointlist = [(self.x - width / 2, self.y - height), (self.x + width / 2, self.y - height), (self.x + width / 2, self.y), (self.x - width / 2, self.y)] self.rect = pygame.Rect(self.x - width / 2 + 1, self.y - height + 1, 0, height - 2) self.color = color self.outcolor = outcolor self.width = width self.height = height self.presentshu = presentshu self.allshu = allshu def drawjindutiao(self, x, y): # x是进度条中点,y是最底边 self.rect.x = x - self.width / 2 + 1 self.rect.y = y - self.height + 1 self.rect.width = (self.presentshu / self.allshu) * (self.width - 2) self.pointlist = [(x - self.width / 2, y - self.height), (x + self.width / 2, y - self.height), (x + self.width / 2, y), (x - self.width / 2, y)] pygame.draw.rect(dissurf, self.color, self.rect) pygame.draw.lines(dissurf, self.outcolor, True, self.pointlist, width=1) def flipmovelr(enemy): if enemy['moveright']: enemy['moveright'] = False enemy['moveleft'] = True elif enemy['moveleft']: enemy['moveleft'] = False enemy['moveright'] = True def updateplayerlocation(playerobj): if moveright and not moveleft: playerobj['x'] += playerobj['speed'] elif moveleft and not moveright: playerobj['x'] -= playerobj['speed'] if moveup and not movedown: playerobj['y'] -= playerobj['speed'] elif movedown and not moveup: playerobj['y'] += playerobj['speed'] def updatebulletlocation(bulletlist): for bullet in bulletlist: bullet['y'] -= bullet['speed'] def createenemy(): enemy = {'x': 0, 'y': 0, 'width': enemywidth, 'height': enemyheight, 'xspeed': 1, 'yspeed': 1, 'moveright': False, 'moveleft': False, 'health': enemymaxhealth, 'surf': pygame.image.load('敌人飞船.png'), 'score': 100, 'attack': 1, 'bulletspeed': enemybulletspeed, 'bulletsize': enemybulletsize, 'bulletcolor': enemybulletcolor, } enemy['surf'] = pygame.transform.scale(enemy['surf'], (enemywidth, enemyheight)) enemy['surf'] = pygame.transform.flip(enemy['surf'], False, True) jindutiao = JinzhiJindutiao(enemy['x'] + enemy['width'] / 2, enemy['y'] - 2, enemy['width'] / 3 * 2, 8, green, red, enemy['health'], enemymaxhealth) enemy['healthjindutiao'] = jindutiao if random.randint(0, 1) == 0: enemy['moveleft'] = True else: enemy['moveright'] = True return enemy def updateenemylist(enemylist, number=1, delflag=False, delnumber=0): if not delflag: for i in range(number): enemylist.append(createenemy()) else: for i in range(delnumber): del enemylist[-1] def updatebulletlist(bulletlist, bullet, number=1, delflag=False, delnumber=0): if not delflag: for i in range(number): bulletlist.append(bullet) else: for i in range(delnumber): del bulletlist[-1] def createfleet(enemylist): # 只在每次舰队刚开始出现时调用 xcishu = 0 ycishu = 0 for enemy in enemylist: if enemybreadth + (enemy['width'] + enemybreadth) * (xcishu + 1) <= winwidth: enemy['x'] = enemybreadth + (enemy['width'] + enemybreadth) * xcishu enemy['y'] = enemybreadth + (enemy['height'] + enemybreadth) * ycishu xcishu += 1 else: xcishu = 0 ycishu += 1 enemy['x'] = enemybreadth enemy['y'] = enemybreadth + (enemy['height'] + enemybreadth) * ycishu xcishu = 1 def updatefleet(enemy): enemy['y'] += enemy['yspeed'] if enemybreadth + enemy['width'] + enemy['x'] > winwidth: enemy['moveright'], enemy['moveleft'] = False, True elif enemy['x'] - enemybreadth < 0: enemy['moveright'], enemy['moveleft'] = True, False if enemy['moveright'] and not enemy['moveleft']: enemy['x'] += enemy['xspeed'] elif enemy['moveleft'] and not enemy['moveright']: enemy['x'] -= enemy['xspeed'] def allattack(enemy, bulletlist, playerobj): global score enemyrect = pygame.Rect(enemy['x'], enemy['y'], enemy['width'], enemy['height']) for bullet in bulletlist: bulletrect = pygame.Rect(bullet['x'], bullet['y'], bullet['width'], bullet['height']) if enemyrect.colliderect(bulletrect): bullet['cishu'] -= 1 enemy['health'] -= 1 if bullet['cishu'] <= 0: bulletlist.remove(bullet) if enemy['health'] <= 0: enemylist.remove(enemy) score += enemy['score'] beiattack(enemy, playerobj) def beiattack(enemy, playerobj): global score, wudiflag, wudistarttime, wuditime enemyrect = pygame.Rect(enemy['x'], enemy['y'], enemy['width'], enemy['height']) playerrect = pygame.Rect(playerobj['x'], playerobj['y'], playerobj['width'], playerobj['height']) if enemyrect.colliderect(playerrect): enemylist.remove(enemy) if not wudiflag: playerobj['health'] -= 1 wudiflag = True wudistarttime = time.time() wuditime = wudistarttime score += enemy['score'] if playerobj['health'] <= 0: showgameover() def dealxiaoshi(bulletlist, enemylist): for bullet in bulletlist: if bullet['cishu'] <= 0 or bullet['x'] > winwidth or \ bullet['y'] - bullet['height'] < 0: bulletlist.remove(bullet) for enemy in enemylist: if enemy['y'] > winheight: enemylist.remove(enemy) def createbullet(x, y, width, height, speed, cishu=1): # cishu为剩余穿透次数 bullet = {'x': x, 'y': y, 'width': width, 'height': height, 'speed': speed, 'cishu': cishu, 'surf': pygame.Surface((width, height))} bullet['surf'].fill(red) return bullet def drawenemyfleet(enemylist): for enemy in enemylist: dissurf.blit(enemy['surf'], (enemy['x'], enemy['y'])) def drawbullets(bulletlist): for bullet in bulletlist: dissurf.blit(bullet['surf'], (bullet['x'], bullet['y'])) def terminate(): pygame.quit() sys.exit() main()