前言

今年世界杯有人欢喜有人愁,我想愁的人应该居多,不得不说,小日本是真菜啊,特么的!

今天还是搞点咱们好玩点的,世界杯嘛,大家看看就行,大家不是都说,看国足比看相声还搞笑吗?

好了,不笑了。今天给大家带来一款非常简单的足球小游戏,希望大家喜欢,也喜欢大家能在这次世界杯旗开得胜。如果喜欢的话,点点小赞呗

开发工具

Python版本:3.7.8

相关模块:

pygame模块;

以及一些python自带的模块。

环境搭建

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

游戏实现

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

'''定义游戏开始界面'''
def StartInterface(screen, resource_loader, cfg):clock = pygame.time.Clock()font, flag, count = resource_loader.fonts['default30'], True, 0font_render = font.render('按任意键开始游戏', False, cfg.RED)while True:count += 1if count > 20: count, flag = 0, not flagfor event in pygame.event.get():if event.type == pygame.QUIT:QuitGame()elif event.type == pygame.KEYDOWN:return Truescreen.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.positionif self.rect.bottom > 305 and self.rect.top < 505 and (self.rect.right > 1121 or self.rect.left < 75):self.position = ori_positionself.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.positionif 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 = Trueself.setdirection((1, 0))if self.prepare_for_kicking:self.prepare_for_kicking_count += 1if self.prepare_for_kicking_count > self.prepare_for_kicking_freq:self.prepare_for_kicking_count = 0self.prepare_for_kicking = Falseball.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 = Trueself.setdirection((-1, 0))if self.prepare_for_kicking:self.prepare_for_kicking_count += 1if self.prepare_for_kicking_count > self.prepare_for_kicking_freq:self.prepare_for_kicking_count = 0self.prepare_for_kicking = Falseball.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 = Trueif self.prepare_for_kicking:self.prepare_for_kicking_count += 1if self.prepare_for_kicking_count > self.prepare_for_kicking_freq:self.prepare_for_kicking_count = 0self.prepare_for_kicking = Falseball.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.positionif self.rect.bottom > 305 and self.rect.top < 505 and (self.rect.right > 1121 or self.rect.left < 75):self.position = ori_positionself.rect.left, self.rect.top = self.positionelse: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 = 0else:self.keep_direction_count += 1self.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.positionif self.rect.bottom > 305 and self.rect.top < 505 and (self.rect.right > 1121 or self.rect.left < 75):self.position = ori_positionself.rect.left, self.rect.top = self.position

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

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

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

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

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

接下来定义一下足球类:


'''定义足球类'''
class Ball(pygame.sprite.Sprite):def __init__(self, images, position):pygame.sprite.Sprite.__init__(self)self.images = imagesself.image = self.images[0]self.rect = self.image.get_rect()self.rect.centerx, self.rect.centery = positionself.mask = pygame.mask.from_surface(self.image)# 球的速度self.speed = 0# 球的方向self.direction = [0, 0]# 控制球的球员self.taken_by_player = None# 用于切换球动作的变量self.action_pointer = 0self.count = 0self.switch_frequency = 3# 是否在运动状态self.is_moving = False'''更新'''def update(self, screen_size):# 静止状态if not self.is_moving: return# 切换球动作实现动画效果self.count += 1if self.count == self.switch_frequency:self.count = 0self.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 + 30elif 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 + 30elif 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 - 15elif 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 + 50return# 根据方向移动球ori_position = self.rect.left, self.rect.right, self.rect.top, self.rect.bottomself.speed = max(self.speed - 1.7 * 0.05, 0.0)if self.speed == 0.0: self.is_moving = Falsevector = [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 = 305self.direction = self.direction[0], self.direction[1] * -0.8elif self.direction[1] < 0:self.rect.top = 505self.direction = self.direction[0], self.direction[1] * -0.8if 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 = Trueself.direction = direction'''踢球'''def kick(self, direction):self.speed = 12self.direction = directionself.taken_by_player = Noneself.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] -= 1if pressed_keys[pygame.K_d]: direction[0] += 1if pressed_keys[pygame.K_s]: direction[1] += 1if pressed_keys[pygame.K_a]: direction[0] -= 1if 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 = Trueball.taken_by_player = itemfor item in players_group2:if pygame.sprite.collide_mask(item, ball) and ball.taken_by_player != item: ball.is_moving = Trueball.taken_by_player = itemfor 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 1elif 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')

效果展示

是不是很简单吗,是个非常简易版的游戏,适合和自己的小孩边看世界杯边玩,谢谢大家观看到这里,需要源代码的可以关注下方小卡片哦,点点赞呗。

这届世界杯是不是让你出乎意料?写个足球小游戏来模拟一下!相关推荐

  1. c++ 小游戏_C/C++编程笔记:C语言写推箱子小游戏,大一学习C语言练手项目

    C语言,作为大多数人的第一门编程语言,重要性不言而喻,很多编程习惯,逻辑方式在此时就已经形成了.这个是我在大一学习 C语言 后写的推箱子小游戏,自己的逻辑能力得到了提升,在这里同大家分享这个推箱子小游 ...

  2. 利用js写的见缝插针小游戏

    利用js写的见缝插针小游戏 今天给大家带来的就是一款叫做<见缝插针>的游戏.有空你就往里插,直到你无处可插!看你能过多少关! 游戏截图 失败时 代码如下 js代码 index.js 测试游 ...

  3. Python写王者荣耀小游戏

    Python写王者荣耀小游戏 文章目录 Python写王者荣耀小游戏 说明: 一.socket创建 二.实现多进程 三.面向对象版本 四.主体部分搭建 1. 服务器主要步骤的实现 1-1主体部分 1- ...

  4. 弹力细胞,一个由JavaScript写的网页小游戏

    弹力细胞 (BounceCell) 一个由JavaScript写的网页小游戏 作为大一菜鸟,这是我第一次比较正式的写文章 [害臊] 游戏玩法 通过鼠标或触屏控制屏幕底部的滑动弹板将发射的小球反弹出去撞 ...

  5. scratch制作2022世界杯足球小游戏

    2022卡塔尔世界杯进行的如火如荼,多匹"黑马"击退热门劲旅,在这里,我们也使用scratch制作一个足球小游戏,废话不多说,直接上程序. 1.角色一程序(游戏者控制) 2.角色二 ...

  6. python弹球小游戏程序设计_Python写的弹球小游戏

    原标题:Python写的弹球小游戏 Python 的功能强大应用广泛,从爬虫到 Web 开发,从科学计算到人工智能,都能见到它的身影.当然,Python 还可以编写游戏代码,虽然不是主流,但却十分有趣 ...

  7. c 语言500行小游戏代码,500行代码使用python写个微信小游戏飞机大战游戏.pdf

    500行行代代码码使使用用python写写个个微微信信小小游游戏戏飞飞机机大大战战游游戏戏 这篇文章主要介绍了500行代码使用python写个微信小游戏飞机大战游戏,本文通过实例代码给大家介绍的非常详 ...

  8. 【python小游戏】用python写一款小游戏--贪吃蛇

    大家好,我是爱吃饼干的小白鼠,今天给大家分享一款自制小游戏.如何用python编写贪吃蛇. 今天,突发奇想的想用python写一款小游戏--贪吃蛇.相信大家都玩过,那么玩一款自己写的是一种什么样的体验 ...

  9. 熬夜写了一个小游戏,向SpaceX聊表敬意

    2019独角兽企业重金招聘Python工程师标准>>> 这是我长久放在桌面上的一张图片. 这张照片的名字叫做 Pale Blue Dot(暗淡蓝点),是旅行者1号在距地球64亿公里回 ...

最新文章

  1. 计算机类东北大学和大连理工,东北大学VS大连理工大学,谁才是第一,辽宁本地考生也两难...
  2. python怎么做界面自动化_mac+python3+selenium做pc的界面自动化测试
  3. 机器学习笔试精选题精选(四)
  4. C++设计模试之S状态模式
  5. 检测到在集成的托管管道模式下不适用的ASP.NET设置的解决方法(非简单设置为【经典】模式)...
  6. 对RESTful Web API的理解与设计思路
  7. SpringBoot 基础上传操作
  8. synchronized()_JMM(四):浅谈synchronized锁
  9. erlang的dict源码解析(1)
  10. 工信部:老年人拨打三大运营商客服享受一键呼入等服务
  11. matlab双立方插值法_双三次插值(Bicubic interpolation)缩放图片
  12. Effective C++读书笔记 第1章
  13. opengl矩阵变换与平移缩放旋转
  14. 力扣——字符串转换整数 (atoi)
  15. Could not open Hibernate Session for transaction, 数据库连接超时解决方法
  16. 在MACBook笔记本上通过Safari 访问EBS系统
  17. 如何修改Maven本地仓库位置
  18. 计算机视觉--图像导数-图像梯度向量
  19. 如何制作手机自适应网页
  20. 计算机毕业设计-问答交流论坛小程序系统【代码讲解+安装调试+文档指导】

热门文章

  1. 配置centos虚拟机以及虚拟机联网问题
  2. spring @RequestBody注解无法接收x-www-form-urlencoded 解决方案
  3. 我的创新成长之路(二)
  4. 选项卡 bootstrap_使Bootstrap选项卡与砌体一起发挥作用
  5. MySQL查看字符集以及修改字符集
  6. 数据挖掘之缺失值处理
  7. python 映射表结构_Python 中常见的数据结构:字典、映射和散列表
  8. django设置cookie
  9. 均值滤波计算_图像处理之低通滤波
  10. 【面试题】 「中高级前端面试」JavaScript手写代码无敌秘籍