Coding efficiently (pygame)

perks
Unregistered
 
Post: #1
In my last post I attempted to make a simple bare bones style map and movement system for a would be tile based game. I've gotten all the bugs sorted out and the small scale version was working perfectly (its a simple row of ten tiles with a character that moves one tile at a time). Anywho I decided to expand on what I already had. (made it 10X10 Added the apropriate up and down movements) I realised the way I coded it was probly quite silly seeing as in order to expand upon it I had to repeat alot of code (Maybe I didn't but I just started getting into programming this week).

So my question and request is for somone to look at my code and explain how I can get rid of the repeating code

Code:
import pygame,sys,os
from pygame.locals import *

screen = pygame.display.set_mode((1000,1000))



def image_load(name):
    print 'image loaded'
    path = os.path.join('my images', name)
    return pygame.image.load(path).convert()


type1 = image_load('background1.bmp')
type2 = image_load('background2.bmp')
player = image_load('player.bmp')


background1 = [type1, type2, type1, type2, type2, type1, type1, type1, type2, type1]
background2 = [type2, type2, type1, type2, type1, type2, type2, type1, type1, type2]
background3 = [type1, type2, type1, type2, type2, type1, type1, type1, type2, type1]
background4 = [type2, type1, type1, type2, type1, type2, type2, type1, type1, type2]
background5 = [type1, type2, type1, type1, type2, type1, type1, type1, type2, type1]
background6 = [type2, type2, type2, type2, type1, type2, type2, type2, type1, type2]
background7 = [type1, type1, type1, type1, type2, type1, type1, type1, type2, type1]
background8 = [type2, type2, type2, type2, type2, type2, type2, type2, type1, type2]
background9 = [type1, type1, type1, type2, type2, type1, type1, type1, type2, type1]
background10 = [type2, type2, type1, type1, type1, type2, type2, type1, type1, type2]



whatyousee1 = [0]*10
whatyousee2 = [0]*10
whatyousee3 = [0]*10
whatyousee4 = [0]*10
whatyousee5 = [0]*10
whatyousee6 = [0]*10
whatyousee7 = [0]*10
whatyousee8 = [0]*10
whatyousee9 = [0]*10
whatyousee10 = [0]*10

for i in range(0, 10):
        whatyousee1[i] = background1[i]
        whatyousee2[i] = background2[i]
        whatyousee3[i] = background3[i]
        whatyousee4[i] = background4[i]
        whatyousee5[i] = background5[i]
        whatyousee6[i] = background6[i]
        whatyousee7[i] = background7[i]
        whatyousee8[i] = background8[i]
        whatyousee9[i] = background9[i]
        whatyousee10[i] = background10[i]
        
        

def setcharposition(playerpos):
    for i in range(0,10):
        whatyousee1[i] = background1[i]
        whatyousee2[i] = background2[i]
        whatyousee3[i] = background3[i]
        whatyousee4[i] = background4[i]
        whatyousee5[i] = background5[i]
        whatyousee6[i] = background6[i]
        whatyousee7[i] = background7[i]
        whatyousee8[i] = background8[i]
        whatyousee9[i] = background9[i]
        whatyousee10[i] = background10[i]
        if i == 9:
            x = playerpos[0]
            y = playerpos[1]
            if y == 0:
                whatyousee1[x] = player
            if y == 1:
                whatyousee2[x] = player
            if y == 2:
                whatyousee3[x] = player
            if y == 3:
                whatyousee4[x] = player
            if y == 4:
                whatyousee5[x] = player
            if y == 5:
                whatyousee6[x] = player
            if y == 6:
                whatyousee7[x] = player
            if y == 7:
                whatyousee8[x] = player
            if y == 8:
                whatyousee9[x] = player
            if y == 9:
                whatyousee10[x] = player
            setwhatyousee(0)
                
def setwhatyousee(x):
    print 'setbackground', playerpos
    for item in whatyousee1:
        screen.blit(item, (x*100,0))
        x = x+1
        if x == 10:
            pygame.display.flip()
            x = 0
            for item in whatyousee2:
                screen.blit(item, (x*100,100))
                x = x + 1
                if x == 10:
                    pygame.display.flip()
                    x = 0
                    for item in whatyousee3:
                        screen.blit(item, (x*100,200))
                        x = x + 1
                        if x == 10:
                            pygame.display.flip()
                            x = 0
                            for item in whatyousee4:
                                screen.blit(item, (x*100,300))
                                x = x + 1
                                if x == 10:
                                    pygame.display.flip()
                                    x = 0
                                    for item in whatyousee5:
                                        screen.blit(item, (x*100,400))
                                        x = x + 1
                                        if x == 10:
                                            pygame.display.flip()
                                            x = 0
                                            for item in whatyousee6:
                                                screen.blit(item, (x*100,500))
                                                x = x + 1
                                                if x == 10:
                                                    pygame.display.flip()
                                                    x = 0
                                                    for item in whatyousee7:
                                                        screen.blit(item, (x*100,600))
                                                        x = x + 1
                                                        if x == 10:
                                                            pygame.display.flip()
                                                            x = 0
                                                            for item in whatyousee8:
                                                                screen.blit(item, (x*100,700))
                                                                x = x + 1
                                                                if x == 10:
                                                                    pygame.display.flip()
                                                                    x = 0
                                                                    for item in whatyousee9:
                                                                        screen.blit(item, (x*100,800))
                                                                        x = x + 1
                                                                        if x == 10:
                                                                            pygame.display.flip()
                                                                            x = 0
                                                                            for item in whatyousee10:
                                                                                screen.blit(item, (x*100,900))
                                                                                x = x + 1
                                                                                if x == 10:
                                                                                    pygame.display.flip()
                                                                                    x = 0
                                                                                                        
        
playerpos = [5,1]
setcharposition(playerpos)
while 1 is 1:
    for event in pygame.event.get():
        print(event)
        if event.type == QUIT:
            sys.exit()
            
        if event.type == KEYDOWN and event.key == 276:
            playerpos[0] = playerpos[0] - 1        
            if playerpos[0] <0:
                playerpos[0] = 9
            setcharposition(playerpos)
            
        if event.type == KEYDOWN and event.key == 275:
            playerpos[0] = playerpos[0] + 1
            if playerpos[0] >9:
                playerpos[0] = 0
            setcharposition(playerpos)

        if event.type == KEYDOWN and event.key == 273:
            playerpos[1] = playerpos[1] - 1
            if playerpos[1] <0:
                playerpos[1] = 9
            setcharposition(playerpos)
            
        if event.type == KEYDOWN and event.key == 274:
            playerpos[1] = playerpos[1] + 1
            if playerpos[1] >9:
                playerpos[1] = 0
            setcharposition(playerpos)
so there it is probly good for a laugh from you more experianced folks any and all help is muchly appreciated. THANK YOU!.
Quote this message in a reply
Member
Posts: 257
Joined: 2004.06
Post: #2
Um, you know you lists can contain lists, right? Maybe move all your lists into one big list and loop over that? At least, I think that's what you need to do. I'm finding it difficult to properly parse what that giant if-for-loop construction does. Blink

The brains and fingers behind Malarkey Software (plus caretaker of the world's two brattiest felines).
Quote this message in a reply
perks
Unregistered
 
Post: #3
I knew how I did it was quite riddiculous but the giant loop thing in there is drawing each row individually(regardless if it actually needed to be updated Shock) every time the player position changes. I did not know items in lists could be lists and thats the core of all my idiocy. Thank you very much SmileSmile
Quote this message in a reply
perks
Unregistered
 
Post: #4
Look what you did!Smile Well the code is much cleaner looking. I am however having a problem with it now though. instead of moving the player image around one tile at a time; it turns one tile at a time to a player.



Code:
import pygame,sys,os
from pygame.locals import *

screen = pygame.display.set_mode((1000,1000))

def image_load(name):
    print 'image loaded'
    path = os.path.join('my images', name)
    return pygame.image.load(path).convert()

type1 = image_load('background1.bmp')
type2 = image_load('background2.bmp')
player = image_load('player.bmp')
background =['whatever']*10        
whatyousee =['whatever']*10        

background[0] = [type1, type2, type1, type2, type2, type1, type1, type1, type2, type1]
background[1] = [type2, type2, type1, type2, type1, type2, type2, type1, type1, type2]
background[2] = [type1, type2, type1, type2, type2, type1, type1, type1, type2, type1]
background[3] = [type2, type1, type1, type2, type1, type2, type2, type1, type1, type2]
background[4] = [type1, type2, type1, type1, type2, type1, type1, type1, type2, type1]
background[5] = [type2, type2, type2, type2, type1, type2, type2, type2, type1, type2]
background[6] = [type1, type1, type1, type1, type2, type1, type1, type1, type2, type1]
background[7] = [type2, type2, type2, type2, type2, type2, type2, type2, type1, type2]
background[8] = [type1, type1, type1, type2, type2, type1, type1, type1, type2, type1]
background[9] = [type2, type2, type1, type1, type1, type2, type2, type1, type1, type2]

    
def setcharposition(playerpos):
    for i in range(0, 2):
        if playerpos[i] <0:
            playerpos[i] = 9
        if playerpos[i] >9:
            playerpos[i] = 0
    for i in range(0,10):
        whatyousee[i] = background[i]
        if i == 9:
            whatyousee[playerpos[0]][playerpos[1]] = player
    setwhatyousee()
                      
def setwhatyousee():
    for y in range(0,10):
        for x in range(0,10):
            screen.blit(whatyousee[x][y], (x*100,y*100))    
    pygame.display.flip()

playerpos = [0,0]
setcharposition(playerpos)
while 1:
    for event in pygame.event.get():
        print(event)
        if event.type == QUIT:
            sys.exit()              
        if event.type == KEYDOWN and event.key == 276:
            playerpos[0] = playerpos[0] - 1
        if event.type == KEYDOWN and event.key == 275:
            playerpos[0] = playerpos[0] + 1
        if event.type == KEYDOWN and event.key == 273:
            playerpos[1] = playerpos[1] - 1
        if event.type == KEYDOWN and event.key == 274:
            playerpos[1] = playerpos[1] + 1
    setcharposition(playerpos)

it seems like whenever I move the player I'm changing the background list. I can't find how thats happening though so I'm looking to hire a super sleuth for a minute to track down the pesky problem. Also if there's anything else that could be done to shorten the code do tell please
Quote this message in a reply
Member
Posts: 254
Joined: 2005.10
Post: #5
The reason that happens is that python assignment (a = b) makes a point to b. So when you do whatyousee[i] = background[i], you are really saying that whatyousee[i] points to the list at background[i]. Then when you add in the player image you are editing the background row directly/permanently. What you really want is a copy of background[i]. In python you can do this with a list by splicing the whole list.
Code:
whatyousee[i] = background[i][:]
Quote this message in a reply
perks
Unregistered
 
Post: #6
I'm still trying to make sense of that Blacktiger but either way it works. If my thanks where algy in a turtle tank; It would be a mighty scummy tank indeed.
Quote this message in a reply
Member
Posts: 254
Joined: 2005.10
Post: #7
perks Wrote:I'm still trying to make sense of that Blacktiger but either way it works. If my thanks where algy in a turtle tank; It would be a mighty scummy tank indeed.

Let me see if I can explain it better. Here is the code where you set up the background variable.

Code:
background[0] = [type1, type2, type1, type2, type2, type1, type1, type1, type2, type1]
background[1] = [type2, type2, type1, type2, type1, type2, type2, type1, type1, type2]
background[2] = [type1, type2, type1, type2, type2, type1, type1, type1, type2, type1]
background[3] = [type2, type1, type1, type2, type1, type2, type2, type1, type1, type2]
background[4] = [type1, type2, type1, type1, type2, type1, type1, type1, type2, type1]
background[5] = [type2, type2, type2, type2, type1, type2, type2, type2, type1, type2]
background[6] = [type1, type1, type1, type1, type2, type1, type1, type1, type2, type1]
background[7] = [type2, type2, type2, type2, type2, type2, type2, type2, type1, type2]
background[8] = [type1, type1, type1, type2, type2, type1, type1, type1, type2, type1]
background[9] = [type2, type2, type1, type1, type1, type2, type2, type1, type1, type2]

You probably thought that you set each row to be a list of those elements, but in reality you made each cell of the row refer/point to a location in memory where python stored the other list.

Code:
[0] -> [type1, type2, type1, type2, type2, type1, type1, type1, type2, type1]
[1] -> [type2, type2, type1, type2, type1, type2, type2, type1, type1, type2]
[2] -> [type1, type2, type1, type2, type2, type1, type1, type1, type2, type1]
[3] -> [type2, type1, type1, type2, type1, type2, type2, type1, type1, type2]
[4] -> [type1, type2, type1, type1, type2, type1, type1, type1, type2, type1]
[5] -> [type2, type2, type2, type2, type1, type2, type2, type2, type1, type2]
[6] -> [type1, type1, type1, type1, type2, type1, type1, type1, type2, type1]
[7] -> [type2, type2, type2, type2, type2, type2, type2, type2, type1, type2]
[8] -> [type1, type1, type1, type2, type2, type1, type1, type1, type2, type1]
[9] -> [type2, type2, type1, type1, type1, type2, type2, type1, type1, type2]

In other words "whatyousee = background[i]" doesn't copy the list, it copies the reference/pointer. After you perform that action, you do "whatyousee[position.x][position.y] = playerimage". Let's see if we can translate this a bit to make it more clear. First, we know that "whatyousee[position.x]" is the same as "background[position.x]". Now you are dealing directly with the row so when you assign playerimage to a particular column in that row, your assignment actually changes the background row! Thus, you overwrite the value there and when you try to copy background again, you are getting the one that you just changed! You may as well have forgotten about the whatyousee variable in the first place!

The key to all this is to understand that [i]all
Python variables are references to some location in memory and assignment copies that reference, not the actual value.

Clear as mud? If not, shoot me an email. blktiger-AT-gmail
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #8
Blacktiger Wrote:Clear as mud? If not, shoot me an email. blktiger-AT-gmail

Hopefully "If so"...
Quote this message in a reply
Member
Posts: 254
Joined: 2005.10
Post: #9
OneSadCookie Wrote:Hopefully "If so"...

Uh, yeah that. Sneaky
Quote this message in a reply
perks
Unregistered
 
Post: #10
Below is what I thought up for rotating an image based on which way it is moving. It looks like I have alot more code than I really need once again... If somone has any ideas, I'll take advice where I can get it
Code:
def update(self):
        if self.movedown == True:
            self.rect.top += self.speed
            if self.facingup == True:
                self.image = pygame.transform.flip(self.image, False, True)
                self.facingup = False
                self.facingdown = True
            if self.facingright == True:
                self.image = pygame.transform.rotate(self.image, -90)
                self.facingdown = True
                self.facingright = False
            if self.facingleft == True:
                self.image = pygame.transform.rotate(self.image, 90)
                self.facingleft = False
                self.facingdown = True


I have three more very similar blocks depending on if the object is moving either up, left, or right. I'm assuming one way to do it would be to make an 'original' image and load that every time the direction changes and flip or rotate that according to which ever direction its heading in. My main concern about that is actually loading the image every time the direction changes. Would that not bog down the program if there where plently of sprites changing direction alot?
Quote this message in a reply
Member
Posts: 254
Joined: 2005.10
Post: #11
That code looks alright to me. You aren't actually loading the image every time, but instead you are making a copy of the image that is already in memory. You need to do this anyway in order to flip the sprite.
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  Coding A Card Game Jerm #1 3 4,969 Apr 11, 2010 03:05 PM
Last Post: TimMcD
  Advice on coding of On-Screen Controls ( Joystick and multiple buttons) Elphaba 5 3,069 Aug 10, 2009 11:02 PM
Last Post: Elphaba
  Troubles with simple events in Pygame perks 4 3,088 Aug 27, 2007 10:23 PM
Last Post: Malarkey
  Coding a Tic Tac Toe game in C dongski19 5 6,879 Aug 21, 2006 01:17 PM
Last Post: Jones
  Coding Styles and Speed aqua_scummm 7 4,114 Oct 27, 2005 02:47 PM
Last Post: aqua_scummm