当前位置: 首页 > 知识库问答 >
问题:

Pyplay中的自上而下运动

齐高寒
2023-03-14

如果这个问题以前已经被问过,我很抱歉,但是我到处都查过了,找不到答案。

你如何做自上而下的移动pyplay?

如果我只使用矩形,这将很容易,但我将使用单个角色精灵(例如,如果我按d键使玩家向右移动,它将显示他向右移动的角色精灵并将角色向右移动)。

我所指的示例图像:

这是我的代码:

import pygame # imports pygame
import random # imports the random module
import time
from pygame import mixer # import mixer from pygame
"1) If you see a button(...) or text(...), those are functions I've made.
They don't come with Pygame. But, the stuff inside functions is from Pygame.

2) ... """
pygame.init() # initialises the window. Without this, pygame won't work.

window = pygame.display.set_mode((800, 600)) # window size

running = False 
intro = True # intro value set to true for intro loop

# title of game window
pygame.display.set_caption("Castle Kräftig - Pygame Edition")

# screen sizes in var
screenWidth = 800
screenHeight = 600

background = pygame.image.load('bg.png')  # this stores background in var (actual background is in mainloop)

sprite = pygame.image.load('characterUp.png')

rect = sprite.get_rect()


### rgb for white
##white = (255, 255, 255)
### rgb for green
##green = (0, 200, 0)
### rgb for red
##red = (200, 0, 0)
### rgb for bright green
##brightGreen = (0,255,0)
### rgb for bright red
##brightRed = (255,0,0)

# ----------- CLASSES -------------------------------------

# player class
class player:
    def __init__(self, x, y, w, h, xChange, yChange, vel):
        self.x = x # plater x value
        self.y = y # player y value
        self.w = w # player w (width)
        self.h = h # player h (height)
        self.xChange = xChange # player xChange (to add to x value to move player horizontally)
        self.yChange = yChange # player yChange (to aad to y value to move player vertically)
        self.vel = vel # velocity of player (needed for collision)

    #def draw(self, window):
    #    if self.left:
    #           window.blit(characterAssets[2]

# enemy class
class enemy:
    def __init__(self, x, y, w, h):
        self.x = x # enemy x value
        self.y = y # enemy y value 
        self.w = w # enemy w (width) value
        self.h = h # enemy h (height) value

# ----------------------------------------------------------------

"""enemy's x value (random value) (we pick 750 because the enemy width is 50 and
the screen width is 800. If we set the random value to 800, then the enemy has a
chance of spawning outside of the screen.)"""
enemyX = random.randint(0, 700)

"""enemy's y value (random value) (we pick 540 because the enemy height is 60
and the screen height is 600. If we set the random value to 600, the enemy has a
chance of spawning outside of the screen.)"""
enemyY = random.randint(0, 540) # enemy's y value

score = 0 # score set to 0. Will update in while loop.

rec = player(50, 50, 24, 32, 0, 0, 5) # the player's values (x, y, w, h, xChange, yChange, vel)
redRec = enemy(enemyX, enemyY, 24, 32) # the enemy's values (x, y, w, h)
#---------------------- FUNCTIONS ------------------------

# https://youtu.be/jeZkAKtDIX0 Explination
# collision system function
def detCollision(x, y, w, h, x2, y2, w2, h2):
    if (x2 + w2 >= x >= x2 and y2 + h2 >= y >= y2):
        return True
    elif (x2 + w2 >= x + w >= x2 and y2 + h2 >= y >= y2):
        return True
    elif (x2 + w2 >= x >= x2 and y2 + h2 >= y + h >= y2):
        return True
    elif (x2 + w2 >= x + w >= x2 and y2 + h2 >= y + h >= y2):
        return True
    else:
        return False

"""In case if exiting Pygame for like the window or a button isn't working
properly"""
# quit game function
def quitGame():
    pygame.quit() # quit's pygame
    """SystemExit is here so Pygame doesn't through initialization errors"""
    raise SystemExit # raises a SystemExit so python won't keep running it.

# button function
# message to display,x,y,width,height,colour,colour when mouse is on button,
# locationX of text, locationY of text, and what the button should do
def button(msg,x,y,w,h,locX,locY,action):
    global intro, running, pause, score
    mouse = pygame.mouse.get_pos() # saves mouse position in var
    click = pygame.mouse.get_pressed() # saves if clicked positon in var
    # mouse[0] means no click. mouse[1] means left click. 
    # if the x coordinate + width > x value of mouse > x coordinate and y location + 50 (bottom of box) > y of mouse > then top and bottom of y
    if x + w > mouse[0] > x and y + h > mouse[1] > y:
        # if mouse is on button, make the button brighter
        pygame.draw.rect(window, (124,124,124), (x, y, w, h)) 
        if click[0] == 1: # if mouse click is now left click
            mixer.music.load('click.wav')
            mixer.music.play()
            if action == "start": # if the action is "start"
                """The next 2 lines were added because if u started the game
                then paused, then clicked the main menu, then click start,
                the player would keep moving if you held down any of WASD buttons
                while hitting pause menu button"""
                rec.xChange = 0 # resets player's x change so the player doesn't keep moving without player hitting any key
                rec.yChange = 0 # resets player's y change so the player doesn't keep moving without player hitting any key
                running=True # set running to True
                mainloop() # call mainloop to start game

            elif action == "quit": # if action is "quit"
                quitGame() # call quitGame function

            elif action == "mainMenu": # if action is "mainMenu"
                pause = False # pause var will be set to False
                intro = True # intro var will be set to True to have menu work
                score = 0 # reset score
                rec.x = 50 # put player's x back in starting pos
                rec.y = 50 # put player's y back in starting pos
                mainMenu() # call mainMenu function to start menu

            elif action == "restart": # if action is "restart"
                pause = False # set to false so pausemenu won't keep running
                running = True # set's running to True 
                score = 0 # restart's score
                rec.x = 50 # resets player's x value
                rec.y = 50 # reset player's y value
                rec.xChange = 0 # resets player's x change so player doesn't keep moving without player hitting any key
                rec.yChange = 0 # resets player's y change so player doesn't keep moving without player hitting any key
                mainloop() # starts mainloop to restart the game

            elif action == "resume": # if action is "resume"
                running = True # set running to True again
                rec.xChange = 0 # resets player's x change so player doesn't keep moving without player hitting any key
                rec.yChange = 0 # resets player's y change so player doesn't keep moving without player hitting any key
                mainloop() # start the game once more

            elif action == "direct": # if action is direct
                intro = False # stop showing intro screen
                dMenu() # show the directionsMenu

    else: # other wise
        # if mouse is not on button, don't change colour
        pygame.draw.rect(window, (94,94,94), (x,y,w,h)) 

    # msg = is the message locX is text x pos and locY is text y pos
    text(msg, (0,0,0), locX, locY, 20, True) # the text on the button

# text function which will make text with parameters
""" msg is the message to display. Colour is the colour of text. textX is text's
x pos and textY is text's y pos. size is text size and bold is if we want text
to be bold"""
def text(msg, colour, textX, textY, size, bold):
    font = pygame.font.SysFont('times-new-roman', size, bold)
    window.blit(font.render(msg, 1, colour), (textX, textY))

# redraw game window 
def redrawWin(collisions):
    global score, sprite
    # draws the enemy
    pygame.draw.rect(window, (255,0,0), (redRec.x, redRec.y, redRec.w, redRec.h))
    # draws the player

    pygame.draw.rect(window, (0,255,0), (rec.x, rec.y, rec.w, rec.h))
    # renders Score
    text("Score: " + str(score), (255,0,0), 5, 10, 30, True) 
    # updates screen

    pygame.display.update()
    if collisions == True: # if collisions happen
        score += 1 # add one to score
        redRec.x = random.randint(0, 750) # set a new enemy x value
        redRec.y = random.randint(0, 540) # set a new enemy y value



# mainMenu function
def mainMenu():
    global running, largeText, intro

    while intro:
        for event in pygame.event.get(): # for every event in game
            #print(event)
            if event.type == pygame.QUIT: # if tries to quit
                quitGame()

            if event.type == pygame.KEYDOWN: # if any key is pressed
                if event.key == pygame.K_F4:
                    quitGame()




        # fills window with white
        window.fill((0,0,0))
        # Text for main menu (one is there cuz it has to be)

        # title
        text("Castle Kräftig", (255,0,0), (screenWidth / 2 - 230), (screenHeight - (screenHeight / 2 + 150)), 75, True)
        # where to place the text above
        # directions text
        button("Directions", 350, 290, 100, 50, 353, 300, "direct") 
        #text('Controls: WASD to move', (0,0,0), (screenWidth / 2 - 200), (screenHeight - (screenHeight / 2)), 30, True)

        # buttons for main menu

        button("Start", 150, 450, 100, 50, 175, 465, "start")
        button("Quit", 550, 450, 100, 50, 580, 465, "quit")


        pygame.display.update() # updates screen
        pygame.time.delay(15) # delays by 15 ticks

    pygame.quit()   

def pauseMenu():
    global running, largeText 
    intro = False # intro set to false and...
    running = False # running set to false so mainlooop & mainmenu won't run 
    pause = True # to start the Pause sreen
    while pause: # while pause is true
        for event in pygame.event.get(): # for all events in pygame
            if event.type == pygame.QUIT: # if tries to quit window
                quitGame() # call quitGame() function

            if event.type == pygame.KEYDOWN: # if any key is pressed
                if event.key == pygame.K_F4: # if F4 is pressed 
                    quitGame() # call quitGame() function

        # keep filling window with white (so no weirdness and also have
        # background white)
        window.fill((0,0,0))
        # Pause menu text display
        text("PAUSED", (255,0,0), (screenWidth / 2 - 150), (screenHeight - (screenHeight / 2 + 150)), 75, True)
        # Button for Main Menu
        button("Main Menu", 345, 450, 110, 50, 350, 465, "mainMenu")
        # button for restarting game 
        button("Restart", 350, 375, 100, 50, 365, 390, "restart")
        # button for resuming game
        button("Resume", 350, 300, 100, 50, 365, 315, "resume")
        # button for quitting game
        button("Quit", 350, 525, 100, 50, 380, 540, "quit")
        pygame.display.update() # updates screen
        pygame.time.delay(15) # delays by 15 ticks

# directions menu
def dMenu(): 
    insMenu = True # set loop to true
    while insMenu: # whiles insMenu is True
        for event in pygame.event.get(): # for all events that happen
            if event.type == pygame.QUIT: # if player tries to quit
                quitGame() # call quitGame()

            if event.type == pygame.KEYDOWN: # if any key is pressed
                if event.key == pygame.K_F4: # if F4 is pressed
                    quitGame() # call quitGame()

        window.fill((0,0,0)) # fill screen with white
        """ALL TEXT FOR DIRECTIONS/CONTROLS MENU WITH PLACEMENT"""
        text("DIRECTIONS/CONTROLS", (255,0,0), (screenWidth / 2 - 300), (screenHeight - (screenHeight / 2 + 250)), 50, True)
        text("W = Move Up", (140,140,140), (screenWidth / 2 - 75), (screenHeight - (screenHeight / 2 + 150)), 25, False)
        text("A = Move Left", (140,140,140), (screenWidth / 2 - 75), (screenHeight - (screenHeight / 2 + 125)), 25, False)
        text("S = Move Down", (140,140,140), (screenWidth / 2 - 75), (screenHeight - (screenHeight / 2 + 100)), 25, False)
        text("D = Move Right", (140,140,140), (screenWidth / 2 - 75), (screenHeight - (screenHeight / 2 + 75)), 25, False)
        text("F4 = Exit Game", (140,140,140), (screenWidth / 2 - 75), (screenHeight - (screenHeight / 2 + 50)), 25, False)
        text("O = Pause Game", (140,140,140), (screenWidth / 2 - 75), (screenHeight - (screenHeight / 2 + 25)), 25, False)
        text("Your goal in this game is to kill all ", (140,140,140), (screenWidth / 2 - 175), (screenHeight - (screenHeight / 2 - 75)), 25, False)
        text("the Nazis in Castle Kräftig. This game ", (140,140,140), (screenWidth / 2 - 175), (screenHeight - (screenHeight / 2 - 100)), 25, False)
        text("does NOT end. Play until you want to  ", (140,140,140), (screenWidth / 2 - 175), (screenHeight - (screenHeight / 2 - 125)), 25, False)      
        text("stop.", (140,140,140), (screenWidth / 2  - 175), (screenHeight - (screenHeight / 2 - 150)), 25, False)

        # Main Menu button to go back to main menu
        button("Main Menu", 345, 525, 110, 50, 350, 540, "mainMenu")

        pygame.display.update() # update python
        pygame.time.delay(15) # delay by 15 ticks

############################## mainloop #############################
def mainloop():
    global running, score, intro, sprite, degrees

    while running:
        """keeps filling window with the colour of choice. without this, the
        rectangle will "paint" the screen."""
        window.blit(background, (0, 0))

        #window.blit(background, (0, 0))
        pygame.time.delay(25) # delay
        for event in pygame.event.get(): # for every event in game
            if event.type == pygame.QUIT: # if I exit the game
                pygame.quit()

            if event.type == pygame.KEYUP: # if any keys are let go
                if event.key == pygame.K_a: # if key a
                    rec.xChange = 0 # set xChange to 0 (stop moving rec)

                if event.key == pygame.K_d: # if key d
                    rec.xChange = 0 # set xChange to 0 (stop moving rec)

                if event.key == pygame.K_w: # if key w
                    rec.yChange = 0 # set xChange to 0 (stop moving rec)

                if event.key == pygame.K_s: # if key s
                    rec.yChange = 0 # set xChange to 0 (stop moving rec)

                # pause key to pause game
                if event.key == pygame.K_o: # if key o
                    running = False # set running to false
                    intro = False # intro set to False
                    pauseMenu() # pauseMenu is called

            if event.type == pygame.KEYDOWN: # if any keys are pressed
                if event.key == pygame.K_F4: # if key F4
                    """(when set to false, the game will exit because of the
                    pygame.quit() command below mainloop)"""
                    pygame.quit() # set running to false

                if event.key == pygame.K_a: # if key a
                    rec.xChange += -5 # add -5 to xChange (move rec left)

                if event.key == pygame.K_d: # if key a
                    rec.xChange += 5 # adds 5 to xChange (move rec right)

                if event.key == pygame.K_w: # if key a
                    #adds -5 to yChange (moves rec up). Yes, this is supposed to say up.
                    rec.yChange += -5 # 

                if event.key == pygame.K_s: # if key a
                    # adds 5 to yChange (moves rec down). Yes, this is supposed to say down.
                    rec.yChange += 5 


        rec.x += rec.xChange # add rec's xChange to x (to do the moving)
        rec.y += rec.yChange # adds rec's yChange to y (to do the moving)



        # ----------------BOUNDARIES------------------------------
        if rec.x <= 0: # if rec's x is less than or equal to 0 (if tries to escape screen)
            rec.x  = 0 # rec's x is set to 0 so it won't go off screen.

        """(we pick 750 because the player width is 50 and the screen width is 800.
        If we set it to 800, then the player can go outside of screen."""   
        if rec.x  >= 750: # if rec's x is greater than or equal to 750 (if tries to escape screen)
            rec.x  = 750  # set rec's x to 750 so it won't go off screen

        if rec.y <= 0: # if rec's y is less than or equal to 0 (if tries to escape screen)
            rec.y = 0 # set rec's y to 0 so it won't go off screen
        """we pick 540 because the player height is 60 and the screen height is 600.
            If we set it to 600, then the player can go outside of screen"""
        if rec.y >= 540: # if rec'y is greater than or equal to 540 (if tries to escape screen) 
            rec.y = 540 # set rec's y to 540 so it won't go off screen  

        collisions = detCollision(rec.x, rec.y, rec.w, rec.h, redRec.x, redRec.y, redRec.w, redRec.h)
        # activate the redrawWin function
        redrawWin(collisions)


mainMenu() # call mainMenu first
mainloop() # call mainloop if can
pygame.quit() # activates if nothing else is now running

我知道这段代码可以改进,但我真的只想知道如何移动精灵。

共有2个答案

柴茂材
2023-03-14

Pygame的(0,0)坐标位于屏幕的左上角,因此,如果您想让某个对象从上到下移动,您可以将值添加到y。它看起来是这样的:rec.y=5,或者任何其他数字

杨豪
2023-03-14

加载4个不同的精灵,为4个方向:

spriteUp    = pygame.image.load('characterUp.png')
spriteDown  = pygame.image.load('characterDown.png')
spriteLeft  = pygame.image.load('characterLeft.png')
spriteRight = pygame.image.load('characterRight.png')

通过其中一个图像初始化sprite,例如:

sprite = spriteUp

按下一个键(pygame.KEYDOWNevent),然后更改sprite

for event in pygame.event.get():
    # [...]

    if event.type == pygame.KEYDOWN: # if any keys are pressed
        # [...]

       if event.key == pygame.K_a: # if key a
           rec.xChange += -5 # add -5 to xChange (move rec left)
           sprite = spriteLeft

       if event.key == pygame.K_d: # if key a
           rec.xChange += 5 # adds 5 to xChange (move rec right)
           sprite = spriteRight

       if event.key == pygame.K_w: # if key a
           #adds -5 to yChange (moves rec up). Yes, this is supposed to say up.
           rec.yChange += -5 #
           sprite = spriteUp 

       if event.key == pygame.K_s: # if key a
           # adds 5 to yChange (moves rec down). Yes, this is supposed to say down.
           rec.yChange += 5 
           sprite = spriteDown

bite精灵表面,而不是绘制矩形:

pygame.draw.rect(窗口,(0,255,0),(rec. x, rec. y, rec. w, rec. h)

 
  window.blit(sprite, (rec.x, rec.y))

 

 类似资料:
  • 如果这个问题以前已经被问过,我很抱歉,但是我到处都查过了,找不到答案。 如何在pygame中进行自上而下的移动? 如果我只是使用矩形,这将很容易,但我将使用单个角色精灵(例如。如果我按d让玩家向右走,它会显示他向右走的角色精灵,并将角色向右移动)。 我的意思的示例图像:

  • 问题内容: 为什么我们说C这样的语言是自上而下的,而Java或C ++这样的OOP语言是自下而上的呢?这种分类在软件开发中是否有任何重要性? 问题答案: “自上而下”的方法对问题进行了高级定义,并将其细分为子问题,然后您可以递归地进行处理,直到发现明显且易于编码的部分为止。这通常与编程的“功能分解”风格相关联,但不是必须的。 在“自下而上”编程中,您确定了可以构成更大程序的较低级工具。 实际上,几

  • 本文向大家介绍自上而下和自下而上的解析之间的区别,包括了自上而下和自下而上的解析之间的区别的使用技巧和注意事项,需要的朋友参考一下 在这篇文章中,我们将了解自顶向下和自底向上解析之间的区别- 自上而下的解析和自下而上的解析是解析树以到达树的开头的不同技术。这可以通过以下讨论的两种不同方法来完成。 自上而下的解析 这是一种解析技术,它首先查看解析树的最高级别,然后再向下处理直到解析树。 它使用语法规

  • 问题内容: 假设我们有3种方法:从方法1调用方法2,从方法2调用方法3。方法2和3的大小均为30个字节码。同样,对于确定性,假设总是总是从方法1一次调用方法2,而总是从方法2一次调用方法3。 如果首先内联方法2,则将直接从方法1的主体中调用方法3,并且可以依次内联。如果首先将方法3内联到方法2中,则方法2的大小将变为大约60个字节码,并且无法内联,因为默认阈值为35个字节码。 HotSpot JI

  • 本文向大家介绍自下而上模型与自上而下模型之间的区别,包括了自下而上模型与自上而下模型之间的区别的使用技巧和注意事项,需要的朋友参考一下 自下而上的模型 自下而上模型是一种系统设计方法,其中详细定义了系统的各个部分。一旦设计和开发了这些零件,然后将这些零件或组件链接在一起以准备更大的组件。重复此方法,直到构建完整的系统。自下而上模型的优势在于可以在非常低的级别上进行决策并确定组件的可重用性。 自顶向

  • 本文向大家介绍自上而下的解析与自下而上的解析之间的区别,包括了自上而下的解析与自下而上的解析之间的区别的使用技巧和注意事项,需要的朋友参考一下 自顶向下解析 自顶向下语法分析技术是从语法树的顶端开始,向下移动,对语法规则进行评价的一种语法分析技术。 自底向上解析 自顶向下的语法分析技术又是一种从语法树的最底层开始,向上移动并评价语法规则的语法分析技术。 以下是“自上而下”解析和“自下而上”解析之间