【问题标题】:Why is my platform moving when my player is moving right or left为什么当我的播放器向右或向左移动时我的平台在移动
【发布时间】:2020-07-23 16:54:58
【问题描述】:

1) 在我的代码中,问题是我的玩家类下面的平台是连接的,当玩家移动时,平台也会连接,如果是这样,玩家会一直在平台上移动。有人可以告诉我如何解决吗?如果您想知道在哪里查找所有代码以及它将在哪里查找所有代码,因为我不知道是什么导致了我的代码中的问题。

import math
import os
import sys
# It is importing everything
import pygame
from pygame.locals import *

#The platform class is the problem I'm having
class Platform:
    def __init__(self, size, x, y, length, color, velocity):
        self.length = length
        self.size = size
        self.x = x
        self.y = y
        self.color = color
        self.velocity = velocity
        self.xVelocity = 0

    # This is what the platform class has and what it does
    def draw(self):
        display = pygame.display.get_surface()
        pygame.draw.rect(display, self.color, (int(self.x) - 80, int(self.y) + 225, int(self.x), int(self.y) - 45))

    # This is def draw function is showing that how I want my Platform to look like
    def do(self):
        self.draw()

2) 当我的玩家到达屏幕的“末端”时它会停止,但我想让它成为一个滚动屏幕并且没有任何反应,然后当玩家移动并自行滚动时就没有游戏了。在有人告诉我如何解决我的第二个问题之后,如果背景越过玩家,我希望背景杀死玩家。

# The def do function is running def draw function

class Player:
    def __init__(self, velocity, maxJumpRange, x, y, size):
        self.falling = True
        self.jumpCounter = 0
        self.xVelocity = 0
        self.y = y
        self.x = x
        self.jumping = False
        self.velocity = velocity
        self.maxJumpRange = maxJumpRange
        self.jump_offset = 0
        self.size = size

    # The player class is making how the Player is going to look and what are his limits

    def keys(self):
        k = pygame.key.get_pressed()
        # The def keys(self): is creating a variable for pygame.key.get_pressed() and underneath is a function to make the player move around
        if k[K_LEFT]:
            self.xVelocity = -self.velocity
        elif k[K_RIGHT]:
            self.xVelocity = self.velocity
        else:
            self.xVelocity = 0

        if k[K_SPACE] or k[K_UP] and not self.jumping and not self.falling:
            self.jumping = True
            self.jumpCounter = 0


    # The if k[K_Space] or k[K_UP] is making sure the player has a jump limit and can't continue jumping forever.
    def move(self):
        self.x += self.xVelocity
        # This to make sure that the player can move while he is jumping.
        if self.jumping:
            self.y -= self.velocity
            self.jumpCounter += 1
            if self.jumpCounter == self.maxJumpRange:
                self.jumping = False
                self.falling = True
        elif self.falling:
            if self.y <= h - 10 <= self.y + self.velocity:
                self.y = h - 10
                self.falling = False
            else:
                self.y += self.velocity

    def draw(self):
        display = pygame.display.get_surface()
        pygame.draw.circle(display, White, (int(self.x), int(self.y) - 25), 25, 0)

    def do(self):
        self.keys()
        self.move()
        self.draw()


# This Function is doing all of the Functions self.keys(), self.move(), self.draw()

def events():
    for event in pygame.event.get():
        if event.type == QUIT or (event.type == KEYDOWN and event.key == K_ESCAPE):
            pygame.quit()
            sys.exit()


# This is to make sure that you can exit the game is needed

def keys(player):
    keys = pygame.key.get_pressed()
    if keys[K_UP] or keys[K_SPACE] and player.jumping == False and player.jump_offset == 0:
        player.jumping = True


# The function here to make sure that the player can jump

def do_jumping(player):
    jump_height = 25
    # Def do_jumping(player): is to adjust the jump_height of the player
    if player.jumping:
        player.jump_offset += 1
        if player.jump_offset >= jump_height:
            player.jumping = False
    elif player.jump_offset > 0 and player.jumping == False:
        player.jump_offset -= 1


# The above is showing how the makes sure the player doesn't jump higher then the jump height

w = 576
h = 516
hw = w / 2
hh = h / 2
AREA = w * h
# The above is showing the width the height and Area
os.environ['SDL_VIDEO_WINDOW_POS'] = "50,50"
p = Player(hh, hw, 290, 250, 30)
# the above is showing what the graphics are
pygame.init()
Clock = pygame.time.Clock()
DS = pygame.display.set_mode((w, h))  # This is what the display size is
pygame.display.set_caption("Try to get point B")
FPS = 120
Black = (0, 0, 0, 255)
White = (255, 255, 255, 255)
pl = Platform(290, 250, 50, 70, White, 0)
Red = (255, 0, 0)
Solid_Fill = 0
# Bkgd stands for background
bkgd = pygame.image.load("scroll.png").convert()  # scroll.png is the png im using to use as the background
bkgdWidth = bkgd.get_rect().size[0]
print(bkgdWidth)
bkgdHeight = bkgd.get_rect().size
stageWidth = bkgdWidth * 2
StagePosX = 0
startScollingPosx = hw
circleRadius = 25
circlePosX = circleRadius
playerPosX = circleRadius
playerPosY = 377
playerVelocityX = 0
playerVelocityY = 0
platformVelocityX = 0
platformVelocityY = 0
x = 0
# The above is showing the player Velocity, player position y and x and what the stage position is, Ignore platform 
# velocity. 
# What the while true loop is doing is to make sure that the background moves while the player moves
while True:
    events()

    k = pygame.key.get_pressed()
    if k[K_RIGHT]:
        playerVelocityX = 1
        pl.xVelocity = 0
    elif k[K_LEFT]:
        playerVelocityX = -1
        pl.xVelocity = 0
    else:
        playerVelocityX = 0
        pl.xVelocity = 0

    playerPosX += playerVelocityX
    if playerPosX > stageWidth - circleRadius:
        playerPosX = stageWidth - circleRadius
    if playerPosX < circleRadius:
        playerPosX = circleRadius
    if playerPosX < startScollingPosx:
        circlePosX = playerPosX
    elif playerPosX > stageWidth - startScollingPosx:
        circlePosX - stageWidth + w
    else:
        circlePosX = startScollingPosx
        StagePosX -= playerVelocityX
# The code below show is working how to balance the Display size and rel x is the easier of saying that
    rel_x = StagePosX % bkgdWidth
    DS.blit(bkgd, (rel_x - bkgdWidth, 0))
    if rel_x < w:
        DS.blit(bkgd, (rel_x, 0))
    events()
    keys(p)
    do_jumping(p)
    pygame.draw.circle(DS, White, (math.floor(p.x), math.floor(p.y) - math.floor(p.jump_offset)), math.floor(p.size), math.floor(Solid_Fill))
    platform_color = Red
    pl.color = Red
    pl.draw()
    if p.jump_offset == 0:
        pl.color = White
    pl.do()
    pygame.display.update()
    Clock.tick(FPS)
    DS.fill(Black)

3) 最后很抱歉缺少好的代码以及在哪里查看代码,因为我不知道是什么导致了我的代码中的问题,所以我不得不把它全部放出来。

【问题讨论】:

  • 您有一个播放器类,但仅用于 x 和 y 位置,您不调用 do()。为什么不使用它而不是在循环中绘制和检查事件。这将更容易找到错误并实现滚动
  • 谢谢,但我仍然不明白,但我认为你想说的是,在播放器类中删除我的 do() 函数并在循环中实现它
  • 不,相反,你基本上已经实现了它,但你不应该。如果你取出循环中的playerPosXkey(p)draw.circle 行,以及所有关键的if 语句。播放器不在屏幕上,但是如果您添加 p.do() 它应该可以解决所有这些问题,拥有一个类的全部意义在于您不需要将所有这些都放在循环中,所以摆脱它并使用该类,它使它看起来更干净,也更容易。

标签: python python-3.x pygame 2d-games


【解决方案1】:

我稍微编辑了您的代码,以便解决您遇到的问题,我确实更改了图像,因为我没有它,但我通过让玩家不断跌倒并检查玩家是否与平台。我还添加了滚动背景。摆脱了我的 cmets 中提到的不必要的代码。改变了玩家从那里跳跃的动作。将平台中的大小更改为列表,使其具有宽度和高度。由于平台没有移动,因此也摆脱了速度。

import math
import os
import sys
# It is importing everything
import pygame
from pygame.locals import *

class Platform:
    def __init__(self, size, x, y, color):
        #size is a list, this means it has width and height
        self.size = size
        self.x = x
        self.y = y
        self.color = color

    # This is what the platform class has and what it does
    def draw(self):
        display = pygame.display.get_surface()
        pygame.draw.rect(display, self.color, (int(self.x), int(self.y), self.size[0], self.size[1]))

    # This is def draw function is showing that how I want my Platform to look like
    def do(self):
        self.draw()


# The def do function is running def draw function

class Player:
    def __init__(self, velocity, maxJumpRange, x, y, size):
        self.falling = True
        self.jumpCounter = 0
        self.xVelocity = 0
        self.y = y
        self.x = x
        self.jumping = False
        self.velocity = velocity
        self.maxJumpRange = maxJumpRange
        self.jump_offset = 0
        self.size = size
        self.TouchedGround = False

    # The player class is making how the Player is going to look and what are his limits

    def keys(self):
        k = pygame.key.get_pressed()
        # The def keys(self): is creating a variable for pygame.key.get_pressed() and underneath is a function to make the player move around
        if k[K_LEFT]:
            self.xVelocity = -self.velocity
        elif k[K_RIGHT]:
            self.xVelocity = self.velocity
        else:
            self.xVelocity = 0

        if (k[K_SPACE] or k[K_UP]) and not self.jumping and self.TouchedGround:
            self.jumping = True
            self.jumpCounter = 0
            self.TouchedGround = False


    # The if k[K_Space] or k[K_UP] is making sure the player has a jump limit and can't continue jumping forever.
    def move(self):
        self.x += self.xVelocity
        # if the player is jumping, change y value
        if self.jumping:
            self.y -= self.velocity
            self.jumpCounter += 1
            if self.jumpCounter == self.maxJumpRange:
                self.jumping = False
                self.falling = True
        elif self.falling:
            self.y += self.velocity
            self.jumpCounter -= 1


    def draw(self):
        display = pygame.display.get_surface()
        pygame.draw.circle(display, White, (int(self.x), int(self.y)), self.size)

    def do(self):
        self.keys()
        self.move()
        self.draw()


# This Function is doing all of the Functions self.keys(), self.move(), self.draw()

def events():
    for event in pygame.event.get():
        if event.type == QUIT or (event.type == KEYDOWN and event.key == K_ESCAPE):
            pygame.quit()
            sys.exit()



#window size

w = 576
h = 516

# The above is showing the width the height and Area
os.environ['SDL_VIDEO_WINDOW_POS'] = "50,50"
# the above is showing what the graphics are

#player
p = Player(1, 100, 290, 250, 30)


#start pygame
pygame.init()
Clock = pygame.time.Clock()
DS = pygame.display.set_mode((w, h))  # This is what the display size is
pygame.display.set_caption("Try to get point B")



#variables
FPS = 120
Black = (0, 0, 0, 255)
White = (255, 255, 255, 255)
Red = (255, 0, 0)


# Bkgd stands for background
bkgd = pygame.Surface((w,h))  # didnt have the image so i made it blue
bkgd.fill((0,0,255))


#platforms
pl = Platform([290,20], 250, 350, White)
#this is a list that holds all the platforms
platforms_list = [pl,Platform([200,20], 100, 450, White), Platform([200,20], 400, 250, White)]

#this is how much to scroll the background by
background_scroll = 0


# What the while true loop is doing is to make sure that the background moves while the player moves
while True:
    events()

    #blit the background, since the image is same size as window blit twice so when scrolls, you dont have blackness 
    DS.blit(bkgd, (-background_scroll, 0))
    DS.blit(bkgd, (w-background_scroll, 0))

    #check for x button clicked
    events()

    #update the player
    p.do()

    #update platforms and check for collision with player
    platform_color = Red
    for platform in platforms_list:
        platform.color = platform_color
        if p.jumping == 0:
            platform.color = White
        platform.do()
        #if bottom of player is in the platform, move the player on top of the platform
        if p.y + p.size > platform.y and p.y + p.size < platform.y + platform.size[1]:
            if p.x > platform.x and p.x < platform.x + platform.size[0]:
                p.y = platform.y - p.size  
                p.TouchedGround = True

    #if the player reaches the side of the screen, move the background and platforms to make it look like it is moving
    if p.x + p.size >= w:
        p.x = w - p.size
        background_scroll += 1
        for platform in platforms_list:
            platform.x -= 1
        if background_scroll == w:
            background_scroll = 0
    #same but for the left
    if p.x - p.size <= 0:
        p.x = 0 + p.size
        background_scroll -= 1
        for platform in platforms_list:
            platform.x += 1
        if background_scroll == 0:
            background_scroll = w

    #update screen
    pygame.display.update()
    Clock.tick(FPS)
    DS.fill(Black)

【讨论】:

  • 我还有一个问题,那就是如果你按空格键让它停留在空中,你如何让玩家停止向上飞行,你不应该在代码中有一个 jump_height 吗?限制玩家跳跃的像素数。
  • 我编辑了我的代码来解决这个问题。我所做的只是在 Player 类中创建一个名为 TouchedGround 的变量。如果玩家与平台发生碰撞,我将其设为 eqaul True,当玩家跳跃时,我将其设为 false,并且玩家只有在等于 True 时才能跳跃,所以玩家跳跃后,你必须等到它与平台碰撞再次跳跃。我还在if (k[K_UP] or k[K_SPACE]) and... 周围添加了括号,否则无论如何它都会跳转。
  • 对不起,我来晚了,但我有一个问题,如何让一个大条出现在下面,这样玩家就不会掉出这个世界就再也回不来了。
  • @MantraMittal 只需用p = Platform()创建一个平台,并将位置设置为底部,宽度设置为屏幕宽度,然后添加到plaforms_list,您可以使用platforms_list.append(Platform([w,20],0,h-20,White))在一行中完成此操作
  • @MantraMittal 不用担心,我喜欢这样做
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-12-09
  • 2016-02-13
  • 2014-05-03
相关资源
最近更新 更多