PyGame游戏制作: 弹球游戏Pong(附上Python完整代码)

介绍

使用 Python 的 PyGame 做了一个弹球游戏,第一次使用Py做游戏,分享一下。
在这里插入图片描述

下载地址
下载链接:
http://101.201.112.95/2021/PyGame_Pong.zip 复制到浏览器

在这里插入图片描述
执行 index.py 就可以运行游戏了

.
PyGame开发游戏感觉上比H5、Unity等其他语言要反锁一点(可能刚接触不太习惯吧 _

.
分享下 HTML5 做的弹球游戏及完整源码

https://blog.csdn.net/fujian87232/article/details/115037280
.
.

制作

这里简单总结下 PyGame 开发游戏时的一些基础知识点
.

一、创建应用

1、首先,需要初始化下应用及显示窗口大小
pygame.init();  # 初始化pygame
pygame.display.set_caption("Pong") # 设置标题
2、设置游戏窗口大小并创建
size = width, height = 800, 600;  # 设置窗口大小
scene = pygame.display.set_mode(size); # 创建显示窗口

.

二、添加显示元素

1、添加图片,设置图片位置
ball = pygame.image.load(dirname + '/img/ball.jpg');
ballRect = ball.get_rect();
ballRect.centerx = 100; # 设置图片位置
ballRect.centery = 200;
scene.blit(ball, ballRect);  # 将小球图片画到场景中上
2、添加文字显示
font = pygame.font.Font(None, 100); # 创建文字,定义大小
leftScore = font.render("文字显示内容", 1, (255, 255, 255)); # 渲染并设置颜色
leftScoreRect = leftScore.get_rect();
leftScoreRect.centerx = 200; # 设置文字位置
leftScoreRect.centery = 70; # 设置文字位置
scene.blit(leftScore, leftScoreRect);  # 将文字添加到显示窗口
3、绘制图形

这里画了40个小的线段

lineColor = (255, 255, 255); # 线段颜色
for i in range(0, 40):
    start = (400, i * 15); # 线段开始位置
    end = (400, i * 15 + 10); # 线段结束位置
    pygame.draw.line(scene, lineColor, start, end, 4); # 绘制到窗口中

.
.

三、动画

实现动画功能时,定义一个死循环,使用PyGame的时钟让循环按照一定时间间隔执行。

1、定义一个无限循环体
fpsClock = pygame.time.Clock(); # 获得pygame的时钟
while True: # 死循环确保窗口一直显示

    # 这里实现动画效果

    fpsClock.tick(30);  # 设置pygame时钟的间隔时间
2、实现图片移动动画
# 死循环确保窗口一直显示
while True:
    # 小球移动
    ballRect.centerx += 1;
    ballRect.centery += 1;

    scene.blit(ball, ballRect);  # 将小球图片重新画到窗口上
    pygame.display.update();  # 更新窗口显示

    fpsClock.tick(30);  # 设置pygame时钟的间隔时间

.

四、添加控制

PyGame的控制都是在动画循环中实现的

1、添加键盘事件
while True: # 死循环确保窗口一直显示
    for event in pygame.event.get():  # 遍历所有事件
	    if event.type == pygame.KEYDOWN: # 键盘按下事件
	        if event.key == pygame.K_UP: # 当按下的按键是向上箭头时

	        if event.key == pygame.K_DOWN: # 当按下的按键是向下箭头时
	
	    if event.type == pygame.KEYUP: # 键盘抬起事件
	        if event.key == pygame.K_UP:

	        if event.key == pygame.K_DOWN:


    fpsClock.tick(30);  # 设置pygame时钟的间隔时间
2、添加窗口关闭按钮,退出程序
while True: # 死循环确保窗口一直显示
    if event.type == pygame.QUIT:  # 如果单击关闭窗口,则退出
        sys.exit();

    fpsClock.tick(30);  # 设置pygame时钟的间隔时间

.

完整代码

import pygame;
import sys;
import os;
import math;

dirname, runFile = os.path.split(os.path.abspath(sys.argv[0]));

pygame.init();  # 初始化pygame
pygame.display.set_caption("Pong") # 设置标题
size = width, height = 800, 600;  # 设置窗口大小

# 显示窗口
scene = pygame.display.set_mode(size);
bgColor = (0, 0, 0);  # 设置颜色

# 添加小球图片
ball = pygame.image.load(dirname + '/img/ball.jpg');
ballRect = ball.get_rect();

# 添加左挡板图片
leftBlock = pygame.image.load(dirname + '/img/block.jpg');
leftBlockRect = leftBlock.get_rect();
leftBlockRect.centerx = 40;
leftBlockRect.centery = 300;

# 添加右挡板图片
rightBlock = pygame.image.load(dirname + '/img/block.jpg');
rightBlockRect = rightBlock.get_rect();
rightBlockRect.centerx = 760;
rightBlockRect.centery = 300;


#定义画中线函数
def drawLine():
    lineColor = (255, 255, 255);
    for i in range(0, 40):
        start = (400, i * 15);
        end = (400, i * 15 + 10);
        pygame.draw.line(scene, lineColor, start, end, 4);


# 得分
leftScoreNum = 0;
rightScoreNum = 0;

# 左侧分数
def leftScoreShow():
    font = pygame.font.Font(None, 100); # 创建字体对象
    leftScore = font.render(str(leftScoreNum), 1, (255, 255, 255)); # 文本与颜色
    leftScoreRect = leftScore.get_rect();
    leftScoreRect.centerx = 200;
    leftScoreRect.centery = 70;
    scene.blit(leftScore, leftScoreRect); # 将左侧得分画到场景中上

# 右侧分数
def rightScoreShow():
    font = pygame.font.Font(None, 100); # 创建字体对象
    rightScore = font.render(str(rightScoreNum), 1, (255, 255, 255)); # 文本与颜色
    rightScoreRect = rightScore.get_rect();
    rightScoreRect.centerx = 600;
    rightScoreRect.centery = 70;
    scene.blit(rightScore, rightScoreRect); # 将右侧得分画到场景中上


# 得分
def addScore(type):
    if type == 1 :
        global leftScoreNum;
        leftScoreNum = leftScoreNum + 1;

    else :
        global rightScoreNum;
        rightScoreNum = rightScoreNum + 1;


# 重置小球
def resetBall(type):
    global ballRect;
    global ballSpeedAngle;
    ballRect.centerx = 400;
    ballRect.centery = 300;

    if type == 1 :
        ballSpeedAngle = 0;

    else :
        ballSpeedAngle = math.pi;


# 挡板与球的碰撞
isLeftBlockCrash = False;
isRightBlockCrash = False;
def blockCrash(speedX):
    global isLeftBlockCrash;
    global isRightBlockCrash;
    global ballSpeedAngle;
    if (ballRect.centerx < leftBlockRect.centerx + leftBlockRect.width / 2 and ballRect.centerx > leftBlockRect.centerx - leftBlockRect.width / 2) and (ballRect.centery < leftBlockRect.centery + leftBlockRect.height / 2 and ballRect.centery > leftBlockRect.centery - leftBlockRect.height / 2) :
        if isLeftBlockCrash == False :
            if speedX > 0 :
                ballSpeedAngle = -(ballSpeedAngle - math.pi);

            else :
                #回弹角度增益
                ballSpeedAngle = (ballRect.centery - leftBlockRect.centery)/50;

            isLeftBlockCrash = True;

    else :
        isLeftBlockCrash = False;


    if (ballRect.centerx < rightBlockRect.centerx + rightBlockRect.width / 2 and ballRect.centerx > rightBlockRect.centerx - rightBlockRect.width / 2) and (ballRect.centery < rightBlockRect.centery + rightBlockRect.height / 2 and ballRect.centery > rightBlockRect.centery - rightBlockRect.height / 2) :
        if isRightBlockCrash == False :
            if speedX > 0 :
                ballSpeedAngle = -(ballSpeedAngle - math.pi);

            else :
                #回弹角度增益
                ballSpeedAngle = (ballRect.centery - rightBlockRect.centery)/50;

            isRightBlockCrash = True;

    else :
        isRightBlockCrash = False;


# 获得pygame的时钟
fpsClock = pygame.time.Clock();

#定义小球移动速度
ballSpeed = 15;
#定义小球移动方向
ballSpeedAngle = 1/4 * math.pi;

#定义横杆移动速度
leftMoveSpeed = 0;
rightMoveSpeed = 0;




# 死循环确保窗口一直显示
while True:

    # 计算小球移动速度
    speedX = math.cos(ballSpeedAngle) * ballSpeed;
    speedY = math.sin(ballSpeedAngle) * ballSpeed;

    # 小球移动
    ballRect.centerx += speedX;
    ballRect.centery += speedY;

    # 左横杆移动
    leftBlockRect.centery += leftMoveSpeed;
    if(leftBlockRect.centery < 50):
        leftBlockRect.centery = 50;

    if(leftBlockRect.centery > 550):
        leftBlockRect.centery = 550;

    # 右横杆移动
    rightBlockRect.centery += rightMoveSpeed;
    if(rightBlockRect.centery < 50):
       rightBlockRect.centery = 50;

    if(rightBlockRect.centery > 550):
        rightBlockRect.centery = 550;


    # 碰撞上下边界
    if(ballRect.centery > 600):
        ballSpeedAngle = -ballSpeedAngle;

    if(ballRect.centery < 0):
        ballSpeedAngle = -ballSpeedAngle;

    if(ballRect.centerx > 800):
        ballSpeedAngle = -(ballSpeedAngle - math.pi);
        addScore(1); # 左边得分
        resetBall(1); # 重置小球并先向右发射

    if(ballRect.centerx < 0):
        ballSpeedAngle = -(ballSpeedAngle - math.pi);
        addScore(0);  # 右边得分
        resetBall(0); # 重置小球并先向左发射


    for event in pygame.event.get():  # 遍历所有事件
        if event.type == pygame.QUIT:  # 如果单击关闭窗口,则退出
            sys.exit();


        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_UP:
                rightMoveSpeed = -8;

            if event.key == pygame.K_DOWN:
                rightMoveSpeed = 8;

            if event.key == pygame.K_w:
                leftMoveSpeed = -8;

            if event.key == pygame.K_s:
                leftMoveSpeed = 8;


        if event.type == pygame.KEYUP:
            if event.key == pygame.K_UP:
                rightMoveSpeed = 0;

            if event.key == pygame.K_DOWN:
                rightMoveSpeed = 0;

            if event.key == pygame.K_w:
                leftMoveSpeed = 0;

            if event.key == pygame.K_s:
                leftMoveSpeed = 0;



    scene.fill(bgColor);  # 填充黑色背景
    scene.blit(ball, ballRect);  # 将小球图片画到场景中上
    scene.blit(leftBlock, leftBlockRect);  # 将左侧挡板图片画到场景中上
    scene.blit(rightBlock, rightBlockRect);  # 将右侧挡板图片画到场景中上
    drawLine(); # 画中心虚线
    leftScoreShow(); # 左侧分数显示
    rightScoreShow(); # 右侧分数显示

    blockCrash(speedX); # 碰撞检测
    pygame.display.update();  # 更新全部显示

    fpsClock.tick(30);  # 设置pygame时钟的间隔时间









猜你喜欢

转载自blog.csdn.net/fujian87232/article/details/115221627