【Python语言学习】小人躲子弹-小游戏学习

Python小游戏

​ 在python整个语言系统学完以后,我得知了Pygame这个扩展,发现相当的好用,所以在个人兴趣下写了小游戏(还没彻底写完)作为学习.

游戏整体设计

​ 窗口大小:1200×600

​ 游戏基本内容:使用一个类似马里奥的小人,进行类似飞机大战形式的躲子弹游戏:

​ 大致py文件分类:

​ box类:类似马里奥箱子那种,可以站立

​ bullet类:boss发射的子弹

​ hinder类:障碍物类,从屏幕的左右两边发射火球,击中后主角死亡

​ part类:主人公类

​ road类:地面类,(emmmmmm本来可以不要这个,不知道咋的就加上了)

​ boss类:就是boss类

​ game_function:储存游戏的主要判定函数等等

​ main_cycle:游戏主函数部分

​ setting类:储存游戏的设置等等

代码块

main_cycle.py:

from time import sleep
import pygame
from settings import Settings
from part import Part
from BOSS import BOSS
from road import Road
from box import Box
import game_function as gf
from pygame.sprite import Group
import datetime
def run():
    pygame.init()
    game_setting=Settings()
    screen = pygame.display.set_mode((game_setting.screen_width, game_setting.screen_height))
    pygame.display.set_caption("茄理奥")
    box = Box(game_setting, screen)
    road = Road(game_setting, screen)
    boss = BOSS(screen,game_setting)
    part = Part(game_setting, screen,box,road)
    hinders=Group()
    hinder1s = Group()
    bullets = Group()
    # dt = datetime.datetime.now()
    gf.create_fleet(game_setting, screen, hinders)
    gf.create_fleet1(game_setting, screen, hinder1s)
    gf.create_bullet(game_setting,screen,bullets,boss)
    # gf.create_bullet(game_setting,screen,bullets,boss)
    while True:
        # 监听
            gf.check_events(part)
            part.update()
            boss.update()
            hinders.update()
            hinder1s.update()
            bullets.update()
            for hinder in hinders.copy():
                if hinder.rect.bottom >550 or hinder.rect.top<0 or hinder.rect.left<0 or hinder.rect.right>1200:
                    hinders.remove(hinder)
                if len(hinders)<1:
                    hinders.remove(hinder)
                    gf.create_fleet(game_setting, screen, hinders)
            for hinder1 in hinder1s.copy():
                if hinder1.rect.bottom > 550 or hinder1.rect.top < 0 or hinder1.rect.left < 0 or hinder1.rect.right > 1500:
                    hinder1s.remove(hinder1)
                if len(hinder1s) < 1:
                    hinder1s.remove(hinder1)
                    gf.create_fleet1(game_setting, screen, hinder1s)
            for bullet in bullets.copy():
                if bullet.rect.bottom > 550 or bullet.rect.top < 0 or bullet.rect.left < 0 or bullet.rect.right > 1200:
                    bullets.remove(bullet)
                if len(bullets) < 5:
                    bullets.remove(bullet)
                    gf.create_bullet(game_setting, screen, bullets,boss)
            gf.update_screen(game_setting, screen, part,hinders,boss,bullets,road,box,hinder1s)
run()

settings.py:

#因为后面代码越写越乱,本来好多东西应该放在设置类里面,请大家别学习这种行为
import pygame
class Settings(object):
    """储存游戏中所有的设置类"""
    def __init__(self):
        """初始化游戏设置"""
        #屏幕设置
        self.screen_width = 1200
        self.screen_height =600
        self.bg_img =pygame.image.load("image/backgroud.jpg")
        self.img1 = pygame.transform.scale(self.bg_img, (1200, 553))
        self.a = 1
        self.part_speed_factor = 3
        self.time = 5
        self.boss_speed_factor = 1.5

game_function.py:

import pygame,sys,random
from hinder import Hinder
from hinder1 import Hinder1
from bullet import  BULLET
def check_keydown_events(event,part):
    if event.key == pygame.K_RIGHT:
        part.moving_right = True
        part.direction = True
    if event.key == pygame.K_LEFT:
        part.moving_left = True
        part.direction = False
    if event.key == pygame.K_UP:
        part.isjump = True
def check_keyup_events(event,part):
    if event.key == pygame.K_RIGHT:
        part.moving_right = False
    if event.key == pygame.K_LEFT:
        part.moving_left = False
def check_events(part):
    """响应按键和鼠标事件"""
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
        elif event.type == pygame.KEYDOWN:
            check_keydown_events(event,part)
        elif event.type ==pygame.KEYUP:
            check_keyup_events(event,part)
def update_screen(game_setting,screen,part,hinders,boss,bullets,road,box,hinder1s):
    """更新屏幕上的图像"""
    #每次调用时都循环绘制屏幕
    screen.blit(game_setting.img1,(0,0))     #在游戏窗口上显示背景图片,背景图片比游戏窗口大,否则窗口周边将用黑边填充
    # screen.fill(255,0,0)
    part.blitme()
    hinders.draw(screen)
    boss.blitim()
    road.blitme()
    box.blitme()
    hinder1s.draw(screen)
    bullets.draw(screen)
    for hinder in hinders:
         part.part_hinder_collide(hinder)
    for hinder1 in hinders:
        part.part_hinder_collide(hinder1)

    # part.Ispeng()
    for bullet in bullets:
        part.part_bullet_collide(bullet)


    #绘制屏幕课件(测试)
    pygame.display.flip()
def create_fleet(game_setting, screen,hinders):
    for hinder_number in range(1):
        hinder=Hinder(game_setting, screen)
        hinder.x=0
        hinder.y =random.randint(0,500)
        hinder.rect.x=hinder.x
        hinders.add(hinder)

def create_fleet1(game_setting, screen,hinder1s):
    for hinder1_number in range(1):
        hinder1=Hinder1(game_setting, screen)
        hinder1.x=1180
        hinder1.y =random.randint(0,500)
        hinder1.rect.x=hinder1.x
        hinder1s.add(hinder1)

def create_bullet(game_setting,screen,bullets,boss):
    for bullet_number in range(10):
        bullet = BULLET(game_setting,screen)
        bullet.x = boss.rect.centerx
        bullet.y = boss.rect.bottom
        bullet.rect.x = bullet.x
        bullets.add(bullet)

part.py:

from time import sleep

import pygame

class Part():
    def __init__(self, game_setting, screen,box,road):
        """设置角色的初始化位置"""
        self.road=road
        self.box = box
        self.screen = screen
        self.game_setting = game_setting
        # 加载角色图像,并获得他的外解矩形位置
        self.image = pygame.image.load("image/part_0.png")
        self.rect = self.image.get_rect()
        self.screen_rect = screen.get_rect()
        # 将新绘制的角色放在屏幕底部中间
        self.rect.centerx = self.screen_rect.centerx-200
        self.rect.centery = self.screen_rect.bottom-100
        # 在属性中储存小数值
        self.center = float(self.rect.centerx)
        self.center2 = float(self.rect.centery)
        # # 移动标志
        self.moving_right = False
        self.moving_left = False
        self.moving_top = False
        self.moving_bottom = False
        self.isjump=False
        self.direction=True#角色图片的朝向
        self.ispeng=False
        self.isdie=False

    def jump(self):
        if self.game_setting.time >= -5 and not(self.isdie):
            a = self.game_setting.a  # 前半段减速上跳
            if self.game_setting.time < 0:
                a = -self.game_setting.a  # 后半段加速下落
            self.center2 -= 0.5 * a * (self.game_setting.time ** 2)  # 匀加速直线运动的位移公式
            if self.center2 < 60:
                self.center2 = 60  # 防止跳出边界
            if self.center2 > self.road.rect.top - 110:
                self.center2 = self.road.rect.top - 110  # 防止跳出边界
            self.game_setting.time -= 0.1
        else:
            a = self.game_setting.a
            self.isjump = False
            self.game_setting.time = 5
    def update(self):
        """根据移动标志调整角色的位置"""
        # 更新角色的center值,不是rect
        if not(self.isjump) and not(self.isdie) :
            if not (self.ispeng):
                if self.moving_right and self.rect.right < self.screen_rect.right:
                    self.center += self.game_setting.part_speed_factor
                if self.moving_left and self.rect.left > 0:
                    self.center -= self.game_setting.part_speed_factor
                if self.center2 != self.road.rect.top-50:
                    self.center2 = self.road.rect.top-50
            else:
                if self.moving_right and self.rect.right < self.screen_rect.right:
                    self.center += self.game_setting.part_speed_factor
                if self.moving_left and self.rect.left > 0:
                    self.center -= self.game_setting.part_speed_factor
        if not(self.isjump) and self.isdie:
            if not (self.ispeng):
                if self.center2 != self.road.rect.top:
                    self.center2 = self.road.rect.top
        if self.isjump:
            if self.moving_right and self.rect.right < self.screen_rect.right:
                self.center += self.game_setting.part_speed_factor
            if self.moving_left and self.rect.left > 0:
                self.center -= self.game_setting.part_speed_factor
            self.jump()

        # 根据self.center 更新 rect
        self.rect.centerx = self.center
        self.rect.centery = self.center2
        if self.isjump==True and not(self.isdie):
            self.image = pygame.image.load("image/part_1.png")
        if self.isjump==False and not(self.isdie):
            self.image = pygame.image.load("image/part_0.png")
        if self.isjump==False and self.moving_left==True and not(self.isdie):
            self.image = pygame.image.load("image/part_4.png")
        if self.isjump==False and self.moving_right==True and not(self.isdie):
            self.image = pygame.image.load("image/part_4.png")
        if self.isjump==False and self.moving_right==False and self.moving_left==False and not(self.isdie):
            self.image = pygame.image.load("image/part_0.png")
        if self.isdie:
            self.image = pygame.image.load("image/part_die.png")
    def blitme(self):
        """在指定位置绘制角色"""
        img1 = pygame.transform.flip(self.image, True, False)
        if self.direction==False:
            self.screen.blit(img1, self.rect)
        else:
            self.screen.blit(self.image, self.rect)

    def part_hinder_collide(self, hinders):
        if pygame.Rect.colliderect(pygame.Rect(self.rect.x+35, self.rect.y, 50, 80), pygame.Rect(hinders.rect.x+122, hinders.rect.y+88, 60, 60)):
            self.isdie = True

    def part_bullet_collide(self, bullets):
        if pygame.Rect.colliderect(pygame.Rect(self.rect.x+35, self.rect.y, 50, 80), pygame.Rect(bullets.rect.x, bullets.rect.y, 22, 22)):
            self.isdie = True

road.py:

import pygame
class Road():
    def __init__(self, game_setting, screen):
        """设置角色的初始化位置"""
        self.screen = screen
        self.game_setting = game_setting
        # 加载角色图像,并获得他的外解矩形位置
        self.image = pygame.image.load("image/road.png")
        self.rect = self.image.get_rect()
        self.screen_rect = screen.get_rect()
        self.rect.centery = 710
        self.img1 = pygame.transform.scale(self.image, (1200, 47))
        # 在属性中储存小数值
        self.center1 = float(self.rect.centerx)
        self.center2 = float(self.rect.centery)
    def blitme(self):
        """在指定位置绘制角色"""
        self.screen.blit(self.img1, self.rect)

box.py :

#箱子还没实例化出来,后续会写
import pygame
class Box():
    def __init__(self, game_setting, screen):
        """设置角色的初始化位置"""
        self.screen = screen
        self.game_setting = game_setting
        # 加载角色图像,并获得他的外解矩形位置
        self.image = pygame.image.load("image/box.png")
        self.rect = self.image.get_rect()
        self.screen_rect = screen.get_rect()
        # 将新绘制的角色放在屏幕底部中间
        self.rect.centerx = self.screen_rect.centerx + 200
        self.rect.centery = 470
        self.img1=pygame.transform.scale(self.image,(200,40))

boss.py:

import pygame

#boss类
class BOSS():
    def __init__(self, screen, game_setting):
        # 初始化BOSS并设置初始位置
        self.screen = screen
        self.game_setting = game_setting
        # 加载BOSS图像
        self.image = pygame.image.load("image/boss.png")
        self.rect = self.image.get_rect()
        self.screen_rect = screen.get_rect()
        # 让BOSS出生在屏幕顶侧
        self.rect.centerx = self.screen_rect.centerx
        self.rect.top = self.screen_rect.top
        # 在boss属性中存储小数值
        self.center = float(self.rect.centerx)
        # 移动标志
        self.moving_right = True

    def update(self):
        if self.moving_right:
            if self.center < self.screen_rect.right:
                self.center += self.game_setting.boss_speed_factor
            else:
                self.center -= self.game_setting.boss_speed_factor
                self.moving_right = False
        else:
            if self.center > self.screen_rect.left:
                self.center -= self.game_setting.boss_speed_factor
                self.moving_right = False
            else:
                self.center += self.game_setting.boss_speed_factor
                self.moving_right = True
        # # # 根据self.center跟新rect
        self.rect.centerx = self.center
    # 指定位置绘制BOSS
    def blitim(self):
        img1 = pygame.transform.flip(self.image, True, False)
        if self.moving_right==False:
            self.screen.blit(img1, self.rect)
        else:
            self.screen.blit(self.image, self.rect)

bullet.py:

import pygame,random
from pygame.sprite import Sprite

class BULLET(Sprite):
    def __init__(self,game_setting,screen):
        #初始化子弹位置
        super(BULLET, self).__init__()
        self.screen = screen
        self.game_setting = game_setting
        #加载子弹图像,
        self.image = pygame.image.load("image/bullet.png")
        self.rect = self.image.get_rect()
        self.screen_rect = screen.get_rect()
        #让子弹出生在boss图下
        # self.rect.x = self.boss.rect.centerx
        # self.rect.y = self.boss.rect.bottom

        # 在属性中储存小数值
        self.rect.x = self.rect.width
        self.rect.y = self.rect.height

        # 在属性中储存小数值
        self.x = float(self.rect.x)
        self.y = float(self.rect.y)
        # 设置子弹速度
        self.speed_factor_Y = random.randint(-5, 5)
        self.speed_factor_X = random.randint(-3,3)

    def update(self):
        self.x += self.speed_factor_X
        self.y += self.speed_factor_Y
        self.rect.y = self.y
        self.rect.x = self.x
    # def blitme(self):
    #     """在指定位置绘制角色"""
    #     self.screen.blit(self.image, self.rect)

hinder.py:

import pygame,random
from pygame.sprite import Sprite

class Hinder(Sprite):
    def __init__(self, game_setting, screen):
        """设置角色的初始化位置"""
        super(Hinder,self).__init__()
        self.screen = screen
        self.game_setting = game_setting
        # 加载角色图像,并获得他的外解矩形位置
        self.image = pygame.image.load("image/hinder.png")
        self.rect = self.image.get_rect()
        self.screen_rect = screen.get_rect()
        # 将新绘制的角色放在屏幕底部中间
        self.rect.x = self.rect.width
        self.rect.y = self.rect.height

        # 在属性中储存小数值
        self.x = float(self.rect.x)
        self.y = float(self.rect.y)
        #设置子弹速度
        self.speed_factor_Y = random.randint(1,2)
        self.speed_factor_X = random.randint(2,4)
    def update(self):
        self.x += self.speed_factor_X
        self.y +=self.speed_factor_Y
        self.rect.y=self.y
        self.rect.x=self.x
    # def blitme(self):
    #     """在指定位置绘制角色"""
    #     self.screen.blit(self.image, self.rect)

​ ps:为了省事,我直接写了个hinder1类,实际上直接用hinder在实例化一个就可以了,但是把生成位置写死了,改起来很简单,但是我有点懒:所以

hinder1.py:

import pygame,random
from pygame.sprite import Sprite

class Hinder1(Sprite):
    def __init__(self, game_setting, screen):
        """设置角色的初始化位置"""
        super(Hinder1,self).__init__()
        self.screen = screen
        self.game_setting = game_setting
        # 加载角色图像,并获得他的外解矩形位置
        self.image = pygame.image.load("image/hinder1.png")
        self.rect = self.image.get_rect()
        self.screen_rect = screen.get_rect()
        # 将新绘制的角色放在屏幕底部中间
        self.rect.x = self.rect.width
        self.rect.y = self.rect.height

        # 在属性中储存小数值
        self.x = float(self.rect.x)
        self.y = float(self.rect.y)
        #设置子弹速度
        self.speed_factor_Y = random.randint(1,2)
        self.speed_factor_X = random.randint(-4,-2)
    def update(self):
        self.x += self.speed_factor_X
        self.y +=self.speed_factor_Y
        self.rect.y=self.y
        self.rect.x=self.x
    # def blitme(self):
    #     """在指定位置绘制角色"""
    #     self.screen.blit(self.image, self.rect)

​ 代码完成的很草率,有很多地方还能优化,死亡画面和计分都没加

后续完成: 功能(boss血量,主人公血量,死亡画面,等)

​ 函数(代码整合优化,主人公攻击boss,计分,等)

#代码完成:
@by本人
	main_cycle,game_function,part,settings,部分整合
@by Siranyu
	boss,bullet,部分整合	
@by 小zhang
	hinder,hinder1,road,box

猜你喜欢

转载自blog.csdn.net/qq_44126342/article/details/109059993