• 14
• 12
• 9
• 10
• 13

# python, game maker tut maze game...

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

## Recommended Posts

2 questions... how do I create all those sprites for the wall, but get rid of the lag it produces and wall of code that is needed to produce it...there must be a way. all the sprites are 32x32px, how would i go about making sure that a sprite doesn't stop so it is not lined up to an imaginary grid. Basically i want to make sure when the player needs to turn they can turn without problem...right now you have to wrestle with it. Just now I was thinking maybe make a last_key variable and if the x,y isn't divisible by 32 make it move +4 in the previously pressed key... note: so you don't have to look for it, this code needs 3 sprites to run it, player.gif, flag.gif, wall.gif, and they are all 32x32px
from livewires import games, color
import random

games.init(screen_width = 480, screen_height = 480, fps = 50)

class Player(games.Sprite):

def __init__(self):
super(Player, self).__init__(image = Player.image, top = 416, left = 416)

def update(self):
if games.keyboard.is_pressed(games.K_w):
if self.top < 0:
self.top = 0
else:
self.y -= 4
if games.keyboard.is_pressed(games.K_s):
if self.bottom > games.screen.height:
self.bottom = games.screen.height
else:
self.y += 4
if games.keyboard.is_pressed(games.K_a):
if self.left < 0:
self.left = 0
else:
self.x -= 4
if games.keyboard.is_pressed(games.K_d):
if self.right > games.screen.width:
self.right = games.screen.width
else:
self.x += 4

self.check_collide()

def check_collide(self):
for flag in self.overlapping_sprites:
flag.handle_collide(self)

class Flag(games.Sprite):

def __init__(self):
super(Flag, self).__init__(image = Flag.image, top = 160, left = 416)

def handle_collide(self, player):
self.destroy()
# show 'Game Over' for 5 seconds
end_message = games.Message(value = "Congrats",
size = 90,
color = color.red,
x = games.screen.width/2,
y = games.screen.height/2,
after_death = games.screen.quit,
is_collideable = False)

class Wall(games.Sprite):
image = games.load_image("wall.gif", transparent = False)

def __init__(self, top, left):
super(Wall, self).__init__(image = Wall.image, top = top, left = left)

def handle_collide(self, player):
if games.keyboard.is_pressed(games.K_w):
player.y += 4
if games.keyboard.is_pressed(games.K_s):
player.y -= 4
if games.keyboard.is_pressed(games.K_a):
player.x += 4
if games.keyboard.is_pressed(games.K_d):
player.x -= 4

def main():
player = Player()

flag = Flag()

#left wall
w1 = Wall(0, 0)
w2 = Wall(32, 0)
w3 = Wall(64, 0)
w4 = Wall(96, 0)
w5 = Wall(128, 0)
w6 = Wall(160, 0)
w7 = Wall(192, 0)
w8 = Wall(224, 0)
w9 = Wall(256, 0)
w10 = Wall(288, 0)
w11 = Wall(320, 0)
w12 = Wall(352, 0)
w13 = Wall(384, 0)
w14 = Wall(416, 0)
w15 = Wall(448, 0)

#right wall
w16 = Wall(0, 448)
w17 = Wall(32, 448)
w18 = Wall(64, 448)
w19 = Wall(96, 448)
w20 = Wall(128, 448)
w21 = Wall(160, 448)
w22 = Wall(192, 448)
w23 = Wall(224, 448)
w24 = Wall(256, 448)
w25 = Wall(288, 448)
w26 = Wall(320, 448)
w27 = Wall(352, 448)
w28 = Wall(384, 448)
w29 = Wall(416, 448)
w30 = Wall(448, 448)

#top wall
w31 = Wall(0, 32)
w32 = Wall(0, 64)
w33 = Wall(0, 96)
w34 = Wall(0, 128)
w35 = Wall(0, 160)
w36 = Wall(0, 192)
w37 = Wall(0, 224)
w38 = Wall(0, 256)
w39 = Wall(0, 288)
w40 = Wall(0, 320)
w41 = Wall(0, 352)
w42 = Wall(0, 384)
w43 = Wall(0, 416)

#bottom wall
w44 = Wall(448, 32)
w45 = Wall(448, 64)
w46 = Wall(448, 96)
w47 = Wall(448, 128)
w48 = Wall(448, 160)
w49 = Wall(448, 192)
w50 = Wall(448, 224)
w51 = Wall(448, 256)
w52 = Wall(448, 288)
w53 = Wall(448, 320)
w54 = Wall(448, 352)
w55 = Wall(448, 384)
w56 = Wall(448, 416)

#inside walls
#row 2
i0206 = Wall(32, 160)

#row 3
i0303 = Wall(64, 64)
i0304 = Wall(64, 96)
i0305 = Wall(64, 128)
i0306 = Wall(64, 160)
i0308 = Wall(64, 224)
i0309 = Wall(64, 256)
i0310 = Wall(64, 288)
i0311 = Wall(64, 320)
i0313 = Wall(64, 384)
i0314 = Wall(64, 416)

#row 4
i0403 = Wall(96, 64)
i0408 = Wall(96, 224)

#row 5
i0503 = Wall(128, 64)
i0505 = Wall(128, 128)
i0506 = Wall(128, 160)
i0507 = Wall(128, 192)
i0508 = Wall(128, 224)
i0509 = Wall(128, 256)
i0510 = Wall(128, 288)
i0511 = Wall(128, 320)
i0512 = Wall(128, 352)
i0513 = Wall(128, 384)

#row 6
i0605 = Wall(160, 128)
i0613 = Wall(160, 384)

#row 7
i0703 = Wall(192, 64)
i0704 = Wall(192, 96)
i0705 = Wall(192, 128)
i0706 = Wall(192, 160)
i0707 = Wall(192, 192)
i0708 = Wall(192, 224)
i0709 = Wall(192, 256)
i0710 = Wall(192, 288)
i0711 = Wall(192, 320)
i0713 = Wall(192, 384)
i0714 = Wall(192, 416)

#row 8

#row 9
i0902 = Wall(256, 32)
i0903 = Wall(256, 64)
i0904 = Wall(256, 96)
i0905 = Wall(256, 128)
i0906 = Wall(256, 160)
i0907 = Wall(256, 192)
i0908 = Wall(256, 224)
i0909 = Wall(256, 256)
i0910 = Wall(256, 288)
i0911 = Wall(256, 320)
i0912 = Wall(256, 352)
i0913 = Wall(256, 384)

#row 10
i1011 = Wall(288, 320)

#row 11
i1103 = Wall(320, 64)
i1104 = Wall(320, 96)
i1106 = Wall(320, 160)
i1108 = Wall(320, 224)
i1109 = Wall(320, 256)
i1110 = Wall(320, 288)
i1111 = Wall(320, 320)
i1112 = Wall(320, 352)
i1113 = Wall(320, 384)

#row 12
i1204 = Wall(352, 96)
i1206 = Wall(352, 160)

#row 13
i1302 = Wall(384, 32)
i1303 = Wall(384, 64)
i1304 = Wall(384, 96)
i1306 = Wall(384, 160)
i1307 = Wall(384, 192)
i1308 = Wall(384, 224)
i1309 = Wall(384, 256)
i1310 = Wall(384, 288)
i1311 = Wall(384, 320)
i1312 = Wall(384, 352)
i1313 = Wall(384, 384)
i1314 = Wall(384, 416)

games.screen.event_grab = True
games.screen.mainloop()

# start it up!
main()



##### Share on other sites
I'm having a hard time figuring out what exactly your problem is. Can you explain more clearly, without us having to look through a wall of code first to figure out what is going on?

As for all those walls, it's much easier to use a list for that, which you can fill with a loop:
walls = []for i in xrange(numberOfWalls):    walls.append(Wall(i * 32))

Actually, it's probably smarter to store level layouts in additional level files (plain text files, or bitmaps, or whatever else that's easy to read in). That'll make levels easier to modify, and you can more easily ensure that tiles are placed on a regular grid.

##### Share on other sites
Quote:
 Original post by Durakken2 questions...how do I create all those sprites for the wall, but get rid of the lag it produces

I don't particularly see a reason for there to be lag. How bad is it? I'm also not familiar with 'livewires'. There might be something in the documentation about how to handle the image loading properly.

Quote:
 and wall of code that is needed to produce it...there must be a way.

There certainly is. Here's the first version.

First, we extract what's repeated about all of that code: we create a temporary variable, and call 'games.screen.add' with the result. Notice that the temporary is not needed: it's perfectly OK to write something like 'games.screen.add(Wall(0, 0))'. Then we just have a bunch of calls to the same function with different parameters. To simplify that, we make a container with all the parameter-sets that we want to pass, and use a loop to call the function repeatedly. We can represent each location with a pair (tuple of 2 elements), and put all those tuples in another tuple, over which we iterate. To call the function, we want to "unpack" the pair; Python's for-loop syntax makes this easy.

Second, observe that the sprite positions are all multiples of 32 (as to be expected since "all the sprites are 32x32px". So we should encode the positions as tile coordinates (by dividing out the 32), and do the math at the point where the Wall is created.

Third, we notice that some of the walls can be neatly organized into lines. To avoid repeatedly writing (0, 0), (1, 0), (2, 0) etc. for coordinates, we can make Python do a loop "in place" to generate all the desired tuples with a given pattern. For this, we use a 'generator comprehension' and convert the result to a tuple. The general form of that looks like 'tuple(f(x) for x in y if g(x))', which does exactly what it looks like. (We don't need the 'if g(x)' part here.) We use 'range' to generate the 'y' that gets looped over - for all the numbers in a range, we calculate the desired position.

We can add (concatenate) tuples together to create the final tuple of all the walls. A bit of care is needed here to make sure everything is at the same "level of nesting": ((1, 2), (3, 4)) + (5, 6) will yield ((1, 2), (3, 4), 5, 6), not ((1, 2), (3, 4), (5, 6)).

walls = tuple((i, 0) for i in range(15)) + \ # left wall        tuple((i, 14) for i in range(15)) + \ # right wall        tuple((0, i) for i in range(15)) + \ # top wall        tuple((14, i) for i in range(15)) + \ # bottom wall        ((1, 5),) + \ # inside walls, row 2 <-- notice how we make a 1-tuple        tuple((2, i) for i in range(2, 6)) + \ # inside walls, row 3, 1st set        tuple((2, i) for i in range(7, 11)) + \ # inside walls, row 3, 2nd set        tuple((2, i) for i in range(12, 14)) + \ # inside walls, row 3, 3rd set        ((3, 2), (3, 7)) + \ # inside walls, row 4        ((4, 2),) + \ # inside walls, row 5, 1st set        tuple((4, i) for i in range(4, 13)) + \ # inside walls, row 5, 2nd set        # I'll let you fill out the rest of this ;)# Then we feed those to our loop:for wall_x, wall_y in walls:  # the two values wall_x and wall_y are used to 'unpack' each pair.  games.screen.add(Wall(wall_x * 32, wall_y * 32))

The second version is to create a data file and read it to figure out where the walls go. :) You can do this very simply by making a map with 'X' and '.' symbols (Xs for walls), and reading it one symbol at a time (keeping track of the current symbol and line numbers); each time you encounter an 'X', you .add the corresponding Wall. (Keep in mind that starting counting from 0 will simplify your math.)

Quote:
 all the sprites are 32x32px, how would i go about making sure that a sprite doesn't stop so it is not lined up to an imaginary grid. Basically i want to make sure when the player needs to turn they can turn without problem...right now you have to wrestle with it.

Try adjusting the collision handling so that it also moves the Player in the perpendicular direction, if such an adjustment would align the Player with the grid.

##### Share on other sites
Thank you Captain and Zahlman.

I have no idea why I didn't think of that

live wires from what was said in the book is just a more beginners friendly addon for pygames that some group made... so basically it should run nearly the same as pygames since it is calling it in it's call.

The lag causes the player to move like 4 times slower with the list of walls up, but is remedied with increasing the player move speed...I just don't think that will solve the problem with bigger games so I'd like to correct it now if there is any way.

I think I'll be using the file way because it seems that it would be the quickest way to actually generate content with the least amount of code and seems more understandable than all the fors. (speaking of which i shouldn't have looked at that the first thing when I woke up...brain couldn't even translate the english into comprehensible meaning)

##### Share on other sites
Quote:
 Original post by DurakkenThe lag causes the player to move like 4 times slower with the list of walls up, but is remedied with increasing the player move speed...I just don't think that will solve the problem with bigger games so I'd like to correct it now if there is any way.

Sounds like the players movement is not tied to the actual frame-time. That is, you're moving the player 4 pixels every frame, regardless of how long that frame took to be processed. For example, without walls, say that a frame takes 10 ms. That's 100 fps. With walls, let's say that a frame now takes 40 ms. Now you've gone to 25 fps. So, your player now moves 4 times as slow.

If you take the frame-time into account, the can make the player move equally fast in both situations (at 100 fps, he's being updated more frequently, but he moves less per update).