python项目分享 热血足球游戏设计与实现 (源码)

这篇具有很好参考价值的文章主要介绍了python项目分享 热血足球游戏设计与实现 (源码)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


0 项目简介

🔥 Hi,各位同学好呀,这里是L学长!

🥇今天向大家分享一个今年(2022)最新完成的毕业设计项目作品

热血足球游戏设计与实现

🥇 学长根据实现的难度和等级对项目进行评分(最低0分,满分5分)

  • 难度系数:3分

  • 工作量:3分

  • 创新点:4分

  • 项目获取:https://gitee.com/sinonfin/system-sharing


1 游戏介绍

利用Python实现的简单的足球小游戏。

游戏规则:

比较简单,就不过多介绍了,按WASD控制上下左右,空格键射门。

2 实现效果

python项目分享 热血足球游戏设计与实现 (源码),python

python项目分享 热血足球游戏设计与实现 (源码),python

3 开发工具

3.1 环境配置

  • Python版本:3.6.4

  • 相关模块:

  • pygame模块;

  • 以及一些Python自带的模块。

3.2 Pygame介绍

简介

Pygame是一系列专门为编写电子游戏而设计的Python模块(modules)。Pygame在已经非常优秀的SDL库的基础上增加了许多功能。这让你能够用Python语言编写出丰富多彩的游戏程序。

Pygame可移植性高,几乎能在任何平台和操作系统上运行。

Pygame已经被下载过数百万次。

Pygame免费开源。它在LGPL许可证(Lesser General Public License,GNU宽通用公共许可证)下发行。使用Pygame,你可以创造出免费开源,可共享,或者商业化的游戏。详情请见LGPL许可证。

优点

  • 能够轻松使用多核CPU(multi core CPUs) :如今双核CPU很常用,8核CPU在桌面系统中也很便宜,而利用好多核系统,能让你在你的游戏中实现更多东西。特定的pygame函数能够释放令人生畏的python GIL(全局解释器锁),这几乎是你用C语言才能做的事。

  • 核心函数用最优化的C语言或汇编语言编写:C语言代码通常比Python代码运行速度快10-20倍。而汇编语言编写的代码(assembly code)比Python甚至快到100多倍。

  • 安装便捷:一般仅需包管理程序或二进制系统程序便能安装。

  • 真正地可移植:支持Linux (主要发行版), Windows (95, 98, ME, 2000, XP, Vista, 64-bit Windows,), Windows CE, BeOS, MacOS, Mac OS X, FreeBSD, NetBSD, OpenBSD, BSD/OS, Solaris, IRIX, and QNX等操作系统.也能支持AmigaOS, Dreamcast, Atari, AIX, OSF/Tru64, RISC OS, SymbianOS and OS/2,但是还没有受到官方认可。你也可以在手持设备,游戏控制台, One Laptop Per Child (OLPC) computer项目的电脑等设备中使用pygame.

  • 用法简单:无论是小孩子还是大人都能学会用pygame来制作射击类游戏。

  • 很多Pygame游戏已发行:其中包括很多游戏大赛入围作品、非常受欢迎的开源可分享的游戏。

  • 由你来控制主循环:由你来调用pygame的函数,pygame的函数并不需要调用你的函数。当你同时还在使用其他库来编写各种各种的程序时,这能够为你提供极大的掌控权。

  • 不需要GUI就能使用所有函数:仅在命令行中,你就可以使用pygame的某些函数来处理图片,获取游戏杆输入,播放音乐……

  • 对bug反应迅速:很多bug在被上报的1小时内就能被我们修复。虽然有时候我们确实会卡在某一个bug上很久,但大多数时候我们都是很不错的bug修复者。如今bug的上报已经很少了,因为许多bug早已被我们修复。

  • 代码量少:pygame并没有数以万计的也许你永远用不到的冗杂代码。pygame的核心代码一直保持着简洁特点,其他附加物诸如GUI库等,都是在核心代码之外单独设计研发的。

  • 模块化:你可以单独使用pygame的某个模块。想要换着使用一个别的声音处理库?没问题。pygame的很多核心模块支持独立初始化与使用。

最小开发框架

import pygame,sys #sys是python的标准库,提供Python运行时环境变量的操控

pygame.init()  #内部各功能模块进行初始化创建及变量设置,默认调用
size = width,height = 800,600  #设置游戏窗口大小,分别是宽度和高度
screen = pygame.display.set_mode(size)  #初始化显示窗口
pygame.display.set_caption("小游戏程序")  #设置显示窗口的标题内容,是一个字符串类型
while True:  #无限循环,直到Python运行时退出结束
    for event in pygame.event.get():  #从Pygame的事件队列中取出事件,并从队列中删除该事件
        if event.type == pygame.QUIT:  #获得事件类型,并逐类响应
            sys.exit()   #用于退出结束游戏并退出          
    pygame.display.update()  #对显示窗口进行更新,默认窗口全部重绘

代码执行流程

python项目分享 热血足球游戏设计与实现 (源码),python

4 具体实现

这里简单介绍一下原理吧,首先我们整个简单的开始界面吧:

'''定义游戏开始界面'''
def StartInterface(screen, resource_loader, cfg):
    clock = pygame.time.Clock()
    font, flag, count = resource_loader.fonts['default30'], True, 0
    font_render = font.render('按任意键开始游戏', False, cfg.RED)
    while True:
        count += 1
        if count > 20: count, flag = 0, not flag
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                QuitGame()
            elif event.type == pygame.KEYDOWN:
                return True
        screen.blit(resource_loader.images['background_start'], (0, 0))
        if flag: screen.blit(font_render, ((cfg.SCREENSIZE[0] - font.size('按任意键开始游戏')[0]) // 2, cfg.SCREENSIZE[1] - 200))
        clock.tick(cfg.FPS)
        pygame.display.update()

效果大概是这样子的:

python项目分享 热血足球游戏设计与实现 (源码),python
方便起见,我们设置成了按任意键都可以开始游戏。

接下来,我们来定义一下球员类,球员分为电脑自动控制和我们手动控制两种类型,其中我们手动控制的核心代码如下:

'''更新'''
def update(self, screen_size, ball):
    # 电脑自动控制
    if self.auto_control:
        self.autoupdate(screen_size, ball)
        return
    # 静止状态
    if not self.is_moving: return
    # 切换人物动作实现动画效果
    self.switch()
    # 根据方向移动人物
    ori_position = self.position.copy()
    speed = self.speed * self.direction[0], self.speed * self.direction[1]
    self.position[0] = min(max(0, self.position[0] + speed[0]), screen_size[0] - 48)
    self.position[1] = min(max(0, self.position[1] + speed[1]), screen_size[1] - 48)
    self.rect.left, self.rect.top = self.position
    if self.rect.bottom > 305 and self.rect.top < 505 and (self.rect.right > 1121 or self.rect.left < 75):
        self.position = ori_position
        self.rect.left, self.rect.top = self.position
    # 设置为静止状态
    self.is_moving = False

电脑自动控制的核心代码如下:

'''自动更新'''
def autoupdate(self, screen_size, ball):
    # 守门员
    if self.player_type == 'goalkeeper':
        self.speed = 1
        # --沿着门漫步
        def wondering(self):
            self.switch()
            self.position[1] = min(max(305, self.position[1] + self.direction[1] * self.speed), 459)
            self.rect.left, self.rect.top = self.position
            if self.rect.top == 305 or self.rect.top == 459: 
                self.direction = self.direction[0], -self.direction[1]
                self.setdirection(self.direction)
        # --有球就随机射球
        if ball.taken_by_player == self:
            if self.group_id == 1:
                if random.random() > 0.8 or self.prepare_for_kicking:
                    self.prepare_for_kicking = True
                    self.setdirection((1, 0))
                    if self.prepare_for_kicking:
                        self.prepare_for_kicking_count += 1
                        if self.prepare_for_kicking_count > self.prepare_for_kicking_freq:
                            self.prepare_for_kicking_count = 0
                            self.prepare_for_kicking = False
                            ball.kick(self.direction)
                            self.setdirection(random.choice([(0, 1), (0, -1)]))
                else:
                    wondering(self)
            else:
                if random.random() > 0.8 or self.prepare_for_kicking:
                    self.prepare_for_kicking = True
                    self.setdirection((-1, 0))
                    if self.prepare_for_kicking:
                        self.prepare_for_kicking_count += 1
                        if self.prepare_for_kicking_count > self.prepare_for_kicking_freq:
                            self.prepare_for_kicking_count = 0
                            self.prepare_for_kicking = False
                            ball.kick(self.direction)
                            self.setdirection(random.choice([(0, 1), (0, -1)]))
                else:
                    wondering(self)
        # --没球来回走
        else:
            wondering(self)
    # 其他球员跟着球走
    else:
        if ball.taken_by_player == self:
            self.switch()
            if self.group_id == 1:
                self.direction = min(max(1150 - self.rect.left, -1), 1), min(max(405 - self.rect.top, -1), 1)
            else:
                self.direction = min(max(350 - self.rect.left, -1), 1), min(max(405 - self.rect.top, -1), 1)
            self.setdirection(self.direction)
            if (random.random() > 0.9 and self.position[0] > 350 and self.position[0] < 1150) or self.prepare_for_kicking:
                if self.group_id == 1:
                    self.direction = min(max(1190 - self.rect.left, -1), 1), min(max(405 - self.rect.top, -1), 1)
                else:
                    self.direction = min(max(310 - self.rect.left, -1), 1), min(max(405 - self.rect.top, -1), 1)
                self.setdirection(self.direction)
                self.prepare_for_kicking = True
                if self.prepare_for_kicking:
                    self.prepare_for_kicking_count += 1
                    if self.prepare_for_kicking_count > self.prepare_for_kicking_freq:
                        self.prepare_for_kicking_count = 0
                        self.prepare_for_kicking = False
                        ball.kick(self.direction)
            else:
                speed = self.speed * self.direction[0], self.speed * self.direction[1]
                ori_position = self.position.copy()
                self.position[0] = min(max(0, self.position[0] + speed[0]), screen_size[0] - 48)
                self.position[1] = min(max(0, self.position[1] + speed[1]), screen_size[1] - 48)
                self.rect.left, self.rect.top = self.position
                if self.rect.bottom > 305 and self.rect.top < 505 and (self.rect.right > 1121 or self.rect.left < 75):
                    self.position = ori_position
                    self.rect.left, self.rect.top = self.position
        else:
            self.switch()
            if (ball.rect.centery > 400 and self.player_type == 'bottomhalf') or (ball.rect.centery <= 400 and self.player_type == 'upperhalf') or self.player_type == 'common':
                self.direction = min(max(ball.rect.left - self.rect.left, -1), 1), min(max(ball.rect.top - self.rect.top, -1), 1)
                self.direction = self.direction[0] * random.random(), self.direction[1] * random.random()
            else:
                if self.keep_direction_count >= self.keep_direction_freq:
                    self.direction = random.choice([-1, 0, 1]), random.choice([-1, 0, 1])
                    self.keep_direction_count = 0
                else:
                    self.keep_direction_count += 1
            self.setdirection(self.direction)
            speed = self.speed * self.direction[0], self.speed * self.direction[1]
            ori_position = self.position.copy()
            self.position[0] = min(max(0, self.position[0] + speed[0]), screen_size[0] - 48)
            self.position[1] = min(max(0, self.position[1] + speed[1]), screen_size[1] - 48)
            self.rect.left, self.rect.top = self.position
            if self.rect.bottom > 305 and self.rect.top < 505 and (self.rect.right > 1121 or self.rect.left < 75):
                self.position = ori_position
                self.rect.left, self.rect.top = self.position

逻辑比较简单,大概是这样子的:

  • 守门员:就在球门边上来回走

  • 负责上半场的球员:在上半场出现球的时候就往球的位置移动,如果捕获到了球,则往对方球门移动并随机射门,否则随机移动;

  • 负责下半场的球员:在下半场出现球的时候就往球的位置移动,如果捕获到了球,则往对方球门移动并随机射门,否则随机移动;

  • 负责全场的球员:往球的位置移动,果捕获到了球,则往对方球门移动并随机射门。

接下来定义一下足球类:

'''定义足球类'''
class Ball(pygame.sprite.Sprite):
    def __init__(self, images, position):
        pygame.sprite.Sprite.__init__(self)
        self.images = images
        self.image = self.images[0]
        self.rect = self.image.get_rect()
        self.rect.centerx, self.rect.centery = position
        self.mask = pygame.mask.from_surface(self.image)
        # 球的速度
        self.speed = 0
        # 球的方向
        self.direction = [0, 0]
        # 控制球的球员
        self.taken_by_player = None
        # 用于切换球动作的变量
        self.action_pointer = 0
        self.count = 0
        self.switch_frequency = 3
        # 是否在运动状态
        self.is_moving = False
    '''更新'''
    def update(self, screen_size):
        # 静止状态
        if not self.is_moving: return
        # 切换球动作实现动画效果
        self.count += 1
        if self.count == self.switch_frequency:
            self.count = 0
            self.action_pointer = (self.action_pointer + 1) % len(self.images)
            self.image = self.images[self.action_pointer]
        # 如果球是被球员控制的
        if self.taken_by_player is not None:
            self.setdirection(self.taken_by_player.direction)
            if self.taken_by_player.direction[0] < 0:
                self.rect.left, self.rect.top = self.taken_by_player.rect.left - 15, self.taken_by_player.rect.top + 30
            elif self.taken_by_player.direction[0] > 0:
                self.rect.left, self.rect.top = self.taken_by_player.rect.left + 30, self.taken_by_player.rect.top + 30
            elif self.taken_by_player.direction[1] < 0:
                self.rect.left, self.rect.top = self.taken_by_player.rect.left + 15, self.taken_by_player.rect.top - 15
            elif self.taken_by_player.direction[1] > 0:
                self.rect.left, self.rect.top = self.taken_by_player.rect.left + 10, self.taken_by_player.rect.top + 50
            return
        # 根据方向移动球
        ori_position = self.rect.left, self.rect.right, self.rect.top, self.rect.bottom
        self.speed = max(self.speed - 1.7 * 0.05, 0.0)
        if self.speed == 0.0: self.is_moving = False
        vector = [self.speed * self.direction[0], self.speed * self.direction[1]]
        vector[0] = vector[0] / math.pow(self.direction[0] ** 2 + self.direction[1] ** 2, 0.5)
        vector[1] = vector[1] / math.pow(self.direction[0] ** 2 + self.direction[1] ** 2, 0.5)
        self.rect.left = min(max(0, self.rect.left + vector[0]), screen_size[0] - 48)
        if self.rect.left == 0 or self.rect.left == screen_size[0] - 48: 
            self.direction = self.direction[0] * -0.8, self.direction[1]
        self.rect.top = min(max(0, self.rect.top + vector[1]), screen_size[1] - 48)
        if ori_position[1] > 1121 or ori_position[0] < 75:
            if self.rect.bottom > 305 and self.rect.top < 505:
                if self.direction[1] > 0:
                    self.rect.bottom = 305
                    self.direction = self.direction[0], self.direction[1] * -0.8
                elif self.direction[1] < 0:
                    self.rect.top = 505
                    self.direction = self.direction[0], self.direction[1] * -0.8
        if self.rect.top == 0 or self.rect.top == screen_size[1] - 48:
            self.direction = self.direction[0], self.direction[1] * -0.8
    '''设置方向'''
    def setdirection(self, direction):
        self.is_moving = True
        self.direction = direction
    '''踢球'''
    def kick(self, direction):
        self.speed = 12
        self.direction = direction
        self.taken_by_player = None
        self.is_moving = True
    '''在屏幕上显示'''
    def draw(self, screen):
        screen.blit(self.image, self.rect)

比较简单,主要就是两种状态:

  • 被球员捕获,跟着球员走;

  • 被球员踢出去之后根据球员踢的方向和设定的初速度进行减速运动,如果碰到边界则反方向弹出。

最后写个主循环就大功告成啦:

# 游戏主循环
clock = pygame.time.Clock()
while True:
    # --基础背景绘制
    screen.fill(cfg.LIGHTGREEN)
    pygame.draw.circle(screen, cfg.WHITE, (600, 400), 80, 5)
    pygame.draw.rect(screen, cfg.WHITE, (10, 10, 600, 790), 5)
    pygame.draw.rect(screen, cfg.WHITE, (600, 10, 590, 790), 5)
    pygame.draw.rect(screen, cfg.WHITE, (10, 150, 300, 500), 5)
    pygame.draw.rect(screen, cfg.WHITE, (890, 150, 300, 500), 5)
    screen.blit(resource_loader.images['doors'][0].convert(), (8, 305))
    screen.blit(resource_loader.images['doors'][1].convert(), (1121, 305))
    screen.blit(score_board, (565, 15))
    # --事件监听
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            QuitGame()
        elif event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
            QuitGame()
    pressed_keys = pygame.key.get_pressed()
    direction = [0, 0]
    if pressed_keys[pygame.K_w]: direction[1] -= 1
    if pressed_keys[pygame.K_d]: direction[0] += 1
    if pressed_keys[pygame.K_s]: direction[1] += 1
    if pressed_keys[pygame.K_a]: direction[0] -= 1
    if direction != [0, 0]: player_controlled.setdirection(direction)
    if pressed_keys[pygame.K_SPACE] and player_controlled == ball.taken_by_player: 
        ball.kick(player_controlled.direction)
    # --更新玩家
    for item in players_group1:
        if pygame.sprite.collide_mask(item, ball) and ball.taken_by_player != item: 
            ball.is_moving = True
            ball.taken_by_player = item
    for item in players_group2:
        if pygame.sprite.collide_mask(item, ball) and ball.taken_by_player != item: 
            ball.is_moving = True
            ball.taken_by_player = item
    for item in players_group1:
        item.update(cfg.SCREENSIZE_GAMING, ball)
    for item in players_group2:
        item.update(cfg.SCREENSIZE_GAMING, ball)
    # --更新球
    ball.update(cfg.SCREENSIZE_GAMING)
    # --更新屏幕
    ball.draw(screen)
    players_group1.draw(screen)
    players_group2.draw(screen)
    clock.tick(cfg.FPS)
    pygame.display.update()
    # --计算得分
    if ball.rect.bottom > 305 and ball.rect.top < 505:
        if ball.rect.right > 1121: return 1
        elif ball.rect.left < 75: return 2

5 最后

项目获取:https://gitee.com/sinonfin/system-sharing文章来源地址https://www.toymoban.com/news/detail-804149.html

到了这里,关于python项目分享 热血足球游戏设计与实现 (源码)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • python项目分享 - 扫雷小游戏设计与实现 (源码)

    🔥 Hi,各位同学好呀,这里是L学长! 🥇今天向大家分享一个今年(2022)最新完成的毕业设计项目作品 python小游戏毕设 扫雷小游戏设计与实现 (源码) 🥇 学长根据实现的难度和等级对项目进行评分(最低0分,满分5分) 难度系数:3分 工作量:3分 创新点:4分 项目获取: https:

    2024年02月19日
    浏览(50)
  • python项目分享 扫雷小游戏设计与实现 (源码)

    🔥 Hi,各位同学好呀,这里是L学长! 🥇今天向大家分享一个今年(2022)最新完成的毕业设计项目作品 python小游戏毕设 扫雷小游戏设计与实现 (源码) 🥇 学长根据实现的难度和等级对项目进行评分(最低0分,满分5分) 难度系数:3分 工作量:3分 创新点:4分 项目获取: https:

    2024年01月19日
    浏览(59)
  • python项目分享 滑雪小游戏设计与实现 (源码)

    🔥 Hi,各位同学好呀,这里是L学长! 🥇今天向大家分享一个今年(2022)最新完成的毕业设计项目作品 python小游戏毕设 滑雪小游戏设计与实现 (源码) 🥇 学长根据实现的难度和等级对项目进行评分(最低0分,满分5分) 难度系数:3分 工作量:3分 创新点:4分 项目获取: https:

    2024年01月17日
    浏览(48)
  • python项目分享 - 滑雪小游戏设计与实现 (源码)

    🔥 Hi,各位同学好呀,这里是L学长! 🥇今天向大家分享一个今年(2022)最新完成的毕业设计项目作品 python小游戏毕设 滑雪小游戏设计与实现 (源码) 🥇 学长根据实现的难度和等级对项目进行评分(最低0分,满分5分) 难度系数:3分 工作量:3分 创新点:4分 项目获取: https:

    2024年02月19日
    浏览(51)
  • python项目分享 打砖块小游戏设计与实现 (源码)

    🔥 Hi,各位同学好呀,这里是L学长! 🥇今天向大家分享一个今年(2022)最新完成的毕业设计项目作品 python小游戏毕设 打砖块小游戏设计与实现 🥇 学长根据实现的难度和等级对项目进行评分(最低0分,满分5分) 难度系数:3分 工作量:3分 创新点:3分 项目获取: https://gite

    2024年02月02日
    浏览(50)
  • python项目分享 接金币小游戏设计与实现 (源码)

    🔥 Hi,各位同学好呀,这里是L学长! 🥇今天向大家分享一个今年(2022)最新完成的毕业设计项目作品 python小游戏毕设 接金币小游戏设计与实现 (源码) 🥇 学长根据实现的难度和等级对项目进行评分(最低0分,满分5分) 难度系数:3分 工作量:3分 创新点:3分 项目获取: htt

    2024年03月09日
    浏览(53)
  • python项目分享 消消乐小游戏设计与实现 (源码)

    🔥 Hi,各位同学好呀,这里是L学长! 🥇今天向大家分享一个今年(2022)最新完成的毕业设计项目作品 python小游戏毕设 消消乐小游戏设计与实现 (源码) 🥇 学长根据实现的难度和等级对项目进行评分(最低0分,满分5分) 难度系数:3分 工作量:3分 创新点:4分 项目获取: htt

    2024年01月22日
    浏览(50)
  • python项目分享 - 炸弹人小游戏设计与实现 (源码)

    🔥 Hi,各位同学好呀,这里是L学长! 🥇今天向大家分享一个今年(2022)最新完成的毕业设计项目作品 **python小游戏毕设 炸弹人小游戏设计与实现 ** 🥇 学长根据实现的难度和等级对项目进行评分(最低0分,满分5分) 难度系数:3分 工作量:3分 创新点:4分 项目获取: https:/

    2024年02月20日
    浏览(51)
  • python项目分享 - 坦克大战小游戏设计与实现 (源码)

    🔥 Hi,各位同学好呀,这里是L学长! 🥇今天向大家分享一个今年(2022)最新完成的毕业设计项目作品 python小游戏毕设 坦克大战小游戏设计与实现 (源码) 🥇 学长根据实现的难度和等级对项目进行评分(最低0分,满分5分) 难度系数:3分 工作量:3分 创新点:4分 项目获取:

    2024年02月01日
    浏览(54)
  • python项目分享 - 接金币小游戏设计与实现 (源码)

    🔥 Hi,各位同学好呀,这里是L学长! 🥇今天向大家分享一个今年(2022)最新完成的毕业设计项目作品 python小游戏毕设 接金币小游戏设计与实现 (源码) 🥇 学长根据实现的难度和等级对项目进行评分(最低0分,满分5分) 难度系数:3分 工作量:3分 创新点:3分 项目获取: htt

    2024年02月22日
    浏览(49)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包