Python 简单游戏的碰撞检测/物理

Python 简单游戏的碰撞检测/物理,python,python-3.x,pygame,collision-detection,game-physics,Python,Python 3.x,Pygame,Collision Detection,Game Physics,嗨,我目前正在为班级制作一个小游戏(第一次做这样的事情),我真的不知道如何从碰撞检测开始。好的,我正在创建的游戏是一个自上而下的相扑格斗游戏,在一个冰冷的圆形竞技场上,你四处移动,获得动量和速度,并尝试互相击倒以获得分数。到目前为止,我的运动加速度/摩擦力都很低,我也有一个系统来检测何时发生碰撞,我只是不知道当角色发生碰撞时如何将其推开。我想我将根据攻击者的速度和我将添加的角色的阻力属性来计算击退量/伤害。我还假设我必须用切线之类的东西做一些密集的数学运算才能得到正确的方向,但我根本不知道该怎么

嗨,我目前正在为班级制作一个小游戏(第一次做这样的事情),我真的不知道如何从碰撞检测开始。好的,我正在创建的游戏是一个自上而下的相扑格斗游戏,在一个冰冷的圆形竞技场上,你四处移动,获得动量和速度,并尝试互相击倒以获得分数。到目前为止,我的运动加速度/摩擦力都很低,我也有一个系统来检测何时发生碰撞,我只是不知道当角色发生碰撞时如何将其推开。我想我将根据攻击者的速度和我将添加的角色的阻力属性来计算击退量/伤害。我还假设我必须用切线之类的东西做一些密集的数学运算才能得到正确的方向,但我根本不知道该怎么做。我将非常感谢任何帮助,我对未来的帮助,如果你想在这个项目上帮助我以后通过像不和谐或什么。谢谢你所做的一切

import pygame, sys, time
from pygame.locals import *
import random
import math


#Colors
colorRed=pygame.Color(241,59,62)
colorPurple=pygame.Color(200,254,249)
colorBlue=pygame.Color(52, 207, 235)
colorGreen=pygame.Color(100,182,100)
colorWhite=pygame.Color(255,250,250)
colorBlack=pygame.Color(0,0,0)
colorOrange=pygame.Color(242,164,0)
colorBrown=pygame.Color(148,103,58)

#Dimensions
w=800
h=600
pygame.init()
fpsClock=pygame.time.Clock()
screen=pygame.display.set_mode((w,h))
pygame.display.set_caption ('SUMO')
centerX=w//2
centerY=h//2

#Stage
stageR=250
def stage (centerX,centerY):
    """stage (centerX,centerY) - creates a stage with given centerpoint"""
    pygame.draw.circle(screen, colorBlue, (centerX,centerY),stageR)

#Character 1
xR=int((stageR//10))
x1=int(centerX-(stageR*0.8))
y1=centerY
x1_dir=0
y1_dir=0
def char1 (x1,y1):
    """char1 (x1,y1) - creates char1 at given coordinates"""
    pygame.draw.circle(screen, colorRed, (x1,y1),xR)
print (x1)
print (centerX)

#Character 2
x2=int(centerX+(stageR*0.8))
y2=centerY
x2_dir=0
y2_dir=0
def char2 (x2,y2):
    """char2 (x2,y2) - creates char1 at given coordinates"""
    pygame.draw.circle(screen, colorGreen, (x2,y2),xR)





while True:
    screen.fill(colorBlack)
    for event in pygame.event.get():
        #Game Exit
        if event.type== QUIT:
            pygame.quit()
            sys.exit()

    distance=math.hypot(x1-x2,y1-y2)
    if distance <= 2*xR:
        print ("HIT")

    keys = pygame.key.get_pressed()

    if keys[K_d] or keys[K_a]:
        x1_dir += 0.1 if keys[K_d] else -0.1
    else:
        x1_dir *= 0.98

    if keys[K_w] or keys[K_s]:
        y1_dir += 0.1 if keys[K_s] else -0.1
    else:
        y1_dir *= 0.98

# -------------------- CHAR2 MOVEMENT --------------------

    if keys[K_RIGHT] or keys[K_LEFT]:
        x2_dir += 0.1 if keys[K_RIGHT] else -0.1
    else:
        x2_dir *= 0.98

    if keys[K_UP] or keys[K_DOWN]:
        y2_dir += 0.1 if keys[K_DOWN] else -0.1
    else:
        y2_dir *= 0.98


    stage (centerX,centerY)
    char1 (round(x1),round(y1))
    char2 (round(x2),round(y2))
    x1+=x1_dir
    y1+=y1_dir
    x2+=x2_dir
    y2+=y2_dir
    pygame.display.update()
    fpsClock.tick(60)
import pygame,sys,time
从pygame.locals导入*
随机输入
输入数学
#颜色
colorRed=pygame.Color(241,59,62)
colorPurple=pygame.Color(200254249)
colorBlue=pygame.Color(52207235)
colorGreen=pygame.Color(100182100)
colorWhite=pygame.Color(255250250)
colorBlack=pygame.Color(0,0,0)
colorOrange=pygame.Color(242164,0)
colorBrown=pygame.Color(148103,58)
#尺寸
w=800
h=600
pygame.init()
fpscall=pygame.time.Clock()
screen=pygame.display.set_模式((w,h))
pygame.display.set_标题('SUMO')
centerX=w//2
centerY=h//2
#舞台
stageR=250
def阶段(centerX、centerY):
“”“舞台(centerX、centerY)-创建具有给定中心点的舞台”“”
pygame.draw.circle(屏幕,彩色蓝色,(centerX,centerY),stageR)
#字符1
xR=int((stageR//10))
x1=int(中心X-(阶段*0.8))
y1=中心Y
x1_dir=0
y1_dir=0
def char1(x1,y1):
“”“char1(x1,y1)-在给定坐标处创建char1”“”
pygame.draw.circle(屏幕,红色,(x1,y1),xR)
打印(x1)
打印(centerX)
#字符2
x2=int(centerX+(stageR*0.8))
y2=中心
x2_dir=0
y2_dir=0
def char2(x2,y2):
“”“char2(x2,y2)-在给定坐标处创建char1”“”
pygame.draw.circle(屏幕,绿色,(x2,y2),xR)
尽管如此:
屏幕填充(彩色黑色)
对于pygame.event.get()中的事件:
#游戏出口
如果event.type==退出:
pygame.quit()
sys.exit()
距离=数学正压(x1-x2,y1-y2)

如果距离,则必须反映物体撞击时的运动矢量(
x1_-dir
y1_-dir
)和(
x2_-dir
y2_-dir
)。 对于给定的入射矢量
I
和表面法线
N
,反射方向计算为
I-2.0*点(N,I)*N

法向量是物体撞击时从一个中心点到另一个中心点的距离, 检测命中并规范化中心点之间的向量(将向量除以距离
):

nv=[x1-x2,y1-y2]
距离=数学海波(nv[0],nv[1])
如果距离为0:
rd2.缩放到长度(len1)
x2_dir,y2_dir=rd2.x,rd2.y
其他:
x2_-dir,y2_-dir=-x1_-dir,-y1_-dir


由于无法准确检测“命中”,因此当播放机之间的距离为
2*xR
时,有必要纠正播放机的位置,并在距离为
2*xR
时找到点:

v12=pygame.math.Vector2(x1-x2,y1-y2)
距离=v12.length()
点击距离=2*xR
如果距离为0,则为d1
如果d2l>0,则d2n=d2/d2l,否则d2
x1-=d1n.x*d1l/(d1l+d2l)
y1-=d1n.y*d1l/(d1l+d2l)
x2-=d2n.x*d2l/(d1l+d2l)
y2-=d2n.y*d2l/(d1l+d2l)
#重新计算中心点之间的矢量
v12=pygame.math.Vector2(x1-x2,y1-y2)
nv=v12.normalize()
#反射运动矢量
rd1=d1.反射(nv)
rd2=d2.反射(nv)
len1,len2=rd1.length(),rd2.length()
如果len1>0:
rd1=rd1*len2/len1
x1_dir,y1_dir=rd1.x,rd1.y
其他:
x1_dir,y1_dir=-x2_dir,-y2_dir
如果len2>0:
rd2=rd2*len1/len2
x2_dir,y2_dir=rd2.x,rd2.y
其他:
x2_-dir,y2_-dir=-x1_-dir,-y1_-dir

pygame.Rect()
colliderect()
所以你可以做
player.Rect.colliderect(敌方.Rect)
pygame.Sprite
甚至有
Collide Circle
(x1-x2)/(y1-y2)或
(y1-y2)/(x1-x2)
在玩家之间提供
切线(alpha)
,所以你可以在碰撞后使用这个角度来获得新的方向。,另请参阅类似的门户网站问题是否已解决?抱歉,我忙了几天,感谢您的回复我只是有点困惑,我不太擅长这一点,所以这看起来非常困惑,还不完全确定这是如何工作的,嗯,我假设最后一段代码就是我使用的,但我遇到了类似ddn=dd.normalize()的错误ValueError:无法规范化长度为Zerouhm的向量它表示返回超出函数范围对不起,你是什么意思?答案在哪里?我试着用你发给我的东西。我用的是经过编辑的,上面写着“返回不在功能范围内”嘿@rabbi76 yo-uhm它对你有用吗?我只是试了一下,两个圆圈仍然彼此相通,没有交互作用