导语
“宇宙比任何人所能想像的大得多,如果只有我们,那不是太浪费空间了吗?”
忘了到底是从哪搞来的,可能是隔壁班借的,也可能是亲戚朋友给买的。
总之,打着手电筒躲在被窝里看到12点,还越怕越想看~
百慕大三角、UFO、消失多年的飞机、解剖外星人、水晶头盖骨、大脚怪、麦田怪圈、埃及金字塔……
今天的文章就是大家感兴趣的外星人话题!小编脑容量有限倒是想象不出来外星人长什么样子。
但是我可以卡通化一下这款外星人小游戏给大家!绝对不恐怖,甚至还有点儿可爱~
正文
写游戏嘛?还是大家熟悉的pygame模块,主要是分为三块py源码文件。
游戏规则:我方控制炮台击落外星人入侵地球🌏,每次可以重生三次,击毁一次外星人相应加分,进入下一关,完成全部关卡即可通关。
首先定义我方炮台类:有相应注释可看。
'''我方类'''
class aircraftSprite(pygame.sprite.Sprite):def __init__(self, color, bullet_color, **kwargs):pygame.sprite.Sprite.__init__(self)# 生命值self.num_life = 3self.max_num_life = 5# 最小单元self.cell = [3, 3]self.num_cols = 15self.num_rows = 8# 用于碰撞检测self.rect = pygame.Rect(0, 550, self.cell[0] * self.num_cols, self.cell[0] * self.num_rows)# 填充颜色区域self.filled_cells = [7,21,22,23,36,37,38,46,47,48,49,50,51,52,53,54,55,56,57,58,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119]# 飞船颜色self.color = color# 飞船子弹颜色self.bullet_color = bullet_color# 子弹是否在冷却中self.is_cooling = Falseself.init_count = 35self.cooling_count = self.init_count# 得分self.score = 0# 避免重复增加生命值self.old_score = -1self.resetBoom()'''射击'''def shot(self):if self.is_cooling:return Noneself.is_cooling = Trueself.cooling_count = self.init_countreturn myBulletSprite(self.rect.x + self.rect.width // 2, self.rect.y, self.bullet_color)'''在屏幕上画出来'''def draw(self, screen):for i in range(0, len(self.filled_cells)):y = self.filled_cells[i] // self.num_colsx = self.filled_cells[i] % self.num_colsrect = [x * self.cell[0] + self.rect[0], y * self.cell[1] + self.rect[1], self.cell[0], self.cell[1]]pygame.draw.rect(screen, self.color, rect)'''更新飞船位置等信息'''def update(self, WIDTH):# 位置信息x = pygame.mouse.get_pos()[0] - (self.rect.width // 2)if x < 0:x = pygame.mouse.get_pos()[0]elif x > WIDTH - self.rect.width:x = WIDTH - self.rect.widthself.rect.x = x# 子弹信息if self.is_cooling:self.cooling_count -= 1if self.cooling_count == 0:self.is_cooling = False'''被击中后爆炸'''def boom(self, screen):self.boomed_rect.x = self.rect.xself.boomed_rect.y = self.rect.yself.boomed_count += 1if self.boomed_count % 1 == 0:self.boomed_frame += 1for i in range(0, len(self.boomed_filled_cells)):y = self.boomed_filled_cells[i] // self.boomed_num_colsx = self.boomed_filled_cells[i] % self.boomed_num_colsrect = [x * self.boomed_cell[0] + self.boomed_rect[0], y * self.boomed_cell[1] + self.boomed_rect[1], self.boomed_cell[0], self.boomed_cell[1]]pygame.draw.rect(screen, self.color, rect)if self.boomed_frame > 4:return Trueelse:return False'''重置爆炸所用到的数据'''def resetBoom(self):# 被击中爆炸时用self.one_dead = Falseself.boomed_filled_cells = [3,7,12,15,17,20,24,30,36,40,44,45,53,54,58,62,68,74,78,81,83,86,91,95]self.boomed_cell = [3, 3]self.boomed_num_cols = 11self.boomed_num_rows = 9self.boomed_rect = pygame.Rect(0, 0, self.boomed_num_cols*self.boomed_cell[0], self.boomed_num_rows*self.boomed_cell[1])# 控制每帧的时间self.boomed_count = 0# 爆炸特效当前帧self.boomed_frame = 0
然后定义地方ufo类:
class enemySprite(pygame.sprite.Sprite):def __init__(self, category, number, color, bullet_color, **kwargs):pygame.sprite.Sprite.__init__(self)self.cell = [3, 3]# 编号self.number = number# 种类self.category = categoryif category == 'small':self.reward = 20self.num_cols = 8self.num_rows = 8self.rect = pygame.Rect(0, 0, self.num_cols * self.cell[0], self.num_rows * self.cell[1])self.filled_cells = [[3,4,10,11,12,13,17,18,19,20,21,22,24,25,27,28,30,31,32,33,34,35,36,37,38,39,42,45,49,51,52,54,56,58,61,63], [3,4,10,11,12,13,17,18,19,20,21,22,24,25,27,28,30,31,32,33,34,35,36,37,38,39,41,43,44,46,48,55,57,62]]elif category == 'medium':self.reward = 15self.num_cols = 11self.num_rows = 8self.rect = pygame.Rect(0, 0, self.num_cols * self.cell[0], self.num_rows * self.cell[1])self.filled_cells = [[2,8,11,14,18,21,22,24,25,26,27,28,29,30,32,33,34,35,37,38,39,41,42,43,44,45,46,47,48,49,50,51,52,53,54,56,57,58,59,60,61,62,63,64,68,74,78,86], [2,8,14,18,24,25,26,27,28,29,30,34,35,37,38,39,41,42,44,45,46,47,48,49,50,51,52,53,54,55,57,58,59,60,61,62,63,65,66,68,74,76,80,81,83,84]]elif category == 'large':self.reward = 10self.num_cols = 12self.num_rows = 8self.rect = pygame.Rect(0, 0, self.num_cols * self.cell[0], self.num_rows * self.cell[1])self.filled_cells = [[4,5,6,7,13,14,15,16,17,18,19,20,21,22,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,41,42,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,62,63,64,67,68,69,73,74,77,78,81,82,86,87,92,93], [4,5,6,7,13,14,15,16,17,18,19,20,21,22,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,41,42,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,63,64,67,68,74,75,77,78,80,81,84,85,94,95]]self.color = colorself.bullet_color = bullet_colorself.speed = [8, 20]self.change_count = 0self.change_flag = False# 被击中爆炸时用self.boomed_filled_cells = [3,7,12,15,17,20,24,30,36,40,44,45,53,54,58,62,68,74,78,81,83,86,91,95]self.boomed_cell = [3, 3]self.boomed_num_cols = 11self.boomed_num_rows = 9self.boomed_rect = pygame.Rect(0, 0, self.boomed_num_cols * self.boomed_cell[0], self.boomed_num_rows * self.boomed_cell[1])self.boomed_count = 0self.boomed_frame = 0'''射击'''def shot(self):return enemyBulletSprite(self.rect.x + self.rect.width // 2, self.rect.y, self.bullet_color)'''在屏幕上画出来'''def draw(self, screen):if self.change_count > 50:self.change_count = 0self.change_flag = not self.change_flagif self.change_flag:for i in range(0, len(self.filled_cells[0])):y = self.filled_cells[0][i] // self.num_colsx = self.filled_cells[0][i] % self.num_colsrect = [x * self.cell[0] + self.rect[0], y * self.cell[1] + self.rect[1], self.cell[0], self.cell[1]]pygame.draw.rect(screen, self.color, rect)else:for i in range(0, len(self.filled_cells[1])):y = self.filled_cells[1][i] // self.num_colsx = self.filled_cells[1][i] % self.num_colsrect = [x * self.cell[0] + self.rect[0], y * self.cell[1] + self.rect[1], self.cell[0], self.cell[1]]pygame.draw.rect(screen, self.color, rect)'''更新敌方位置等信息'''def update(self, direction, HEIGHT):# 用于改变形状self.change_count += 1# 更新位置信息if direction == 'right':self.rect.x += self.speed[0]elif direction == 'left':self.rect.x -= self.speed[0]elif direction == 'down':self.rect.y += self.speed[1]if self.rect.y >= HEIGHT - self.rect.height:return Trueelse:return False'''被击中后爆炸'''def boom(self, screen):self.boomed_rect.x = self.rect.xself.boomed_rect.y = self.rect.yself.boomed_count += 1if self.boomed_count % 1 == 0:self.boomed_frame += 1for i in range(0, len(self.boomed_filled_cells)):y = self.boomed_filled_cells[i] // self.boomed_num_colsx = self.boomed_filled_cells[i] % self.boomed_num_colsrect = [x * self.boomed_cell[0] + self.boomed_rect[0], y * self.boomed_cell[1] + self.boomed_rect[1], self.boomed_cell[0], self.boomed_cell[1]]pygame.draw.rect(screen, self.color, rect)if self.boomed_frame > 4:return Trueelse:return False
敌人跟我方交涉,射击子弹:
class myBulletSprite(pygame.sprite.Sprite):def __init__(self, x, y, color, **kwargs):pygame.sprite.Sprite.__init__(self)self.cell = [2, 2]self.num_cols = 1self.num_rows = 4self.rect = pygame.Rect(x, y, self.num_cols * self.cell[0], self.num_rows * self.cell[1])self.filled_cells = [0,1,2,3]self.speed = 8self.color = color'''在屏幕上画出来'''def draw(self, screen):for i in range(0, len(self.filled_cells)):y = self.filled_cells[i] // self.num_colsx = self.filled_cells[i] % self.num_colsrect = [x * self.cell[0] + self.rect[0], y * self.cell[1] + self.rect[1], self.cell[0], self.cell[1]]pygame.draw.rect(screen, self.color, rect)'''更新子弹位置等信息'''def update(self):self.rect.y -= self.speedif self.rect.y + self.rect.height < 0:return Trueelse:return False'''敌方子弹精灵类'''
class enemyBulletSprite(pygame.sprite.Sprite):def __init__(self, x, y, color):pygame.sprite.Sprite.__init__(self)self.cell = [3, 3]self.num_cols = 3self.num_rows = 7self.rect = pygame.Rect(x, y, self.num_cols * self.cell[0], self.num_rows * self.cell[1])self.filled_cells = [[0,4,8,10,12,16,20], [2,4,6,10,14,16,18]]self.change_count = 0self.change_flag = Falseself.speed = 4self.color = color'''在屏幕上画出来'''def draw(self, screen):if self.change_count > 2:self.change_count = 0self.change_flag = not self.change_flagif self.change_flag:for i in range(0, len(self.filled_cells[0])):y = self.filled_cells[0][i] // self.num_colsx = self.filled_cells[0][i] % self.num_colsrect = [x * self.cell[0] + self.rect[0], y * self.cell[1] + self.rect[1], self.cell[0], self.cell[1]]pygame.draw.rect(screen, self.color, rect)else:for i in range(0, len(self.filled_cells[1])):y = self.filled_cells[1][i] // self.num_colsx = self.filled_cells[1][i] % self.num_colsrect = [x * self.cell[0] + self.rect[0], y * self.cell[1] + self.rect[1], self.cell[0], self.cell[1]]pygame.draw.rect(screen, self.color, rect)'''更新子弹位置等信息'''def update(self, HEIGHT):# 用于改变子弹形状的计数self.change_count += 1# 位置信息self.rect.y += self.speedif self.rect.y > HEIGHT:return Trueelse:return False
代码很多,附主要代码文件:
import os
import sys
import cfg
import random
import pygame
from modules import *'''开始游戏'''
def startGame(screen):clock = pygame.time.Clock()# 加载字体font = pygame.font.SysFont('arial', 18)if not os.path.isfile('score'):f = open('score', 'w')f.write('0')f.close()with open('score', 'r') as f:highest_score = int(f.read().strip())# 敌方enemies_group = pygame.sprite.Group()for i in range(55):if i < 11:enemy = enemySprite('small', i, cfg.WHITE, cfg.WHITE)elif i < 33:enemy = enemySprite('medium', i, cfg.WHITE, cfg.WHITE)else:enemy = enemySprite('large', i, cfg.WHITE, cfg.WHITE)enemy.rect.x = 85 + (i % 11) * 50enemy.rect.y = 120 + (i // 11) * 45enemies_group.add(enemy)boomed_enemies_group = pygame.sprite.Group()en_bullets_group = pygame.sprite.Group()ufo = ufoSprite(color=cfg.RED)# 我方myaircraft = aircraftSprite(color=cfg.GREEN, bullet_color=cfg.WHITE)my_bullets_group = pygame.sprite.Group()# 用于控制敌方位置更新# --移动一行enemy_move_count = 24enemy_move_interval = 24enemy_move_flag = False# --改变移动方向(改变方向的同时集体下降一次)enemy_change_direction_count = 0enemy_change_direction_interval = 60enemy_need_down = Falseenemy_move_right = Trueenemy_need_move_row = 6enemy_max_row = 5# 用于控制敌方发射子弹enemy_shot_interval = 100enemy_shot_count = 0enemy_shot_flag = False# 游戏进行中running = Trueis_win = False# 主循环while running:screen.fill(cfg.BLACK)for event in pygame.event.get():# --点右上角的X或者按Esc键退出游戏if event.type == pygame.QUIT:pygame.quit()sys.exit()if event.type == pygame.KEYDOWN:if event.key == pygame.K_ESCAPE:pygame.quit()sys.exit()# --射击if event.type == pygame.MOUSEBUTTONDOWN:my_bullet = myaircraft.shot()if my_bullet:my_bullets_group.add(my_bullet)# --我方子弹与敌方/UFO碰撞检测for enemy in enemies_group:if pygame.sprite.spritecollide(enemy, my_bullets_group, True, None):boomed_enemies_group.add(enemy)enemies_group.remove(enemy)myaircraft.score += enemy.rewardif pygame.sprite.spritecollide(ufo, my_bullets_group, True, None):ufo.is_dead = Truemyaircraft.score += ufo.reward# --更新并画敌方# ----敌方子弹enemy_shot_count += 1if enemy_shot_count > enemy_shot_interval:enemy_shot_flag = Trueenemies_survive_list = [enemy.number for enemy in enemies_group]shot_number = random.choice(enemies_survive_list)enemy_shot_count = 0# ----敌方移动enemy_move_count += 1if enemy_move_count > enemy_move_interval:enemy_move_count = 0enemy_move_flag = Trueenemy_need_move_row -= 1if enemy_need_move_row == 0:enemy_need_move_row = enemy_max_rowenemy_change_direction_count += 1if enemy_change_direction_count > enemy_change_direction_interval:enemy_change_direction_count = 1enemy_move_right = not enemy_move_rightenemy_need_down = True# ----每次下降提高移动和射击速度enemy_move_interval = max(15, enemy_move_interval-3)enemy_shot_interval = max(50, enemy_move_interval-10)# ----遍历更新for enemy in enemies_group:if enemy_shot_flag:if enemy.number == shot_number:en_bullet = enemy.shot()en_bullets_group.add(en_bullet)if enemy_move_flag:if enemy.number in range((enemy_need_move_row-1)*11, enemy_need_move_row*11):if enemy_move_right:enemy.update('right', cfg.SCREENSIZE[1])else:enemy.update('left', cfg.SCREENSIZE[1])else:enemy.update(None, cfg.SCREENSIZE[1])if enemy_need_down:if enemy.update('down', cfg.SCREENSIZE[1]):running = Falseis_win = Falseenemy.change_count -= 1enemy.draw(screen)enemy_move_flag = Falseenemy_need_down = Falseenemy_shot_flag = False# ----敌方爆炸特效for boomed_enemy in boomed_enemies_group:if boomed_enemy.boom(screen):boomed_enemies_group.remove(boomed_enemy)del boomed_enemy# --敌方子弹与我方飞船碰撞检测if not myaircraft.one_dead:if pygame.sprite.spritecollide(myaircraft, en_bullets_group, True, None):myaircraft.one_dead = Trueif myaircraft.one_dead:if myaircraft.boom(screen):myaircraft.resetBoom()myaircraft.num_life -= 1if myaircraft.num_life < 1:running = Falseis_win = Falseelse:# ----更新飞船myaircraft.update(cfg.SCREENSIZE[0])# ----画飞船myaircraft.draw(screen)if (not ufo.has_boomed) and (ufo.is_dead):if ufo.boom(screen):ufo.has_boomed = Trueelse:# ----更新UFOufo.update(cfg.SCREENSIZE[0])# ----画UFOufo.draw(screen)# --画我方飞船子弹for bullet in my_bullets_group:if bullet.update():my_bullets_group.remove(bullet)del bulletelse:bullet.draw(screen)# --画敌方子弹for bullet in en_bullets_group:if bullet.update(cfg.SCREENSIZE[1]):en_bullets_group.remove(bullet)del bulletelse:bullet.draw(screen)if myaircraft.score > highest_score:highest_score = myaircraft.score# --得分每增加2000我方飞船增加一条生命if (myaircraft.score % 2000 == 0) and (myaircraft.score > 0) and (myaircraft.score != myaircraft.old_score):myaircraft.old_score = myaircraft.scoremyaircraft.num_life = min(myaircraft.num_life + 1, myaircraft.max_num_life)# --敌人都死光了的话就胜利了if len(enemies_group) < 1:is_win = Truerunning = False# --显示文字# ----当前得分showText(screen, 'SCORE: ', cfg.WHITE, font, 200, 8)showText(screen, str(myaircraft.score), cfg.WHITE, font, 200, 24)# ----敌人数量showText(screen, 'ENEMY: ', cfg.WHITE, font, 370, 8)showText(screen, str(len(enemies_group)), cfg.WHITE, font, 370, 24)# ----历史最高分showText(screen, 'HIGHEST: ', cfg.WHITE, font, 540, 8)showText(screen, str(highest_score), cfg.WHITE, font, 540, 24)# ----FPSshowText(screen, 'FPS: ' + str(int(clock.get_fps())), cfg.RED, font, 8, 8)# --显示剩余生命值showLife(screen, myaircraft.num_life, cfg.GREEN)pygame.display.update()clock.tick(cfg.FPS)with open('score', 'w') as f:f.write(str(highest_score))return is_win'''主函数'''
def main():# 初始化pygame.init()pygame.display.set_caption('外星人入侵 ')screen = pygame.display.set_mode(cfg.SCREENSIZE)pygame.mixer.init()pygame.mixer.music.load(cfg.BGMPATH)pygame.mixer.music.set_volume(0.4)pygame.mixer.music.play(-1)while True:is_win = startGame(screen)endInterface(screen, cfg.BLACK, is_win)'''run'''
if __name__ == '__main__':main()
效果如下:
总结
好啦!这款外星人大战的小游戏就完成了~想要这款游戏嘛?
💖关注小编——获取更多精彩内容源码哦!
你们的支持是我最大的动力!!记得三连哦~mua 欢迎大家阅读往期更多的游戏文章~
源码基地:
主页(pc端)左侧源码基地免费拿小程序!或者私信小编也可!
1.1Python—2021 |已有文章汇总 | 持续更新,直接看这篇就够了~