赞
踩
哈喽!大家好!今天给大家更新一款经典小游戏吖!
十几年过去了,这款游戏渐渐被人遗忘。这是多少人的童年呢?
过气游戏?小鸟不angry,你还真以为我是“hello bird”?
现在的冷天气,除了穿多点儿衣服,可能就要靠这只火爆的小鸟给大家升温了!
首先环境安装部分:
准备—Python3.6、Pycharm2021、最主要的游戏模块Pygame、以及一些自带的模块直接可用的。
游戏源码可版本不一致也能运行,相应的模块安装好就可,自行安排!
pip install -i https://pypi.douban.com/simple/ pygame
准备—相应的素材图片、音乐背景等:
定义精灵类这里定义的是对手的猪猪。
- class Pig(pygame.sprite.Sprite):
- def __init__(self, screen, imagepaths, loc_info, velocity=None, **kwargs):
- pygame.sprite.Sprite.__init__(self)
- assert len(loc_info) == 3
- assert len(imagepaths) == 3
- # 设置必要的属性常量
- self.screen = screen
- self.loc_info = list(loc_info)
- self.imagepaths = imagepaths
- self.velocity = VelocityVector() if velocity is None else velocity
- self.type = 'pig'
- self.is_dead = False
- self.elasticity = 0.8
- self.switch_freq = 20
- self.animate_count = 0
- self.inverse_friction = 0.99
- self.gravity = VelocityVector(0.2, math.pi)
- # 屏幕大小
- self.screen_size = screen.get_rect().size
- self.screen_size = (self.screen_size[0], self.screen_size[1] - 50)
- # 导入图像
- self.pig_images = []
- for imagepath in imagepaths: self.pig_images.append(pygame.image.load(imagepath))
- # 设置当前图像
- self.image = random.choice(self.pig_images[:2])
- '''画到屏幕上'''
- def draw(self):
- self.animate_count += 1
- if (self.animate_count % self.switch_freq == 0) and (not self.is_dead):
- self.animate_count = 0
- self.image = random.choice(self.pig_images[:2])
- position = self.loc_info[0] - self.loc_info[2], self.loc_info[1] - self.loc_info[2]
- self.screen.blit(self.image, position)
- '''移动猪'''
- def move(self):
- # 根据重力改变猪的速度向量
- self.velocity = VectorAddition(self.velocity, self.gravity)
- self.loc_info[0] += self.velocity.magnitude * math.sin(self.velocity.angle)
- self.loc_info[1] -= self.velocity.magnitude * math.cos(self.velocity.angle)
- self.velocity.magnitude *= self.inverse_friction
- # 宽度超出屏幕
- if self.loc_info[0] > self.screen_size[0] - self.loc_info[2]:
- self.loc_info[0] = 2 * (self.screen_size[0] - self.loc_info[2]) - self.loc_info[0]
- self.velocity.angle *= -1
- self.velocity.magnitude *= self.elasticity
- elif self.loc_info[0] < self.loc_info[2]:
- self.loc_info[0] = 2 * self.loc_info[2] - self.loc_info[0]
- self.velocity.angle *= -1
- self.velocity.magnitude *= self.elasticity
- # 高度超出屏幕
- if self.loc_info[1] > self.screen_size[1] - self.loc_info[2]:
- self.loc_info[1] = 2 * (self.screen_size[1] - self.loc_info[2]) - self.loc_info[1]
- self.velocity.angle = math.pi - self.velocity.angle
- self.velocity.magnitude *= self.elasticity
- elif self.loc_info[1] < self.loc_info[2]:
- self.loc_info[1] = 2 * self.loc_info[2] - self.loc_info[1]
- self.velocity.angle = math.pi - self.velocity.angle
- self.velocity.magnitude *= self.elasticity
- '''猪死掉了'''
- def setdead(self):
- self.is_dead = True
- self.image = self.pig_images[-1]
然后这里定义的精灵类是小鸟即玩家:
- class Bird(pygame.sprite.Sprite):
- def __init__(self, screen, imagepaths, loc_info, velocity=None, color=(255, 255, 255), **kwargs):
- pygame.sprite.Sprite.__init__(self)
- assert len(loc_info) == 3
- assert len(imagepaths) == 1
- # 设置必要的属性常量
- self.color = color
- self.screen = screen
- self.loc_info = list(loc_info)
- self.imagepaths = imagepaths
- self.velocity = VelocityVector() if velocity is None else velocity
- self.type = 'bird'
- self.fly_path = []
- self.is_dead = False
- self.elasticity = 0.8
- self.is_loaded = False
- self.is_selected = False
- self.inverse_friction = 0.99
- self.gravity = VelocityVector(0.2, math.pi)
- # 屏幕大小
- self.screen_size = screen.get_rect().size
- self.screen_size = (self.screen_size[0], self.screen_size[1] - 50)
- # 导入图像
- self.image = pygame.image.load(imagepaths[0])
- '''画到屏幕上'''
- def draw(self):
- if not self.is_loaded:
- for point in self.fly_path:
- pygame.draw.ellipse(self.screen, self.color, (point[0], point[1], 3, 3), 1)
- position = self.loc_info[0] - self.loc_info[2], self.loc_info[1] - self.loc_info[2]
- self.screen.blit(self.image, position)
- '''判断有没有被鼠标选中'''
- def selected(self):
- pos = pygame.mouse.get_pos()
- dx, dy = pos[0] - self.loc_info[0], pos[1] - self.loc_info[1]
- dist = math.hypot(dy, dx)
- if dist < self.loc_info[2]:
- return True
- return False
- '''加载到弹弓上'''
- def load(self, slingshot):
- self.loc_info[0], self.loc_info[1] = slingshot.x, slingshot.y
- self.is_loaded = True
- '''重新设置位置'''
- def reposition(self, slingshot):
- pos = pygame.mouse.get_pos()
- if self.selected:
- self.loc_info[0], self.loc_info[1] = pos[0], pos[1]
- dx, dy = slingshot.x - self.loc_info[0], slingshot.y - self.loc_info[1]
- self.velocity.magnitude = min(int(math.hypot(dx, dy) / 2), 80)
- self.velocity.angle = math.pi / 2 + math.atan2(dy, dx)
- '''显示发射小鸟的路径'''
- def projectpath(self):
- if self.is_loaded:
- path = []
- bird = Bird(self.screen, self.imagepaths, self.loc_info, velocity=self.velocity)
- for i in range(30):
- bird.move()
- if i % 5 == 0: path.append((bird.loc_info[0], bird.loc_info[1]))
- for point in path:
- pygame.draw.ellipse(self.screen, self.color, (point[0], point[1], 2, 2))
- '''移动小鸟'''
- def move(self):
- # 根据重力改变小鸟的速度向量
- self.velocity = VectorAddition(self.velocity, self.gravity)
- self.loc_info[0] += self.velocity.magnitude * math.sin(self.velocity.angle)
- self.loc_info[1] -= self.velocity.magnitude * math.cos(self.velocity.angle)
- self.velocity.magnitude *= self.inverse_friction
- # 宽度超出屏幕
- if self.loc_info[0] > self.screen_size[0] - self.loc_info[2]:
- self.loc_info[0] = 2 * (self.screen_size[0] - self.loc_info[2]) - self.loc_info[0]
- self.velocity.angle *= -1
- self.velocity.magnitude *= self.elasticity
- elif self.loc_info[0] < self.loc_info[2]:
- self.loc_info[0] = 2 * self.loc_info[2] - self.loc_info[0]
- self.velocity.angle *= -1
- self.velocity.magnitude *= self.elasticity
- # 高度超出屏幕
- if self.loc_info[1] > self.screen_size[1] - self.loc_info[2]:
- self.loc_info[1] = 2 * (self.screen_size[1] - self.loc_info[2]) - self.loc_info[1]
- self.velocity.angle = math.pi - self.velocity.angle
- self.velocity.magnitude *= self.elasticity
- elif self.loc_info[1] < self.loc_info[2]:
- self.loc_info[1] = 2 * self.loc_info[2] - self.loc_info[1]
- self.velocity.angle = math.pi - self.velocity.angle
- self.velocity.magnitude *= self.elasticity
定义地图里面的木桩:
- class Block(pygame.sprite.Sprite):
- def __init__(self, screen, imagepaths, loc_info, velocity=None, **kwargs):
- pygame.sprite.Sprite.__init__(self)
- assert len(loc_info) == 3
- assert len(imagepaths) == 2
- # 设置必要的属性常量
- self.type = 'block'
- self.screen = screen
- self.loc_info = list(loc_info)
- self.imagepaths = imagepaths
- self.velocity = VelocityVector() if velocity is None else velocity
- self.elasticity = 0.7
- self.is_destroyed = False
- self.inverse_friction = 0.99
- self.gravity = VelocityVector(0.2, math.pi)
- # 导入图像
- self.block_images = []
- for imagepath in imagepaths: self.block_images.append(pygame.transform.scale(pygame.image.load(imagepath), (100, 100)))
- # 屏幕大小
- self.screen_size = screen.get_rect().size
- self.screen_size = (self.screen_size[0], self.screen_size[1] - 50)
- # 设置当前图像
- self.image = self.block_images[0]
- self.rect = self.image.get_rect()
- self.rotate_angle = math.radians(0)
- '''画到屏幕上'''
- def draw(self):
- pygame.transform.rotate(self.image, self.rotate_angle)
- self.screen.blit(self.image, (self.loc_info[0] - self.rect.width // 2, self.loc_info[1]))
- '''设置为损坏状态'''
- def setdestroy(self):
- self.is_destroyed = True
- self.image = self.block_images[1]
- '''移动木块'''
- def move(self):
- # 根据重力改变木块的速度向量
- self.velocity = VectorAddition(self.velocity, self.gravity)
- self.loc_info[0] += self.velocity.magnitude * math.sin(self.velocity.angle)
- self.loc_info[1] -= self.velocity.magnitude * math.cos(self.velocity.angle)
- self.velocity.magnitude *= self.inverse_friction
- # 宽度超出屏幕
- if self.loc_info[0] > self.screen_size[0] - self.rect.width:
- self.loc_info[0] = 2 * (self.screen_size[0] - self.rect.width) - self.loc_info[0]
- self.velocity.angle *= -1
- self.rotate_angle = -self.velocity.angle
- self.velocity.magnitude *= self.elasticity
- elif self.loc_info[0] < self.rect.width:
- self.loc_info[0] = 2 * self.rect.width - self.loc_info[0]
- self.velocity.angle *= -1
- self.rotate_angle = -self.velocity.angle
- self.velocity.magnitude *= self.elasticity
- # 高度超出屏幕
- if self.loc_info[1] > self.screen_size[1] - self.rect.height:
- self.loc_info[1] = 2 * (self.screen_size[1] - self.rect.height) - self.loc_info[1]
- self.velocity.angle = math.pi - self.velocity.angle
- self.rotate_angle = math.pi - self.velocity.angle
- self.velocity.magnitude *= self.elasticity
- elif self.loc_info[1] < self.rect.height:
- self.loc_info[1] = 2 * self.rect.height - self.loc_info[1]
- self.velocity.angle = math.pi - self.velocity.angle
- self.rotate_angle = math.pi - self.velocity.angle
- self.velocity.magnitude *= self.elasticity
游戏主程序:
-
- import sys
- import cfg
- import pygame
- from modules import *
-
-
- '''游戏主程序'''
- def main(cfg):
- # 初始化
- pygame.init()
- pygame.mixer.init()
- pygame.mixer.music.load(cfg.BGMPATH)
- pygame.mixer.music.play(-1, 0.0)
- screen = pygame.display.set_mode(cfg.SCREENSIZE)
- pygame.display.set_caption(' 愤怒的小鸟')
- # 开始游戏
- def startgame():
- game_levels = GameLevels(cfg, screen)
- game_levels.start()
- # 退出游戏
- def quitgame():
- pygame.quit()
- sys.exit()
- # 开始界面
- components = pygame.sprite.Group()
- title_label = Label(screen, 700, 100, 400, 200)
- title_label.addtext('ANGRY BIRDS', 80, cfg.FONTPATH['arfmoochikncheez'], (236, 240, 241))
- components.add(title_label)
- start_btn = Button(screen, 500, 400, 300, 100, startgame, (244, 208, 63), (247, 220, 111))
- start_btn.addtext('START GAME', 60, cfg.FONTPATH['arfmoochikncheez'], cfg.BACKGROUND_COLOR)
- components.add(start_btn)
- quit_btn = Button(screen, 1000, 400, 300, 100, quitgame, (241, 148, 138), (245, 183, 177))
- quit_btn.addtext('QUIT', 60, cfg.FONTPATH['arfmoochikncheez'], cfg.BACKGROUND_COLOR)
- components.add(quit_btn)
- charles_label = Label(screen, cfg.SCREENSIZE[0] - 300, cfg.SCREENSIZE[1] - 80, 300, 100)
- charles_label.addtext('CHARLES', 60, cfg.FONTPATH['arfmoochikncheez'], (41, 41, 41))
- components.add(charles_label)
- clock = pygame.time.Clock()
- while True:
- for event in pygame.event.get():
- if event.type == pygame.QUIT:
- quitgame()
- elif event.type == pygame.KEYDOWN:
- if event.key == pygame.K_q:
- quitgame()
- elif event.type == pygame.MOUSEBUTTONDOWN:
- if start_btn.selected():
- start_btn.action()
- elif quit_btn.selected():
- quit_btn.action()
- screen.fill(cfg.BACKGROUND_COLOR)
- for component in components: component.draw()
- pygame.display.update()
- clock.tick(cfg.FPS)
-
-
- '''run'''
- if __name__ == '__main__':
- main(cfg)
-
-
由于这款愤怒的小鸟代码量太对,所以全部代码没放进来!文末有代码!
效果图:
赶紧先跟着小编涨姿势啊!这款游戏你也想拥嘛?
好啦!本次文章就到这里了~如有想跟着小编一起学习交流的,欢迎大家!
学无止境哦!你们的支持是我最大的动力!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。