# Setting the scene for a role-playing game

I made some games in Pygame, but I am still new to making games. I made this RPG game, and this code is just a part of the game. The game executes different Pygame files for different levels of the game as it can be seen in this part of the code (this is for random battles):

 if (mainCharacterCoordinates.colliderect(battlefield) and (keys_pressed[pygame.K_DOWN] or keys_pressed[pygame.K_UP] or keys_pressed[pygame.K_RIGHT] or keys_pressed[pygame.K_LEFT])):
f = open('x.txt', 'w')
f.write(str(x))
f.close()

f = open('y.txt', 'w')
f.write(str(y))
f.close()
execfile('battlefield.py')
Exit = True


This is a screenshot of the game:

My concern about this code is whether my way of coding is efficient. At this moment, I am mostly concerned about two things in my game. I am not sure I am doing the collision the correct way (they still work, but it looks bad in the code as it can be seen below). I created 4 rectangles at left,right,top and bottom of the main character and each object has just one rectangle that is the size of the objects. After this I tell the program if there is collision on the left and do not walk left and the same for other 3 sides of the main character. Would it be possible to give me and tips if there is a better way of creating collisions? So that the 'mainCharacter' cannot walk over an object.

    if (keys_pressed[pygame.K_LEFT] and not mainCharacterCoordinatesLeft.colliderect(treeCoordinates8) and not mainCharacterCoordinatesLeft.colliderect(treeCoordinates7) and not mainCharacterCoordinatesLeft.colliderect(treeCoordinates6) and not mainCharacterCoordinatesLeft.colliderect(treeCoordinates5) and not mainCharacterCoordinatesLeft.colliderect(treeCoordinates4) and not mainCharacterCoordinatesLeft.colliderect(treeCoordinates3) and not mainCharacterCoordinatesLeft.colliderect(treeCoordinates2) and not mainCharacterCoordinatesLeft.colliderect(treeCoordinates1) and not mainCharacterCoordinatesLeft.colliderect(crossCoordinates) and not mainCharacterCoordinatesLeft.colliderect(leftborder) and not mainCharacterCoordinatesLeft.colliderect(wellCoordinates) and not mainCharacterCoordinatesLeft.colliderect(trainCoordinates) and not mainCharacterCoordinatesLeft.colliderect(graveyardCoordinates)):
counter = (counter + 1) % len(mainCharacterLeft)
x -= 2
CameraX -= 2

if (keys_pressed[pygame.K_RIGHT] and not mainCharacterCoordinatesRight.colliderect(treeCoordinates8) and not mainCharacterCoordinatesRight.colliderect(treeCoordinates7) and not mainCharacterCoordinatesRight.colliderect(treeCoordinates6) and not mainCharacterCoordinatesRight.colliderect(treeCoordinates5) and not mainCharacterCoordinatesRight.colliderect(treeCoordinates4) and not mainCharacterCoordinatesRight.colliderect(treeCoordinates3) and not mainCharacterCoordinatesRight.colliderect(treeCoordinates2) and not mainCharacterCoordinatesRight.colliderect(treeCoordinates1) and not mainCharacterCoordinatesRight.colliderect(crossCoordinates) and not mainCharacterCoordinatesLeft.colliderect(rightborder) and not mainCharacterCoordinatesRight.colliderect(wellCoordinates) and not mainCharacterCoordinatesRight.colliderect(trainCoordinates) and not mainCharacterCoordinatesRight.colliderect(graveyardCoordinates)):
counter = (counter + 1) % len(mainCharacterRight)
x += 2
CameraX += 2

if (keys_pressed[pygame.K_UP] and not mainCharacterCoordinatesTop.colliderect(treeCoordinates8) and not mainCharacterCoordinatesTop.colliderect(treeCoordinates7) and not mainCharacterCoordinatesTop.colliderect(treeCoordinates6) and not mainCharacterCoordinatesTop.colliderect(treeCoordinates5) and not mainCharacterCoordinatesTop.colliderect(treeCoordinates4) and not mainCharacterCoordinatesTop.colliderect(treeCoordinates3) and not mainCharacterCoordinatesTop.colliderect(treeCoordinates2) and not mainCharacterCoordinatesTop.colliderect(treeCoordinates1) and not mainCharacterCoordinatesTop.colliderect(crossCoordinates) and not mainCharacterCoordinatesTop.colliderect(topborder) and not mainCharacterCoordinatesTop.colliderect(wellCoordinates) and not mainCharacterCoordinatesTop.colliderect(trainCoordinates) and not mainCharacterCoordinatesTop.colliderect(graveyardCoordinates)):
counter = (counter + 1) % len(mainCharacterBack)
y -= 2
CameraY -= 2

if (keys_pressed[pygame.K_DOWN] and not mainCharacterCoordinatesBottom.colliderect(treeCoordinates8) and not mainCharacterCoordinatesBottom.colliderect(treeCoordinates7) and not mainCharacterCoordinatesBottom.colliderect(treeCoordinates6) and not mainCharacterCoordinatesBottom.colliderect(treeCoordinates5) and not mainCharacterCoordinatesBottom.colliderect(treeCoordinates4) and not mainCharacterCoordinatesBottom.colliderect(treeCoordinates3) and not mainCharacterCoordinatesBottom.colliderect(treeCoordinates2) and not mainCharacterCoordinatesBottom.colliderect(treeCoordinates1) and not mainCharacterCoordinatesBottom.colliderect(crossCoordinates) and not mainCharacterCoordinatesBottom.colliderect(bottomborder) and not mainCharacterCoordinatesBottom.colliderect(wellCoordinates)and not mainCharacterCoordinatesBottom.colliderect(trainCoordinates) and not mainCharacterCoordinatesBottom.colliderect(graveyardCoordinates)):
counter = (counter + 1) % len(mainCharacterFront)
y += 2
CameraY += 2


The second Issue which I have is whether I should create functions for the stationary objects. For example at this moment, I have:

 crossImage1 = pygame.image.load('cross.png')
gameDisplay.blit(crossImage1,( 680 - CameraX , 300 - CameraY))


Should I change these into functions like the 'mainCharacter' as it can be seen below?

def mainCharacter(x,y,CameraX,CameraY):
gameDisplay.blit(mainCharacterImage,(x - CameraX,y - CameraY))

mainCharacter(x,y,CameraX,CameraY)


Or should I keep the functions for only moving objects?

Here is my whole code:

import pygame
import random

pygame.init()
gameDisplay = pygame.display.set_mode((800,600))
pygame.display.set_caption("No Name")
clock = pygame.time.Clock()
pygame.key.set_repeat(1, 1)

pygame.mixer.music.load('09 Terras Theme (Final Fantasy VI).mp3')
pygame.mixer.music.play(-1)

CameraX = 0
CameraY = 0
x = 626
y = 384
counter = 0

f = open('x.txt')

f = open('y.txt')

CameraX = x-400
CameraY = y-300

def mainCharacter(x,y,CameraX,CameraY):
gameDisplay.blit(mainCharacterImage,(x - CameraX,y - CameraY))

Exit = False

while (Exit == False):

for event in pygame.event.get():
if event.type == pygame.QUIT:
Exit = True
mainCharacterLeft = ['main character (left-left leg).png','main character (left-left leg).png','main character (left-left leg).png','main character (left-left leg).png','main character (left).png','main character (left).png','main character (left).png','main character (left).png','main character (left-right leg).png','main character (left-right leg).png','main character (left-right leg).png','main character (left-right leg).png']
mainCharacterRight = ['main character (right-left leg).png','main character (right-left leg).png','main character (right-left leg).png','main character (right-left leg).png','main character (right).png','main character (right).png','main character (right).png','main character (right).png','main character (right-right leg).png','main character (right-right leg).png','main character (right-right leg).png','main character (right-right leg).png']
mainCharacterBack = ['main character (back-left leg).png','main character (back-left leg).png','main character (back-left leg).png','main character (back-left leg).png','main character (back).png','main character (back).png','main character (back).png','main character (back).png','main character (back-right leg).png','main character (back-right leg).png','main character (back-right leg).png','main character (back-right leg).png']
mainCharacterFront = ['main character (front-left leg).png','main character (front-left leg).png','main character (front-left leg).png','main character (front-left leg).png','main character (front).png','main character (front).png','main character (front).png','main character (front).png','main character (front-right leg).png','main character (front-right leg).png','main character (front-right leg).png','main character (front-right leg).png']
keys_pressed = pygame.key.get_pressed()
mainCharacterCoordinates = pygame.Rect((x,y),(x+30,y+30))
wellCoordinates = pygame.Rect((0,600),(33,34))
trainCoordinates = pygame.Rect((-1000,20),(2000,54))
crossCoordinates = pygame.Rect((680,300),(80,180))

mainCharacterCoordinatesLeft = pygame.Rect((x,y+27),(1,5))
mainCharacterCoordinatesRight = pygame.Rect((x+28,y+27),(1,5))
mainCharacterCoordinatesTop = pygame.Rect((x+2,y+20),(26,5))
mainCharacterCoordinatesBottom = pygame.Rect((x+2,y+27),(26,7))

leftborder = pygame.Rect((-1200,-2000),(10,6000))
rightborder = pygame.Rect((800,-2000),(10,6000))
topborder = pygame.Rect((-1200,-200),(6000,10))
bottomborder = pygame.Rect((-1200,800),(6000,10))

treeCoordinates1 = pygame.Rect((-1200,300),(30,31))
treeCoordinates2 = pygame.Rect((-800,500),(30,31))
treeCoordinates3 = pygame.Rect((-400,400),(30,31))
treeCoordinates4 = pygame.Rect((-600,400),(30,31))
treeCoordinates5 = pygame.Rect((100,300),(30,31))
treeCoordinates6 = pygame.Rect((500,600),(30,31))
treeCoordinates7 = pygame.Rect((-1000,500),(30,31))
treeCoordinates8 = pygame.Rect((-300,700),(30,31))

graveyardCoordinates = pygame.Rect((630,350),(30,31))

if (keys_pressed[pygame.K_LEFT] and not mainCharacterCoordinatesLeft.colliderect(treeCoordinates8) and not mainCharacterCoordinatesLeft.colliderect(treeCoordinates7) and not mainCharacterCoordinatesLeft.colliderect(treeCoordinates6) and not mainCharacterCoordinatesLeft.colliderect(treeCoordinates5) and not mainCharacterCoordinatesLeft.colliderect(treeCoordinates4) and not mainCharacterCoordinatesLeft.colliderect(treeCoordinates3) and not mainCharacterCoordinatesLeft.colliderect(treeCoordinates2) and not mainCharacterCoordinatesLeft.colliderect(treeCoordinates1) and not mainCharacterCoordinatesLeft.colliderect(crossCoordinates) and not mainCharacterCoordinatesLeft.colliderect(leftborder) and not mainCharacterCoordinatesLeft.colliderect(wellCoordinates) and not mainCharacterCoordinatesLeft.colliderect(trainCoordinates) and not mainCharacterCoordinatesLeft.colliderect(graveyardCoordinates)):
counter = (counter + 1) % len(mainCharacterLeft)
x -= 2
CameraX -= 2

if (keys_pressed[pygame.K_RIGHT] and not mainCharacterCoordinatesRight.colliderect(treeCoordinates8) and not mainCharacterCoordinatesRight.colliderect(treeCoordinates7) and not mainCharacterCoordinatesRight.colliderect(treeCoordinates6) and not mainCharacterCoordinatesRight.colliderect(treeCoordinates5) and not mainCharacterCoordinatesRight.colliderect(treeCoordinates4) and not mainCharacterCoordinatesRight.colliderect(treeCoordinates3) and not mainCharacterCoordinatesRight.colliderect(treeCoordinates2) and not mainCharacterCoordinatesRight.colliderect(treeCoordinates1) and not mainCharacterCoordinatesRight.colliderect(crossCoordinates) and not mainCharacterCoordinatesLeft.colliderect(rightborder) and not mainCharacterCoordinatesRight.colliderect(wellCoordinates) and not mainCharacterCoordinatesRight.colliderect(trainCoordinates) and not mainCharacterCoordinatesRight.colliderect(graveyardCoordinates)):
counter = (counter + 1) % len(mainCharacterRight)
x += 2
CameraX += 2

if (keys_pressed[pygame.K_UP] and not mainCharacterCoordinatesTop.colliderect(treeCoordinates8) and not mainCharacterCoordinatesTop.colliderect(treeCoordinates7) and not mainCharacterCoordinatesTop.colliderect(treeCoordinates6) and not mainCharacterCoordinatesTop.colliderect(treeCoordinates5) and not mainCharacterCoordinatesTop.colliderect(treeCoordinates4) and not mainCharacterCoordinatesTop.colliderect(treeCoordinates3) and not mainCharacterCoordinatesTop.colliderect(treeCoordinates2) and not mainCharacterCoordinatesTop.colliderect(treeCoordinates1) and not mainCharacterCoordinatesTop.colliderect(crossCoordinates) and not mainCharacterCoordinatesTop.colliderect(topborder) and not mainCharacterCoordinatesTop.colliderect(wellCoordinates) and not mainCharacterCoordinatesTop.colliderect(trainCoordinates) and not mainCharacterCoordinatesTop.colliderect(graveyardCoordinates)):
counter = (counter + 1) % len(mainCharacterBack)
y -= 2
CameraY -= 2

if (keys_pressed[pygame.K_DOWN] and not mainCharacterCoordinatesBottom.colliderect(treeCoordinates8) and not mainCharacterCoordinatesBottom.colliderect(treeCoordinates7) and not mainCharacterCoordinatesBottom.colliderect(treeCoordinates6) and not mainCharacterCoordinatesBottom.colliderect(treeCoordinates5) and not mainCharacterCoordinatesBottom.colliderect(treeCoordinates4) and not mainCharacterCoordinatesBottom.colliderect(treeCoordinates3) and not mainCharacterCoordinatesBottom.colliderect(treeCoordinates2) and not mainCharacterCoordinatesBottom.colliderect(treeCoordinates1) and not mainCharacterCoordinatesBottom.colliderect(crossCoordinates) and not mainCharacterCoordinatesBottom.colliderect(bottomborder) and not mainCharacterCoordinatesBottom.colliderect(wellCoordinates)and not mainCharacterCoordinatesBottom.colliderect(trainCoordinates) and not mainCharacterCoordinatesBottom.colliderect(graveyardCoordinates)):
counter = (counter + 1) % len(mainCharacterFront)
y += 2
CameraY += 2

a = random.randrange(-3000,4000)
b = random.randrange(-2000,3000)

battlefield = pygame.Rect((a,b),(10,10))

if (mainCharacterCoordinates.colliderect(battlefield) and (keys_pressed[pygame.K_DOWN] or keys_pressed[pygame.K_UP] or keys_pressed[pygame.K_RIGHT] or keys_pressed[pygame.K_LEFT])):
f = open('x.txt', 'w')
f.write(str(x))
f.close()

f = open('y.txt', 'w')
f.write(str(y))
f.close()
execfile('battlefield.py')
Exit = True

if (x <= 630 and):
if (x >= 660 and):
if(y <= 350 and ):
if(y >= 380 and ):

gameDisplay.blit(Background,(-2000 - CameraX, -600 - CameraY))
gameDisplay.blit(trainbottomImage,(-1000 - CameraX ,25 - CameraY))
gameDisplay.blit(wellImage,(0 - CameraX , 600 - CameraY))

gameDisplay.blit(treebottomImage1,( -1200 - CameraX , 300 - CameraY))
gameDisplay.blit(treebottomImage2,( -800 - CameraX , 500 - CameraY))
gameDisplay.blit(treebottomImage3,( -400 - CameraX , 400 - CameraY))
gameDisplay.blit(treebottomImage4,(  -600 - CameraX , 400 - CameraY))
gameDisplay.blit(treebottomImage5,( 100 - CameraX , 300 - CameraY))
gameDisplay.blit(treebottomImage6,( 500 - CameraX , 600 - CameraY))
gameDisplay.blit(treebottomImage7,( -1000 - CameraX , 500 - CameraY))
gameDisplay.blit(treebottomImage8,( -300 - CameraX , 700 - CameraY))

gameDisplay.blit(crossImage1,( 680 - CameraX , 300 - CameraY))
gameDisplay.blit(crossImage2,( 680 - CameraX , 350 - CameraY))
gameDisplay.blit(crossImage3,( 680 - CameraX , 400 - CameraY))
gameDisplay.blit(crossImage4,( 680 - CameraX , 450 - CameraY))
gameDisplay.blit(crossImage5,( 730 - CameraX , 300 - CameraY))
gameDisplay.blit(crossImage6,( 730 - CameraX , 350 - CameraY))
gameDisplay.blit(crossImage7,( 730 - CameraX , 400 - CameraY))
gameDisplay.blit(crossImage8,( 730 - CameraX , 450 - CameraY))

gameDisplay.blit(graveyard,(630 - CameraX , 350 - CameraY))
mainCharacter(x,y,CameraX,CameraY)

gameDisplay.blit(treetopImage1,( -1200 - CameraX , 269 - CameraY))
gameDisplay.blit(treetopImage2,( -800 - CameraX , 469 - CameraY))
gameDisplay.blit(treetopImage3,( -400 - CameraX , 369 - CameraY))
gameDisplay.blit(treetopImage4,(  -600 - CameraX , 369 - CameraY))
gameDisplay.blit(treetopImage5,( 100 - CameraX , 269 - CameraY))
gameDisplay.blit(treetopImage6,( 500 - CameraX , 569 - CameraY))
gameDisplay.blit(treetopImage7,( -1000 - CameraX , 469 - CameraY))
gameDisplay.blit(treetopImage8,( -300 - CameraX , 669 - CameraY))

gameDisplay.blit(traintopImage,(-1000 - CameraX ,-7 - CameraY))
pygame.display.update()
clock.tick(60)

pygame.quit()
quit()

-
+1 for having a cute looking game – Insane Feb 3 at 6:20

crossImage1 = pygame.image.load('cross.png')


This is bad practice on so many levels.

• You have a bunch variables named like myNameX; always a bad sign.
• These variables are all equal to the same thing.

Now, I would go through how to fix these individually, but looking at how you are using these variables, there is no need. Again, each of these variables all contains the same exact image. And, the only time you are using these variables is to print the image out. Here is an example of one place:

gameDisplay.blit(treetopImage1,( -1200 - CameraX , 269 - CameraY))
gameDisplay.blit(treetopImage2,( -800 - CameraX , 469 - CameraY))
gameDisplay.blit(treetopImage3,( -400 - CameraX , 369 - CameraY))
gameDisplay.blit(treetopImage4,(  -600 - CameraX , 369 - CameraY))
gameDisplay.blit(treetopImage5,( 100 - CameraX , 269 - CameraY))
gameDisplay.blit(treetopImage6,( 500 - CameraX , 569 - CameraY))
gameDisplay.blit(treetopImage7,( -1000 - CameraX , 469 - CameraY))
gameDisplay.blit(treetopImage8,( -300 - CameraX , 669 - CameraY))


Why do you need 8 different variables holding the same image to do this? Why can you not just use a single variable? You are wasting so much space and time to store these and the way you are using them is super overkill.

All you really need is love one:

crossImage = pygame.image.load('cross.png')

...

gameDisplay.blit(crossImage, ...)
gameDisplay.blit(crossImage, ...)


The same can be applied to those similar series of repetitive image variables, and simplifies the rest of your code too.

treeCoordinates1 = pygame.Rect((-1200,300),(30,31))
treeCoordinates2 = pygame.Rect((-800,500),(30,31))
treeCoordinates3 = pygame.Rect((-400,400),(30,31))
treeCoordinates4 = pygame.Rect((-600,400),(30,31))
treeCoordinates5 = pygame.Rect((100,300),(30,31))
treeCoordinates6 = pygame.Rect((500,600),(30,31))
treeCoordinates7 = pygame.Rect((-1000,500),(30,31))
treeCoordinates8 = pygame.Rect((-300,700),(30,31))


Again. These chains of variables with numbers at the end of them. Typically, when you have variables named like this, ya dun goofed.

Instead of keeping a bunch of variables like this, you should be storing them in an array (or in this case, a tuple).

treeCoordinates = (pygame.Rect(...), pygame.Rect(...))


This will really simplify your code in a lot of places. For example, inthosereallylongifstatementswhereyouarecheckingwhichkeywaspressed, rather than going through each coordinate in the conditionals, you can simplify it with a loop:

for treeCoordinate in treeCoordinates


This will make your code a lot easier on the eye (and could made even better if incorporated into a comprehension).

if (x <= 630 and):
if (x >= 660 and):
if(y <= 350 and ):
if(y >= 380 and ):


What's with these floating ands? If you don't have a second clause, then you aren't to put an and down; it's just plain wrong.

-
why not for treeCoord in treeCoordinates: ? – Eugene Feb 3 at 0:32
@Eugene Thanks! I've edited my answer. – SirPython Feb 3 at 0:54

You should always close any file you open. You can guarantee this by using a context manager.

with open("some_file_name") as f:


This is a safe (and clean) way to guarantee that a file is closed, no matter what happens inside the with block.

-
Have missed that one – Eugene Feb 3 at 10:49

Welcome here!

First of all, you have a lot of vars for images. Consider using image lists, like:

CROSS_IMAGE_FILENAME = ['cross.png'] * 8 # or different list
crossImages = [pygame.image.load(filename) for filename in CROSS_IMAGE_FILENAME]


Camera and current position should be grouped into Points or something else, so instead of SomethingX and SomethingY you'll have something.x and something.y

mainCharacter is better named something like drawMainCharacter. It is better to use verbs here for function names.

Exit == False condition could be written just as not Exit

do you really want to read main character (front).png every loop iteration?

Use lists instead of lots of similarly named variables. Your vars are exactly the reason you have to write such long conditions:

if (keys_pressed[pygame.K_LEFT] and not mainCharacterCoordinatesLeft.colliderect(treeCoordinates8) and not mainCharacterCoordinatesLeft.colliderect(treeCoordinates7) and not mainCharacterCoordinatesLeft.colliderect(treeCoordinates6) and not mainCharacterCoordinatesLeft.colliderect(treeCoordinates5) and not mainCharacterCoordinatesLeft.colliderect(treeCoordinates4) and not mainCharacterCoordinatesLeft.colliderect(treeCoordinates3) and not mainCharacterCoordinatesLeft.colliderect(treeCoordinates2) and not mainCharacterCoordinatesLeft.colliderect(treeCoordinates1) and not mainCharacterCoordinatesLeft.colliderect(crossCoordinates) and not mainCharacterCoordinatesLeft.colliderect(leftborder) and not mainCharacterCoordinatesLeft.colliderect(wellCoordinates) and not mainCharacterCoordinatesLeft.colliderect(trainCoordinates) and not mainCharacterCoordinatesLeft.colliderect(graveyardCoordinates)):


where it could be written something like that:

if keys_pressed[pygame.K_LEFT] not any(mainCharacterCoordinatesLeft.colliderect(obj) for obj in objects):


where objects is a list of all in-game objects like trees and houses

all blits should be moved to separate function like drawScene

-