• Advertisement
Sign in to follow this  

Scrolling and Obstacle Detection [PYTHON/PYGAME]

This topic is 2989 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

What I'm trying to do is implement scrolling into my top-view game. I would like the player to stay in the middle of the screen until they reach the out boundaries. Once the screen has hit the boundary the play is free to move to the outer boundary, then when they return to the middle, the screen will continue to scroll. PROBLEMS:::::: (1) The scrolling appears to be working until I reach a boundary, once this happens the player cannot go past the center of the screen, and the screen does not scroll anymore. (2) The collisions between the player and the walls are being detected, but unless the wall s part of the outer boundary, the player walks through the wall. (3) The scrolling doesn't seem consistent. Sometimes it works, sometimes my player flies across the screen really fast. THANK YOU in advance for any help or suggestions. The entire game folder (.zip file) can be downloaded here: http://trovna.googlecode.com/files/Game%28fixing%20scrolling%29.zip But I think that the following parts of my code are all that you will need to help me. Game.py:::
######initializing global variables########
movecount = 0
map1 = Map.Map()
charImages = ImagePaths.CharImagePaths(movecount)
last_key_pressed = "DOWN"



#######initialize pygame#######
pygame.init()



#D - Display configuration
resolution = (800,600)
screen = pygame.display.set_mode(resolution)





######main game loop#######
def main():
#E - Entities (things moving about on screen)
    pygame.display.set_caption("THE GAME")

    background = pygame.Surface(screen.get_size())
    background.fill((50,255,50)) # what color the background is in RGB
    screen.blit(background, (0, 0))
    framecount = 0
    last_key_pressed = "DOWN"

    # Assign sprite classes and other classes to variables
    info = HUDs.HUD()
    info.center = (100, 50)
    char = CharacterSprites.Char(movecount, charImages, map1)
    wiz = EnemySprites.Wiz(screen)
    wiz1 = EnemySprites.Wiz(screen)
    wiz2 = EnemySprites.Wiz(screen)
    gold = ItemSprites.Gold()
    gold1 = ItemSprites.Gold()
    gold2 = ItemSprites.Gold()
    cache = ImageCache.ImageCache()
    map1.load('Map/map.txt')

    #A - Action (broken into ALTER steps)

      #A Assign values to key variables
    goodSprites = pygame.sprite.Group(char)
    itemSprites = pygame.sprite.Group(gold, gold1, gold2)
    badSprites = pygame.sprite.Group(wiz, wiz1, wiz2)
    infoSprites = pygame.sprite.Group(info)
    
    clock = pygame.time.Clock() #initializing the clock
    
    keepGoing = True #initialally we want to Keep Going

        # Main caption
    pygame.display.set_caption("THE GAME")


    #L - Set up main loop
    while keepGoing:
        
        #T - Timer to set frame rate
        clock.tick(30) #setting frame rate number = fps
        #UPDATE = pygame.USEREVENT
        #pygame.time.set_timer(UPDATE, int(1000.0/30))
        
        
        #for animation######
        framecount += 1 
        framecount = framecount % 4 #lower the number to speed up animation
        #The aboove code is for animation

        #pygame.mouse.set_visible(True)

        #E - Event handling
        
        #saving the old position, before we change it, just incase we hit a wall.
        char.old_x = char.rect.centerx
        char.old_y = char.rect.centery
        map1.old_vp_x = map1.vpCoordinate_x
        map1.old_vp_y = map1.vpCoordinate_y
        # The above is for wall collisions
        
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                keepGoing = False
        
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_LEFT:
                    if char.rect.centerx == char.start_x:
                        map1.advanceVelocity_x += -char.speed
                        map1.vpCoordinate_x += map1.advanceVelocity_x
                    last_key_pressed = "LEFT"
                elif event.key == pygame.K_RIGHT:
                    if char.rect.centerx == char.start_x:
                        map1.advanceVelocity_x += char.speed
                        map1.vpCoordinate_x += map1.advanceVelocity_x
                    last_key_pressed = "RIGHT"
                elif event.key == pygame.K_UP:
                    if char.rect.centery == char.start_y:
                        map1.advanceVelocity_y += -char.speed
                        map1.vpCoordinate_y += map1.advanceVelocity_y
                    last_key_pressed = "UP"
                elif event.key == pygame.K_DOWN:
                    if char.rect.centery == char.start_y:
                        map1.advanceVelocity_y += char.speed
                        map1.vpCoordinate_y += map1.advanceVelocity_y
                    last_key_pressed = "DOWN"
     
                elif event.key == pygame.K_ESCAPE:
                    pygame.event.post(pygame.event.Event(pygame.QUIT, {}))
     
            elif event.type == pygame.KEYUP:
                if event.key == pygame.K_LEFT:
                    map1.advanceVelocity_x += char.speed
                    #char.rect.centerx += char.speed
                elif event.key == pygame.K_RIGHT:
                    map1.advanceVelocity_x += -char.speed
                    #char.rect.centerx -= char.speed
                elif event.key == pygame.K_UP:
                    map1.advanceVelocity_y += char.speed
                    #char.rect.centery += char.speed
                elif event.key == pygame.K_DOWN:
                    map1.advanceVelocity_y += -char.speed
                    #char.rect.centery -= char.speed
     
            #map1.vpCoordinate_x += map1.advanceVelocity_x
            #map1.vpCoordinate_y += map1.advanceVelocity_y
            if map1.vpCoordinate_x < map1.minHorzScrollBounds:
                map1.vpCoordinate_x = map1.minHorzScrollBounds
                print "minHorz"
            if map1.vpCoordinate_x > map1.maxHorzScrollBounds:
                map1.vpCoordinate_x = map1.maxHorzScrollBounds
                print "maxHorz"
            if map1.vpCoordinate_y < map1.minVertScrollBounds:
                map1.vpCoordinate_y = map1.minVertScrollBounds
                print "minVert"
            if map1.vpCoordinate_y > map1.maxVertScrollBounds:
                map1.vpCoordinate_y = map1.maxVertScrollBounds
                print "maxVert"

            if last_key_pressed == "LEFT":
                if map1.vpCoordinate_x == map1.minHorzScrollBounds:
                    char.rect.centerx -= char.speed
                if map1.vpCoordinate_x == map1.maxHorzScrollBounds:
                    if char.rect.centerx > char.start_x:
                        char.rect.centerx -= char.speed
                        
                
            if last_key_pressed == "RIGHT":
                if map1.vpCoordinate_x == map1.maxHorzScrollBounds:
                    char.rect.centerx += char.speed
                if map1.vpCoordinate_x == map1.minHorzScrollBounds:
                    if char.rect.centerx < char.start_x:
                        char.rect.centerx += char.speed    

                    
            if last_key_pressed == "UP":
                if map1.vpCoordinate_y == map1.minVertScrollBounds:
                    char.rect.centery -= char.speed
                if map1.vpCoordinate_y == map1.maxVertScrollBounds:
                    if char.start_y < char.rect.centery:
                        char.rect.centery -= char.speed
                        
                    
            if last_key_pressed == "DOWN":
                if map1.vpCoordinate_y == map1.maxVertScrollBounds:
                    char.rect.centery += char.speed
                if map1.vpCoordinate_y == map1.minVertScrollBounds:
                    if char.start_y > char.rect.centery:
                        char.rect.centery += char.speed
                     

            #######directional controls
            

            #This is for the character animation
            #When we switch directions we switch which pictures are animated
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT or event.key == pygame.K_DOWN or event.key == pygame.K_UP:    
                    if framecount == 0:
                        if last_key_pressed == "UP": 
                            char.movecount += 1
                            char.movecount = char.movecount % len(charImages.character_array_back)
                            char.image = pygame.image.load(charImages.character_array_back[char.movecount])
                        elif last_key_pressed == "DOWN": 
                            char.movecount += 1
                            char.movecount = char.movecount % len(charImages.character_array_front)
                            char.image = pygame.image.load(charImages.character_array_front[char.movecount])
                        elif last_key_pressed == "LEFT": 
                            char.movecount += 1
                            char.movecount = char.movecount % len(charImages.character_array_left)
                            char.image = pygame.image.load(charImages.character_array_left[char.movecount])
                        elif last_key_pressed == "RIGHT": 
                            char.movecount += 1
                            char.movecount = char.movecount % len(charImages.character_array_right)
                            char.image = pygame.image.load(charImages.character_array_right[char.movecount])
 
        ######Check for sprites colliding with other sprites######
        hitItem = pygame.sprite.spritecollide(char, itemSprites, False)
        if hitItem:
            for theItem in hitItem:
                theItem.reset() #resets location
                info.gold += 1 #adds one to gold

        hitBad = pygame.sprite.spritecollide(char, badSprites, False)
        if hitBad:
            for theBad in hitBad:
                char.reset()#resets location
                info.life -= 1# ads one to kills
                if info.life <= 0:
                    keepGoing = False





                    
        
        #R - Refresh display "blit" means printing an image

        ###Clear old sprite groups
        goodSprites.clear(screen, background)
        itemSprites.clear(screen, background)
        badSprites.clear(screen, background)
        infoSprites.clear(screen, background)

        ###Update the sprite group positions, etc.
        goodSprites.update(last_key_pressed)
        itemSprites.update()
        badSprites.update()
        infoSprites.update()

        ###Draw new sprite groups
        map1.startXTile = int(math.floor(float(map1.vpCoordinate_x) / map1.tilewidth))
        map1.startYTile = int(math.floor(float(map1.vpCoordinate_y) / map1.tileheight))

        #print "tile width = " + str(map1.tilewidth)
        #print "tile height = " + str(map1.tileheight)
              
        
        map1.draw(screen)
        goodSprites.draw(screen)
        itemSprites.draw(screen)
        badSprites.draw(screen)
        infoSprites.draw(screen)

        #print "length of map1.tiles:"+str(len(map1.tiles))
        #print "length of map1.tiles[0]:"+str(len(map1.tiles[0]))
        #print "length of map1.images:"+str(len(map1.images))

        #print "map1.startXTile = " + str(map1.startXTile)
        #print "map1.startYTile = " + str(map1.startYTile)

        #print "map1.numXTiles = " + str(map1.numXTiles)
        #print "map1.numYTiles = " + str(map1.numYTiles)
        if (char.rect.centerx != char.old_x) or (char.rect.centery != char.old_y):
            print "Character Position: (" + str(char.rect.centerx) + ", " + str(char.rect.centery) + ")"

        ####Switch the screen to the new information
        pygame.display.flip()
            
# End main game loop
if __name__ == "__main__":
    main()


Map.py:::
import pygame, math, ImageCache

class Map:
    def __init__(self):
	self.tiles = []
	self.images = []
	self.collision = []	
	self.tilewidth = 0
	self.tileheight = 0
	self.shift_wall_x = 0
        self.shift_wall_y = 0
	
    def load(self, map_file):
	cache = ImageCache.ImageCache()
	self.images.append(cache.getImage('Images/Scenery/ocean.png'))
	self.images.append(cache.getImage('Images/Scenery/pathway.png'))
	self.images.append(cache.getImage('Images/Scenery/brick.png'))

		
	self.tilewidth = self.images[0].get_width()
	self.tileheight = self.images[0].get_height()
		
	for line in open(map_file, 'r'):
	    characters = line.strip().split(',')
		
	    if len(characters) > 0:
                self.tiles.append([])
                self.collision.append([])
			
		# Run through all the tile characters
		for character in characters:
		    if character == 'OCN':
			# [-1] means: the last element of
			# I'm pushing 0 here, because 'red' is the 0th element in self.images
			self.tiles[-1].append(0)
			self.collision[-1].append(True)
		    elif character == 'PTH':
			self.tiles[-1].append(1)
			self.collision[-1].append(False)
		    elif character == 'BRK':
			self.tiles[-1].append(2)
			self.collision[-1].append(True)
		    else:
			# Right now this makes each row one tile shorter, because
			# we're not storing any data for this tile.
			print 'Wrong tile: [' + character + ']'

            self.vpRenderOffset = (0,0)
            self.vpStatsOffset_x = (80,540)
            self.vpStatsOffset_y = (80, 555)
             
            self.vpCoordinate_x = 0
            self.vpCoordinate_y = 0
            self.vpDimensions = (800, 600)

            self.minHorzScrollBounds = 0
            self.maxHorzScrollBounds = 400
            self.minVertScrollBounds = 0
            self.maxVertScrollBounds = 400

            self.advanceVelocity_x = 0
            self.advanceVelocity_y = 0
             
            self.numXTiles = int(math.ceil(float(self.vpDimensions[0]) / self.tilewidth)) + 1
            self.numYTiles = int(math.ceil(float(self.vpDimensions[1]) / self.tileheight)) + 1
            self.tiledBG = pygame.Surface((self.numXTiles * self.tilewidth, self.numYTiles * self.tileheight)).convert()
            self.wallsBG = pygame.Surface((self.numXTiles * self.tilewidth, self.numYTiles * self.tileheight)).convert()




            
    def draw(self,screen):
        for x in range(self.startXTile, self.startXTile + self.numXTiles):
            for y in range(self.startYTile, self.startYTile + self.numYTiles):
                #print map1.images[map1.tiles[y][x]]
            
                self.tiledBG.blit(self.images[self.tiles[y][x]], ((x - self.startXTile) * self.tilewidth, (y - self.startYTile) * self.tileheight))
        screen.blit(self.tiledBG, self.vpRenderOffset, (self.vpCoordinate_x - (self.startXTile * self.tilewidth), (self.vpCoordinate_y - (self.startYTile * self.tileheight))) + self.vpDimensions)
      

CharacterSprites.py:::
import pygame, math
from Images import ImagePaths
from Map import Map, ImageCache

class Char(pygame.sprite.Sprite):
    def __init__(self, movecount, charImages, map1):
        pygame.sprite.Sprite.__init__(self)

        self.map1 = map1
        self.movecount = movecount
        self.image = charImages.character_front_image
        self.image = self.image.convert()
        self.rect = self.image.get_rect()

        # Transparent
        self.colorkey = self.image.get_at((0, 0))
        self.image.set_colorkey(self.colorkey)
        # end transparent

        self.rect.centerx = 400
        self.rect.centery = 300
        self.speed = 7

        self.old_x = self.rect.centerx
        self.old_y = self.rect.centery

        self.start_x = self.rect.centerx
        self.start_y = self.rect.centery
         
    def reset(self):

        self.rect.centerx = 400
        self.rect.centery = 300

    def update(self, last_key_pressed):    
     # Put the player in the new spot
        
        self.rect.center = (self.rect.centerx, self.rect.centery)

        self.last_key_pressed = last_key_pressed

        cal_x = 0
        cal_y = 0
        
        if self.last_key_pressed == "LEFT":
            cal_x = -10
            cal_y = 0
        if self.last_key_pressed == "RIGHT":
            cal_x = 5
            cal_y = 0
        if self.last_key_pressed == "UP":
            cal_x = 0
            cal_y = -11
        if self.last_key_pressed == "DOWN":
            cal_x = 0
            cal_y = 10
        else:
            pass



        

        
        #######%$$*^%^&*%^$#%^#&%$*&%
        #Did we hit a wall???????????
        #######$#$%^#^%#$^%#^%$#%$#%$

        if self.map1.old_vp_x != self.map1.vpCoordinate_x or self.map1.old_vp_y != self.map1.vpCoordinate_y:
            print "vpCoordinates = (" + str(self.map1.vpCoordinate_x) + ", " + str(self.map1.vpCoordinate_y) +")"
            if self.last_key_pressed == "UP" or self.last_key_pressed == "DOWN":
                self.map1.shift_wall_y = int(math.ceil((self.map1.vpCoordinate_y)/40))
            if self.last_key_pressed == "RIGHT" or self.last_key_pressed == "LEFT":
                self.map1.shift_wall_x = int(math.ceil((self.map1.vpCoordinate_x)/40))
            print "map1.shift_wall = (" + str(self.map1.shift_wall_x) + ", " + str(self.map1.shift_wall_y) + ")"  
        
        if self.map1.collision[self.map1.shift_wall_y + int(math.ceil((self.rect.centery)/40))][self.map1.shift_wall_x + int(math.ceil((self.rect.centerx)/40))] == True:
            print "shift_wall = (" + str(self.map1.shift_wall_x) + ", " + str(self.map1.shift_wall_x) + ")"
            print "[y][x] = [" + str(int(math.floor((self.rect.centery+cal_y)/40))) + "][" + str(int(math.ceil((self.rect.centerx+cal_x)/40))) + "]" 
            self.rect.center = (self.old_x, self.old_y)
            
        else:
            #Didn't hit a wall
            self.old_x = self.rect.centerx
            self.old_y = self.rect.centery


Thanks again. Dusty

Share this post


Link to post
Share on other sites
Advertisement
You probably need a locked frame rate for your code to be consistent as far as moving the character.

Unless you change your moving to go by velocity, then you can define a character moves X ammount of pixels per Y amount of milliseconds.

If you set it up that way no matter what frame rate your game is running at you character will still move at a consistent speed.


And here why are you dividing by 40? wouldn't you just want to move the character back 1 space if he hits a wall?

if self.last_key_pressed == "UP" or self.last_key_pressed == "DOWN":
self.map1.shift_wall_y = int(math.ceil((self.map1.vpCoordinate_y)/40))
if self.last_key_pressed == "RIGHT" or self.last_key_pressed == "LEFT":
self.map1.shift_wall_x = int(math.ceil((self.map1.vpCoordinate_x)/40))




Edit: I should mention that I know nothing of python so take this with a grain of salt =p

Share this post


Link to post
Share on other sites
The reason why I divided by 40 is because I wanted to find tile position, and since my tiles are 40X40 I needed to take the position and divide it by 40 and then round it to an integer. I should have divided the the x by my tile width and the y by my tile length to make my code more universal. Discussing this made me think of something else, that is probably wrong in my code. Thanks.

I changed the following piece of code from my Game.py file


map1.advanceVelocity_y += char.speed
map1.vpCoordinate_y += map1.advanceVelocity_y


to this:


map1.advanceVelocity_y = char.speed
map1.vpCoordinate_y += map1.advanceVelocity_y



I was unknowingly incrementing my scrolling twice for every 1 character move.

The scrolling appears to be working now, but I am still having trouble with the walls. Thanks again.

Dusty


Dusty

[Edited by - dustfilledhobo on December 5, 2009 10:38:14 AM]

Share this post


Link to post
Share on other sites
I fixed my walls by adding the last two lines of the following code to my CharacterSprites.py file:


if self.map1.collision[self.map1.shift_wall_y + int(math.ceil((self.rect.centery)/40))][self.map1.shift_wall_x + int(math.ceil((self.rect.centerx)/40))] == True:
print "shift_wall = (" + str(self.map1.shift_wall_x) + ", " + str(self.map1.shift_wall_x) + ")"
print "[y][x] = [" + str(int(math.floor((self.rect.centery+cal_y)/40))) + "][" + str(int(math.ceil((self.rect.centerx+cal_x)/40))) + "]"
self.rect.center = (self.old_x, self.old_y)
self.map1.vpCoordinate_x = self.map1.old_vp_x
self.map1.vpCoordinate_y = self.map1.old_vp_y



I was binding my character's position when he encountered a wall (which was already bound to the center of the screen), but I was not binding the scrolling, so he scrolled right over the walls. Thanks.

Dusty

Share this post


Link to post
Share on other sites
Here I am again. ;) I took a look at your code, and here's some comments. Enjoy. :)

- You're still mixing tabs and spaces. Take a look at the following article, specifically the part about spaces and tabs: PEP 8 - style Guide for Python Code. Granted, it's a style guide, but it's a good read nonetheless. :) Either way, since you're mixing those, and since you seem to be using a different tab size than me (I'm using 4, you're using 8?), it's pretty hard to identify scope - and therefore it's hard to determine how your code actually runs.

- After figuring out the above, I found out that your Map.load() function runs a bunch of code for every line found in the map file - lines 48 - 67. That code only needs to be executed once. Also, those variables are better stored in the map file itself, for more flexibility. Currently every map is limited to having the same size.

- Your input handling and player movement code is kinda messy. There's a little bit of everything all over the place. Have you considered simplifying it to something like this:
class Character:
def __init__(self, ... ):
self.moveNorth = False
self.moveSouth = False
# east, west, and the rest of the initialization

def update(self, delta):
if self.moveNorth:
self.position.y -= self.speed * delta
if self.moveSouth:
self.position.y += self.speed * delta
# and the same for east and west.
# NOTE: no elif! This makes it possible to press the up and down keys
# at the same time - this stops movement - and once one of the keys is
# released, the player will continue to move in the direction of the key
# that is still held down.
# All that's left is setting moveNorth to True when the up key is pressed,
# and setting it to False when that key is released. Same goes for the
# other keys.


One of the things that will be fixed is the choppy movement. The player now keeps moving while a key is held down, instead of only moving a bit when a key is pressed or when some other event happens (because you're only changing the player position inside your event handling code). Event handling should at most set some flags, change some data. Updating the game logic should do the actual work of reacting to those changes.

- Pass the map rendering offset to the draw function for more control. No member variable that needs to be kept in sync. In fact, do this for all draw functions - this allows you to use a single camera variable. Don't mix this with player position (due to map boundaries but also because you shouldn't mix responsibilities). A camera is a separate thing, even though it might follow the player most of the time.

Personally, I would dump the use of sprite groups. Draw order is not defined, you can't pass a drawing offset... I just think they're not very practical.

- Don't divide by '40'. Magic numbers are bad, because it's not clear what they mean, and when that something changes, the magic numbers don't change along with it. Instead, divide by map.tilewidth or map.tileheight, whatever you needed at that point. Use the actual variables that hold the values you need, don't sprinkle numbers throughout your code like that.

- I would place map collision detection inside the Map class - simply because it's likely that other kind of objects will need to check for collisions also, and you don't want to duplicate such code. Duplicated code is harder to maintain (it's easy to fix something in one place and to forget about the other places...).

- Checking tile collision values alone works fine for games that allow per-tile movement, but your characters move with a finer granularity. Doing an array lookup like this is still useful for determining what tiles you need to look at, but once that's done, I would use a rectangle-rectangle collision check to see if the character is running into a wall. If so, check how far the rectangle sticks into the wall, and only allow it to move up to that point.


Well, I hope all of that was useful to you, even though it doesn't point out any direct problems with the collision code (it's late here, no interest in digging up off-by-one errors and all that). ;)


EDIT: Ugh, I suppose I should bundle all these posts into a tutorial of sorts...

Share this post


Link to post
Share on other sites
Captain P, thanks again for analyzing my code. I haven't had a chance to try any of your suggestions yet, but I have read through them and they make sense (I'm sure I'll have questions later). In a previous post you mentioned that there are advanced editors that allow you too see whitespace characters, which program do you recommend? I am running Mac OS X 10.5 (if that makes a difference). Thanks again.

Dusty

Share this post


Link to post
Share on other sites
Captain P,

If I understood your previous post correctly, you stated that I needed to make a camera variable that is not tied to the player's movement. The only way I can think of using a camera variable would be to tie it to the player's movement. Could you please elaborate on this suggestion a little more (it seems like it won't be that hard, but I can't think how to do it). Also, I am currently in the process and everything you have suggested is working great, thanks again.

Dusty

Share this post


Link to post
Share on other sites
Quote:
Original post by dustfilledhobo
In a previous post you mentioned that there are advanced editors that allow you too see whitespace characters, which program do you recommend? I am running Mac OS X 10.5 (if that makes a difference).

Alas, the OS makes a difference. :( I'm on a Mac too now at work and I certainly miss some tools - but I haven't had much time to look for Mac counterparts to them. I did notice that IDLE is available if you install Python yourself, it doesn't seem to be included with the Python bundles that are shipped with Mac OS. But that's for interactive Python programming, not really an IDE for big programs. So yeah, if you find something, do tell. ;)

Quote:
If I understood your previous post correctly, you stated that I needed to make a camera variable that is not tied to the player's movement. The only way I can think of using a camera variable would be to tie it to the player's movement.

Here you go:
# Let's create separate variables for each
# (assume that Vec2 is a class that contains an x and y variable,
# it's a bit more descriptive than using a tuple or list)
camera = Vec2(0, 0)
player = Character( ... )

# As long as the camera is following the player, you'd do something like this every frame
# (perhaps with some sort of offset, like half the screen width and height):
camera.x = player.position.x - half_screen_width
camera.y = player.position.y - half_screen_height
# Oh, and to keep the camera 'inside' the map, store a bounding rectangle
# and snap the camera to those value ranges. The max() and min() functions
# should come in handy there.

# Note: creating cut-scenes that center on other objects or positions is
# doable now - you're no longer limited to always following a player. :)

# For rendering, you'd pass the camera along, not the player position:
map.draw(screen, camera)

# And the map draws everything relative to the camera (not automatically,
# of course... you'll have to add the camera position to the sprite draw
# positions, but that's an easy thing to do)

Share this post


Link to post
Share on other sites
Quote:
Original post by Captain P
Checking tile collision values alone works fine for games that allow per-tile movement, but your characters move with a finer granularity. Doing an array lookup like this is still useful for determining what tiles you need to look at, but once that's done, I would use a rectangle-rectangle collision check to see if the character is running into a wall. If so, check how far the rectangle sticks into the wall, and only allow it to move up to that point.


I tried to follow your suggestion, but I must be missing something. Here is what I tried (the black rectangle was for debugging purposes). I thought it might be because I use the center of my character's rectangle, or the fact that my character's left and right images have different widths than its up and down images, but I was unable to figure out how these problems affected my code, because no matter what I tried, my character still was able to go half-way through each wall.

Here's my collision detection code:


if self.collision[int(math.ceil((char.rect.centery)/self.tileheight))][int(math.ceil((char.rect.centerx)/self.tilewidth))] == True:
self.rec_check_x = int(math.floor((char.rect.centerx)/self.tilewidth))
self.rec_check_y = int(math.floor((char.rect.centery)/self.tileheight))
wall = pygame.draw.rect(screen, (0, 0, 0), (self.tilewidth*self.rec_check_x, self.tileheight*self.rec_check_y, self.tilewidth, self.tileheight))
if char.rect.colliderect(wall) == True:
char.rect.center = (char.old_x, char.old_y)


The full source code is here: http://trovna.googlecode.com/files/Game%28fixing%20walls%29.zip

Just run Game.py

Dusty

Share this post


Link to post
Share on other sites
Quote:
Original post by dustfilledhobo
I thought it might be because I use the center of my character's rectangle, or the fact that my character's left and right images have different widths than its up and down images, but I was unable to figure out how these problems affected my code, because no matter what I tried, my character still was able to go half-way through each wall.

Personally I'd use a predetermined rectangle instead of the bounding box of the current sprite. It's a bit more flexible, and you can be certain that your collision area never changes (e.g. it could suddenly become larger when you turn around, pushing you out of the wall, which may not be what you want when simply turning).

As for your collision test, the problem lies with the tile lookup code. Indeed, you're using only the center of the player, so only once the center comes into contact with a solid tile you're doing a rectangle-rectangle check. Those rectangles did already collide, but you skipped that test. If you're working with rectangles, you often need to check a range of tiles, not just one. For each corner, check what tile it is in. Those are the boundary tiles of the tile area that you need to perform collision tests on.

Say, you're controlling a huge elephant, and his left side just touches the 4th collumn. His right side touches the 8th collumn. That means he's touching tiles in 5 collumns! The same goes for the top and bottom. Let's say those are rows 6 - 9, 4 rows in total. The elephant is touching or overlapping 20 tiles. At the very least you will have to test against the border tiles of that area - not just one tile. The same applies to your game: even though the player is small, he can still touch 4 tiles at once.

Share this post


Link to post
Share on other sites
Captain P, it worked perfectly. I had never used topleft, topright, etc. before. Your solution should have been obvious to me, but it wasn't. So, thanks again for helping a struggling (and sometimes dense) newbie.

Dusty

Share this post


Link to post
Share on other sites
No problem - we all have to learn things. :)

To come back to the IDE question, you may want to try some of the tools mentioned here. There are some cross-platform and Mac programs mentioned, maybe there's one that suits your needs.

Share this post


Link to post
Share on other sites
Quote:
Original post by Captain P

To come back to the IDE question, you may want to try some of the tools mentioned here. There are some cross-platform and Mac programs mentioned, maybe there's one that suits your needs.


I downloaded the TextMate trial, and I think that I fixed my mixing tabs and spaces problem (please let me know if I didn't).

Also, I have been trying to create the camera in my game based on Captain P's suggestions, just a few posts above this one.

My current code leaves the player centered with respect to the background, and the entire background shifts with the player, where I want the player to stay in the middle of the screen and have the background scroll. Sorry if my explanation is not clear. It seems like the scrolling is almost working in reverse.

If you would like, you can download my current code here:
http://trovna.googlecode.com/files/Game%28Fixing%20Camera%29.zip

I am not fully understanding the Vec2(0,0) part of Captain P's suggestion. I created the class below, but I believe that I am still using a list where it was suggested that a vector would be better.

Camera.py::::

import pygame

class CameraVector:
def __init__(self, resolution, map1):
self.bounding_rectangle = pygame.Rect(0, 0, resolution[0], resolution[1])#map1.numXTiles*map1.tilewidth, map1.numYTiles*map1.tileheight)
self.camera_vector = resolution
self.x = self.camera_vector[0]
self.y = self.camera_vector[1]
self.camera_rect = pygame.Rect(self.x, self.y,resolution[0], resolution[1])

def update(self, resolution, char):
self.x = char.rect.centerx - resolution[0]/2
self.y = char.rect.centery - resolution[1]/2
self.camera_rect.clamp(self.bounding_rectangle)



MapFunctions.py::::::

import pygame, math
from Map import ImageCache

class Map():
def __init__(self, resolution, last_key_pressed):
self.tiles = []
self.images = []
self.collision = []
self.tilewidth = 40
self.tileheight = 40

self.resolution = resolution
self.last_key_pressed = last_key_pressed

self.numXTiles = int(math.ceil(float(self.resolution[0]) / self.tilewidth)) + 1
self.numYTiles = int(math.ceil(float(self.resolution[1]) / self.tileheight)) + 1
self.tiledBG = pygame.Surface((self.numXTiles * self.tilewidth, self.numYTiles * self.tileheight)).convert()
self.wallsBG = pygame.Surface((self.numXTiles * self.tilewidth, self.numYTiles * self.tileheight)).convert()

def load(self, map_file, resolution, char):
self.char = char
cache = ImageCache.ImageCache()
self.images.append(cache.getImage('Images/Scenery/ocean.png'))
self.images.append(cache.getImage('Images/Scenery/pathway.png'))
self.images.append(cache.getImage('Images/Scenery/brick.png'))


self.tilewidth = self.images[0].get_width()
self.tileheight = self.images[0].get_height()

for line in open(map_file, 'r'):
characters = line.strip().split(',')

if len(characters) > 0:
self.tiles.append([])
self.collision.append([])

# Run through all the tile characters
for character in characters:
if character == 'OCN':
# [-1] means: the last element of
# I'm pushing 0 here, because 'red' is the 0th element in self.images
self.tiles[-1].append(0)
self.collision[-1].append(True)
elif character == 'PTH':
self.tiles[-1].append(1)
self.collision[-1].append(False)
elif character == 'BRK':
self.tiles[-1].append(2)
self.collision[-1].append(True)
else:
# Right now this makes each row one tile shorter, because
# we're not storing any data for this tile.
print 'Wrong tile: [' + character + ']'

#print "Max: (" +str(self.maxHorzScrollBounds)+ ", " +str(self.maxVertScrollBounds)+ ")"


def draw(self, screen, char, camera):
startXTile = int(math.floor(camera.x/self.tilewidth))
startYTile = int(math.floor(camera.y/self.tileheight))
#print "camera coords: (" +str(camera.x)+", "+str(camera.y)+")"
#print "start tiles: (" +str(startXTile)+", "+str(startYTile)+")"

for x in range(startXTile, self.numXTiles + startXTile):
for y in range(startYTile, self.numYTiles + startYTile):
self.tiledBG.blit(self.images[self.tiles[y][x]], ((x) * self.tilewidth, (y) * self.tileheight))
screen.blit(self.tiledBG, (startXTile*self.tilewidth, startYTile*self.tileheight))

#Did we hit a wall????
### The following if/else block checks the topleft, topright, bottomleft, and bottomright coordinates of the character's
### rectangle to see if they collide with any walls. If they collide the player is not allowed to advance, if there is no
### collision, then the char_old variables are reset to the current position of the charactcer.

if self.collision[int(math.floor((char.rect.topleft[1])/self.tileheight))][int(math.ceil((char.rect.topleft[0])/self.tilewidth))] == True: #checking topleft coordinate for collision
char.rect.center = (char.old_x, char.old_y)
elif self.collision[int(math.floor((char.rect.topright[1])/self.tileheight))][int(math.ceil((char.rect.topright[0])/self.tilewidth))] == True: #checking topright coordinate for collision
char.rect.center = (char.old_x, char.old_y)
elif self.collision[int(math.floor((char.rect.bottomright[1])/self.tileheight))][int(math.ceil((char.rect.bottomright[0])/self.tilewidth))] == True: #checking bottomright coordinate for collision
char.rect.center = (char.old_x, char.old_y)
elif self.collision[int(math.floor((char.rect.bottomleft[1])/self.tileheight))][int(math.ceil((char.rect.bottomleft[0])/self.tilewidth))] == True: #checking bottomleft coordinate for collision
char.rect.center = (char.old_x, char.old_y)
else:
#Didn't hit a wall
char_old_x = char.rect.centerx
char_old_y = char.rect.centery




Thanks in advance for any help.

Dusty






Share this post


Link to post
Share on other sites
I am still having trouble with the code in my previous post. I think that it might have something to do with the way I am attempting to snap to my bounding rectangle, but I can't figure it out. Sorry for the re-post, but I keep attempting to solve this and nothing I try seems to work. Thanks in advance for any help that you can offer.

Dusty

Share this post


Link to post
Share on other sites
I don't have much time now, but if you want to snap the camera to a certain rectangular area, you'll need to keep the size of the screen in mind as well. What it comes down to is keeping one rectangle inside another.

The logic is fairly easy: if the inner rectangle's left side is further to the left than the outer rectangle's left side, then set it's left side to the left side of the outer rectangle. Same goes for all four sides. In your case, the inner rectangle is the camera position combined with the screen dimension, and the outer rectangle is the map boundary.


As for vectors, using tuples or lists will work just as well, they're just a little more obscure (camera.x is more descriptive than camera[0]). Same goes for rectangles. The above approach is easier to implement when you've got a Rectangle class that provides left(), right(), top() and bottom() functions (besides just containing an x, y, width and height).

Share this post


Link to post
Share on other sites
I'm still having trouble with the scrolling/obstacle detection of my game. Currently my game scrolls exactly how I want it to (the player stays in the center of the screen unless he reaches one of the outer bounds of the map). My problem lies in the obstacle detection. Here are some things I have tried:

(1) I have tried shifting the walls based on my camera's x and y coordinates, but this always allowed me to go partially into the wall, or it restricted me from passing when I was far away from a wall.

(2) I tried creating a list that contained rectangles for each tile that was not walkable, but failed when I didn't know how to determine which rectangle to test for a collision. Also, the way I was doing this I was still using the same list to look up for the collision as (1), so I think even if I got this to work I would have had similar results as (1)

(3) I even tried defining each pixel as being walkable or not. This was my last resort, and was way too slow (obviously) to do anything with.

My current code allows scrolling and it leaves the walls in their original position on the screen, so if Im in the top left portion of the map my upper and left walls work, but everything else does not, and I know this is because I don't have any code to allow the walls to shift. Captain P has given me many great suggestions, but I am not fully understanding how to implement them with my code. So, I am asking for help once again. Thank You!!!

You can download the full code here: http://trovna.googlecode.com/files/Game%28stable%20scrolling%20%5Bno%20walls%5D%29%20.zip

But I think this is all you will need:

Game.py::::

#Change the version number and put your name after you edit

#V Whatever

#Whoever



# KEEP THE CODE ORGANIZED
# make changes in the right section
# comments will help others (and YOU) understand
# IDEA/ALTER model



#I - Import and initialize
import pygame
import random
import math
import CharacterSprites
import EnemySprites
import ItemSprites
import HUDs
import MapFunctions
import ImagePaths
import Camera
from Map import ImageCache
from pygame.locals import *



######initializing global variables########




#######initialize pygame#######
pygame.init()



#D - Display configuration
resolution = (800,600)
screen = pygame.display.set_mode(resolution)
last_key_pressed = "DOWN"
charImages = ImagePaths.CharImagePaths()
fps = 30


######main game loop#######
def main():
#E - Entities (things moving about on screen)
pygame.display.set_caption("THE GAME")

background = pygame.Surface(screen.get_size())
background.fill((50,255,50)) # what color the background is in RGB
screen.blit(background, (0, 0))
last_key_pressed = "DOWN"

# Assign sprite classes and other classes to variables
char = CharacterSprites.Char(charImages, fps, resolution, last_key_pressed)
info = HUDs.HUD()
info.center = (100, 50)
map1 = MapFunctions.Map(resolution, last_key_pressed)
map1.load('Map/map.txt', resolution, char)
boundingRectangle = Camera.BoundingRectangle(map1)
camera = Camera.Camera(boundingRectangle, char)
wiz = EnemySprites.Wiz(screen)
wiz1 = EnemySprites.Wiz(screen)
wiz2 = EnemySprites.Wiz(screen)
gold = ItemSprites.Gold()
gold1 = ItemSprites.Gold()
gold2 = ItemSprites.Gold()
cache = ImageCache.ImageCache()


#A - Action (broken into ALTER steps)

#A Assign values to key variables
goodSprites = pygame.sprite.Group(char)
itemSprites = pygame.sprite.Group(gold, gold1, gold2)
badSprites = pygame.sprite.Group(wiz, wiz1, wiz2)
infoSprites = pygame.sprite.Group(info)

clock = pygame.time.Clock() #initializing the clock

keepGoing = True #initialally we want to Keep Going

# Main caption
pygame.display.set_caption("THE GAME")


#L - Set up main loop
while keepGoing:

#T - Timer to set frame rate
clock.tick(fps) #setting frame rate number = fps

#E - Event handling

#saving the old position, before we change it, just incase we hit a wall.
char.old_x = char.rect.centerx
char.old_y = char.rect.centery
# The above is for wall collisions

for event in pygame.event.get():
if event.type == pygame.QUIT:
keepGoing = False

elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
char.moveWest = True
last_key_pressed = "LEFT"
elif event.key == pygame.K_RIGHT:
char.moveEast = True
last_key_pressed = "RIGHT"
elif event.key == pygame.K_UP:
char.moveNorth = True
last_key_pressed = "UP"
elif event.key == pygame.K_DOWN:
char.moveSouth = True
last_key_pressed = "DOWN"

elif event.key == pygame.K_ESCAPE:
pygame.event.post(pygame.event.Event(pygame.QUIT, {}))

elif event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT:
char.moveWest = False
char.image = char.charImages.character_images_left[0]
elif event.key == pygame.K_RIGHT:
char.moveEast = False
char.image = char.charImages.character_images_right[0]
elif event.key == pygame.K_UP:
char.moveNorth = False
char.image = char.charImages.character_images_back[0]
elif event.key == pygame.K_DOWN:
char.moveSouth = False
char.image = char.charImages.character_images_front[0]


######Check for sprites colliding with other sprites######
hitItem = pygame.sprite.spritecollide(char, itemSprites, False)
if hitItem:
for theItem in hitItem:
theItem.reset() #resets location
info.gold += 1 #adds one to gold

hitBad = pygame.sprite.spritecollide(char, badSprites, False)
if hitBad:
for theBad in hitBad:
char.reset()#resets location
info.life -= 1# ads one to kills
if info.life <= 0:
keepGoing = False


#R - Refresh display "blit" means printing an image

###Clear old sprite groups
goodSprites.clear(screen, background)
itemSprites.clear(screen, background)
badSprites.clear(screen, background)
infoSprites.clear(screen, background)

###Update the sprite group positions, etc.
goodSprites.update(last_key_pressed, pygame.time.get_ticks(), camera, boundingRectangle)
itemSprites.update()
badSprites.update()
infoSprites.update()
camera.update(char, boundingRectangle, map1)

###Draw new sprite groups
map1.draw(screen, char, camera)
goodSprites.draw(screen)
itemSprites.draw(screen)
badSprites.draw(screen)
infoSprites.draw(screen)

####Switch the screen to the new information
pygame.display.flip()

# End main game loop
if __name__ == "__main__":
main()




MapFunctions.py::::

import pygame, math
from Map import ImageCache

class Map():
def __init__(self, resolution, last_key_pressed):
self.tiles = []
self.images = []
self.collision = []
self.shift_wall_x = 0
self.shift_wall_y = 0

cache = ImageCache.ImageCache()
self.images.append(cache.getImage('Images/Scenery/ocean.png'))
self.images.append(cache.getImage('Images/Scenery/pathway.png'))
self.images.append(cache.getImage('Images/Scenery/brick.png'))

self.tilewidth = self.images[0].get_width()
self.tileheight = self.images[0].get_height()

self.resolution = resolution
self.last_key_pressed = last_key_pressed

self.advanceVelocity_x = 0
self.advanceVelocity_y = 0

self.numXTiles = int(math.ceil(float(self.resolution[0]) / self.tilewidth)) + 1
self.numYTiles = int(math.ceil(float(self.resolution[1]) / self.tileheight)) + 1
self.tiledBG = pygame.Surface((self.numXTiles * self.tilewidth, self.numYTiles * self.tileheight)).convert()
self.wallsBG = pygame.Surface((self.numXTiles * self.tilewidth, self.numYTiles * self.tileheight)).convert()

def load(self, map_file, resolution, char):
self.char = char
self.resolution = resolution


for line in open(map_file, 'r'):
characters = line.strip().split(',')

if len(characters) > 0:
self.tiles.append([])
self.collision.append([])

# Run through all the tile characters
for character in characters:
if character == 'OCN':
# [-1] means: the last element of
# I'm pushing 0 here, because 'red' is the 0th element in self.images
self.tiles[-1].append(0)
self.collision[-1].append(True)
elif character == 'PTH':
self.tiles[-1].append(1)
self.collision[-1].append(False)
elif character == 'BRK':
self.tiles[-1].append(2)
self.collision[-1].append(True)
else:
# Right now this makes each row one tile shorter, because
# we're not storing any data for this tile.
print 'Wrong tile: [' + character + ']'

#print "Max: (" +str(self.maxHorzScrollBounds)+ ", " +str(self.maxVertScrollBounds)+ ")"


def draw(self, screen, char, camera):
self.startXTile = int(math.floor(float(camera.x) / self.tilewidth))
self.startYTile = int(math.floor(float(camera.y) / self.tileheight))

for x in range(self.startXTile, self.startXTile + self.numXTiles):
for y in range(self.startYTile, self.startYTile + self.numYTiles):
#print map1.images[map1.tiles[y][x]]

self.tiledBG.blit(self.images[self.tiles[y][x]], ((x - self.startXTile) * self.tilewidth, (y - self.startYTile) * self.tileheight))
screen.blit(self.tiledBG, (0, 0), (camera.x - (self.startXTile * self.tilewidth), (camera.y - (self.startYTile * self.tileheight))) + self.resolution)

#Did we hit a wall????
### The following if/else block checks the topleft, topright, bottomleft, and bottomright coordinates of the character's
### rectangle to see if they collide with any walls. If they collide the player is not allowed to advance, if there is no
### collision, then the char_old variables are reset to the current position of the charactcer.
if self.collision[int(math.floor((char.rect.topleft[1])/self.tileheight))][int(math.ceil((char.rect.topleft[0])/self.tilewidth))]: #checking topleft coordinate for collision
char.rect.center = (char.old_x, char.old_y)
camera.x = camera.old_x
camera.y = camera.old_y
elif self.collision[int(math.floor((char.rect.topright[1])/self.tileheight))][int(math.ceil((char.rect.topright[0])/self.tilewidth))]: #checking topright coordinate for collision
char.rect.center = (char.old_x, char.old_y)
camera.x = camera.old_x
camera.y = camera.old_y
elif self.collision[int(math.floor((char.rect.bottomright[1])/self.tileheight))][int(math.ceil((char.rect.bottomright[0])/self.tilewidth))]: #checking bottomright coordinate for collision
char.rect.center = (char.old_x, char.old_y)
camera.x = camera.old_x
camera.y = camera.old_y
elif self.collision[int(math.floor((char.rect.bottomleft[1])/self.tileheight))][int(math.ceil((char.rect.bottomleft[0])/self.tilewidth))]: #checking bottomleft coordinate for collision
char.rect.center = (char.old_x, char.old_y)
camera.x = camera.old_x
camera.y = camera.old_y
else:
#Didn't hit a wall
char_old_x = char.rect.centerx
char_old_y = char.rect.centery
camera.old_x = camera.x
camera.old_y = camera.y




Camera.py::::

import pygame, math

class BoundingRectangle:
def __init__(self, map1):
self.max_right_bound = map1.tilewidth * len(map1.tiles[0]) - map1.resolution[0] - 1
self.max_left_bound = 0
self.max_top_bound = 0
self.max_bottom_bound = map1.tileheight * len(map1.tiles) - map1.resolution[1] - 1

def right(self):
return self.max_right_bound

def left(self):
return self.max_left_bound

def top(self):
return self.max_top_bound

def bottom(self):
return self.max_bottom_bound

class Camera:
def __init__(self, boundingRectangle, char):
self.x = 0
self.y = 0
self.advanceVelocity_x = 0
self.advanceVelocity_y = 0
self.scrollVelocity = char.speed
self.wall_shift_x = 0
self.wall_shift_y = 0
self.old_x = self.x
self.old_y = self.y
self.max_bound = False

def update(self, char, boundingRectangle, map1):
#Snap scrolling window to the Bounding Rectangle
max_bound = False
if self.x <= boundingRectangle.left():
self.x = boundingRectangle.left()
self.max_bound = True
if self.x >= boundingRectangle.right():
self.x = boundingRectangle.right()
self.max_bound = True
if self.y <= boundingRectangle.top():
self.y = boundingRectangle.top()
self.max_bound = True
if self.y >= boundingRectangle.bottom():
self.y = boundingRectangle.bottom()
self.max_bound = True

#shift wall positions (x,y)
self.wall_shift_x = int(math.floor(self.x / map1.tilewidth))
self.wall_shift_y = int(math.floor(self.y / map1.tileheight))

#print "wall shifts: (" +str(self.wall_shift_x)+ ", " +str(self.wall_shift_y)+ ")"

#print "Camera Coordinates: (" +str(self.x)+ ", " +str(self.y)+ ")"



CharacterSprites.py::::

import pygame, math, Map, ImagePaths
from Map import ImageCache

class Char(pygame.sprite.Sprite):
def __init__(self, charImages, fps, resolution, last_key_pressed):
pygame.sprite.Sprite.__init__(self)
self.charImages = charImages
self.start = pygame.time.get_ticks()
self.delay = 1000 / fps
self.last_update = 0
self.frame = 0
self.last_key_pressed = last_key_pressed
self.image = self.charImages.character_images_front[self.frame]

if self.last_key_pressed == "UP":
self.image = self.charImages.character_images_back[self.frame]
if self.last_key_pressed == "DOWN":
self.image = self.charImages.character_images_front[self.frame]
if self.last_key_pressed == "RIGHT":
self.image = self.charImages.character_images_right[self.frame]
if self.last_key_pressed == "LEFT":
self.image = self.charImages.character_images_left[self.frame]

self.resolution = resolution


self.image = self.image.convert()
self.rect = self.image.get_rect()

self.rect.centerx = 400
self.rect.centery = 300
self.speed = 7

self.old_x = self.rect.centerx
self.old_y = self.rect.centery

self.start_x = self.rect.centerx
self.start_y = self.rect.centery

self.moveNorth = False
self.moveSouth = False
self.moveEast = False
self.moveWest = False

def reset(self):

self.rect.centerx = self.start_x
self.rect.centery = self.start_y

def update(self, last_key_pressed, t, camera, boundingRectangle):
# Put the player in the new spot
self.last_key_pressed = last_key_pressed
#if abs(self.start_x - self.rect.centerx) < self.speed:
#self.rect.centerx = self.start_x


if self.moveNorth:
self.animate(self.charImages.character_images_back, t)
if camera.y == boundingRectangle.top() or self.rect.centery > self.start_y:
self.rect.centery -= self.speed
if self.rect.centery == self.start_y:
camera.y -= self.speed



if self.moveSouth:
self.animate(self.charImages.character_images_front, t)
if camera.y == boundingRectangle.bottom() or self.rect.centery < self.start_y:
self.rect.centery += self.speed
if self.rect.centery == self.start_y:
camera.y += self.speed



if self.moveEast:
self.animate(self.charImages.character_images_right, t)
if camera.x == boundingRectangle.right() or self.rect.centerx < self.start_x:
self.rect.centerx += self.speed
if self.rect.centerx == self.start_x:
camera.x += self.speed



if self.moveWest:
self.animate(self.charImages.character_images_left, t)
if camera.x == boundingRectangle.left() or self.rect.centerx > self.start_x:
self.rect.centerx -= self.speed
if self.rect.centerx == self.start_x:
camera.x -= self.speed



if self.moveNorth == False and self.moveSouth == False and self.moveEast == False and self.moveWest == False:
if self.last_key_pressed == "UP":
self.image = self.charImages.character_images_back[0]
if self.last_key_pressed == "DOWN":
self.image = self.charImages.character_images_front[0]
if self.last_key_pressed == "RIGHT":
self.image = self.charImages.character_images_right[0]
if self.last_key_pressed == "LEFT":
self.image = self.charImages.character_images_left[0]
self.frame = 0

#print "Frame: " + str(self.frame)
#print "last_key_pressed: " + self.last_key_pressed
#print self.image


self.rect.center = (self.rect.centerx, self.rect.centery)


def animate(self, image_array, t):
if t - self.last_update > self.delay:
self.frame += 1
if self.frame >= len(image_array):
self.frame = 0
self.image = image_array[self.frame]
self.colorkey = self.image.get_at((0, 0))
self.image.set_colorkey(self.colorkey)
self.last_update = t



#map1.vpCoordinate_x += map1.advanceVelocity_x
#map1.vpCoordinate_y += map1.advanceVelocity_y
#if map1.vpCoordinate_x < map1.minHorzScrollBounds:
# map1.vpCoordinate_x = map1.minHorzScrollBounds
#print "minHorz"
#if map1.vpCoordinate_x > map1.maxHorzScrollBounds:
# map1.vpCoordinate_x = map1.maxHorzScrollBounds
#print "maxHorz"
#if map1.vpCoordinate_y < map1.minVertScrollBounds:
# map1.vpCoordinate_y = map1.minVertScrollBounds
#print "minVert"
#if map1.vpCoordinate_y > map1.maxVertScrollBounds:
# map1.vpCoordinate_y = map1.maxVertScrollBounds
#print "maxVert"

# if last_key_pressed == "LEFT":
# if map1.vpCoordinate_x == map1.minHorzScrollBounds:
# char.rect.centerx -= char.speed
# if map1.vpCoordinate_x == map1.maxHorzScrollBounds:
# if char.rect.centerx > char.start_x:
# char.rect.centerx -= char.speed


#if last_key_pressed == "RIGHT":
# if map1.vpCoordinate_x == map1.maxHorzScrollBounds:
# char.rect.centerx += char.speed
# if map1.vpCoordinate_x == map1.minHorzScrollBounds:
# if char.rect.centerx < char.start_x:
# char.rect.centerx += char.speed


# if last_key_pressed == "UP":
# if map1.vpCoordinate_y == map1.minVertScrollBounds:
# char.rect.centery -= char.speed
# if map1.vpCoordinate_y == map1.maxVertScrollBounds:
# if char.start_y < char.rect.centery:
# char.rect.centery -= char.speed


#if last_key_pressed == "DOWN":
# if map1.vpCoordinate_y == map1.maxVertScrollBounds:
# char.rect.centery += char.speed
# if map1.vpCoordinate_y == map1.minVertScrollBounds:
# if char.start_y > char.rect.centery:
# char.rect.centery += char.speed




Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement