基于Python制作的热血足球小游戏

基于 Python 制作的热血足球小游戏 导语 最近有读者说我发的文章太水了,都是炒冷饭的,那就带大家整点新鲜的东西吧,反正估计今年都得"坐牢"了,炒冷饭的机会有得是

本文包含相关资料包-----> 点击直达获取<-------

基于 Python 制作的热血足球小游戏

导语

最近有读者说我发的文章太水了,都是炒冷饭的,那就带大家整点新鲜的东西吧,反正估计今年都得"坐牢"了,炒冷饭的机会有得是。

好像好久没带大家写新的小游戏了,那么今天就来带大家写个简单的足球小游戏咯(与近期热点绝对无关,狗头戏谑),废话不多说,让我们愉快地开始吧~

开发工具

Python 版本:3.7.8

相关模块:

pygame 模块;

以及一些 python 自带的模块。

环境搭建

安装 Python 并添加到环境变量,pip 安装需要的相关模块即可。

游戏实现

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

```python

'''定义游戏开始界面''' 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() ```

效果大概是这样子的:

方便起见,我们设置成了按任意键都可以开始游戏。

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

'''更新''' 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

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

```python

'''自动更新''' 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 ```

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

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

接下来定义一下足球类:

python '''定义足球类''' 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)

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

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

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

```python

游戏主循环

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 ```

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

完整源代码详见相关文件~

效果展示

首先安装最新版本的 cpgames:

pip install cpgames==0.1.2

然后写如下代码调用即可运行:

``` from cpgames import cpgames

game_client = cpgames.CPGames() game_client.execute('bloodfootball') ```

效果如下:

参考文献

  • 基于J2EE的球队纪念品销售管理系统的设计与实现(中国地质大学(北京)·王英杰)
  • 基于SSH的大学生联谊交友管理系统设计与实现(华中科技大学·王海波)
  • 面向高职信息技术教育的严肃游戏设计与实施(大连理工大学·王晓姝)
  • 基于ASP.NET开发技术的BBS论坛研究与设计(中国海洋大学·马章勤)
  • 3D云游戏平台的设计与实现(北京交通大学·闫璐)
  • 基于VF的社区物业信息管理系统的设计与实现(电子科技大学·徐玮)
  • 3D云游戏平台的设计与实现(北京交通大学·闫璐)
  • 基于Android的足球球迷综合服务平台的设计与实现(北京工业大学·陈鑫)
  • 基于轻量级J2EE的网络游戏虚拟物品交易系统的设计与实现(北京邮电大学·曹鹃)
  • 基于.NET自定义控件的社区网站系统研究与实现(武汉理工大学·刘亚)
  • 基于云平台的校园足球管理系统的设计与实现(内蒙古大学·张艳秋)
  • 基于SSH架构的个人空间交友网站的设计与实现(北京邮电大学·隋昕航)
  • 基于.NET平台的游戏门户系统设计与实现(电子科技大学·余胜鹏)
  • 基于云平台的校园足球管理系统的设计与实现(内蒙古大学·张艳秋)
  • 基于J2ME的Java手机软件——足球彩票手机投注系统(华侨大学·许向锋)

本文内容包括但不限于文字、数据、图表及超链接等)均来源于该信息及资料的相关主题。发布者:源码货栈 ,原文地址:https://m.bishedaima.com/yuanma/36070.html

相关推荐

  • 基于Python实现图像分类

    一, 理论知识 1,1 softmax线性分类器 线性分类器的函数为线性形式,即为(这里将偏置项看做参与乘积的一部分): $$ f(x_1,,,,x_m)=w_0+w_1x_1+
    2024年05月14日
    3 1 1
  • 人事管理系统

    这是一个🔥🔥基于SpringBoot框架的人事管理系统设计与实现🔥🔥的项目源码,开发语言Java,框架使用的SpringBoot+vue技术,开发环境Idea/Eclipse
    2024年05月23日
    1 1 1
  • 基于Python制作的热血足球小游戏

    基于 Python 制作的热血足球小游戏 导语 最近有读者说我发的文章太水了,都是炒冷饭的,那就带大家整点新鲜的东西吧,反正估计今年都得"坐牢"了,炒冷饭的机会有得是
    2024年05月14日
    5 1 2
  • 基于jsp+servlet+mysql的大学社团交流BBS平台

    这是一个🔥🔥基于jsp的大学社团交流BBS平台🔥🔥的项目源码,开发语言Java,开发环境Idea/Eclipse,这个 大学社团交流BBS开发技术栈为JSP项目,可以作为毕业设计课程设计作业大学生社团作为大学生活的重要一部分
    2024年05月23日
    6 1 2
  • Python 新浪微博爬虫

    Python 新浪微博爬虫,支持模拟登陆,微博文字另存为本地文件 网上大部分对微博的爬虫都是先人工登陆获取cookie再进行接下来的抓取操作的,所以我写了一份模拟登陆获取cookie的(因为是分析为主要目的
    2024年05月14日
    2 1 1
  • 基于SpringBoot框架的酒店客房管理系统

    这是一套采用Java语言编写的🔥🔥酒店客房管理系统的源代码,基于SpringBoot框架构建,我们运用了现代化的SpringBoot和Vue技术栈,开发工具为Idea或Eclipse
    2024年05月23日
    1 1 1
  • Spring boot 实战--- 社区论坛

    Spring boot 实战--- 社区论坛 开发社区首页 开发流程 1 次请求的执行过程 分步实现 开发社区首页
    2024年05月14日
    2 1 2
  • 基于 flask 的 Web 计算器

    基于 flask 的 Web 计算器 需求分析 1, 前言 开发基于 flask 作为框架的计算器 Web 应用是为了能够方便快捷的使用计算器
    2024年05月14日
    22 1 3
  • 基于Python实现成绩统计系统

    1, 课程设计目的 《软件设计基础-Python》课程设计是这门课程的实践性教学环节之一,本次设计结合实际应用的要求,使课程设计既覆盖Python的知识点,又接近工程实际需要
    2024年05月14日
    1 1 1
  • 基于WEB的图书阅读器的实现

    2017-毕业设计(基于 Web 平台的阅读 APP 设计与实现) 该项目实现了一款基于 Web 平台的阅读 APP,该 APP 采用简洁护眼颜色搭配,简洁舒适的设计风格
    2024年05月14日
    2 1 1

发表回复

登录后才能评论