【问题标题】:Can someone help implement gravity and running animation into my pygame code? [closed]有人可以帮助在我的 pygame 代码中实现重力和运行动画吗? [关闭]
【发布时间】:2020-09-17 05:11:27
【问题描述】:

我正在用 pygame 制作马里奥,用于本学期的课堂评估,我对 pygame 有点陌生,我找不到任何地方如何在我的游戏中正确实施重力,所以当马里奥跳跃时,他会回来。我的第二个问题是试图制作一个跑步动画,我希望马里奥在他左右移动的顺序中浏览图片; 1、2、3、2(一遍又一遍)。如果有人可以提供帮助,那就太好了!

import pygame

import time

import random


pygame.init()


display_width = 800
display_height = 600
mario_width = 55

blue = (77, 240, 255)
green = (0, 186, 43)
ground_colour = (186, 150, 97)

gameDisplay = pygame.display.set_mode((display_width,display_height))
pygame.display.set_caption("Super Italiano Bros")

direction = 'right'
clock = pygame.time.Clock()
cloudImg = pygame.image.load('Cloud.png')


rightMarioImg = pygame.image.load('MarioRight.png')
rightMarioImg2 = pygame.image.load("MarioRight2.png")
rightMarioImg3 = pygame.image.load("MarioRight3.png")

leftMarioImg = pygame.image.load('MarioLeft.png')
leftMarioImg2 = pygame.image.load('MarioLeft2.png')
leftMarioImg3 = pygame.image.load('MarioLeft3.png')

def marioRight(x,y):
    gameDisplay.blit(rightMarioImg, (x,y))

def marioLeft(x,y):
    gameDisplay.blit(leftMarioImg, (x,y))

def cloud(x_cloud,y_cloud):
    gameDisplay.blit(cloudImg, (x_cloud,y_cloud))

def cloud_two(x_cloud_two,y_cloud_two):
    gameDisplay.blit(cloudImg, (x_cloud_two,y_cloud_two))       

def game_loop():
    global direction

    x = (320)
    y = (360)

    x_cloud = (-200)
    y_cloud = (-220)

    x_cloud_two = (200)
    y_cloud_two = (-170)

    x_change = (0)
    y_change = (0)

    gameExit = False

    while not gameExit:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                gameExit = True
            print(event)

        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT:
                x_change = -5
                direction = 'left'
            if event.key == pygame.K_RIGHT:
                x_change = 5
                direction = 'right'
            if event.key == pygame.K_UP:
                y_change = -60
            if event.key == pygame.K_ESCAPE:
                gameExit = True
        if event.type == pygame.KEYUP:
            if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT or event.key == pygame.K_UP:
                x_change = 0
                y_change = 60

        x += x_change
        y += y_change

        if x <= 0:
            x = 0
        if y <= 300:
            y = 300
        if y >= 360:
            y = 360
            
        gameDisplay.fill(blue)
        pygame.draw.rect(gameDisplay, ground_colour, (0,500,800,500))
        pygame.draw.rect(gameDisplay, green, (0, 470, 800, 30))
        cloud(x_cloud,y_cloud)
        cloud_two(x_cloud_two,y_cloud_two)

        if direction == 'right':
            marioRight(x,y)
        else:
            marioLeft(x,y)

        pygame.display.update()
        clock.tick(60)

game_loop()
pygame.quit()
quit()

【问题讨论】:

  • 您能否提供图片以便示例可以运行?
  • 请从intro tour 重复on topichow to ask。 “告诉我如何解决这个编码问题?”与 Stack Overflow 无关。您必须诚实地尝试解决方案,然后就您的实施提出具体问题。

标签: python pygame gravity


【解决方案1】:

修复了一些问题并做了很多代码样式。当你按下向上键时,他会跳跃一个固定的量,当你松开它时,他会回到地面。现在它自己动画了。每个循环都会更改图像,这可能非常快,因此您可能只想每隔一定数量的帧增加状态。

我改变的总结:

  1. 导入通常分为三个不同的块(由单个空行分隔)并按字母顺序排列:
    1. 第一个块包含所有标准库导入
    2. 第二个块包含第三方库
    3. 第三个块包含对该项目中其他文件的本地导入
  2. 一个文件应该有 0 个未使用的导入
  3. python 中的函数和变量名称遵循蛇形表示法:my_variablemy_function。 “常量”用蛇形大写字母书写:MY_CONSTANT。类使用驼峰式:MyClass
  4. dicts 和lists 允许您以更有条理的方式存储数据。例如,我们可以有一个 MARIO_IMGS dictlists 来存储所有 mario 图像,以便可以像 MARIO_IMGS['right'][0] 一样访问它们(第一个图像是索引 0,因为列表从 0 开始计数)。李>
  5. 尽量避免使用全局变量,我将循环内仅需要的变量移至 game_loop 函数,其余不是定义的顶级语句位于 if __name__ == '__main__': 块内,该块在启动此脚本时运行,但不是在导入此脚本时。
  6. 函数是用来重复使用的,拥有完全相同的cloudcloud_two函数是没有意义的。拨打cloud(x_cloud, y_cloud),然后拨打cloud(x_cloud_two, y_cloud_two)
  7. 如果括号不清晰,请不要使用不需要的括号,例如:x = (320) 应该是 x = 320
  8. 您在处理事件循环之外的事件时遇到缩进错误,因此只会处理最后一个事件(退出除外,该部分在循环内,因此每个事件都将根据pygame.QUIT 进行检查)
  9. 行数不得超过 80 个字符。
  10. 不需要 python 文件末尾的quit()quit() 主要用于从终端窗口关闭 python 解释器。
import pygame

# Window width and height in px
DISPLAY_SIZE = (800, 600)
# Window title
TITLE = "Super Italiano Bros"

# Predefined colors
BLUE = (77, 240, 255)
GREEN = (0, 186, 43)
GROUND_COLOR = (186, 150, 97)

# Images
MARIO_IMGS = {
    'right': [
        pygame.image.load('MarioRight.png'),
        pygame.image.load("MarioRight2.png"),
        pygame.image.load("MarioRight3.png"),
        pygame.image.load("MarioRight2.png"),
    ],
    'left': [
        pygame.image.load('MarioLeft.png'),
        pygame.image.load('MarioLeft2.png'),
        pygame.image.load('MarioLeft3.png'),
        pygame.image.load('MarioLeft2.png'),
    ]
}
CLOUD_IMG = pygame.image.load('Cloud.png')
MAX_STATES = min(map(len, MARIO_IMGS.values()))  # 3


def draw_mario(x, y, direction='right', state=0):
    screen.blit(MARIO_IMGS[direction][state], (x, y))


def draw_cloud(x_cloud, y_cloud):
    screen.blit(CLOUD_IMG, (x_cloud, y_cloud))


def game_loop():
    # Mario position
    x = 320
    y = 360
    x_change = 0
    state = 0
    direction = 'right'

    # Cloud positions
    x_cloud = -200
    y_cloud = -220
    x_cloud_two = 200
    y_cloud_two = -170

    # Clock used to limit the FPS
    clock = pygame.time.Clock()

    game_exit = False
    while not game_exit:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                game_exit = True
            print(event)

            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_LEFT:
                    x_change = -5
                    direction = 'left'
                if event.key == pygame.K_RIGHT:
                    x_change = 5
                    direction = 'right'
                if event.key == pygame.K_UP:
                    y = 300
                if event.key == pygame.K_ESCAPE:
                    game_exit = True
            if event.type == pygame.KEYUP:
                if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
                    x_change = 0
                elif event.key == pygame.K_UP:
                    y = 360

        x += x_change

        if x < 0:
            x = 0
        elif x > DISPLAY_SIZE[0]:
            x = DISPLAY_SIZE[0]

        screen.fill(BLUE)
        pygame.draw.rect(screen, GROUND_COLOR, (0, 500, 800, 500))
        pygame.draw.rect(screen, GREEN, (0, 470, 800, 30))
        draw_cloud(x_cloud, y_cloud)
        draw_cloud(x_cloud_two, y_cloud_two)

        draw_mario(x, y, direction, state)
        # Increase the state to animate Mario
        state += 1
        state %= MAX_STATES  # Start back from 0 if we have reached the end

        pygame.display.update()
        clock.tick(60)


if __name__ == '__main__':
    pygame.init()

    screen = pygame.display.set_mode(DISPLAY_SIZE)
    pygame.display.set_caption(TITLE)
    game_loop()

    pygame.quit()

您可能应该将 mario 和 cloud 更改为 Sprites。 Sprite 是一个类,它有一个 rect 和一个 image 属性来定义它们是如何绘制的,然后你不使用 screen.blit(IMAGE, POSITION) 而是告诉 pygame 来绘制精灵,他将使用这两个属性来在rect的位置绘制想要的image

【讨论】:

  • 天哪,非常感谢!这是一个巨大的帮助!
  • 另外,看看pygame.transform.flip。您可能想使用它而不是翻转图像。
  • @ThomasLivy 如果这回答了您的问题,您能否将其标记为选定的答案,以便将问题标记为已解决。
猜你喜欢
  • 2020-04-01
  • 1970-01-01
  • 2021-01-04
  • 2018-04-24
  • 2022-06-14
  • 1970-01-01
  • 2014-01-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多