当使用pygame的重力时,对象通过屏幕。

发布于 2025-02-10 14:25:37 字数 4369 浏览 1 评论 0原文

我是五年级学生,我正在制作平台游戏。当我使用重力时,我正在尝试防止玩家穿透屏幕。我还需要一键单击一次跳跃,并以2个点击的高度跳跃。我还使用了一些在网上找到的代码。所以这是我的代码:

import pygame

canvas_width = 1000
canvas_height = 500
pygame.init()
screen = pygame.display.set_mode([canvas_width,canvas_height])
screen_rect = screen.get_rect()
clock = pygame.time.Clock()

red = (255,0,0)
blue = (0,0,255)
green = (0,255,0)
white = (255,255,255)
black = (0,0,0)


class Ground:
    def __init__ (self,position,size,color):
        self.xPos = position[0]
        self.yPos = position[1]
        self.width = size[0]
        self.height = size[1]
        self.color = color
        self.rect = pygame.rect.Rect(position,size)

#class Enemyline:
#    def __init__ (self,position,size,color):
#        self.xPos = position[0]
#        self.yPos = position[1]
#        self.width = size[0]
#        self.height = size[1]
#        self.color = color
#        self.rect = pygame.rect.Rect(position,size)
#        #self.rect[(xPos,yPos),(width,height)]
        
#     def __init__(self, xsize, ysize,  color):
#         self.color = color
#         self.xsize = xsize
#         self.ysize = ysize
#         self.pos = [0, 10]
#         self.rect = pygame.rect.Rect(self.pos, (xsize, ysize))

class Ball:
    
    def __init__(self,position,size,color):
        self.xPos = position[0]
        self.yPos = position[1]
        self.width = size[0]
        self.height = size[1]
        self.color = color
        #self.size = size
        #self.pos = [10, 450]
        self.speed = [0.001, 0.001]
        #speed [xSpeed,ySpeed]
        self.rect = pygame.rect.Rect(position,size)
        #self.rect = pygame.rect.Rect(self.pos,(size,size))

    def move (self):
        self.keymove()
        #self.hitRect(Enemyline)
        self.gravity()
        #self.edge()
        self.rect.move_ip(self.speed)
        #self.pos = self.rect[0:2]
        pygame.draw.rect(screen, self.color,self.rect)
        
    def touchRect(self,Enemyline, Ground):
        #if self.rect.colliderect(Enemyline):
            #self.speed[1] = self.speed[1] * -1
            
        if self.rect.colliderect(Ground):
            self.speed[1] = self.speed[1] * 0
    
    
    def gravity(self):
        self.speed[1] = self.speed[1] + 0.5
        
#     def edge(self):
#         spot = self.rect[0:2]
#         xPos = spot[0]
#         yPos = spot[1]
#         if xPos <= 0 or xPos >= (canvas_width - self.size):
#             self.speed[0] = self.speed[0] + 0
#         
#         if yPos <= 0 or yPos >= (canvas_height - self.size):
#             self.speed[1] = self.speed[1] + 0
    
    def keymove(self):
        spot = self.rect[0:2]
        xPos = spot[0]
        yPos = spot[1]
        
        
        key = pygame.key.get_pressed()
        
        if key[pygame.K_LEFT]:
            self.speed[0] = self.speed[0] - 0.5

        
        #RIGHT
        if key[pygame.K_RIGHT]:
            self.speed[0] = self.speed[0] + 0.5
        
        #UP
        if key[pygame.K_UP]:
            self.speed[1] = self.speed[1] - 0.5
        #DOWN
        if key[pygame.K_DOWN]:
            self.speed[1] = self.speed[1] + 0.5
                    
        if xPos <= 0 or xPos >= (canvas_width - (self.width + self.height)):
            self.speed[0] = self.speed[0] * -1
        
        if yPos <= 0 or yPos >= (canvas_height - (self.width + self.height)):
            self.speed[1] = self.speed[1] * -1
            
    
#     def stop(self):
#         self.speed[0] = 0
#         self.speed[1] = 0
#         
#     def key_up(self):
#         if [pygame.K_LEFT] == pygame.KEYUP:
#             stop()


        

        
ball = Ball ([500,250],[30,30],blue)
ground = Ground ([0,470],[1000,10],green)
#L1enemy1 = Enemyline ([0,10], [1000,10],red)

Game = True

while Game:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            Game = False
    
    
    ball.move()
#     if (ball.hitRect(L1enemy1) == True):
#         self.speed = [0.001, 0.001]
#         self.speed[1] = self.speed[1] * -1
    screen.fill(black)
    pygame.draw.rect(screen, ball.color, ball.rect)
    pygame.draw.rect(screen, ground.color, ground.rect)
#    pygame.draw.rect(screen, L2enemy2.color, L2enemy2.rect)
    
    pygame.display.update()
    clock.tick(60)

pygame.quit()```

Is there anything you could do?

Thank you.

I am a fifth-grader and I'm making a platformer. I'm trying to keep my player from penetrating through the screen when I use gravity. I also need help jumping once with one click and jumping twice as high with 2 clicks. I also used some pieces of code that I found online. So this is my code:

import pygame

canvas_width = 1000
canvas_height = 500
pygame.init()
screen = pygame.display.set_mode([canvas_width,canvas_height])
screen_rect = screen.get_rect()
clock = pygame.time.Clock()

red = (255,0,0)
blue = (0,0,255)
green = (0,255,0)
white = (255,255,255)
black = (0,0,0)


class Ground:
    def __init__ (self,position,size,color):
        self.xPos = position[0]
        self.yPos = position[1]
        self.width = size[0]
        self.height = size[1]
        self.color = color
        self.rect = pygame.rect.Rect(position,size)

#class Enemyline:
#    def __init__ (self,position,size,color):
#        self.xPos = position[0]
#        self.yPos = position[1]
#        self.width = size[0]
#        self.height = size[1]
#        self.color = color
#        self.rect = pygame.rect.Rect(position,size)
#        #self.rect[(xPos,yPos),(width,height)]
        
#     def __init__(self, xsize, ysize,  color):
#         self.color = color
#         self.xsize = xsize
#         self.ysize = ysize
#         self.pos = [0, 10]
#         self.rect = pygame.rect.Rect(self.pos, (xsize, ysize))

class Ball:
    
    def __init__(self,position,size,color):
        self.xPos = position[0]
        self.yPos = position[1]
        self.width = size[0]
        self.height = size[1]
        self.color = color
        #self.size = size
        #self.pos = [10, 450]
        self.speed = [0.001, 0.001]
        #speed [xSpeed,ySpeed]
        self.rect = pygame.rect.Rect(position,size)
        #self.rect = pygame.rect.Rect(self.pos,(size,size))

    def move (self):
        self.keymove()
        #self.hitRect(Enemyline)
        self.gravity()
        #self.edge()
        self.rect.move_ip(self.speed)
        #self.pos = self.rect[0:2]
        pygame.draw.rect(screen, self.color,self.rect)
        
    def touchRect(self,Enemyline, Ground):
        #if self.rect.colliderect(Enemyline):
            #self.speed[1] = self.speed[1] * -1
            
        if self.rect.colliderect(Ground):
            self.speed[1] = self.speed[1] * 0
    
    
    def gravity(self):
        self.speed[1] = self.speed[1] + 0.5
        
#     def edge(self):
#         spot = self.rect[0:2]
#         xPos = spot[0]
#         yPos = spot[1]
#         if xPos <= 0 or xPos >= (canvas_width - self.size):
#             self.speed[0] = self.speed[0] + 0
#         
#         if yPos <= 0 or yPos >= (canvas_height - self.size):
#             self.speed[1] = self.speed[1] + 0
    
    def keymove(self):
        spot = self.rect[0:2]
        xPos = spot[0]
        yPos = spot[1]
        
        
        key = pygame.key.get_pressed()
        
        if key[pygame.K_LEFT]:
            self.speed[0] = self.speed[0] - 0.5

        
        #RIGHT
        if key[pygame.K_RIGHT]:
            self.speed[0] = self.speed[0] + 0.5
        
        #UP
        if key[pygame.K_UP]:
            self.speed[1] = self.speed[1] - 0.5
        #DOWN
        if key[pygame.K_DOWN]:
            self.speed[1] = self.speed[1] + 0.5
                    
        if xPos <= 0 or xPos >= (canvas_width - (self.width + self.height)):
            self.speed[0] = self.speed[0] * -1
        
        if yPos <= 0 or yPos >= (canvas_height - (self.width + self.height)):
            self.speed[1] = self.speed[1] * -1
            
    
#     def stop(self):
#         self.speed[0] = 0
#         self.speed[1] = 0
#         
#     def key_up(self):
#         if [pygame.K_LEFT] == pygame.KEYUP:
#             stop()


        

        
ball = Ball ([500,250],[30,30],blue)
ground = Ground ([0,470],[1000,10],green)
#L1enemy1 = Enemyline ([0,10], [1000,10],red)

Game = True

while Game:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            Game = False
    
    
    ball.move()
#     if (ball.hitRect(L1enemy1) == True):
#         self.speed = [0.001, 0.001]
#         self.speed[1] = self.speed[1] * -1
    screen.fill(black)
    pygame.draw.rect(screen, ball.color, ball.rect)
    pygame.draw.rect(screen, ground.color, ground.rect)
#    pygame.draw.rect(screen, L2enemy2.color, L2enemy2.rect)
    
    pygame.display.update()
    clock.tick(60)

pygame.quit()```

Is there anything you could do?

Thank you.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

稍尽春風 2025-02-17 14:25:37

我玩了你的游戏,并采取了同样的行为。测试了各种代码块后,我确定在与地面发生碰撞期间,当从“加上”速度转换为“减去”速度时,“球”位置通常会在地面位置以下。因此,在球向后移动之前,将检查其位置。而且,由于其位置仍然低于地面,这将再次将速度扭转为正值。因此,它显示了“下沉的速度”效果。一旦位置低于地面,它将不断下沉。

您可能想探索其他选项,但是我让它退出在正速值和负速度之间的振荡的方式,而对象似乎处于地面或下方的位置是将以下代码

if yPos <= 0 or yPos >= (canvas_height - (self.width + self.height)):

更改为

if yPos <= 0 or yPos >= (canvas_height - (self.width + self.height)) and self.speed[1] > 0:

行 :当著名的速度为正时,速度从正变为负,似乎提供了“减震器”效果,以抵消球的位置与击中地面的测试之间的任何滞后。

尝试一下,看看是否可以帮助您。

问候。

I played around with your game and got the same behavior. After testing out various blocks of code, I determined that during the collisions with the ground, the "ball" position would often times be below the ground position when the switch from "plus" speed to "minus" speed would occur. So before the ball got moving back up, its position would be checked. And, since its position was still below the ground level which would again reverse the speed to a positive value. Thus it was displaying that "sinking in quicksand" effect. Once the position was below the ground level, it would just keep sinking.

You might want to explore other options, but the way I got it to quit oscillating between positive and negative speed values while the object appeared to be at or under the ground level was to change the following line of code from:

if yPos <= 0 or yPos >= (canvas_height - (self.width + self.height)):

to:

if yPos <= 0 or yPos >= (canvas_height - (self.width + self.height)) and self.speed[1] > 0:

Only doing the speed switch from positive to negative when the noted speed was positive seemed to provide a "shock absorber" effect to counter any lag between the positioning of the ball and the tests for hitting the ground.

Try that out and see if that helps you out.

Regards.

风蛊 2025-02-17 14:25:37

条件

 如果ypos&lt; = 0或ypos&gt; =(canvas_height--(self.width + self.height)):
 

没有意义。在一起增加宽度和高度绝对没有意义。
宽度是沿X轴的尺寸,高度沿Y轴的尺寸。
您的代码偶然工作,因为self.width与从窗口底部到绿线顶部的倍数相同。
您实际想做的是:

if yPos <= 0 or yPos >= ground.rect.top - self.height:

无论如何,这并不能解决您的问题。
该问题类似于此处描述的问题:有时,球不会在乒乓球比赛中弹跳
真正的问题是速度降低。
如果对象位于线以下,并且向上速度不足以将对象提升到线上,则该对象将被卡住。

您有2个选项来解决问题,

  1. 只要物体在地下下方,就可以确保移动升高。
    您可以通过self.speed [1] = -abs(self.speed [1])而不是self.speed [1] = self.speed [1] * -1 -1
if yPos <= 0:
    self.speed[1] = abs(self.speed[1])

elif yPos >= ground.rect.top - self.height:
    self.speed[1] = -abs(self.speed[1])
  1. 当对象撞击地面时,将对象的底部限制为地面的顶部(self.Rect [1] = ground.Rect.top-sfop -self.height):
if yPos <= 0:
    self.speed[1] = self.speed[1] * -1

elif yPos >= ground.rect.top - self.height:
    self.speed[1] = self.speed[1] * -1
    yPos = ground.rect.top - self.height
    self.rect[1] = yPos

The condition

if yPos <= 0 or yPos >= (canvas_height - (self.width + self.height)):

makes no sense. There is absolutely no point in adding width and height together.
The width is a size along the x-axis and the height is a size along the y-axis.
Your code works by chance, because self.width is the same as distacnce from the bottom of the window to the top of the green line.
What you actually wanted to do is:

if yPos <= 0 or yPos >= ground.rect.top - self.height:

Anyway, that doesn't solve your problem.
The problem is similar to the problem described here: Sometimes the ball doesn't bounce off the paddle in pong game.
The real problem is that the speed decreases.
If the object goes below the line and the upward speed is insufficient to lift the object above the line, the object will get stuck.

You have 2 Option to solve the problem

  1. Make sure the movement is up as long as the object is beneath the ground.
    You can achieve that with self.speed[1] = -abs(self.speed[1]) instead of self.speed[1] = self.speed[1] * -1
if yPos <= 0:
    self.speed[1] = abs(self.speed[1])

elif yPos >= ground.rect.top - self.height:
    self.speed[1] = -abs(self.speed[1])
  1. Limit the bottom of the object to the top of the ground when the object hits the ground (self.rect[1] = ground.rect.top - self.height):
if yPos <= 0:
    self.speed[1] = self.speed[1] * -1

elif yPos >= ground.rect.top - self.height:
    self.speed[1] = self.speed[1] * -1
    yPos = ground.rect.top - self.height
    self.rect[1] = yPos
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文