好的,我们继续来制作我们的弹球游戏!昨天我们已经完成了最基本的窗口和最基本的小球,那今天我们就来加入负责与玩家交互的球拍!

首先,我们先来构思一下球拍的基本功能及作用。球拍,顾名思义,就是负责反弹小球的平台,它也负责与玩家的交互功能。如何交互呢?下面有这几种方法:

1,方向键控制。

2,鼠标坐标控制。

以上方法各有利弊,但是我认为使用鼠标控制比较人性。所以我们首先面对初学者比较轻松的鼠标控制。

pygame中的获取坐标比较简单,我们只需要参考第1篇中的“退出键检测”即可。但是在此之前,我们需要绘制出一个球拍。

我们新建一个文件,输入这些代码便可以生成一个长方形:

import pygame

pygame.init()
screen=pygame.display.set_mode([640,480])
screen.fill([0,0,0])
pygame.draw.rect(screen,[255,255,255],[250,150,300,200],0)
pygame.display.update()
running=True
while running:
    for event in pygame.event.get():
        if event.type==pygame.QUIT:
            running=False

pygame.quit()

很眼熟,对吧?

没错,它就是在基本结构上加入了一个填充的矩形。我们可以通过更改第6行的坐标来让矩形出现在我们希望它出现的位置。

那这些坐标怎么看呢?其实很简单。它的格式是这样的:

pygame.draw.rect(窗口名, 颜色, (矩形的左上x坐标, 矩形的左上y坐标, 矩形沿左上x坐标的长度也就是矩形的长, 矩形沿左上x坐标的宽度也就是矩形的宽))

这样一来,我们只需要输入正确的四个角的坐标,便可以让矩形出现在相应的地方,代码如下:

import pygame

pygame.init()
screen=pygame.display.set_mode([800,600])
screen.fill([0,0,0])
pygame.draw.rect(screen,[255,255,255],[300,550,200,25],0)
pygame.display.update()
running=True
while running:
    for event in pygame.event.get():
        if event.type==pygame.QUIT:
            running=False

pygame.quit()

运行后,我们就可以发现一个静止的球拍啦!

但是这个球拍是静止不动的,无法与玩家进行交互,所以我们必须在循环内反复更新它的位置。

由于pygame不需要定义其他三个角的坐标,所以我们只需要让它不断更新左上角的坐标即可。代码如下:

鼠标操作:

首先我们需要获取到鼠标的x坐标,并将其映射在其中。代码如下:

screen.fill(BLACK)
screen.blit(pic, (picx, picy))
paddlex = pygame.mouse.get_pos()[0]
paddlex -= paddlew / 2
pygame.draw.rect(screen, WHITE, (paddlex, paddley, paddlew, paddleh))

当它嵌套在循环中则是:

import pygame

pygame.init()
screen=pygame.display.set_mode([800,600])
pygame.display.set_caption("python弹球游戏")
keepGoing=True
pic=pygame.image.load("ball.png")
colorkey=pic.get_at((0,0))
pic.set_colorkey(colorkey)
picx = 0
picy = 0
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
timer = pygame.time.Clock()
speedx = 5
speedy = 5
paddlew = 200
paddleh = 25
paddlex = 300
paddley = 550
picw = 100
pich = 40
font=pygame.font.SysFont("None",24)
while keepGoing:
    for event in pygame.event.get():
        if event.type==pygame.QUIT:
            keepGoing=False
    picx+=speedx
    picy+=speedy
    if picx<=0 or picx+pic.get_width()>=800:
        speedx= -speedx
    if picy<=0:
        speedy= -speedy
    if picy>=550:
        speedy= -speedy
    screen.fill(BLACK)
    screen.blit(pic, (picx, picy))
    paddlex = pygame.mouse.get_pos()[0]
    paddlex -= paddlew / 2
    pygame.draw.rect(screen, WHITE, (paddlex, paddley, paddlew, paddleh))
    pygame.display.update()
    timer.tick(60)
font_addr = pygame.font.get_default_font()
font = pygame.font.Font(font_addr, 36)
pygame.quit()

我们还可以继续提高代码利用率,代码如下:

import pygame

pygame.init()
width=800
height=600
screen=pygame.display.set_mode([width,height])
pygame.display.set_caption("python弹球游戏")
keepGoing=True
pic=pygame.image.load("ball.png")
colorkey=pic.get_at((0,0))
pic.set_colorkey(colorkey)
picx = 0
picy = 0
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
timer = pygame.time.Clock()
speedx = 5
speedy = 5
paddlew = 200
paddleh = 25
paddlex = 300
paddley = 550
picw = 100
pich = 40
xend=width-50
yend=height-50#这两行的减50为判定提供时间
ticks=60#帧率
font=pygame.font.SysFont("None",24)
while keepGoing:
    for event in pygame.event.get():
        if event.type==pygame.QUIT:
            keepGoing=False
    picx+=speedx
    picy+=speedy
    if picx<=0 or picx+pic.get_width()>=xend:
        speedx= -speedx
    if picy<=0:
        speedy= -speedy
    if picy>=yend:
        speedy= -speedy
    screen.fill(BLACK)
    screen.blit(pic, (picx, picy))
    paddlex = pygame.mouse.get_pos()[0]
    paddlex -= paddlew / 2
    pygame.draw.rect(screen, WHITE, (paddlex, paddley, paddlew, paddleh))
    pygame.display.update()
    timer.tick(ticks)
pygame.quit()

是不是简洁许多?但是我们发现了一个问题,那就是虽然我们已经制作出了球拍,但是却无法拍球。这是因为我们还没有加入球拍与球接触的判定。我们可以通过检测是否与球拍在同一平面与是否超出球拍的左上x坐标来省去复杂的触碰判定。代码如下:

if picy + pich >= paddley and picy + pich <= paddley + paddleh and speedy > 0:
    if picx + picw / 2 >= paddlex and picx + picw / 2 <= paddlex + paddlew:
        speedy = -speedy

这段代码可以以最直接的方法来判定是否超过以上两点坐标。同时可以在接触瞬间立马反弹,这样不仅游戏对玩家的反馈感极强,对新手也特别友好。

好了,弹球游戏完结。我们下次再见,拜拜!

彩蛋

嘻嘻,你们不会觉得我就会这么糊弄过去吧?我将会在下期彩蛋篇中一一解决我们的游戏bug!让我们一起期待吧!


版权声明:本文为CSP_J原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/CSP_J/article/details/128779916