上个星期弄了好久的打飞机,折磨了我好久,其实上周末都已经做好了,整体的一些大功能已经实现,缺少的就是一些小功能,比如说选关啊,变身啊,超级炸弹啊,本来想加上去,但是又比较花费时间,主要以后我也没有想要去从事游戏这么方面的工作,但是Pygame这个东西是真的好用,里面有各种各样的工具,基本可以满足你的所有需求,我只是用了几个必须的方法,做出来了游戏的雏形,以后有时间的话再慢慢优化吧,不过比较Low的事就是我把素材包给换了,我自己再网上找了图片,自己P了一套素材,整出来一个美少女战士,惊了吧,我自己也惊了,好好的打飞机不好吗?其实原理都一样只是换了一个外壳,废话不多说,先给大家看看效果图。
其实就是都做的是飞机没啥意思,就面向‘肥宅’来一个美少女吧,基本就是这个样子,简单的功能,基本没有什么bug,代码全部写在了一个Py文件中,本来想分开写,然后导入呢,但是有点麻烦,现在我的水平只能达到这样,等以后有能力了,把代码优化一下,我基本都是用类来写的,把代码封装起来,显得简洁一点吧(虽然也不是那么简洁),下面给大家看一下我的代码,一共500多行吧。
总体的代码就是这样,下面给大家看看我每个类里面的代码
每个列表里面放的基本都是图片
# 需求 制作一款全新版本的美少女战士
# 分析思路:图片素材 声音素材
# 1:启动界面
# 背景图片 开始游戏按钮 标题(使用sin(x)可以动画)
# 2:游戏界面
# 英雄类:
# 属性:图片 血量 速度 渲染屏幕 初始位置
# 方法:移动 发射子弹 死亡 无敌 碰撞敌机
# 敌人类:
# 属性:图片 血量 速度 初始位置 渲染屏幕
# 方法:移动 死亡
# 子弹类:
# 属性:图片 位置 速度 屏幕
# 方法:移动 碰撞敌机
# 敌机工厂类:负责敌机的产生 敌机的移动
# 3:分数界面
# 历史分数最大值:储存最大值,显示分数
import pygame
import sys
import math
import copy
import random
import os
'''enemy_imgs = [
pygame.image.load('images/enemy1.png'),
pygame.image.load('images/enemy2.png'),
pygame.image.load('images/enemy3.png'),
pygame.image.load('images/enemy4.png'),
pygame.image.load('images/enemy5.png')
]
'''
history = 0
enemy_list = []
enemy_imgs1 = [
pygame.transform.scale((pygame.image.load('images/diren1.png')), (120, 130)),
pygame.transform.scale((pygame.image.load('images/diren1baozha1.png')), (120, 130)),
pygame.transform.scale((pygame.image.load('images/diren1baozha2.png')), (120, 130)),
pygame.transform.scale((pygame.image.load('images/diren1baozha3.png')), (120, 130))
]
enemy_imgs2 = [
pygame.transform.scale((pygame.image.load('images/diren2.png')), (80, 85)),
pygame.transform.scale((pygame.image.load('images/deren2baozha1.png')), (80, 85)),
pygame.transform.scale((pygame.image.load('images/diren2baozha2.png')), (80, 85)),
pygame.transform.scale((pygame.image.load('images/diren2baozha3.png')), (80, 85))
]
enemy_imgs3 = [
pygame.transform.scale((pygame.image.load('images/diren3.png')), (80, 85)),
pygame.transform.scale((pygame.image.load('images/diren3baozha1.png')), (80, 85)),
pygame.transform.scale((pygame.image.load('images/diren3baozha2.png')), (80, 85)),
pygame.transform.scale((pygame.image.load('images/diren3baozha3.png')), (80, 85))
]
enemy_imgs4 = [
pygame.transform.scale((pygame.image.load('images/direndaboss.png')), (220, 160)),
pygame.transform.scale((pygame.image.load('images/bossbaozha1.png')), (220, 160)),
pygame.transform.scale((pygame.image.load('images/bossbaozha2.png')), (220, 160)),
pygame.transform.scale((pygame.image.load('images/bossbaozha3.png')), (220, 160)),
pygame.transform.scale((pygame.image.load('images/bossbaozha4.png')), (220, 160)),
pygame.transform.scale((pygame.image.load('images/bossbaozha5.png')), (220, 160))
]
bullet_img = [
pygame.transform.scale((pygame.image.load('images/bullet2.png')), (36, 34)),
pygame.transform.scale((pygame.image.load('images/heartbullet.png')), (36, 34)),
pygame.transform.scale((pygame.image.load('images/heartbullet.png')), (36, 34)),
]
bullet_list = []
# 加载背景图片
start_bg = [
pygame.image.load('images/beijing2.png'),
pygame.image.load('images/beijing4.png'),
pygame.image.load('images/zitibiaoti5.png'),
pygame.image.load('images/starbit.png'),
pygame.image.load('images/engbg1.png'),
pygame.image.load('images/beijingtu1.png'),
pygame.image.load('images/beijingtu2.png')
]
start_star = [
pygame.image.load("images/star3.png"),
pygame.image.load("images/star2.png"),
pygame.image.load("images/star1.png")
]
# 开始界面类
class StatPanel:
is_inside = False
def __init__(self, screen, start_bg=start_bg, start_star=start_star):
self.screen = screen
self.start_bg = start_bg
self.start_star = start_star
self.index = 0
self.statIndex = 0
self.statAddIndex = 0
def display(self):
self.index += 0.01
# 背景图
self.screen.blit(self.start_bg[0], (0, 0))
self.screen.blit(self.start_bg[5], (10, 520))
self.screen.blit(self.start_bg[6], (370, 530))
# 文字标题
self.screen.blit(self.start_bg[2], (60, 100 + 30 * math.sin(self.index)))
# 开始按钮
btn = self.screen.blit(self.start_bg[3], (180, 380))
# 鼠标是否在按键上方
StatPanel.is_inside = btn.collidepoint(pygame.mouse.get_pos())
# 三张动图
self.statAddIndex += 1
if self.statAddIndex == 1000:
self.statAddIndex = 0
if self.statAddIndex % 7 == 0:
self.statIndex += 1
if self.statIndex == 3:
self.statIndex = 0
self.screen.blit(self.start_star[self.statIndex], (random.randint(-40, 400), random.randint(-60, 150)))
self.screen.blit(self.start_star[self.statIndex], (random.randint(-40, 400), random.randint(-60, 150)))
self.screen.blit(self.start_star[self.statIndex], (random.randint(-40, 400), random.randint(-60, 150)))
self.screen.blit(self.start_star[self.statIndex], (random.randint(-40, 400), random.randint(-60, 150)))
self.screen.blit(self.start_star[self.statIndex], (random.randint(-40, 400), random.randint(-60, 150)))
self.screen.blit(self.start_star[self.statIndex], (random.randint(-40, 400), random.randint(-60, 150)))
# 结束界面类
class EndPanel:
global fontObj1
def __init__(self, screen, start_bg=start_bg, start_star=start_star):
self.screen = screen
# self.start_bg = start_bg
# self.start_star = start_star
def end_panel(self):
endbg = pygame.transform.scale(pygame.image.load('images/endbeijing1.png'), (580, 870))
self.screen.blit(endbg, (0, 0))
def font(self):
scoreSurface = fontObj1.render('The score:%s' % Hero.score, True, (255, 125, 125, 0))
screen.blit(scoreSurface, (180, 400))
hisSurface = fontObj1.render('Highest score in history :%s' % history, True, (255, 125, 125, 0))
screen.blit(hisSurface, (170,450))
# 音效类
pygame.mixer.init()
sounds = [
pygame.mixer.Sound('sound/button.ogg')
]
class AllSound:
@staticmethod
def play_sounds(sound):
if sound != None:
sound.play()
# 主角类
hero_imgs = [
pygame.transform.scale((pygame.image.load('images/hero1.png')), (120, 210)),
pygame.transform.scale((pygame.image.load('images/hero2.png')), (120, 210)),
pygame.transform.scale((pygame.image.load('images/hero3.png')), (120, 210))
]
class Hero(pygame.sprite.Sprite):
up = False
down = False
left = False
right = False
score = 0
# 属性:图片 位置 血量 速度 屏幕
def __init__(self, screen, imgs, pos, hp, speed):
self.screen = screen
self.imgs = imgs
self.image = self.imgs[0]
self.rect = self.imgs[0].get_rect()
self.rect.topleft = pos
self.hp = hp
self.speed = speed
self.indexAdd = 1
self.imgIndex = 0
def Move(self):
# 移动 上下左右
if Hero.right:
self.rect = self.rect.move(self.speed, 0)
if Hero.left:
self.rect = self.rect.move(-self.speed, 0)
if Hero.down:
self.rect = self.rect.move(0, self.speed)
if Hero.up:
self.rect = self.rect.move(0, -self.speed)
# 猪脚动画
self.indexAdd += 1
if self.indexAdd == 1000:
self.indexAdd = 0
if self.indexAdd % 97 == 0:
self.imgIndex += 1
if self.imgIndex == 3:
self.imgIndex = 0
# 鼠标控制
# self.rect.center = pygame.mouse.get_pos()
# 约束区域
if self.rect.x <= 0:
self.rect.x = 0
if self.rect.x >= (self.screen.get_width() - self.imgs[0].get_width()):
self.rect.x = self.screen.get_width() - self.imgs[0].get_width()
if self.rect.y <= 0:
self.rect.y = 0
if self.rect.y >= (self.screen.get_height() - self.imgs[0].get_height()):
self.rect.y = self.screen.get_height() - self.imgs[0].get_height()
# 渲染屏幕
self.screen.blit(self.imgs[self.imgIndex], self.rect)
# 产生子弹
if self.indexAdd % 30 == 0:
Bullet((self.rect.centerx - (bullet_img[0].get_width() / 2), self.rect.y - 20), 4, self.screen)
# 子弹移动
for i in bullet_list:
if i != None and isinstance(i, Bullet):
i.Move()
self.Collide()
if self.hp <= 0:
global isOver
HistroyScore.UpdateHistory(Hero.score)
isOver = True
# 碰撞敌机
def Collide(self, target=enemy_list):
tempEnemy = pygame.sprite.spritecollideany(self, target, collided=pygame.sprite.collide_mask)
if tempEnemy in enemy_list:
self.hp -= 1
self.rect.topleft = (180, 500)
tempEnemy.hp -= 10
# 子弹类
class Bullet(pygame.sprite.Sprite):
# 属性 :图片 位置 速度 屏幕
def __init__(self, pos, speed, screen, img=bullet_img[0]):
self.image = img
self.rect = self.image.get_rect()
self.rect.topleft = pos
self.speed = speed
self.screen = screen
bullet_list.append(self)
# 方法:移动,碰撞敌机
def Move(self):
self.rect = self.rect.move(0, -self.speed)
self.screen.blit(self.image, self.rect)
if self.rect.y <= -69:
if self in bullet_list:
bullet_list.remove(self)
self.CollideEnemy()
# 碰撞敌机
def CollideEnemy(self, target=enemy_list):
# 第三个参数 打开碰撞遮罩
tempEnemy = pygame.sprite.spritecollideany(self, target, collided=pygame.sprite.collide_mask)
if tempEnemy and self in bullet_list:
bullet_list.remove(self)
tempEnemy.hp -= 1
# 背景移动类
class BackGround:
def __init__(self, img, speed, screen):
self.img1 = img
self.img1rect = self.img1.get_rect()
self.img2 = copy.copy(self.img1)
self.img2rect = self.img2.get_rect()
self.img2rect.y = -870
self.speed = speed
self.screen = screen
def Move(self):
self.img1rect = self.img1rect.move(0, self.speed)
self.img2rect = self.img2rect.move(0, self.speed)
if self.img1rect.y >= 880:
self.img1rect.y = self.img2rect.y - 870
if self.img2rect.y >= 880:
self.img2rect.y = self.img1rect.y - 870
self.screen.blit(self.img1, self.img1rect)
self.screen.blit(self.img2, self.img2rect)
# 敌机类
class Enemy(pygame.sprite.Sprite):
# 属性 图片 位置 血量 速度 屏幕 标签
def __init__(self, img, pos, hp, speed, screen, tag, imgs):
self.image = img
self.imgs = imgs
self.rect = self.image.get_rect()
self.rect.topleft = pos
self.hp = hp
self.speed = speed
self.screen = screen
self.tag = tag
enemy_list.append(self)
self.indexAdd = 0
self.indexImg = 0
# 方法 移动死亡
def Move(self):
if self.hp <= 0:
self.dead()
else:
self.rect = self.rect.move(0, self.speed)
self.screen.blit(self.image, self.rect)
# 出画面死亡
if self.rect.y > 880:
if self in enemy_list and self != None:
enemy_list.remove(self)
# 死亡
def dead(self):
global score
self.indexAdd += 1
if self.indexAdd == 1000:
self.indexAdd = 0
# 播放死亡动画
if self.tag == 'enemy0':
if self.indexAdd % 7 == 0:
self.indexImg += 1
if self.indexImg == 3:
# 移除列表
if self in enemy_list:
Hero.score += 3
enemy_list.remove(self)
if self.tag == 'enemy1':
if self.indexAdd % 7 == 0:
self.indexImg += 1
if self.indexImg == 3:
# 移除列表
if self in enemy_list:
Hero.score += 2
enemy_list.remove(self)
if self.tag == 'enemy2':
if self.indexAdd % 7 == 0:
self.indexImg += 1
if self.indexImg == 3:
# 移除列表
if self in enemy_list:
Hero.score += 2
enemy_list.remove(self)
if self.tag == 'enemy3':
if self.indexAdd % 7 == 0:
self.indexImg += 1
if self.indexImg == 5:
# 移除列表
if self in enemy_list:
Hero.score += 5
enemy_list.remove(self)
# 渲染动画
self.screen.blit(self.imgs[self.indexImg], self.rect)
# 飞机工厂类a
class EnemyFactor:
@staticmethod
def Creat_enemy(screen):
r = random.randint(1, 3200)
if r < 700:
Enemy(enemy_imgs1[0], (random.randint(0, 460), -130), 3, 2, screen, 'enemy0', enemy_imgs1)
elif r < 1700:
Enemy(enemy_imgs2[0], (random.randint(0, 500), -85), 1, 3, screen, 'enemy1', enemy_imgs2)
elif r < 2700:
Enemy(enemy_imgs3[0], (random.randint(0, 500), -85), 1, 3, screen, 'enemy2', enemy_imgs3)
elif r < 3200:
Enemy(enemy_imgs4[0], (random.randint(0, 360), -160), 5, 1, screen, 'enemy3', enemy_imgs4)
@staticmethod
def Move():
for i in enemy_list:
if isinstance(i, Enemy):
i.Move()
# 历史分数类
class HistroyScore:
# 历史分数更新
def ReadHistory(path='score.txt'):
global history
if os.path.exists(path):
with open(path, mode='r', encoding='utf-8')as f_r:
history = f_r.read()
else:
with open(path, mode='w', encoding='utf-8')as f_w:
f_w.write('0')
def UpdateHistory(score, path='score.txt'):
if os.path.exists(path):
with open(path, mode='r', encoding='utf-8')as f_r:
if int(f_r.read()) <= score:
with open(path, mode='w', encoding='utf-8')as f_w:
f_w.write(str(score))
screen = None
# 事件监测
def AllEvent():
global screen
global is_play
# 迭代所有事件
for i in pygame.event.get():
# 判断所有事件是否为 退出
if i.type == pygame.QUIT:
pygame.quit()
sys.exit()
if i.type == pygame.MOUSEBUTTONDOWN:
if i.button == 1 and StatPanel.is_inside and is_play == False:
AllSound.play_sounds(sounds[0])
print('开始游戏')
HistroyScore.ReadHistory()
Hero.score = 0
heroObj.hp = 5
enemy_list.clear()
bullet_list.clear()
is_play = True
if i.type == pygame.KEYDOWN:
if i.key == pygame.K_SPACE:
for j in enemy_list:
j.hp = 0
if i.key == pygame.K_ESCAPE:
is_play = False
AllSound.play_sounds(sounds[0])
if i.key == pygame.K_w:
Hero.up = True
if i.key == pygame.K_s:
Hero.down = True
if i.key == pygame.K_a:
Hero.left = True
if i.key == pygame.K_d:
Hero.right = True
if i.type == pygame.KEYUP:
if i.key == pygame.K_w:
Hero.up = False
if i.key == pygame.K_s:
Hero.down = False
if i.key == pygame.K_a:
Hero.left = False
if i.key == pygame.K_d:
Hero.right = False
if i.type == pygame.USEREVENT + 1 and is_play:
EnemyFactor.Creat_enemy(screen)
def Main():
global heroObj
global overObj
global screen
global is_play
global isOver
global fontObj1
HistroyScore.ReadHistory()
# 第一步初始化pygame
pygame.init()
# 第二步初始化display
pygame.display.init()
# 第三步创建一个窗口屏幕
screen = pygame.display.set_mode((580, 870))
pygame.display.set_caption('代表月亮消灭你')
# 设置缩略图图标
icon = pygame.image.load("images/heartbullet.png")
pygame.display.set_icon(icon)
# 开始界面对类
startObj = StatPanel(screen)
# 结束对界面类
overObj = EndPanel(screen)
# 英雄对象
heroObj = Hero(screen, hero_imgs, (180, 500), 5, 3)
# 字体
#运行字体
fontObj = pygame.font.Font('ziti/MarkerFelt.ttf', 25)
fontObj1 = pygame.font.Font('ziti/MarkerFelt.ttf', 25)
# 背景图像
bg = pygame.transform.scale(start_bg[4], (580, 870))
bgobj = BackGround(bg, 0, screen)
# 游戏是否开始
is_play = False
# 游戏是否结束
isOver = False
# 背景音乐
pygame.mixer.music.load('sound/beijing.ogg')
pygame.mixer.music.play(-1)
# 设置计时器
pygame.time.set_timer(pygame.USEREVENT + 1, 1000)
# 第四步 循环计算画面 进行更新显示画面
while True:
AllEvent()
if is_play:
if isOver == False:
# 游戏运行界面
bgobj.Move()
heroObj.Move()
EnemyFactor.Move()
hpSurface = fontObj.render('Hp :', True, (255, 125, 125, 0))
screen.blit(hpSurface, (0, 0))
scoreSurface = fontObj.render('Score :%s' % Hero.score, True, (255, 125, 125, 0))
screen.blit(scoreSurface, (0, 30))
hisSurface = fontObj.render('MAX score :%s' % history, True, (255, 125, 125, 0))
screen.blit(hisSurface, (0, 60))
# 血量显示
for i in range(0, heroObj.hp):
screen.blit(bullet_img[1], (35 + 35 * i, 0))
else:
# print('11111111111111111111111111111')
overObj.end_panel()
overObj.font()
else:
startObj.display()
pygame.display.update()
if __name__ == '__main__':
Main()
代码写的也比较乱,以后再慢慢整理吧,最近要整理的东西太多了。
下面给大家看看正常的飞机大战素材包:
各种飞机大战,雷霆战机,全民飞机大战的素材包,就等你们来了,心动不如行动,赶快留言吧。