Sign in to follow this  
Aku Lalala

Beginner - How to make walkable/not walkable wall

Recommended Posts

hi all,

i'm just a newbie here and in pygame. i could'nt find any simple/easy tutorial of making walkable/not walkable wall.
here's my example code. i manage to create the background map using the tile-sprite image, based on tutorial from
[url="http://arvinbadiola.wordpress.com/2012/01/22/rendering-background-image-using-pygame-in-python-2-7/"]i.am.arvin[/url]. i also add a bird as the player, but my problem now is i dont know how to make the wall (in the background)
walkable/not walkable.

hope someone can give idea how can this be done :)

[CODE]
# -*- coding: utf-8 *-*
import pygame
from pygame import *
import map1
import os
DEFAULT_SCREENSIZE = [512, 448] #16 X 14 grid with 32px X 32px cell
pygame.init()
screen = pygame.display.set_mode(DEFAULT_SCREENSIZE)
display.set_caption('Tile Based')
# -------------------------------- map source for background -------------------------------------
SOURCE = pygame.image.load('images/TileA4.png')
p = pygame.Rect(288, 0, 32, 32) #area of source image containing pavement
g = pygame.Rect(416, 0, 32, 32) #area of source image containing grass
s = pygame.Rect(288, 160, 32, 32) #area of source image containing sand/dirt
b = pygame.Rect(288, 320, 32, 32) #area of source image containing bush
w = pygame.Rect(96, 0, 32, 32) #area containing brick wall
t = pygame.Rect(288, 320, 32, 32) #area of source image containing grass
MAP = [[w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w],\
[w,t,t,t,w,t,t,t,w,t,w,t,w,t,t,w],\
[w,t,w,t,w,t,w,t,t,t,w,t,w,t,t,w],\
[w,t,w,t,w,t,w,t,w,t,w,t,w,t,t,w],\
[w,t,w,t,w,t,w,t,w,t,t,t,t,t,w,w],\
[w,t,w,t,t,t,w,t,w,t,w,t,t,w,t,w],\
[w,g,w,w,w,w,w,w,w,w,w,w,w,t,g,w],\
[w,t,w,t,t,t,w,t,w,t,t,t,t,t,w,w],\
[w,t,w,t,w,t,w,t,t,t,w,w,w,t,w,w],\
[w,t,w,t,w,t,w,t,w,t,t,t,t,t,t,w],\
[w,t,w,t,w,t,t,t,w,t,w,t,w,t,t,w],\
[w,t,w,t,w,w,w,t,w,t,t,w,t,w,t,w],\
[w,t,t,t,w,w,w,t,w,w,t,t,t,t,t,w],\
[w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w]]
# ------------------------------------ function to render tile --------------------------------------
def RenderTiles():
for y in range(len(MAP)):
for x in range(len(MAP[y])):
location = (x*32, y*32)
screen.blit(SOURCE, location, MAP[y][x])
# ------------------------------------ end function to render tile --------------------------------
# ---------------------------------------- bird class ------------------------------------------------
class Bird(pygame.sprite.Sprite):
def __init__(self, startpos=(32, 192)):
pygame.sprite.Sprite.__init__(self, self.groups)
self.image = pygame.image.load(os.path.join('images', 'babytux.png'))
self.image = self.image.convert_alpha()
self.rect = self.image.get_rect()
self.startpos = startpos
self.dx = self.startpos[0]
self.dy = self.startpos[1]
self.move = True
self.rect.center = (self.dx+self.rect.width/2, self.dy+self.rect.height/2)
def moves(self, dx, dy):
if self.dx + dx <= 10 or self.dy + dy <= 10 or\
self.dx + dx >= 480 or self.dy + dy >= 416:
self.move = False
else:
self.move = True
if self.move:
self.dx += dx
self.dy += dy
def update(self, second):
self.seconds = seconds
self.rect.center = (self.dx+self.rect.width/2, self.dy+self.rect.height/2)
RenderTiles()
# ------------------------------- end class bird ------------------------------------------------
FPS = 60
clock = pygame.time.Clock()
play = True
background = pygame.Surface(screen.get_size())
screen.blit(background, (0,0))
birdgroup = pygame.sprite.Group()
Bird.groups = birdgroup
b = Bird()
# main loop start
while play:
miliseconds = clock.tick(FPS)
seconds = miliseconds/1000
for e in event.get():
if e.type == QUIT:
play = False
if e.type == KEYDOWN:
if e.key == K_ESCAPE:
play = False
if e.key == K_UP:
b.moves(0, -32)
if e.key == K_DOWN:
b.moves(0, 32)
if e.key == K_RIGHT:
b.moves(32, 0)
if e.key == K_LEFT:
b.moves(-32, 0)
birdgroup.clear(screen, background)
birdgroup.update(seconds)
birdgroup.draw(screen)
pygame.display.flip()
pygame.quit()
[/CODE]

Share this post


Link to post
Share on other sites
A solution could be making your MAP ítem (p, g, s,...) a dict in the form {Rect, boolean}, meaning the boolean that you can visit that tile or not. If you need more info for your tiles, you can use an int instead of a boolean.

Share this post


Link to post
Share on other sites
hi,

thanks for your quick reply. i manage to solve this problem. but i dont know is it the right way of doing this for tile based game.
any way this is my new code. i just draw a rectangle before i draw the tile map, then i use the rectangle for collision detection. is it correct?

[CODE]
# -*- coding: utf-8 *-*
import pygame
from pygame import *
import map1
import os
DEFAULT_SCREENSIZE = [512, 448] #16 X 14 grid with 32px X 32px cell
pygame.init()
#pygame.key.set_repeat(1000,1000)
screen = pygame.display.set_mode(DEFAULT_SCREENSIZE)
display.set_caption('Tile Based')
# -------------------------------- map source for background -------------------------------------
SOURCE = pygame.image.load('images/TileA4.png')
p = pygame.Rect(288, 0, 32, 32) #area of source image containing pavement
g = pygame.Rect(416, 0, 32, 32) #area of source image containing grass
s = pygame.Rect(288, 160, 32, 32) #area of source image containing sand/dirt
b = pygame.Rect(288, 320, 32, 32) #area of source image containing bush
w = pygame.Rect(96, 0, 32, 32) #area containing brick wall
t = pygame.Rect(288, 320, 32, 32) #area of source image containing grass
MAP = [[w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w],\
[w,t,t,t,w,t,t,t,w,t,w,t,w,t,t,w],\
[w,t,w,t,w,t,w,t,t,t,w,t,w,t,t,w],\
[w,t,w,t,w,t,w,t,w,t,w,t,w,t,t,w],\
[w,t,w,t,w,t,w,t,w,t,t,t,t,t,w,w],\
[w,t,w,t,t,t,w,t,w,t,w,t,t,w,t,w],\
[w,g,w,w,w,w,w,w,w,w,w,w,w,t,g,w],\
[w,t,w,t,t,t,w,t,w,t,t,t,t,t,w,w],\
[w,t,w,t,w,t,w,t,t,t,w,w,w,t,w,w],\
[w,t,w,t,w,t,w,t,w,t,t,t,t,t,t,w],\
[w,t,w,t,w,t,t,t,w,t,w,t,w,t,t,w],\
[w,t,w,t,w,w,w,t,w,t,t,w,t,w,t,w],\
[w,t,t,t,w,w,w,t,w,w,t,t,t,t,t,w],\
[w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w]]
# ------------------------------------ function to render tile --------------------------------------
class Wall(pygame.sprite.Sprite):
def __init__(self,height,width,x,y):
pygame.sprite.Sprite.__init__(self)
# Make a blue wall, of the size specified in the parameters
self.image = pygame.Surface([width, height])
self.image.fill((0,0,255))
# Make our top-left corner the passed-in location.
self.rect = self.image.get_rect()
self.rect.topleft = (x, y)
# ------------------------------------ end function to render tile --------------------------------
# ---------------------------------------- bird class ------------------------------------------------
class Bird(pygame.sprite.Sprite):
def __init__(self, startpos=(48, 208)):
pygame.sprite.Sprite.__init__(self, self.groups)
self.image = pygame.image.load(os.path.join('images', 'babytux.png'))
self.image = self.image.convert_alpha()
self.rect = self.image.get_rect()
self.startpos = startpos
self.dx = self.startpos[0]
self.dy = self.startpos[1]
self.move = True
self.rect.center = (self.dx, self.dy)
self.old_x = self.rect.centerx
self.old_y = self.rect.centery
def moves(self, dx, dy, wall):
self.wall = wall
self.old_x =self.dx
self.old_y = self.dy
self.dx += dx
self.dy +=dy
self.rect.center = (self.dx, self.dy)
collide = pygame.sprite.spritecollide(self,self.wall,False)
if collide:
self.rect.center = (self.old_x, self.old_y)
self.dx = self.old_x
self.dy = self.old_y
print 'collide'
def RenderTiles(self):
for y in range(len(MAP)):
for x in range(len(MAP[y])):
location = (x*32, y*32)
screen.blit(SOURCE, location, MAP[y][x])
def update(self, second):
self.seconds = seconds
self.rect.center = (self.dx, self.dy)
self.RenderTiles()
# ------------------------------- end class bird ------------------------------------------------
FPS = 60
clock = pygame.time.Clock()
play = True
background = pygame.Surface(screen.get_size())
screen.blit(background, (0,0))
birdgroup = pygame.sprite.Group()
Bird.groups = birdgroup
b = Bird()
# ----------------------------------------------------------------------------------------------------------------
# Make the walls. (height, width, x_pos, y_pos)
wall_list=[]
for y in range(len(MAP)):
for x in range(len(MAP[y])):
location = (x*32, y*32)
#print MAP[y][x].topleft
tl = MAP[y][x].topleft[0]
if tl == 96:
wall_list.append(Wall(32,32,x*32,y*32))

wallSprites = pygame.sprite.Group(wall_list)
# ----------------------------------------------------------------------------------------------------------------

# main loop start
while play:
miliseconds = clock.tick(FPS)
seconds = miliseconds/1000
for e in event.get():
if e.type == QUIT:
play = False
if e.type == KEYDOWN:
if e.key == K_ESCAPE:
play = False
if e.key == K_UP:
b.moves(0, -32, wallSprites)
if e.key == K_DOWN:
b.moves(0, 32, wallSprites)
if e.key == K_RIGHT:
b.moves(32, 0, wallSprites)
if e.key == K_LEFT:
b.moves(-32, 0, wallSprites)
birdgroup.clear(screen, background)
birdgroup.update(seconds)
birdgroup.draw(screen)
pygame.display.flip()
pygame.quit()
[/CODE]

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this