使用Snake Game进行奇怪的碰撞检测

时间:2014-01-21 01:45:59

标签: python python-2.7 pygame collision-detection

我遇到了一个我未能找到的奇怪的碰撞检测错误。我正在建造一个小蛇游戏,按照传统,我需要蛇在与自己碰撞时死亡。所以我告诉蛇头如果它与前三个以外的任何部分发生碰撞就会死亡。但即使显然没有发生碰撞,它仍然会引发碰撞..我让代码完全独立于任何想要亲眼看到的人:

import pygame
from pygame.locals import *
from random import randint
pygame.init()
screen=pygame.display.set_mode((320,240))
run=True
prevpos=(0,0)
curid=0
clock=pygame.time.Clock()
points=0
def DrawSeg(x,y,col,size):
    pygame.draw.circle(screen, col, (x,y), size, 0)
class HeadSegment(object):
    def __init__(self,x,y):
        self.x=x
        self.y=y
        self.direct=(0,0)
        self.prevpos=(self.x,self.y)
        self.time=2
        self.rect=pygame.Rect(self.x-5,self.y-5,10,10)
    def update(self):
        global segs
        self.rect=pygame.Rect(self.x-5,self.y-5,10,10)
        self.time-=1
        for s in segs[5:]:
            if self.rect.colliderect(s.rect):
                print 'die'
        if self.time==0:
            self.time=2
            self.prevpos=(self.x,self.y)
        key=pygame.key.get_pressed()
        if key[K_LEFT]:
            if self.direct != (3,0):
                self.direct=(-3,0)
        elif key[K_RIGHT]:
            if self.direct != (-3,0):
                self.direct=(3,0)
        elif key[K_UP]:
            if self.direct != (0,3):
                self.direct=(0,-3)
        elif key[K_DOWN]:
            if self.direct != (0,-3):
                self.direct=(0,3)
        self.x+=self.direct[0]
        self.y+=self.direct[1]
        DrawSeg(self.x,self.y,(255,0,0),5)
head=HeadSegment(20,20)
class Segment(object):
    def __init__(self,x,y):
        global curid
        self.x=x
        self.y=y
        self.direct=(0,0)
        self.id=curid+1
        curid+=1
        self.prevpos=(self.x,self.y)
        self.time=2
        self.rect=pygame.Rect(self.x-5,self.y-5,10,10)
    def update(self):
        self.time-=1
        if self.time==0:
            self.time=2
            self.prevpos=(self.x,self.y)
        global segs
        try:
            nextpos=segs[self.id+1]
            self.x=nextpos.prevpos[0]
            self.y=nextpos.prevpos[1]
        except:
            self.x=head.prevpos[0]
            self.y=head.prevpos[1]
        self.rect=pygame.Rect(self.x-5,self.y-5,10,10)
        DrawSeg(self.x,self.y,(200,0,0),5)
class Fruit(object):
    def __init__(self):
        self.x=randint(7,315)
        self.y=randint(7,235)
        self.rect=pygame.Rect(self.x-6,self.y-6,12,12)
    def update(self):
        global points
        global segs
        DrawSeg(self.x,self.y,(0,0,220),6)
        if self.rect.colliderect(head.rect):
            self.x=randint(7,315)
            self.y=randint(7,235)
            self.rect=pygame.Rect(self.x-6,self.y-6,12,12)
            points+=1
            try:
                segs.append(Segment(segs[len(segs)-1].prevpos[0],segs[len(segs)-1].prevpos[1]))
            except:
                segs.append(Segment(20,20))

segs=[]
fruit=Fruit()
while run:
    screen.fill((0,200,0))
    for s in segs:
        s.update()
    fruit.update()
    head.update()
    for e in pygame.event.get():
        if e.type==QUIT:
            exit()
    clock.tick(60)
    pygame.display.flip()

有人可以指出出了什么问题吗? 检查HeadSegment课程。这就是我认为错误源自的地方。

1 个答案:

答案 0 :(得分:1)

问题,就像我所知道的那样,是你更新分部位置的方式。它现在编码的方式,每个新的段都成为直接位于头部后面的段,而不是“安全”段是跟随头部的段。

实际错误发生在Segment.update函数中:

try:
    nextpos=segs[self.id+1]
    self.x=nextpos.prevpos[0]
    self.y=nextpos.prevpos[1]
except:
    self.x=head.prevpos[0]
    self.y=head.prevpos[1]

我切换了构造函数逻辑,以便curid等于segs列表中Segment的索引,然后使用此代码:

if self.id < 1:
    self.x = head.prevpos[0]
    self.y = head.prevpos[1]
else:
    nextpos = segs[self.id-1]
    self.x = nextpos.prevpos[0]
    self.y = nextpos.prevpos[1]

只有当你遇到更长的蛇时才会发生碰撞。我可以强迫碰撞的最早部分是19。