[英]How do I make it so my square can land on my other square and stay on it
I am a new python and pygame, and I want to learn collisionm but I only know how to detect collision.我是一个新的python和pygame,我想学习碰撞,但我只知道如何检测碰撞。
How can I add collision that allows me to stand on my big square while my little square moves.我怎样才能添加碰撞,让我站在我的大方格上,而我的小方格移动。 I don't know how to make it stand on the other square instead of getting thrown.
我不知道如何让它站在另一个广场上而不是被扔掉。 At the bottom of my script I added collision detection but can't figure out how to make it actually stand on the my big block without it getting thrown to the sides, top and bottom.
在我的脚本底部,我添加了碰撞检测,但无法弄清楚如何让它真正站在我的大块上,而不会被扔到侧面、顶部和底部。
pygame.init()
win = pygame.display.set_mode((500,500))
pygame.display.set_caption("THIS GAME IS KINDA ASS")
# first squrae
x = 50
y = 50
height= 50
width = 50
speed = 5
isJump = False
JumpCount = 10
# square 2
cordx = 100
cordy = 200
cordheight = 100
cordwidth = 100
# First Square
# main loop
runningame = True
while runningame:
pygame.time.delay(50)
for event in pygame.event.get():
if event.type == pygame.QUIT:
runningame = False
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
x -= speed
if keys[pygame.K_RIGHT]:
x += speed
if not(isJump):
if keys[pygame.K_UP]:
y -= speed
if keys[pygame.K_DOWN]:
y += speed
if keys[pygame.K_SPACE]:
isJump = True
else:
if JumpCount >= -10:
y -= (JumpCount *abs(JumpCount))
JumpCount -= 1
else:
isJump = False
JumpCount = 10
win.fill((0,0,0))
# I added a varabial to my player square
Player = pygame.draw.rect(win, (115, 235, 174), (x,y, height,width))
# second square
# this is the big box and its the enemy square that I want my script to stand on
Enemy = pygame.draw.rect(win, (202, 185 , 241), (cordx, cordy, cordheight,cordwidth))
if Player.colliderect(Enemy):
pygame.draw.rect(win, (140, 101, 211), (50,50,50,50))
pygame.display.update()
pygame.quit()
So you have Player.colliderect(Enemy)
so you know when its colliding, you just need to figure out from where and move the player accordingly.所以你有
Player.colliderect(Enemy)
所以你知道它什么时候发生碰撞,你只需要弄清楚从哪里开始并相应地移动玩家。
A simple way to do this which is not perfect is to have a direction the player is moving and if the player is moving down, move the player above the enemy.一种不完美的简单方法是确定玩家移动的方向,如果玩家向下移动,则将玩家移动到敌人上方。
In your code, you need a direction在您的代码中,您需要一个方向
direction = "not moving"
...
if keys[pygame.K_LEFT]:
x -= speed
direction = "left"
if keys[pygame.K_RIGHT]:
x += speed
direction = "right"
...
else:
if JumpCount >= -10:
y -= (JumpCount *abs(JumpCount))
JumpCount -= 1
if (JumpCount *abs(JumpCount)) > 0:
direction = "down"
else:
direction = "up"
...
if Player.colliderect(Enemy):
if direction == "down":
y -= player.bottom - enemy.top #get the amount that that the player is overlapping the enemy and take it off y so it no longer overlapping
elif direction == "up":
y += player.top - enemy.bottom
#do the same for left and right
another way is to make player and enemy Rects
and use them to replace x
and y
另一种方法是制作玩家和敌人
Rects
并使用它们来替换x
和y
so所以
# first squrae
x = 50
y = 50
height= 50
width = 50
player = pygame.Rect(x,y,width,height)
speed = 5
isJump = False
JumpCount = 10
# square 2
cordx = 100
cordy = 200
cordheight = 100
cordwidth = 100
enemy = pygame.Rect(cordc,cordy,cordwidth,cordheight)
you can then draw them with然后你可以用
win.fill((0,0,0))
# I added a varabial to my player square
pygame.draw.rect(win, (115, 235, 174),player)
# second square
# this is the big box and its the enemy square that I want my script to stand on
pygame.draw.rect(win, (202, 185 , 241), enemy)
and update the positions with并更新职位
if keys[pygame.K_LEFT]:
player.x -= speed
if keys[pygame.K_RIGHT]:
player.x += speed
and for collisions和碰撞
if player.colliderect(enemy):
if player.centerx < enemy.left: #if the center of player is left of the enemy
player.right = enemy.left
if player.centerx > enemy.right:
player.left = enemy.right
if player.centery < enemy.top:
player.bottom = enemy.top
if player.centery > enemy.bottom:
player.top = enemy.bottom
both ways work ad neither are perfect, there are also more ways to do it, but i think i would recommend the first method as its easier to understand and easier to add to your code.两种工作方式都不是完美的,还有更多方法可以做到,但我认为我会推荐第一种方法,因为它更容易理解并且更容易添加到您的代码中。 Comment if you need more explanation on how it works or more ways to do it
如果您需要更多关于其工作原理或更多方法的说明,请发表评论
import pygame
pygame.init()
win = pygame.display.set_mode((500,500))
pygame.display.set_caption("THIS GAME IS KINDA ASS")
class Player(pygame.sprite.Sprite):
def __init__(self, x, y, w, h, col):
pygame.sprite.Sprite.__init__(self)
self.rect = pygame.Rect(x,y,w,h)
self.image = pygame.Surface((w,h))
self.image.fill(col)
self.isJump = False
self.JumpCount = 8
def update(self):
if self.isJump:
if self.JumpCount >= -8:
self.rect.y -= (self.JumpCount *abs(self.JumpCount))
self.JumpCount -= 1
else:
self.isJump = False
self.JumpCount = 8
class Platform(pygame.sprite.Sprite):
def __init__(self, x, y, w, h, col):
pygame.sprite.Sprite.__init__(self)
self.rect = pygame.Rect(x,y,w,h)
self.image = pygame.Surface((w,h))
self.image.fill(col)
# first squrae
x = 50
y = 50
height= 50
width = 50
speed = 5
player = Player(x,y,width, height, (115, 235, 174))
# square 2
cordx = 100
cordy = 200
cordheight = 100
cordwidth = 100
enemy1 = Platform(cordx,cordy,cordwidth, cordheight, (202, 185 , 241))
#square 3
enemy2 = Platform(300,90,100,30,(202, 185 , 241))
all_sprites = pygame.sprite.Group()
all_sprites.add(player)
all_sprites.add(enemy1)
all_sprites.add(enemy2)
enemy_sprites = pygame.sprite.Group()
enemy_sprites.add(enemy1, enemy2)
clock = pygame.time.Clock()
# main loop
runningame = True
while runningame:
clock.tick(50)
for event in pygame.event.get():
if event.type == pygame.QUIT:
runningame = False
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
player.rect.x -= speed
if keys[pygame.K_RIGHT]:
player.rect.x += speed
if not(player.isJump):
if keys[pygame.K_UP]:
player.rect.y -= speed
if keys[pygame.K_DOWN]:
player.rect.y += speed
if keys[pygame.K_SPACE]:
player.isJump = True
for enemy in enemy_sprites.sprites():
if player.rect.colliderect(enemy.rect):
if player.rect.centerx < enemy.rect.left: #if the center of player is left of the enemy
player.rect.right = enemy.rect.left
if player.rect.centerx > enemy.rect.right:
player.rect.left = enemy.rect.right
if player.rect.centery < enemy.rect.top:
player.rect.bottom = enemy.rect.top
if player.rect.centery > enemy.rect.bottom:
player.rect.top = enemy.rect.bottom
all_sprites.update()
win.fill((0,0,0))
all_sprites.draw(win)
pygame.display.update()
pygame.quit()
Here is your program but using sprites这是您的程序,但使用精灵
As you can see, i have moved any code relating to the squares to their classes.如您所见,我已将任何与方块相关的代码移至它们的类中。 each sprite has a
rect
and a image
.每个精灵都有一个
rect
和一个image
。 The rect is used the same way as the rect i showed above.矩形的使用方式与我上面显示的矩形相同。 The image is a surface, because that how pygame puts it on the screen.
图像是一个表面,因为 pygame 如何将它放在屏幕上。 it the exact same as before by making it the same size and filling it with the colour.
通过使其大小相同并填充颜色,它与以前完全相同。
Ive got 2 sprite groups, the all_sprites
group which has all of them and the enemy_sprites
group, which only has enemies(platforms that you can stand on).我有 2 个精灵组,
all_sprites
组包含所有精灵组和enemy_sprites
组,只有敌人(您可以站立的平台)。 I can draw all sprites by calling all_sprites.draw(win)
.我可以通过调用
all_sprites.draw(win)
来绘制所有精灵。
For collisions, exact same, except i want to loop through each enemy (as i now have 2).对于碰撞,完全相同,除了我想遍历每个敌人(因为我现在有 2 个)。 so i can call
enemy_sprites.sprites()
to get each sprite.所以我可以调用
enemy_sprites.sprites()
来获取每个精灵。
If you want more explanation or examples, start a chat.如果您需要更多解释或示例,请开始聊天。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.