首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python球加速游戏

Python球加速游戏
EN

Stack Overflow用户
提问于 2022-11-06 03:12:59
回答 1查看 43关注 0票数 2

我已经创建了一个草图代码,应该移动球后,按下键加速。球将按键盘箭头的方向加速,然后从窗口的活动边缘反弹。以下是代码:

代码语言:javascript
复制
import pygame, sys
pygame.init()


def main():

    clock = pygame.time.Clock()
    
    pygame.display.set_caption('BasketBall')
    icon = pygame.image.load('/home/michael/game/ballgame.png')
    pygame.display.set_icon(icon)
    
    pygame.mixer.music.load(r'/home/michael/game/soundtrack.mp3')
    pygame.mixer.music.play(-1)
    
    size = width, height = 800, 600
    screen = pygame.display.set_mode(size)
    
    speed = [0, 0]
    accel = [0.1, 0.1]

    
    image = pygame.image.load(r'/home/michael/game/background.png')
    image = pygame.transform.scale(image, size)
    
    surf_center = (
        (width-image.get_width())/2,
        (height-image.get_height())/2
    )
    
    screen.blit(image, surf_center)
    ball = pygame.image.load('/home/michael/game/ball.png')
    ball = pygame.transform.scale(ball, (ball.get_width()//10, ball.get_height()//10))

    screen.blit(ball, (width/10, height/10))
    ballrect = ball.get_rect(center=(width/2, height/2))
    pygame.display.flip()


    while True:
        clock.tick(60)
        pygame.time.delay(50)
        for event in pygame.event.get():
            if event.type == pygame.QUIT: sys.exit()
        keys = pygame.key.get_pressed()
        if keys[pygame.K_ESCAPE]: sys.exit()
        if keys[pygame.K_UP]:

            ballrect = ballrect.move([0,-50])
        elif keys[pygame.K_DOWN]:
            ballrect = ballrect.move([0,50])
        elif keys[pygame.K_LEFT]:
            ballrect = ballrect.move([-50,0])
        elif keys[pygame.K_RIGHT]:
            ballrect = ballrect.move([50,0])
        ballrect = ballrect.move(speed)
        if ballrect.left < 0 or ballrect.right > width:
            speed[0] = -speed[0]
        if ballrect.top < 0 or ballrect.bottom > height:
            speed[1] = -speed[1]

        
        screen.blit(image,surf_center)
        screen.blit(ball,ballrect)
        pygame.display.flip()


if __name__ == '__main__':
    main()
    pygame.quit()
    sys.exit()

这看起来很复杂,也许是因为我还在学习游戏库,但是我想加速球,直到按下键。理想情况下,球应该从活跃的窗口边缘弹回。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-11-06 07:28:52

因为pygame.Rect应该表示屏幕上的一个区域,所以pygame.Rect对象只能存储积分数据。

-- Rect对象的坐标都是整数。..。

如果要以浮点精度存储对象位置,则必须将对象的位置分别存储在单独的变量属性中,并同步pygame.Rect对象。

为球的位置、速度、加速度建立变量。还为摩擦力(1表示没有摩擦力)和最大速度添加一个变量:

代码语言:javascript
复制
ball_rect = ball.get_rect(center = surf_center)
ball_pos = list(ball_rect.center)
speed = [0, 0]
accel = [0.1, 0.1]
max_speed = 10
friction = 0.99

当按下按钮时,速度取决于加速度和摩擦力:

代码语言:javascript
复制
keys = pygame.key.get_pressed()
dx = keys[pygame.K_RIGHT] - keys[pygame.K_LEFT]
dy = keys[pygame.K_DOWN] - keys[pygame.K_UP]
        
speed[0] = speed[0] * friction + accel[0] * dx
speed[1] = speed[1] * friction + accel[1] * dy

以最大速度限制速度:

代码语言:javascript
复制
speed[0] = max(-max_speed, min(max_speed, speed[0]))
speed[1] = max(-max_speed, min(max_speed, speed[1]))

根据速度移动球:

代码语言:javascript
复制
ball_pos[0] += speed[0]
ball_pos[1] += speed[1]
ball_rect.center = round(ball_pos[0]), round(ball_pos[1])

从墙上弹起球时要小心(参见Sometimes the ball doesn't bounce off the paddle in pong game):

代码语言:javascript
复制
border_rect = screen.get_rect()
if not border_rect.contains(ball_rect):
    if ball_rect.left < 0 or ball_rect.right > width:
        speed[0] = -speed[0]
    if ball_rect.top < 0 or ball_rect.bottom > height:
        speed[1] = -speed[1]
    border_rect.clamp_ip(border_rect)
    ball_pos = list(ball_rect.center)

完整的应用循环:

代码语言:javascript
复制
def main():
    # [...]
    
    ball_rect = ball.get_rect(center = surf_center)
    ball_pos = list(ball_rect.center)
    speed = [0, 0]
    accel = [0.1, 0.1]
    max_speed = 10
    friction = 0.99

    run = True
    while run:
        clock.tick(60)
        pygame.time.delay(50)
        for event in pygame.event.get():
            if event.type == pygame.QUIT: 
                run = False

        keys = pygame.key.get_pressed()
        dx = keys[pygame.K_RIGHT] - keys[pygame.K_LEFT]
        dy = keys[pygame.K_DOWN] - keys[pygame.K_UP]
        
        speed[0] = speed[0] * friction + accel[0] * dx
        speed[1] = speed[1] * friction + accel[1] * dy
        speed[0] = max(-max_speed, min(max_speed, speed[0]))
        speed[1] = max(-max_speed, min(max_speed, speed[1]))

        ball_pos[0] += speed[0]
        ball_pos[1] += speed[1]
        ball_rect.center = round(ball_pos[0]), round(ball_pos[1])
        
        border_rect = screen.get_rect()
        if not border_rect.contains(ball_rect):
            if ball_rect.left < 0 or ball_rect.right > width:
                speed[0] = -speed[0]
            if ball_rect.top < 0 or ball_rect.bottom > height:
                speed[1] = -speed[1]
            border_rect.clamp_ip(border_rect)
            ball_pos = list(ball_rect.center)

        screen.blit(image, (0, 0))
        screen.blit(ball, ball_rect)
        pygame.display.flip()

最起码的例子:

代码语言:javascript
复制
import pygame, sys
pygame.init()

def main():
    clock = pygame.time.Clock()
    screen = pygame.display.set_mode((400, 400))
    image = pygame.Surface(screen.get_size())
    surf_center = screen.get_rect().center
    ball = pygame.Surface((30, 30), pygame.SRCALPHA)
    pygame.draw.circle(ball, "white", (15, 15), 15)
    
    ball_rect = ball.get_rect(center = surf_center)
    ball_pos = list(ball_rect.center)
    speed = [0, 0]
    accel = [0.5, 0.5]
    max_speed = 20
    friction = 0.99

    run = True
    while run:
        clock.tick(60)
        pygame.time.delay(50)
        for event in pygame.event.get():
            if event.type == pygame.QUIT: 
                run = False
            if event == pygame.KEYDOWN  and event.key == pygame.K_ESCAPE:
                run = False

        keys = pygame.key.get_pressed()
        dx = keys[pygame.K_RIGHT] - keys[pygame.K_LEFT]
        dy = keys[pygame.K_DOWN] - keys[pygame.K_UP]
        
        speed[0] = speed[0] * friction + accel[0] * dx
        speed[1] = speed[1] * friction + accel[1] * dy
        speed[0] = max(-max_speed, min(max_speed, speed[0]))
        speed[1] = max(-max_speed, min(max_speed, speed[1]))

        ball_pos[0] += speed[0]
        ball_pos[1] += speed[1]
        ball_rect.center = round(ball_pos[0]), round(ball_pos[1])
        
        border_rect = screen.get_rect().inflate(-50, -50)
        if not border_rect.contains(ball_rect):
            if ball_rect.left < border_rect.left or ball_rect.right > border_rect.right:
                speed[0] = -speed[0]
            if ball_rect.top < border_rect.top or ball_rect.bottom > border_rect.bottom:
                speed[1] = -speed[1]
            border_rect.clamp_ip(border_rect)
            ball_pos = list(ball_rect.center)

        screen.blit(image, (0, 0))
        pygame.draw.rect(screen, "red", border_rect, 3)
        screen.blit(ball, ball_rect)
        pygame.display.flip()

if __name__ == '__main__':
    main()
    pygame.quit()
    sys.exit()
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74333050

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档