Python pygame显示器上的矩形碰撞;碰撞后,按第二个键会导致rect跳转
我在让碰撞100%正常工作方面遇到了问题。如果我一次只按一个键,碰撞似乎可以正常工作,但是如果我在碰撞时按一个键并继续按,然后再按另一个键,碰撞似乎可以同时处理两个键。从研究来看,我似乎需要进行单独的轴计算,但我不确定如何使用我的碰撞算法进行计算。如果可能的话,我希望这是程序性的。如果有人能用一个有效的程序解决方案修改我的代码,我将不胜感激。谢谢Python pygame显示器上的矩形碰撞;碰撞后,按第二个键会导致rect跳转,python,python-3.x,pygame,Python,Python 3.x,Pygame,我在让碰撞100%正常工作方面遇到了问题。如果我一次只按一个键,碰撞似乎可以正常工作,但是如果我在碰撞时按一个键并继续按,然后再按另一个键,碰撞似乎可以同时处理两个键。从研究来看,我似乎需要进行单独的轴计算,但我不确定如何使用我的碰撞算法进行计算。如果可能的话,我希望这是程序性的。如果有人能用一个有效的程序解决方案修改我的代码,我将不胜感激。谢谢 import pygame as pg import sys from math import fabs pg.init() width = 60
import pygame as pg
import sys
from math import fabs
pg.init()
width = 600
height = 600
gameDisplay = pg.display.set_mode((width, height))
pg.display.set_caption('Block')
white = (255, 255, 255)
red = (255, 0, 0)
clock = pg.time.Clock()
closed = False
FPS = 60
Player_Speed = 200
x, y = 270, 0
vx = 0
vy = 0
collision = False
def Collision(hero, enemy):
global vx, vy, x, y, collision
deltay = fabs(block.centery - ENEMY.centery)
deltax = fabs(block.centerx - ENEMY.centerx)
if deltay < ENEMY.height and deltax < ENEMY.width:
collision = True
if vx > 0:
vx = 0
x = ENEMY[0] - block[2]
if vx < 0:
vx = 0
x = ENEMY[0] + 30
if vy > 0:
vy = 0
y = ENEMY[1] - block[3]
if vy < 0:
vy = 0
y = ENEMY[1] + 30
else:
collision = False
def xy_Text(x, y):
font = pg.font.SysFont("Courier", 16, True)
text = font.render("X: " + str(round(x)), True, (0,150,0))
text1 = font.render("Y: " + str(round(y)), True, (0,150,0))
gameDisplay.blit(text, (0,0))
gameDisplay.blit(text1, (0,14))
while not closed:
for event in pg.event.get():
if event.type == pg.QUIT:
closed = True
dt = clock.tick(FPS)/1000
vx, vy = 0, 0
keys = pg.key.get_pressed()
if keys[pg.K_ESCAPE]:
closed = True
if keys[pg.K_LEFT] or keys[pg.K_a]:
vx = -Player_Speed
if keys[pg.K_RIGHT] or keys[pg.K_d]:
vx = Player_Speed
if keys[pg.K_UP] or keys[pg.K_w]:
vy = -Player_Speed
if keys[pg.K_DOWN] or keys[pg.K_s]:
vy = Player_Speed
if vx != 0 and vy != 0:
vx *= 0.7071
vy *= 0.7071
gameDisplay.fill(white)
ENEMY = pg.draw.rect(gameDisplay, red, (270, 270, 30, 30))
block = pg.draw.rect(gameDisplay, (0, 150, 0), (x, y, 30, 30))
xy_Text(x, y)
x += vx * dt
y += vy * dt
Collision(block, ENEMY)
pg.display.update()
clock.tick(FPS)
pg.quit()
sys.exit()
将pygame导入为pg
导入系统
从数学进口工厂
第init页()
宽度=600
高度=600
gameDisplay=pg.display.set_模式((宽度、高度))
pg.display.set_标题(“块”)
白色=(255,255,255)
红色=(255,0,0)
时钟=pg.time.clock()
关闭=错误
FPS=60
玩家速度=200
x、 y=270,0
vx=0
vy=0
冲突=错误
def碰撞(英雄,敌人):
全局vx、vy、x、y、碰撞
deltay=fabs(block.centery-敌军.centery)
deltax=fabs(block.centerx-敌方.centerx)
如果deltay<敌方高度,deltax<敌方宽度:
碰撞=真
如果vx>0:
vx=0
x=敌人[0]-封锁[2]
如果vx<0:
vx=0
x=敌人[0]+30
如果vy>0:
vy=0
y=敌人[1]-封锁[3]
如果vy<0:
vy=0
y=敌人[1]+30
其他:
冲突=错误
定义xy_文本(x,y):
font=pg.font.SysFont(“Courier”,16,True)
text=font.render(“X:+str(圆(X)),True,(0150,0))
text1=font.render(“Y:+str(圆(Y)),True,(0150,0))
blit(文本,(0,0))
游戏显示.blit(text1,(0,14))
未关闭时:
对于pg.event.get()中的事件:
如果event.type==pg.QUIT:
关闭=真
dt=时钟滴答声(FPS)/1000
vx,vy=0,0
keys=pg.key.get_pressed()
如果钥匙[pg.K_ESCAPE]:
关闭=真
如果键[pg.K_左]或键[pg.K_a]:
vx=-玩家速度
如果键[pg.K_RIGHT]或键[pg.K_d]:
vx=玩家速度
如果键[pg.K_UP]或键[pg.K_w]:
vy=-玩家速度
如果键[pg.K_DOWN]或键[pg.K_s]:
vy=玩家速度
如果vx!=0和vy!=0:
vx*=0.7071
vy*=0.7071
游戏显示。填充(白色)
敌人=pg.draw.rect(游戏显示,红色,(270,270,30,30))
block=pg.draw.rect(游戏显示,(0,150,0),(x,y,30,30))
xy_文本(x,y)
x+=vx*dt
y+=vy*dt
碰撞(阻塞、敌人)
pg.display.update()
时钟滴答声(FPS)
第页退出
sys.exit()
经过多次更改后,碰撞仍然有效
我搬家了
x += vx * dt
y += vy * dt
冲撞
我在代码中更改了组织,我总是使用Rect()
来保持玩家和敌人的位置和大小
我还添加了第二个敌人来测试如何检查与许多元素的碰撞
import pygame as pg
import sys
from math import fabs
# - functions --- (lower_case_names)
def check_collision(player, enemy1, enemy2):
global player_vx, player_vy
# --- X ---
player.x += player_vx * dt
# enemy 1
deltay = fabs(player.centery - enemy1.centery)
deltax = fabs(player.centerx - enemy1.centerx)
if deltay < enemy1.height and deltax < enemy1.width:
if player_vx > 0:
player_vx = 0
player.x = enemy1.x - player.w
elif player_vx < 0:
player_vx = 0
player.x = enemy1.x + player.w
# enemy 2
deltay = fabs(player.centery - enemy2.centery)
deltax = fabs(player.centerx - enemy2.centerx)
if deltay < enemy2.height and deltax < enemy2.width:
if player_vx > 0:
player_vx = 0
player.x = enemy2.x - player.w
elif player_vx < 0:
player_vx = 0
player.x = enemy2.x + player.w
# --- Y ---
player.y += player_vy * dt
# enemy 1
deltay = fabs(player.centery - enemy1.centery)
deltax = fabs(player.centerx - enemy1.centerx)
if deltay < enemy1.height and deltax < enemy1.width:
if player_vy > 0:
player_vy = 0
player.y = enemy1.y - player.h
elif player_vy < 0:
player_vy = 0
player.y = enemy1.y + player.w
# enemy 2
deltay = fabs(player.centery - enemy2.centery)
deltax = fabs(player.centerx - enemy2.centerx)
if deltay < enemy2.height and deltax < enemy2.width:
if player_vy > 0:
player_vy = 0
player.y = enemy2.y - player.h
elif player_vy < 0:
player_vy = 0
player.y = enemy2.y + player.w
def xy_text(screen, x, y):
font = pg.font.SysFont("Courier", 16, True)
text = font.render("X: " + str(round(x)), True, (0,150,0))
screen.blit(text, (0,0))
text = font.render("Y: " + str(round(y)), True, (0,150,0))
screen.blit(text, (0,14))
# --- constants --- (UPPER_CASE_NAMES)
WIDTH = 600
HEIGHT = 600
WHITE = (255, 255, 255)
RED = (255, 0, 0)
FPS = 60
# --- main --- (lower_case_names)
player_speed = 200
player_vx = 0
player_vy = 0
player = pg.Rect(270, 0, 30, 30)
enemy1 = pg.Rect(270, 270, 30, 30)
enemy2 = pg.Rect(240, 300, 30, 30)
# - init -
pg.init()
game_display = pg.display.set_mode((WIDTH, HEIGHT))
pg.display.set_caption('Block')
# - mainloop -
clock = pg.time.Clock()
closed = False
while not closed:
dt = clock.tick(FPS)/1000
# - events -
for event in pg.event.get():
if event.type == pg.QUIT:
closed = True
keys = pg.key.get_pressed()
player_vx = 0
player_vy = 0
if keys[pg.K_ESCAPE]:
closed = True
if keys[pg.K_LEFT] or keys[pg.K_a]:
player_vx = -player_speed
if keys[pg.K_RIGHT] or keys[pg.K_d]:
player_vx = player_speed
if keys[pg.K_UP] or keys[pg.K_w]:
player_vy = -player_speed
if keys[pg.K_DOWN] or keys[pg.K_s]:
player_vy = player_speed
if player_vx != 0 and player_vy != 0:
player_vx *= 0.7071
player_vy *= 0.7071
# - updates -
check_collision(player, enemy1, enemy2)
# - draws -
game_display.fill(WHITE)
pg.draw.rect(game_display, RED, enemy1)
pg.draw.rect(game_display, RED, enemy2)
pg.draw.rect(game_display, (0, 150, 0), player)
xy_text(game_display, player.x, player.y)
pg.display.update()
clock.tick(FPS)
# - end -
pg.quit()
sys.exit()
将pygame导入为pg
导入系统
从数学进口工厂
#-函数---(小写字母名称)
def检查_碰撞(玩家、enemy1、enemy2):
全球玩家vx,玩家vy
#---X---
player.x+=player_vx*dt
#敌人1
deltay=fabs(player.centery-enemy1.centery)
deltax=fabs(player.centerx-enemy1.centerx)
如果deltay0:
玩家_vx=0
player.x=enemy1.x-player.w
elif播放器_vx<0:
玩家_vx=0
player.x=enemy1.x+player.w
#敌人2
deltay=fabs(player.centery-enemy2.centery)
deltax=fabs(player.centerx-enemy2.centerx)
如果deltay0:
玩家_vx=0
player.x=enemy2.x-player.w
elif播放器_vx<0:
玩家_vx=0
player.x=enemy2.x+player.w
#---Y---
player.y+=player_vy*dt
#敌人1
deltay=fabs(player.centery-enemy1.centery)
deltax=fabs(player.centerx-enemy1.centerx)
如果deltay0:
玩家=0
player.y=enemy1.y-player.h
elif player_vy<0:
玩家=0
player.y=enemy1.y+player.w
#敌人2
deltay=fabs(player.centery-enemy2.centery)
deltax=fabs(player.centerx-enemy2.centerx)
如果deltay0:
玩家=0
player.y=enemy2.y-player.h
elif player_vy<0:
玩家=0
player.y=enemy2.y+player.w
定义xy_文本(屏幕,x,y):
font=pg.font.SysFont(“Courier”,16,True)
text=font.render(“X:+str(圆(X)),True,(0150,0))
屏幕显示(文本,(0,0))
text=font.render(“Y:+str(圆(Y)),True,(0150,0))
屏幕显示(文本,(0,14))
#---常量---(大写字母\名称)
宽度=600
高度=600
白色=(255,255,255)
红色=(255,0,0)
FPS=60
#---主---(小写字母\名称)
玩家速度=200
玩家_vx=0
玩家=0
player=pg.Rect(270,0,30,30)
enemy1=pg.Rect(270,270,30,30)
enemy2=pg.Rect(240,300,30,30)
#-初始化-
第init页()
游戏显示=pg.display.set_模式((宽度、高度))
pg.display.set_标题(“块”)
#-主回路-
时钟=pg.time.clock()
关闭=错误
未关闭时:
dt=时钟滴答声(FPS)/1000
#-事件-
对于pg.event.get()中的事件:
如果event.type==pg.QUIT:
关闭=真
keys=pg.key.get_pressed()
玩家_vx=0
玩家=0
如果钥匙[pg.K_ESCAPE]:
关闭=真
如果键[pg.K_左]或键[pg.K_a]:
玩家_vx=-玩家_速度
如果键[pg.K_RIGHT]或键[pg.K_d]:
玩家_vx=玩家_速度
如果键[pg.K_UP]或键[pg.K_w]:
玩家_vy=-p
from math import fabs
import pygame as pg
pg.init()
width = 600
height = 600
gameDisplay = pg.display.set_mode((width, height))
white = (255, 255, 255)
red = (255, 0, 0)
clock = pg.time.Clock()
closed = False
FPS = 60
Player_Speed = 200
x, y = 270, 0
vx = 0
vy = 0
# Define the font in the global scope.
FONT = pg.font.SysFont("Courier", 16, True)
# Better don't use global variables.
def handle_horizontal_collisions(hero, blocks, x, vx):
"""Sets the player back to the left or right side."""
for block in blocks:
if hero.colliderect(block):
if vx > 0:
hero.right = block.left
elif vx < 0:
hero.left = block.right
return hero.x # Need to update the actual `x` position.
return x
def handle_vertical_collisions(hero, blocks, y, vy):
"""Sets the player back to the top or bottom side."""
for block in blocks:
if hero.colliderect(block):
if vy > 0:
hero.bottom = block.top
elif vy < 0:
hero.top = block.bottom
return hero.y # Need to update the actual `y` position.
return y
def xy_Text(x, y):
text = FONT.render("X: " + str(round(x)), True, (0,150,0))
text1 = FONT.render("Y: " + str(round(y)), True, (0,150,0))
gameDisplay.blit(text, (0,0))
gameDisplay.blit(text1, (0,14))
# Use pygame.Rects for the player and blocks.
player = pg.Rect(x, y, 30, 30)
# Put the blocks into a list.
blocks = []
for rect in (pg.Rect(200, 200, 60, 30), pg.Rect(230, 230, 60, 30)):
blocks.append(rect)
dt = 0
while not closed:
for event in pg.event.get():
if event.type == pg.QUIT:
closed = True
# clock.tick should not be called in the event loop.
vx, vy = 0, 0
# key.get_pressed should also not be in the event loop.
keys = pg.key.get_pressed()
if keys[pg.K_ESCAPE]:
closed = True
if keys[pg.K_LEFT] or keys[pg.K_a]:
vx = -Player_Speed
if keys[pg.K_RIGHT] or keys[pg.K_d]:
vx = Player_Speed
if keys[pg.K_UP] or keys[pg.K_w]:
vy = -Player_Speed
if keys[pg.K_DOWN] or keys[pg.K_s]:
vy = Player_Speed
if vx != 0 and vy != 0:
vx *= 0.7071
vy *= 0.7071
# Game logic.
x += vx * dt
player.x = x
x = handle_horizontal_collisions(player, blocks, x, vx)
y += vy * dt
player.y = y
y = handle_vertical_collisions(player, blocks, y, vy)
# Rendering.
gameDisplay.fill(white)
for block in blocks:
pg.draw.rect(gameDisplay, red, block)
pg.draw.rect(gameDisplay, (0, 150, 0), player)
xy_Text(x, y)
pg.display.update()
dt = clock.tick(FPS)/1000
pg.quit()