文章目录

  • 零、序章
  • 一、游戏主程序
  • 二、球类
  • 三、球拍类
  • 四、计分板类
  • 五、效果展示

零、序章

这是一个使用Python写的打乒乓游戏。

可以练习一些面向对象的知识。

实现的功能有:

  • 球的发球、碰撞检测及反弹、出界检测
  • 玩家球拍的上下移动、电脑球拍的自动移动
  • 区分玩家、电脑的计分板及刷新

可以改进的地方有:

  • 暂停功能
  • 碰撞检测可以优化,现在是给球加个个碰撞后的加速(闪现)以免卡bug
  • 球和球拍的碰撞可以,现在只能接住球并反弹出去,而不能将球拍的移动或碰撞位置与球的反弹联动起来实现击球效果
  • 电脑球拍的逻辑优化,现在移动过于鬼畜

一、游戏主程序

import time
from turtle import Turtle, Screen
from ball import Ball
from bat import Bat
from scoreboard import ScoreBoard# 设置难度
MODE = 'normal'# 实例化屏幕对象、设置屏幕大小、背景色、标题、关闭实时刷新
screen = Screen()
screen.setup(width=1200, height=600)
screen.bgcolor('black')
screen.title('Ping-Pong')
screen.tracer(False)def cal_limits(screen):"""根据屏幕计算边界的函数:param screen: 屏幕:return: 上下左右四个边界"""u_limit = screen.window_height() // 2 - 30d_limit = -screen.window_height() // 2 + 30l_limit = -screen.window_width() // 2 + 30r_limit = screen.window_width() // 2 - 30return u_limit, d_limit, l_limit, r_limitdef draw_mid_line(limits):"""这是一个绘制中线的函数:param limits: 边界:return: 无"""line = Turtle()line.ht()line.pensize(10)line.pencolor('white')line.penup()line.goto(0, limits[1])line.setheading(90)while line.pos()[1] <= limits[0]:line.pendown()line.forward(10)line.penup()line.forward(30)def game_init():"""这是一个重开一局的函数:return: 无"""# 调用发球函数ball.serve()# 初始化球拍位置player_bat.b_goto(limits[2], 0)computer_bat.b_goto(limits[3], 0)# 停顿1秒time.sleep(1)def quit_game():"""控制退出游戏的函数:return: 无"""screen.bye()# 计算边界
limits = cal_limits(screen)
# 画出中线
draw_mid_line(limits)# 实例化球对象、球拍对象、分数版对象
ball = Ball()player_bat = Bat(limits[2], limits)
computer_bat = Bat(limits[3], limits)player_score = ScoreBoard((-100, limits[0] - 50))
computer_score = ScoreBoard((60, limits[0] - 50))# 监听屏幕
screen.listen()
screen.onkey(key='q', fun=quit_game)
screen.onkey(key='Up', fun=player_bat.up)
screen.onkey(key='Down', fun=player_bat.down)while True:# 每局游戏开始刷新分数player_score.refresh_score()computer_score.refresh_score()while True:# 每隔0.015刷新一次屏幕time.sleep(0.015)# 电脑球拍移动computer_bat.computer_move(ball_pos=ball.pos(), mode=MODE)# 撞击检测hit_result = ball.check_hit(limits, player_bat, computer_bat)# 如果右出界给玩家加分,左出界给电脑加分if hit_result == 1:player_score.score += 1game_init()breakelif hit_result == 2:computer_score.score += 1game_init()break# 球向前移动ball.forward(10)# 屏幕刷新screen.update()

二、球类

import random
from turtle import Turtle# 球类继承自Turtle类,提笔、形状是球、白色
class Ball(Turtle):def __init__(self):super().__init__()self.penup()self.shape('circle')self.color('white')# 调用发球函数self.serve()def serve(self):"""发球函数:return: 无"""self.goto(0, 0)# 发球角度随机heading = random.choice([random.randint(330, 350), random.randint(10, 30), random.randint(150, 170), random.randint(190, 210)])self.setheading(heading)def check_hit_wall(self, limits):"""检测撞上下边界的函数:param limits: 边界:return: 无"""if self.pos()[1] > limits[0] or self.pos()[1] < limits[1]:self.vertical_hit()def check_hit_bat(self, p_bat, c_bat):"""检测撞板子或出左右边界的函数:param p_bat: 玩家控制的球板对象:param c_bat: 电脑控制的球板对象:return: 撞到板子了就触发水平碰撞函数并返回0,什么都没碰到也返回0,左出界返回2,右出界返回1"""ball_x = self.pos()[0]ball_y = self.pos()[1]# 检测逻辑:如果x坐标很靠近,且球的y坐标被包括在了球拍的上下边界之中,则判定为碰撞if ball_x - p_bat.pos()[0] < 20 and p_bat.lower_limit - 20 < ball_y < p_bat.upper_limit:self.horizontal_hit()elif c_bat.pos()[0] - ball_x < 20 and c_bat.lower_limit - 20 < ball_y < c_bat.upper_limit and ball_y:self.horizontal_hit()else:# 这里在检测是否从右、左出界if ball_x > c_bat.pos()[0]:return 1elif ball_x < p_bat.pos()[0]:return 2return 0def check_hit(self, limits, p_bat, c_bat):"""这是一个综合检测是否出界+撞击的函数:param limits: 边界:param p_bat: 玩家控制的球板对象:param c_bat: 电脑控制的球板对象:return: 和上一个函数返回值相同"""self.check_hit_wall(limits)return self.check_hit_bat(p_bat, c_bat)def horizontal_hit(self):"""水平撞击函数,在镜像反弹的基础上加入随机变量,且撞击会给球一个小加速(这是为了防止卡bug):return: 无"""self.setheading(540 - self.heading() + random.randint(-10, 10))# 小加速self.forward(30)def vertical_hit(self):"""垂直撞击函数,没有添加随机变量,完全弹性碰撞:return: 无"""self.setheading(360 - self.heading())

三、球拍类

import random
from turtle import Turtle# 球拍移动距离常数、球拍长度常数
STEP = 30
BAT_SIZE = 6# 球拍类,继承自Turtle类
class Bat(Turtle):# 方形,扯成长条状、提笔、白色、加入上下边界两个属性、也把屏幕边界作为属性记下来,这是为了后面方便移动函数def __init__(self, x, game_edge):super().__init__()self.shape('square')self.shapesize(stretch_wid=BAT_SIZE, stretch_len=1)self.penup()self.color('white')self.upper_limit = 0self.lower_limit = 0# 这个b_goto是goto的改进版self.b_goto(x, 0)self.limits = game_edgedef up(self):"""这是一个控制向上移动的函数,如果已经达到上边界就不允许移动:return: 无"""if self.upper_limit <= self.limits[0] - 30:self.setheading(90)self.forward(STEP)self.setheading(0)self.upper_limit += STEPself.lower_limit += STEPdef down(self):"""同上:return: 无"""if self.lower_limit >= self.limits[1] + 30:self.setheading(270)self.forward(STEP)self.setheading(0)self.upper_limit -= STEPself.lower_limit -= STEPdef computer_move(self, ball_pos, mode):"""这是一个控制电脑球拍移动的函数,移动逻辑是简单地跟随球的y坐标:param ball_pos: 球坐标:param mode: 难度:return: 无"""# 根据难度设置电脑球拍的发呆概率if mode == 'easy':ignore = 0.9elif mode == 'normal':ignore = 0.85elif mode == 'hard':ignore = 0.8else:ignore = 0.75# 如果随机数大于发呆率,则执行移动,否则发呆if random.random() > ignore:if ball_pos[1] - self.pos()[1] > 10:self.up()elif ball_pos[1] - self.pos()[1] < 10:self.down()def b_goto(self, x, y):"""goto的改进版,主要是为了同步刷新上下边界属性:param x: x坐标:param y: y坐标:return: 无"""self.goto(x, y)# 同步刷新上下边界属性self.upper_limit = self.pos()[1] + BAT_SIZE / 2 * 20self.lower_limit = self.pos()[1] - BAT_SIZE / 2 * 20

四、计分板类

from turtle import Turtle# 字体常量
FONT = 'TimeNewRoman', 60, 'normal'# 计分板类,继承自Turtle类
class ScoreBoard(Turtle):# 计分板要隐藏起来、提笔、初始score属性为0分、到指定位置def __init__(self, pos):super().__init__()self.ht()self.penup()self.score = 0self.goto(pos)def refresh_score(self):"""这是一个刷新分数的函数:return: 无"""# 清空之前的分并写上新分self.clear()self.pendown()self.pencolor('white')self.write(self.score, font=FONT)

五、效果展示

【Python项目】乒乓球小游戏相关推荐

  1. 用python编写乒乓球小游戏--Turtle功能的应用

    用python编写乒乓球小游戏–Turtle功能的应用 python有很多功能强大的代码库,Turtle是一款用于游戏开发的代码库.通过编写乒乓球小游戏可以了解这个库的基本的代码的使用 先创建游戏的背 ...

  2. 记录第一个 python项目 外星人入侵小游戏

    学习目标:提升自己的编程能力## 标题 *> 可谓是一波三折 ,刚开始看的一本电子书 里面是python2.0的内容,我敲着在3系列的编译器试着2.0的代码可谓好不酸爽 那报错 绝了 学习内容: ...

  3. Python快速编程入门#学习笔记02# |第十章 :Python计算生态与常用库(附.小猴子接香蕉、双人乒乓球小游戏源码)

    全文目录 学习目标 1. Python计算生态概述 1.1 Python计算生态概述 2. Python生态库的构建与发布 2.1 模块的构建与使用 * 2.1.1第三方库/模块导入的格式 2.2 包 ...

  4. c++代码小游戏_用Python编写一个打乒乓球小游戏

    Python功能十分强大,从科学计算到人工智 能,当然Python还可以编写游戏代码喔,虽然不是主流,但是是否应该了解一下呢?茶余饭后,编写一个很有趣的小游戏,编程半小时,能玩一整天,不断的调整游戏参 ...

  5. python乒乓球小游戏_100行-python乒乓球小游戏

    今天在b站上看到一个好的挺有意思的视频,<用Python开发双人对战乒乓球小游戏>,哈哈哈,于是就快速看完啦,然后照着写了一个.传送门用Python开发双人对战乒乓球小游戏_哔哩哔哩 (゜ ...

  6. 用Python编写一个打乒乓球小游戏

    点击上方"背锅侠Tester",从陌生到恋爱的感觉~ 听说看超哥的文章会上瘾 不要把工作当作生活的工具,把工作当生意做: 愿自己身体健健康康家人平安 祝各位同上,2019更精彩@a ...

  7. python经典小游戏五子棋,适合python编程的小游戏

    python入门可以做的小游戏 1.Python入门拼图小游戏简单介绍:将图像分为m×n个矩形块,并将图像右下角的矩形块替换为空白块后,将这些矩形块随机摆放成原图像的形状. 2.Python入门推箱子 ...

  8. python写游戏脚本-使用Python写一个小游戏

    引言 最近python语言大火,除了在科学计算领域python有用武之地之外,在游戏.后台等方面,python也大放异彩,本篇博文将按照正规的项目开发流程,手把手教大家写个python小游戏,来感受下 ...

  9. python编程小游戏-使用Python写一个小游戏

    引言 最近python语言大火,除了在科学计算领域python有用武之地之外,在游戏.后台等方面,python也大放异彩,本篇博文将按照正规的项目开发流程,手把手教大家写个python小游戏,来感受下 ...

  10. 使用python制作聊天框解谜游戏_使用Python写一个小游戏alien invasion!

    最近python语言大火,除了在科学计算领域python有用武之地之外,在游戏.后台等方面,python也大放异彩,本篇博文将按照正规的项目开发流程,手把手教大家写个python小游戏,来感受下其中的 ...

最新文章

  1. IF10+的数据库文章!这里有5个案例,一起发起来?
  2. 从状态模式看“大神”和“菜鸟”的差别
  3. 32时间片轮转_系统时间
  4. 使用matlab构建一个信号、添加噪声信号并图示信号
  5. 【UGV】小车一些图片 麦轮版小车
  6. C++ 合并文件夹下所有的txt文件
  7. 从零开始学_JavaScript_系列(22)——dojo(9)(表单、JsonRest的post方法,widget的使用思路)...
  8. Flask源码解析:从第一个版本开始阅读Flask源码
  9. 圆方树(bzoj 2125: 最短路)
  10. 两个工作流:什么时候选择BizTalk,什么时候选择WWF?微软人士给了一个简单的判断原则...
  11. Polycom高清视频会议桌面系统HDX 4000
  12. 如何在快手批量下载高清无水印视频方法
  13. 前端培训丁鹿学堂:nodeJS入门指南(一)
  14. logstash-input-jdbc 下载安装 linux
  15. 偏最小二乘(Partial Least Squares,PLS)原理及模型建立
  16. 自己写好的html页面怎么发给别人看,分享自己写的第一个html网页
  17. cube配置定时器ETR2模式测频实验
  18. vs2017c语言playsound,VS2010播放.WAW音频文件
  19. 2023 USAMO(美国数学奥林匹克)试题答案解析
  20. 实现正六边形、圆形及带倒角正六边形的头像显示

热门文章

  1. 查看mysql数据库文件命令_MySQL 数据库常用命令
  2. 三人看《中国合伙人》电影感悟
  3. Java日志框架 -- SLF4J日志门面(入门案例、SLF4J优点、SLF4J日志绑定、SL4J桥接旧的日志框架)
  4. 空间坐标系坐标变换及matlab代码实现
  5. (译)菱形不是银弹,但范加尔、罗杰斯们是如何改造它的?
  6. VS引用第三方插件CSkin
  7. springboot使用Junit进行单元测试报错:Could not initialize plugin: interface org.mockito.plugins.MockMaker
  8. 三菱FX3U画圆程序,程序结构简单,注释清晰,将圆划分为360段,循环调用子程序
  9. 这么讲线程池,彻底明白了
  10. 页面性能:如何系统地优化页面?