[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[pygame] Collision Detection -- Part 2



Hi all,
 
I don't know exactly what i am doing wrong but my sprites seem to get stuck in the walls with my current wall-collison-detection.
 
I thought I'd check the left/right/top/bottom of the hitbox-rect and check if the're within the boundaries of the window, with a margin of 5. but somehow they always end up stuck in the walls.
 
I hope you can take a look at the source which I attached to this messgae and tell me what i am doing so terribly wrong :)
 
thank you,
 
Guyon
"""
BattleBots

Author			:	Guyon Morée <gumuz@looze.net>
Created			:	30 jan 2003 
Filename		:	BaseBot.py

Description		:	Base class for a bot

"""

# Standard library imports
import pygame, os, random, time, math
from pygame.locals import *


class BaseBot(pygame.sprite.Sprite):
    def __init__(self, parentGame):
        pygame.sprite.Sprite.__init__(self)
        self.parentGame = parentGame
        self.hitBox = pygame.Rect(0,0,30,30)
    
    def wallColide(self):
        self.hitBox.center = self.rect.center
        if self.hitBox.left < 5 or self.hitBox > 635 or self.hitBox.top < 5 or self.hitBox.bottom > 475:
            return 1

    def botCollide(self): pass

    def generate_rotations(self, image, numSteps=5):
        self.Rotates = []
        self.numSteps = numSteps
        for angle in range(0, 360, numSteps):
            rot = pygame.transform.rotate(image, angle)
            self.Rotates.append(rot)
        self.Angle = random.choice(range(355))
        self.image = self.Rotates[0]
        self.rect = self.image.get_rect()
        self.rect.midtop = (250,250)
        self.hitBox = pygame.Rect(0,0,30,30)


    def loadImage(self, name):
    	try:
            fullname = os.path.join('data', name)
            image = pygame.image.load(fullname)
            image = image.convert()
            colorkey = image.get_at((0,0))
            image.set_colorkey(colorkey, RLEACCEL)
            self.generate_rotations(image, 5)
        except pygame.error, message:
            print 'Cannot load image:', fullname
            raise SystemExit, message
     
    def updateRotation(self):
        oldCenter = self.rect.center
        Pick = (self.Angle % 360) / self.numSteps
        newRect = self.Rotates[Pick].get_rect()
        newRect.center = oldCenter
        if self.wallColide():
                self.onHitWall()
                self.rect.center = oldCenter
                return
        else:
            self.image = self.Rotates[Pick]
            self.rect = newRect

    def Run(self): pass
    
    def Rotate(self, Degrees):
        Max = self.Angle+Degrees
        if Max > self.Angle:
            while self.Angle < Max:
                time.sleep(0.001)
                self.Angle += 2
                self.updateRotation()
                self.update()
        else:
            while self.Angle > Max:
                time.sleep(0.001)
                self.Angle += -2
                self.updateRotation()
                self.update()
    
    def Drive(self, Distance):
        Angle = (self.Angle % 360)
        Angle = Angle / (360 / (2 * math.pi))
        Steps = 1
        while abs(Distance) > Steps:
            time.sleep(0.05)
            if Distance < 0:
                newStep = Steps*-1
            else:
                newStep = Steps
            newX = newStep * math.sin(Angle) + self.rect.center[0]
            newY = newStep * math.cos(Angle) + self.rect.center[1]
            newRect = self.rect
            newRect.center = (newX, newY)
            oldCenter = self.rect.center
            self.rect = newRect
            if self.wallColide():
                self.onHitWall()
                self.rect.center = oldCenter
                return
            else:
                self.update()
                Steps += 1

    def update(self): 
        self.hitBox.center = self.rect.center
        blitBox = pygame.Surface((30,30))
        blitBox.fill((255,255,255))
        self.parentGame.Arena.blit(blitBox, self.hitBox.topleft)

    def onHitWall(self): pass
    
    def onHitBot(self): pass
"""
BattleBots

Author			:	Guyon Morée <gumuz@looze.net>
Created			:	30 jan 2003 
Filename		:	BattleBots.py

Description		:	A fresh new attempt to making a Python BattleBot Arena.

"""

# Standard library imports
import pygame, os, thread, sys
from pygame.locals import *

# Custom library imports
import BaseBot

class MainGame:
    def __init__(self, arenaSize=(640,480)):
        pygame.init()
        self.Arena = pygame.display.set_mode(arenaSize, HWSURFACE|DOUBLEBUF)
        
        pygame.display.set_caption('BattleBots Arena')
        pygame.mouse.set_visible(1)

        self.setBackground((0, 0, 0), "# BattleBots Arena #")

        self.loadBots()

        self.Clock = pygame.time.Clock()
   
    def setBackground(self, Color, Text):
        self.Background = pygame.Surface(self.Arena.get_size())
        self.Background = self.Background.convert()
        self.Background.fill(Color)

        self.fieldRect = self.Arena.get_rect()

        Text = pygame.font.Font('impact.ttf', 36).render(Text, 1, (255, 255, 255))
        Textpos = Text.get_rect()
        Textpos.centerx = self.Background.get_rect().centerx
        
        self.Background.blit(Text, Textpos)
        self.Arena.blit(self.Background, (0, 0))        
        pygame.display.flip()


    def startGame(self):
        for Bot in self.Bots:
            thread.start_new_thread(Bot.Run, ())
        
        while 1:
            self.Clock.tick(60)
            for event in pygame.event.get():
                if event.type == QUIT:
                    print "out!"
                    sys.exit()                   
        
            self.Arena.blit(self.Background, (0, 0))
            self.allSprites.draw(self.Arena)
            pygame.display.flip()
    
    def loadBots(self):
        self.Bots = []
        for File in os.listdir(os.path.join('bots')):
            if File[-3:] == '.py' and File <> '__init__.py': 
                exec "import bots." + File[:-3]
                botName = eval('bots.'+File[:-3]+'.className')
                botImg = eval('bots.'+File[:-3]+'.botImage')
                print botName
                newBot = eval('bots.'+File[:-3]+'.'+botName+'(self)')
                newBot.loadImage(botImg)
                self.Bots.append(newBot)
            
        self.allSprites = pygame.sprite.RenderPlain(tuple(self.Bots))
    	
    	
	

if __name__ == '__main__':
    newGame = MainGame()
    newGame.startGame()
"""
battleBots

Author			:	Guyon Morée <gumuz@looze.net>
Created			:	23 October
Filename		:	baseBot.py

Description		:	My second battle bot

"""

from BaseBot import *

className = "testBot"
botImage  = "guyonbot.bmp"

class testBot(BaseBot):
    def Run (self):    	
        print "start thread"
        while 1:
            self.Drive(20)
            self.Rotate(80)

    def onHitWall(self): pass#print "test hit a wall"
    
    def onHitBot(self): pass