[英]how do I make triangle collisions with pygame?
I am trying to make a platformer in pygame and I have come across an issue.我正在尝试在 pygame 中制作平台游戏,但遇到了一个问题。 I can easily make collisions for rectangles and squares but I can't do it for right angle triangles.
我可以很容易地对矩形和正方形进行碰撞,但我不能对直角三角形进行碰撞。 Is it possible to even do this using pygame?
甚至可以使用pygame做到这一点吗? I have thought about just removing one of the corners to do it but I am unaware of how to do this and can't find any useful information anywhere.
我曾考虑只移除一个角落来做到这一点,但我不知道如何做到这一点,也无法在任何地方找到任何有用的信息。 one person suggested using smaller rectangular collisions to make the triangles collisions but this didn't give the desired effect.
一个人建议使用较小的矩形碰撞来使三角形碰撞,但这并没有产生预期的效果。 the following code was made by someone else but it is basically the same as mine, the only difference is mine has animations etc and I changed some of the numbers in the jumping physics etc
以下代码是由其他人编写的,但它与我的基本相同,唯一的区别是我的有动画等,我更改了跳跃物理等中的一些数字
#! /usr/bin/python
import pygame
from pygame import *
WIN_WIDTH = 800
WIN_HEIGHT = 640
HALF_WIDTH = int(WIN_WIDTH / 2)
HALF_HEIGHT = int(WIN_HEIGHT / 2)
DISPLAY = (WIN_WIDTH, WIN_HEIGHT)
DEPTH = 32
FLAGS = 0
CAMERA_SLACK = 30
def main():
global cameraX, cameraY
pygame.init()
screen = pygame.display.set_mode(DISPLAY, FLAGS, DEPTH)
pygame.display.set_caption("Use arrows to move!")
timer = pygame.time.Clock()
up = down = left = right = running = False
bg = Surface((32,72))
bg.convert()
bg.fill(Color("#000000"))
entities = pygame.sprite.Group()
player = Player(32, 32)
platforms = []
x = y = 0
level = [
"PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP",
"P P",
"P P",
"P P",
"P PPPPPPPPPPP P",
"P P",
"P P",
"P P",
"P PPPPPPPP P",
"P P",
"P PPPPPPP P",
"P PPPPPP P",
"P P",
"P PPPPPPP P",
"P P",
"P PPPPPP P",
"P P",
"P PPPPPPPPPPP P",
"P P",
"P PPPPPPPPPPP P",
"P P",
"P P",
"P P",
"P P",
"PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP",]
# build the level
for row in level:
for col in row:
if col == "P":
p = Platform(x, y)
platforms.append(p)
entities.add(p)
if col == "E":
e = ExitBlock(x, y)
platforms.append(e)
entities.add(e)
x += 32
y += 32
x = 0
total_level_width = len(level[0])*32
total_level_height = len(level)*32
camera = Camera(complex_camera, total_level_width, total_level_height)
entities.add(player)
while 1:
timer.tick(60)
for e in pygame.event.get():
if e.type == QUIT: raise SystemExit, "QUIT"
if e.type == KEYDOWN and e.key == K_ESCAPE:
raise SystemExit, "ESCAPE"
if e.type == KEYDOWN and e.key == K_UP:
up = True
if e.type == KEYDOWN and e.key == K_DOWN:
down = True
if e.type == KEYDOWN and e.key == K_LEFT:
left = True
if e.type == KEYDOWN and e.key == K_RIGHT:
right = True
if e.type == KEYDOWN and e.key == K_SPACE:
running = True
if e.type == KEYUP and e.key == K_UP:
up = False
if e.type == KEYUP and e.key == K_DOWN:
down = False
if e.type == KEYUP and e.key == K_RIGHT:
right = False
if e.type == KEYUP and e.key == K_LEFT:
left = False
# draw background
for y in range(32):
for x in range(32):
screen.blit(bg, (x * 32, y * 32))
camera.update(player)
# update player, draw everything else
player.update(up, down, left, right, running, platforms)
for e in entities:
screen.blit(e.image, camera.apply(e))
pygame.display.update()
class Camera(object):
def __init__(self, camera_func, width, height):
self.camera_func = camera_func
self.state = Rect(0, 0, width, height)
def apply(self, target):
return target.rect.move(self.state.topleft)
def update(self, target):
self.state = self.camera_func(self.state, target.rect)
def simple_camera(camera, target_rect):
l, t, _, _ = target_rect
_, _, w, h = camera
return Rect(-l+HALF_WIDTH, -t+HALF_HEIGHT, w, h)
def complex_camera(camera, target_rect):
l, t, _, _ = target_rect
_, _, w, h = camera
l, t, _, _ = -l+HALF_WIDTH, -t+HALF_HEIGHT, w, h
l = min(0, l) # stop scrolling at the left edge
l = max(-(camera.width-WIN_WIDTH), l) # stop scrolling at the right edge
t = max(-(camera.height-WIN_HEIGHT), t) # stop scrolling at the bottom
t = min(0, t) # stop scrolling at the top
return Rect(l, t, w, h)
class Entity(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
class Player(Entity):
def __init__(self, x, y):
Entity.__init__(self)
self.xvel = 0
self.yvel = 0
self.onGround = False
self.image = Surface((32,72))
self.image.fill(Color("#0000FF"))
self.image.convert()
self.rect = Rect(x, y, 32, 72)
def update(self, up, down, left, right, running, platforms):
if up:
# only jump if on the ground
if self.onGround: self.yvel -= 10
if down:
pass
if running:
self.xvel = 12
if left:
self.xvel = -8
if right:
self.xvel = 8
if not self.onGround:
# only accelerate with gravity if in the air
self.yvel += 0.3
# max falling speed
if self.yvel > 100: self.yvel = 100
if not(left or right):
self.xvel = 0
# increment in x direction
self.rect.left += self.xvel
# do x-axis collisions
self.collide(self.xvel, 0, platforms)
# increment in y direction
self.rect.top += self.yvel
# assuming we're in the air
self.onGround = False;
# do y-axis collisions
self.collide(0, self.yvel, platforms)
def collide(self, xvel, yvel, platforms):
for p in platforms:
if pygame.sprite.collide_rect(self, p):
if isinstance(p, ExitBlock):
pygame.event.post(pygame.event.Event(QUIT))
if xvel > 0:
self.rect.right = p.rect.left
print "collide right"
if xvel < 0:
self.rect.left = p.rect.right
print "collide left"
if yvel > 0:
self.rect.bottom = p.rect.top
self.onGround = True
self.yvel = 0
if yvel < 0:
self.rect.top = p.rect.bottom
class Platform(Entity):
def __init__(self, x, y):
Entity.__init__(self)
self.image = Surface((32, 32))
self.image.convert()
self.image.fill(Color("#DDDDDD"))
self.rect = Rect(x, y, 32, 32)
def update(self):
pass
class ExitBlock(Platform):
def __init__(self, x, y):
Platform.__init__(self, x, y)
self.image.fill(Color("#0033FF"))
if __name__ == "__main__":
main()
It isn't possible to implement triangle collision with the pygame module methods. 使用pygame模块方法无法实现三角碰撞。 But search about Pylygon module.
但搜索Pylygon模块。
So, if you want to make a triangle collision, you can use this所以,如果你想进行三角形碰撞,你可以使用这个
Require for your triangle to calculate collision:<\/strong>要求您的三角形计算碰撞:<\/strong>
How to calculate the area<\/strong>如何计算面积<\/strong>
self.area = abs((self.points[1][0] - self.points[0][0]) * (self.points[2][1] - self.points[0][1]) - (self.points[2][0] - self.points[0][0]) * (self.points[1][1] - self.points[0][1]))<\/code><\/pre>
Note: this is not really the triangle, it just save a bit of time by not dividing by 2注意:这不是真正的三角形,它只是通过不除以 2 来节省一点时间
How to do the collision<\/strong>碰撞怎么办<\/strong>
def collision(self, pos): area1 = abs((self.points[0][0] - pos[0]) * (self.points[1][1] - pos[1]) - (self.points[1][0] - pos[0]) * (self.points[0][1] - pos[1])) area2 = abs((self.points[1][0] - pos[0]) * (self.points[2][1] - pos[1]) - (self.points[2][0] - pos[0]) * (self.points[1][1] - pos[1])) area3 = abs((self.points[2][0] - pos[0]) * (self.points[0][1] - pos[1]) - (self.points[0][0] - pos[0]) * (self.points[2][1] - pos[1])) areatotal = (area1 + area2 + area3) \/ 2 if areatotal == self.area: return True<\/code><\/pre>
So yeah, this's the tip, if you want to apply more kinds of stuff, check this:所以,是的,这是提示,如果你想应用更多种类的东西,请检查:
http:\/\/www.jeffreythompson.org\/collision-detection\/tri-point.php<\/a>
http:\/\/www.jeffreythompson.org\/collision-detection\/tri-point.php<\/a>
"
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.