Reputation: 34
I am trying to add one of my walls when the player hits a score of 10. The desired behaviour would be for the wall to stay after the score requirement is complete. I have tried a few different ways, first I tried to do a simple if statement the issue is the wall doesn't draw I added a display update and it just flickers I assumed because it was constantly updating where the statement is true so I added
run_once = 0
while True: # main game loop
if run_once == 0 and score >= 10:
run_once = 1
drawWall(wallCoords)
pygame.display.update()
this makes the wall spawn and go away I needed to add my hit logic to the statement however don't want that to run once so I did a elif with the hit logic
elif run_once == 1:
#check if worm hit a wall(one for each block in wall)
if wormCoords[HEAD]['x'] == wallCoords[0]['x'] and wormCoords[HEAD]['y'] == wallCoords[0]['y']:
high_score = score
set_high_score(HIGH_SCORE_FILE, player_name, high_score)
return
elif wormCoords[HEAD]['x'] == wallCoords2[0]['x'] and wormCoords[HEAD]['y'] == wallCoords2[0]:
high_score = score
set_high_score(HIGH_SCORE_FILE, player_name, high_score)
return
if wormCoords[HEAD]['x'] == wallCoords[1]['x'] and wormCoords[HEAD]['y'] == wallCoords[1]['y']:
high_score = score
set_high_score(HIGH_SCORE_FILE, player_name, high_score)
return
elif wormCoords[HEAD]['x'] == wallCoords2[1]['x'] and wormCoords[HEAD]['y'] == wallCoords2[1]['y']:
high_score = score
set_high_score(HIGH_SCORE_FILE, player_name, high_score)
return
if wormCoords[HEAD]['x'] == wallCoords[2]['x'] and wormCoords[HEAD]['y'] == wallCoords[2]['y']:
high_score = score
set_high_score(HIGH_SCORE_FILE, player_name, high_score)
return
elif wormCoords[HEAD]['x'] == wallCoords2[2]['x'] and wormCoords[HEAD]['y'] == wallCoords2[2]['y']:
high_score = score
set_high_score(HIGH_SCORE_FILE, player_name, high_score)
return
if wormCoords[HEAD]['x'] == wallCoords2[3]['x'] and wormCoords[HEAD]['y'] == wallCoords2[3]['y']:
high_score = score
set_high_score(HIGH_SCORE_FILE, player_name, high_score)
return
if wormCoords[HEAD]['x'] == wallCoords2[4]['x'] and wormCoords[HEAD]['y'] == wallCoords2[4]['y']:
high_score = score
set_high_score(HIGH_SCORE_FILE, player_name, high_score)
return
what could I do differently? Here is a minimal version of the full code
import random, pygame, sys, time, pickle, os
from pygame.locals import *
from operator import itemgetter
FPS = 15
EASYFPS = 12
HARDFPS = 25
INSANEFPS = 35
drawHighApple = 10
drawSuperHighApple = 40
WINDOWWIDTH = 640
WINDOWHEIGHT = 480
CELLSIZE = 20
assert WINDOWWIDTH % CELLSIZE == 0, "Window width must be a multiple of cell size."
assert WINDOWHEIGHT % CELLSIZE == 0, "Window height must be a multiple of cell size."
CELLWIDTH = int(WINDOWWIDTH / CELLSIZE)
CELLHEIGHT = int(WINDOWHEIGHT / CELLSIZE)
# R G B
WHITE = (255, 255, 255)
BLACK = ( 0, 0, 0)
RED = (255, 0, 0)
YELLOW = (255, 255, 0)
GREEN = ( 0, 255, 0)
GRAY = (185, 185, 185)
BLUE = ( 0, 0, 255)
NAVYBLUE = ( 60, 60, 100)
ORANGE = (255, 128, 0)
PURPLE = (170, 0, 255)
CYAN = ( 0, 255, 255)
LIGHTRED = (175, 20, 20)
LIGHTGREEN = ( 20, 175, 20)
LIGHTBLUE = ( 20, 20, 175)
LIGHTYELLOW = (175, 175, 20)
BRIGHTBLUE = ( 0, 50, 255)
DARKGREEN = ( 0, 155, 0)
DARKGRAY = ( 40, 40, 40)
BGCOLOR = BLACK
UP = 'up'
DOWN = 'down'
LEFT = 'left'
RIGHT = 'right'
HEAD = 0
def main():
noSelection = True
global FPSCLOCK, DISPLAYSURF, BASICFONT, EASY_SURF, EASY_RECT, NORMAL_SURF, NORMAL_RECT, HARD_SURF, HARD_RECT, INSANE_SURF, INSANE_RECT
pygame.init()
FPSCLOCK = pygame.time.Clock()
DISPLAYSURF = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT))
BASICFONT = pygame.font.Font('freesansbold.ttf', 18)
pygame.display.set_caption('Worms')
showStartScreen()
mousex = 0
mousey = 0
while True:
noSelection = True
for event in pygame.event.get():
if event.type == MOUSEBUTTONUP:
mousex, mousey = event.pos
if noSelection == True:
runGame()
showGameOverScreen()
def runGame():
# Sets a random start point.
# Sets a random start point.
startx = random.randint(5, CELLWIDTH - 6)
starty = random.randint(5, CELLHEIGHT - 6)
wallsx = int(19)
wallsy = int(12)
wallsx2 = int(9)
wallsy2 = int(10)
wormCoords = [{'x': startx, 'y': starty},
{'x': startx - 1, 'y': starty},
{'x': startx - 2, 'y': starty}]
direction = RIGHT
wallCoords = [{'x': wallsx, 'y': wallsy},
{'x': wallsx, 'y': wallsy + 1},
{'x': wallsx, 'y': wallsy + 2}]
wallCoords2 = [{'x': wallsx2, 'y': wallsy2 },
{'x': wallsx2, 'y': wallsy2 + 1},
{'x': wallsx2, 'y': wallsy2 + 2},
{'x': wallsx2 + 1, 'y': wallsy2 },
{'x': wallsx2 + 1, 'y': wallsy2 + 2 }]
# Start the apple in a random place.
apple = getRandomLocation()
highValueApple = getRandomLocation()
superHighValueApple = getRandomLocation()
lastHighValueApple = time.time()
lastSuperHighApple = time.time()
score = 0
run_once = 0
while True: # main game loop
if run_once == 0 and score >= 10:
run_once = 1
drawWall(wallCoords)
pygame.display.update()
elif run_once == 1:
#check if worm hit a wall(one for each block in wall)
if wormCoords[HEAD]['x'] == wallCoords[0]['x'] and wormCoords[HEAD]['y'] == wallCoords[0]['y']:
high_score = score
return
elif wormCoords[HEAD]['x'] == wallCoords2[0]['x'] and wormCoords[HEAD]['y'] == wallCoords2[0]:
high_score = score
return
if wormCoords[HEAD]['x'] == wallCoords[1]['x'] and wormCoords[HEAD]['y'] == wallCoords[1]['y']:
high_score = score
return
elif wormCoords[HEAD]['x'] == wallCoords2[1]['x'] and wormCoords[HEAD]['y'] == wallCoords2[1]['y']:
high_score = score
return
if wormCoords[HEAD]['x'] == wallCoords[2]['x'] and wormCoords[HEAD]['y'] == wallCoords[2]['y']:
high_score = score
return
elif wormCoords[HEAD]['x'] == wallCoords2[2]['x'] and wormCoords[HEAD]['y'] == wallCoords2[2]['y']:
high_score = score
return
if wormCoords[HEAD]['x'] == wallCoords2[3]['x'] and wormCoords[HEAD]['y'] == wallCoords2[3]['y']:
high_score = score
return
if wormCoords[HEAD]['x'] == wallCoords2[4]['x'] and wormCoords[HEAD]['y'] == wallCoords2[4]['y']:
high_score = score
return
if highValueApple == False:
# No high value apple
highValueApple = getRandomLocation()
lastHighValueApple = time.time()
elif superHighValueApple == False:
#No super high value apple
superHighValueApple = getRandomLocation()
lastSuperHighApple = time.time()
for event in pygame.event.get():
if event.type == QUIT:
terminate()
elif event.type == KEYDOWN:
if (event.key == K_LEFT or event.key == K_a) and direction != RIGHT:
direction = LEFT
elif (event.key == K_RIGHT or event.key == K_d) and direction != LEFT:
direction = RIGHT
elif (event.key == K_UP or event.key == K_w) and direction != DOWN:
direction = UP
elif (event.key == K_DOWN or event.key == K_s) and direction != UP:
direction = DOWN
elif event.key == K_ESCAPE:
terminate()
# check if the worm has hit itsself or the edge
if wormCoords[HEAD]['x'] == -1 or wormCoords[HEAD]['x'] == CELLWIDTH or wormCoords[HEAD]['y'] == -1 or wormCoords[HEAD]['y'] == CELLHEIGHT:
return
for wormBody in wormCoords[1:]:
if wormBody['x'] == wormCoords[HEAD]['x'] and wormBody['y'] == wormCoords[HEAD]['y']:
return
# check if worm has eaten an apply
if wormCoords[HEAD]['x'] == apple['x'] and wormCoords[HEAD]['y'] == apple['y']:
# don't remove worms tal segment
score += 1
apple = getRandomLocation()
elif wormCoords[HEAD]['x'] == highValueApple['x'] and wormCoords[HEAD]['y'] == highValueApple['y']:
lastHighValueApple = time.time() # Resets lastHighValueApple (IMPORTANT if you want to keep the draw delay after eating an apple)
score += 2
highValueApple = getRandomLocation()
elif wormCoords[HEAD]['x'] == superHighValueApple['x'] and wormCoords[HEAD]['y'] == superHighValueApple['y']:
lastSuperHighApple = time.time() #resets lastSuperHighApple (IMPORTANT if you want to keep the draw delay after eating an apple)
score += 5
superHighValueApple = getRandomLocation()
else:
del wormCoords[-1] # remove worms tail segment
# move the worm by adding segment in direction it is moving
if direction == UP:
newHead = {'x': wormCoords[HEAD]['x'], 'y': wormCoords[HEAD]['y'] - 1}
elif direction == DOWN:
newHead = {'x': wormCoords[HEAD]['x'], 'y': wormCoords[HEAD]['y'] + 1}
elif direction == LEFT:
newHead = {'x': wormCoords[HEAD]['x'] - 1, 'y': wormCoords[HEAD]['y']}
elif direction == RIGHT:
newHead = {'x': wormCoords[HEAD]['x'] + 1, 'y': wormCoords[HEAD]['y']}
wormCoords.insert(0, newHead)
DISPLAYSURF.fill(BGCOLOR)
drawGrid()
drawWorm(wormCoords)
if time.time() - lastHighValueApple > drawHighApple:
drawHighValueApple(highValueApple)
drawApple(apple)
if time.time() - lastSuperHighApple > drawSuperHighApple:
drawSuperHighValueApple(superHighValueApple)
drawScore(score)
pygame.display.update()
FPSCLOCK.tick(FPS)
def drawPressKeyMsg():
pressKeySurf = BASICFONT.render('Press a Key to play.', True, DARKGRAY)
pressKeyRect = pressKeySurf.get_rect()
pressKeyRect.topleft = (WINDOWWIDTH - 200, WINDOWHEIGHT - 30)
DISPLAYSURF.blit(pressKeySurf, pressKeyRect)
def checkForKeyPress():
if len(pygame.event.get(QUIT)) > 0:
terminate()
keyUpEvents = pygame.event.get(KEYUP)
if len(keyUpEvents) == 0:
return None
if keyUpEvents[0].key == K_ESCAPE:
terminate()
return keyUpEvents[0].key
def showStartScreen():
titleFont = pygame.font.Font('freesansbold.ttf', 100)
titleSurf1 = titleFont.render('Wormy!', True, WHITE, DARKGREEN)
titleSurf2 = titleFont.render('Wormy!', True, GREEN)
degrees1 = 0
degrees2 = 0
while True:
DISPLAYSURF.fill(BGCOLOR)
rotatedSurf1 = pygame.transform.rotate(titleSurf1, degrees1)
rotatedRect1 = rotatedSurf1.get_rect()
rotatedRect1.center = (WINDOWWIDTH / 2, WINDOWHEIGHT / 2)
DISPLAYSURF.blit(rotatedSurf1, rotatedRect1)
rotatedSurf2 = pygame.transform.rotate(titleSurf2, degrees2)
rotatedRect2 = rotatedSurf2.get_rect()
rotatedRect2.center = (WINDOWWIDTH / 2, WINDOWHEIGHT / 2)
DISPLAYSURF.blit(rotatedSurf2, rotatedRect2)
drawPressKeyMsg()
if checkForKeyPress():
pygame.event.get() #clear event que
return
pygame.display.update()
FPSCLOCK.tick(FPS)
degrees1 += 3
degrees2 += 7
def terminate():
pygame.quit()
sys.exit()
def getRandomLocation():
return {'x': random.randint(0, CELLWIDTH - 1), 'y': random.randint(0,
CELLHEIGHT - 1)}
def showGameOverScreen():
gameOverFont = pygame.font.Font('freesansbold.ttf', 150)
gameSurf = gameOverFont.render('Game', True, WHITE)
overSurf = gameOverFont.render('Over', True, WHITE)
gameRect = gameSurf.get_rect()
overRect = overSurf.get_rect()
gameRect.midtop = (WINDOWWIDTH / 2, 10)
overRect.midtop = (WINDOWWIDTH / 2, gameRect.height + 10 + 25)
DISPLAYSURF.blit(gameSurf, gameRect)
DISPLAYSURF.blit(overSurf, overRect)
drawPressKeyMsg()
pygame.display.update()
pygame.time.wait(500)
checkForKeyPress()
while True:
if checkForKeyPress():
pygame.event.get() # clear event queue
return
def drawScore(score):
scoreSurf = BASICFONT.render('Score: %s' % (score), True, WHITE)
scoreRect = scoreSurf.get_rect()
scoreRect.topleft = (WINDOWWIDTH - 120, 10)
DISPLAYSURF.blit(scoreSurf, scoreRect)
def drawWorm(wormCoords):
for coord in wormCoords:
x = coord['x'] * CELLSIZE
y = coord['y'] * CELLSIZE
wormSegmentRect = pygame.Rect(x, y, CELLSIZE, CELLSIZE)
pygame.draw.rect(DISPLAYSURF, GREEN, wormSegmentRect)
wormInnerSegmentRect = pygame.Rect(x + 4, y + 4, CELLSIZE - 8, CELLSIZE - 8)
pygame.draw.rect(DISPLAYSURF, GREEN, wormInnerSegmentRect)
def drawWall(wallCoords):
for coord in wallCoords:
x = coord['x'] * CELLSIZE
y = coord['y'] * CELLSIZE
wallSegmentRect = pygame.Rect(x, y, CELLSIZE, CELLSIZE)
pygame.draw.rect(DISPLAYSURF, BLUE, wallSegmentRect)
wallInnerRect = pygame.Rect(x + 4, y + 4, CELLSIZE - 8, CELLSIZE - 8)
pygame.draw.rect(DISPLAYSURF, BLUE, wallInnerRect)
def drawWall2(wallCoords):
for coord in wallCoords:
x = coord['x'] * CELLSIZE
y = coord['y'] * CELLSIZE
wallSegmentRect2 = pygame.Rect(x, y, CELLSIZE, CELLSIZE)
pygame.draw.rect(DISPLAYSURF, GREEN, wallSegmentRect2)
wallInnerRect2 = pygame.Rect(x + 4, y + 4, CELLSIZE - 8, CELLSIZE - 8)
pygame.draw.rect(DISPLAYSURF, GREEN, wallInnerRect2)
def drawApple(coord):
x = coord['x'] * CELLSIZE
y = coord['y'] * CELLSIZE
appleRect = (x, y, CELLSIZE, CELLSIZE)
pygame.draw.rect(DISPLAYSURF, RED, appleRect)
def drawHighValueApple(coord):
x = coord['x'] * CELLSIZE
y = coord['y'] * CELLSIZE
highValueAppleRect = (x, y, CELLSIZE, CELLSIZE)
pygame.draw.rect(DISPLAYSURF, GREEN, highValueAppleRect)
highValueInnerAppleRect = pygame.Rect(x + 2, y + 2, CELLSIZE - 10, CELLSIZE - 10)
pygame.draw.rect(DISPLAYSURF, RED, highValueInnerAppleRect)
def drawSuperHighValueApple(coord):
x = coord['x'] * CELLSIZE
y = coord['y'] * CELLSIZE
superHighValueAppleRect = (x, y, CELLSIZE, CELLSIZE)
pygame.draw.rect(DISPLAYSURF, CYAN, superHighValueAppleRect)
superHighValueInnerAppleRect = pygame.Rect(x + 3, y + 3, CELLSIZE - 10, CELLSIZE - 10)
pygame.draw.rect(DISPLAYSURF, LIGHTGREEN, superHighValueInnerAppleRect)
def drawGrid():
for x in range(0, WINDOWWIDTH, CELLSIZE):
pygame.draw.line(DISPLAYSURF, DARKGRAY, (x, 0), (x, WINDOWHEIGHT))
for y in range(0, WINDOWHEIGHT, CELLSIZE):
pygame.draw.line(DISPLAYSURF, DARKGRAY, (0, y), (WINDOWWIDTH, y))
if __name__ == '__main__':
main()
Upvotes: 1
Views: 69
Reputation: 267
You can do it diffrent ways :
First you can use a global boolean variable -> show_walls = False
Your wall can exist since the beggining but you only draw them and only check for collision when "show_walls" is True. You set it to True when the score reach 10. Then just never set it back to False, they will stay up like you wish.
As other suggested you can put your walls in a list (which you should honestly, if anything it will simplify you code). You add your walls to the list when the score reach 10, has long as you dont remove them from the list, they will be here.
The problem with your code is your condition before the DrawWall
if run_once == 0 and score >= 10:
run_once = 1
drawWall(wallCoords)
Think about it, when your score, is > or = to 10, you will enter your condition and run_once will be set to 1 so you will never enter this condition again. But you draw your wall inside this if condition. So you will only draw your wall for one frame.
Besides that, there are plenty of concerning points in your code :
DrawWall(...)
and DrawWall2(...)
Yes, I know one draws wall 1 and the other draws wall 2. But just make one function that takes every information about the wall as input and the draw it based on the passed values. Here is an example, obviously the function in my example is pointless but this is just to illustrate what you are doing.
# This is what you are doing :
def print_text1():
print(text1)
def print_text2():
print(text2)
text1 = "foo"
text2 = "bar"
print_text1(text1)
print_text2(text2)
# This is what you should do :
def print_text(text):
print(text)
text1 = "foo"
text2 = "bar"
print_text(text1)
print_text(text2)
Now you could just add as many "text..." variables as you wish, you don't need to write a new function everytime. This may seem obvious here but that is exactly what you are doing with drawWall(...) and drawWall2(...). Here you have two walls, but what if you had 50 ? You would write the same method 50 times with different values ? Very little point in using functions then.
For naming conventions in python, I suggest you check out this link
Don't get discourage ! Many beginners seem to discover their first issues worth asking stack while they make a snake game. Hence I saw many beginners snake's game. And this is one of the best I saw, you have overcomplicated some part of your code and as I mention there are plenty of points that could be greatly improved but this is still a good start ! Keep going
Upvotes: 1