Python-乒乓球小游戏【附完整源码】

这篇具有很好参考价值的文章主要介绍了Python-乒乓球小游戏【附完整源码】。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

乒乓球小游戏

乒乓球小游戏是一个简单而有趣的2D页面交互式游戏,玩家可以通过键盘输入来控制球拍上下移动来接球,从而体验乒乓球的乐趣。该游戏有单人和双人两种模式

运行效果:
Python-乒乓球小游戏【附完整源码】,关于Python的小程序-源码自取,python,pygame,开发语言
Python-乒乓球小游戏【附完整源码】,关于Python的小程序-源码自取,python,pygame,开发语言

一:主程序:

import sys
import cfg
import pygame
from modules import *

'''定义按钮'''
def Button(screen, position, text, button_size=(200, 50)):
    left, top = position
    bwidth, bheight = button_size
    pygame.draw.line(screen, (150, 150, 150), (left, top), (left+bwidth, top), 5)
    pygame.draw.line(screen, (150, 150, 150), (left, top-2), (left, top+bheight), 5)
    pygame.draw.line(screen, (50, 50, 50), (left, top+bheight), (left+bwidth, top+bheight), 5)
    pygame.draw.line(screen, (50, 50, 50), (left+bwidth, top+bheight), (left+bwidth, top), 5)
    pygame.draw.rect(screen, (100, 100, 100), (left, top, bwidth, bheight))
    font = pygame.font.Font(cfg.FONTPATH, 30)
    text_render = font.render(text, 1, (255, 235, 205))
    return screen.blit(text_render, (left+50, top+10))

'''
Function:
    开始界面
Input:
    --screen: 游戏界面
Return:
    --game_mode: 1(单人模式)/2(双人模式)
'''
def startInterface(screen):
    clock = pygame.time.Clock()
    while True:
        screen.fill((41, 36, 33))
        button_1 = Button(screen, (150, 175), '1 Player')
        button_2 = Button(screen, (150, 275), '2 Player')
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            if event.type == pygame.MOUSEBUTTONDOWN:
                if button_1.collidepoint(pygame.mouse.get_pos()):
                    return 1
                elif button_2.collidepoint(pygame.mouse.get_pos()):
                    return 2
        clock.tick(10)
        pygame.display.update()

'''结束界面'''
def endInterface(screen, score_left, score_right):
    clock = pygame.time.Clock()
    font1 = pygame.font.Font(cfg.FONTPATH, 30)
    font2 = pygame.font.Font(cfg.FONTPATH, 20)
    msg = 'Player on left won!' if score_left > score_right else 'Player on right won!'
    texts = [font1.render(msg, True, cfg.WHITE),
            font2.render('Press ESCAPE to quit.', True, cfg.WHITE),
            font2.render('Press ENTER to continue or play again.', True, cfg.WHITE)]
    positions = [[120, 200], [155, 270], [80, 300]]
    while True:
        screen.fill((41, 36, 33))
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_RETURN:
                    return
                elif event.key == pygame.K_ESCAPE:
                    sys.exit()
                    pygame.quit()
        for text, pos in zip(texts, positions):
            screen.blit(text, pos)
        clock.tick(10)
        pygame.display.update()

'''运行游戏Demo'''
def runDemo(screen):
    # 加载游戏素材
    hit_sound = pygame.mixer.Sound(cfg.HITSOUNDPATH)
    goal_sound = pygame.mixer.Sound(cfg.GOALSOUNDPATH)
    pygame.mixer.music.load(cfg.BGMPATH)
    pygame.mixer.music.play(-1, 0.0)
    font = pygame.font.Font(cfg.FONTPATH, 50)
    # 开始界面
    game_mode = startInterface(screen)
    # 游戏主循环
    # --左边球拍(ws控制, 仅双人模式时可控制)
    score_left = 0
    racket_left = Racket(cfg.RACKETPICPATH, 'LEFT', cfg)
    # --右边球拍(↑↓控制)
    score_right = 0
    racket_right = Racket(cfg.RACKETPICPATH, 'RIGHT', cfg)
    # --球
    ball = Ball(cfg.BALLPICPATH, cfg)
    clock = pygame.time.Clock()
    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit(-1)
        screen.fill((41, 36, 33))
        # 玩家操作
        pressed_keys = pygame.key.get_pressed()
        if pressed_keys[pygame.K_UP]:
            racket_right.move('UP')
        elif pressed_keys[pygame.K_DOWN]:
            racket_right.move('DOWN')
        if game_mode == 2:
            if pressed_keys[pygame.K_w]:
                racket_left.move('UP')
            elif pressed_keys[pygame.K_s]:
                racket_left.move('DOWN')
        else:
            racket_left.automove(ball)
        # 球运动
        scores = ball.move(ball, racket_left, racket_right, hit_sound, goal_sound)
        score_left += scores[0]
        score_right += scores[1]
        # 显示
        # --分隔线
        pygame.draw.rect(screen, cfg.WHITE, (247, 0, 6, 500))
        # --球
        ball.draw(screen)
        # --拍
        racket_left.draw(screen)
        racket_right.draw(screen)
        # --得分
        screen.blit(font.render(str(score_left), False, cfg.WHITE), (150, 10))
        screen.blit(font.render(str(score_right), False, cfg.WHITE), (300, 10))
        if score_left == 11 or score_right == 11:
            return score_left, score_right
        clock.tick(100)
        pygame.display.update()

'''主函数'''
def main():
    # 初始化
    pygame.init()
    pygame.mixer.init()
    screen = pygame.display.set_mode((cfg.WIDTH, cfg.HEIGHT))
    pygame.display.set_caption('乒乓球')
    # 开始游戏
    while True:
        score_left, score_right = runDemo(screen)
        endInterface(screen, score_left, score_right)

'''run'''
if __name__ == '__main__':
    main()

二:配置文件 - cfg.py

import os

'''屏幕长宽'''
WIDTH = 500
HEIGHT = 500
'''游戏素材路径'''
CURRPATH = os.getcwd()
RESOURCESDIRPATH = os.path.join(CURRPATH, 'resources')
AUDIOSDIRPATH = os.path.join(RESOURCESDIRPATH, 'audios')
FONTDIRPATH = os.path.join(RESOURCESDIRPATH, 'font')
IMAGESDIRPATH = os.path.join(RESOURCESDIRPATH, 'images')
BALLPICPATH = os.path.join(IMAGESDIRPATH, 'ball.png')
RACKETPICPATH = os.path.join(IMAGESDIRPATH, 'racket.png')
FONTPATH = os.path.join(FONTDIRPATH, 'font.TTF')
GOALSOUNDPATH = os.path.join(AUDIOSDIRPATH, 'goal.wav')
HITSOUNDPATH = os.path.join(AUDIOSDIRPATH, 'hit.wav')
BGMPATH = os.path.join(AUDIOSDIRPATH, 'bgm.mp3')
'''颜色'''
WHITE = (255, 255, 255)

三:文件包 - modules

(1)__init__.py

'''初始化'''
from .sprites import Ball, Racket

(2)sprites.py

import random
import pygame
from .utils import *

'''乒乓球'''
class Ball(pygame.sprite.Sprite):
    def __init__(self, imgpath, cfg, **kwargs):
        pygame.sprite.Sprite.__init__(self)
        self.cfg = cfg
        self.image = loadImage(imgpath)
        self.rect = self.image.get_rect()
        self.reset()
    '''移动'''
    def move(self, ball, racket_left, racket_right, hit_sound, goal_sound):
        self.rect.left = self.rect.left + self.speed * self.direction_x
        self.rect.top = min(max(self.rect.top + self.speed * self.direction_y, 0), self.cfg.HEIGHT - self.rect.height)
        # 撞到球拍
        if pygame.sprite.collide_rect(ball, racket_left) or pygame.sprite.collide_rect(ball, racket_right):
            self.direction_x, self.direction_y = -self.direction_x, random.choice([1, -1])
            self.speed += 1
            scores = [0, 0]
            hit_sound.play()
        # 撞到上侧的墙
        elif self.rect.top == 0:
            self.direction_y = 1
            self.speed += 1
            scores = [0, 0]
        # 撞到下侧的墙
        elif self.rect.top == self.cfg.HEIGHT - self.rect.height:
            self.direction_y = -1
            self.speed += 1
            scores = [0, 0]
        # 撞到左边的墙
        elif self.rect.left < 0:
            self.reset()
            racket_left.reset()
            racket_right.reset()
            scores = [0, 1]
            goal_sound.play()
        # 撞到右边的墙
        elif self.rect.right > self.cfg.WIDTH:
            self.reset()
            racket_left.reset()
            racket_right.reset()
            scores = [1, 0]
            goal_sound.play()
        # 普通情况
        else:
            scores = [0, 0]
        return scores
    '''初始化'''
    def reset(self):
        self.rect.centerx = self.cfg.WIDTH // 2
        self.rect.centery = random.randrange(self.rect.height // 2, self.cfg.HEIGHT - self.rect.height // 2)
        self.direction_x = random.choice([1, -1])
        self.direction_y = random.choice([1, -1])
        self.speed = 1
    '''绑定到屏幕上'''
    def draw(self, screen):
        screen.blit(self.image, self.rect)

'''乒乓球拍'''
class Racket(pygame.sprite.Sprite):
    def __init__(self, imgpath, type_, cfg, **kwargs):
        pygame.sprite.Sprite.__init__(self)
        self.cfg = cfg
        self.type_ = type_
        self.image = loadImage(imgpath, False)
        self.rect = self.image.get_rect()
        self.reset()
    '''移动'''
    def move(self, direction):
        if direction == 'UP':
            self.rect.top = max(0, self.rect.top - self.speed)
        elif direction == 'DOWN':
            self.rect.bottom = min(self.cfg.HEIGHT, self.rect.bottom + self.speed)
        else:
            raise ValueError('[direction] in Racket.move is %s, expect %s or %s...' % (direction, 'UP', 'DOWN'))
    '''电脑自动移动'''
    def automove(self, ball):
        if ball.rect.centery - 25 > self.rect.centery:
            self.move('DOWN')
        if ball.rect.centery + 25 < self.rect.centery:
            self.move('UP')
    '''初始化'''
    def reset(self):
        # 左/右边的拍
        self.rect.centerx = self.cfg.WIDTH - self.rect.width // 2 if self.type_ == 'RIGHT' else self.rect.width // 2
        self.rect.centery = self.cfg.HEIGHT // 2
        # 速度
        self.speed = 5
    '''绑定到屏幕上'''
    def draw(self, screen):
        screen.blit(self.image, self.rect)

(3)utils.py

import pygame

'''导入图片'''
def loadImage(imgpath, transparent=True):
    img = pygame.image.load(imgpath)
    img = img.convert()
    if transparent:
        color = img.get_at((0, 0))
        img.set_colorkey(color, pygame.RLEACCEL)
    return img

四:素材包 - resources

素材包大家根据配置文件自己配置就好,或者私信我发你文章来源地址https://www.toymoban.com/news/detail-757873.html

到了这里,关于Python-乒乓球小游戏【附完整源码】的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • 【Python 随练】乒乓球比赛名单

    两个乒乓球队进行比赛,各出三人。甲队为 a,b,c 三人,乙队为 x,y,z 三人。已抽签决定比赛名单。有人向队员打听比赛的名单。a 说他不和 x 比,c 说他不和 x,z 比,请编程序找出三队赛手的名单。 在本篇博客中,我们将解决一个逻辑推理问题:乒乓球比赛名单。根据已知条件

    2024年02月09日
    浏览(35)
  • python+django高校体育乒乓球场地预约管理系统_s2409

    本系统提供给管理员对首页,个人中心,用户管理,乒乓球场管理,场地类型管理,场地预约管理,暂离申请管理,离开申请管理,管理员管理,留言反馈,系统管理等诸多功能进行管理。本系统对于用户输入的任何信息都进行了一定的验证,为管理员操作提高了效率,也使其数据安全

    2024年02月07日
    浏览(42)
  • 【脑筋急转弯系列】乒乓球称重问题

    💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学习,不断总结,共同进步,活到老学到老 导航 檀越剑指大厂系列:全面总

    2024年01月16日
    浏览(42)
  • 机器人制作开源方案 | 乒乓球自动拾取机器人

    作者:刘众森、王森、王绘东、崔岳震、宋维鑫 单位:山东农业工程学院 指导老师:潘莹月、廖希杰       我们小组选择项目的任务方向乒乓球的捡取与存放,针对此问题我们研发了一款乒乓球自动拾取机器人。众所周知,乒乓球是一种世界流行的球类体育项目,而我国是

    2024年02月01日
    浏览(51)
  • Python编写简易猜数字小游戏(附完整代码)

    Python编写简易猜数字小游戏(附完整代码) 猜数字游戏是一款非常经典的小游戏,本文将介绍如何使用Python编写一个简易的猜数字游戏,并提供完整的源代码。 首先,让我们了解一下游戏规则。游戏开始时,程序会随机生成一个1到100之间的数字,玩家需要通过输入数字来猜

    2024年02月08日
    浏览(75)
  • 基于Python+Pygame实现一个俄罗斯方块小游戏【完整代码】

    俄罗斯方块,一款起源于上世纪80年代的经典电子游戏,凭借简单的规则和独特的魅力,一跃成为全球家喻户晓的经典。你知道其实只需要一些基础的编程知识,就可以自己实现它吗?今天,我们将使用Python的Pygame库,一步步带你构建属于自己的俄罗斯方块小游戏! 游戏初始

    2024年02月04日
    浏览(50)
  • 手把手教你使用Python实现推箱子小游戏(附完整源码)

    我们这个项目是一个基于Python实现的推箱子小游戏,名叫Sokoban: 这个游戏的目的是让玩家,也就是大写的 P ,推着箱子 # ,填充用小写的 o 标记的地面上的洞 该版本的Sokoban的规则如下: 游戏在矩形的二维网格上举行,其 原点(0,0) 位于左上方 网格上的每个单元格可以随时包

    2024年02月03日
    浏览(53)
  • HTML小游戏25 —— HTML5拉杆子过关小游戏(附完整源码)

    本节教程我会带大家使用 HTML 、CSS和 JS 来制作一个HTML5拉杆子过关小游戏 🕹️ 本文已收录于🎖️100个HTML小游戏专栏: 100个H5游戏专栏 https://blog.csdn.net/qq_53544522/category_12064846.html 🎮 目前已有100+小游戏,源码在持续更新中,前100位订阅限时优惠,先到先得。 🐬 订阅专栏后

    2024年02月05日
    浏览(57)
  • HTML小游戏19 —— html5版开心斗地主小游戏(附完整源码)

    💂 网站推荐:【神级源码资源网】【摸鱼小游戏】 🤟 前端学习课程:👉【28个案例趣学前端】【400个JS面试题】 💅 想寻找共同学习交流、摸鱼划水的小伙伴,请点击【摸鱼学习交流群】 本节教程我会带大家使用 HTML 、CSS和 JS 来制作一个 html5版开心斗地主小游戏 🕹️ 本文

    2024年02月03日
    浏览(87)
  • HTML小游戏12 —— 汽车赛道飙车游戏(附完整源码)

    💂 网站推荐:【神级源码资源网】【摸鱼小游戏】 🤟 前端学习课程:👉【28个案例趣学前端】【400个JS面试题】 💅 想寻找共同学习交流、摸鱼划水的小伙伴,请点击【摸鱼学习交流群】 💬 免费且实用的计算机相关知识题库:👉进来逛逛 给大家安利一个免费且实用的前端

    2024年02月07日
    浏览(66)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包