I'm making a game for Flappy Bird, I need to make a score counter, it's there, but it's crooked. It counts a whole bunch of points after the first pipe and does not reset them after death. Below I will attach the code itself and the code of the points.
If you can write the code as it will be correct.
import pygame#импортирование модуля pygame
import random#Добавляет возможность спавнить разные трубы
pygame.init()
WIDTH, HEIGHT = 800, 600#FPS и размеры окна
FPS = 60
window = pygame.display.set_mode((WIDTH, HEIGHT))#Создание окна
clock = pygame.time.Clock()
font1 = pygame.font.Font(None, 35)#шрифты
font2 = pygame.font.Font(None, 80)
imgBG = pygame.image.load('images/fon.png')#Добавление картинок
imgBIRD = pygame.image.load('images/bird.png')
imgPB = pygame.image.load('images/PB.png')
imgPT = pygame.image.load('images/PT.png')
py, sy, ay = HEIGHT // 2, 0, 0 #Значение по py, sy, ay
player = pygame.Rect(HEIGHT // 3, py, 50, 50) #расположение игрока по центру
state = 'start'#состояние старта
timer = 10 #Задержка
pipes = [] #Список труб
bges = [] #Список заднего фона
bges.append(pygame.Rect(0, 0, 288, 600)) #Отображение заднего фона
lives = 3 #Жизни
scores = 0 #Очки
play = True
while play:
for event in pygame.event.get():
if event.type == pygame.QUIT:
play = False
press = pygame.mouse.get_pressed() #Нажатие мыши
keys = pygame.key.get_pressed() #Нажатие пробела
click = press[0] or keys[pygame.K_SPACE]
if timer > 0:
timer -= 1
for i in range(len(bges)-1, -1, -1): #Проверка на удаление и добавление фона
fon = bges[i]
fon.x -= 1
if fon.right < 0:
bges.remove(fon)
if bges[len(bges)-1].right <= WIDTH:
bges.append(pygame.Rect(bges[len(bges)-1].right, 0, 288, 512))##########
for i in range(len(pipes)-1, -1, -1): #Добавление и удаление труб
pipe = pipes[i]
pipe.x -= 3
if pipe.right < 0:
pipes.remove(pipe)###################
if state == 'start':#Состояние статического
if click and timer == 0 and len(pipes) == 0:
state = 'play'
py += (HEIGHT // 2 - py) * 0.1
player.y = py
elif state == 'play': #Состояние если игрок нажимает на кнопку то оно переходит в состояние игры
if click:
ay = -2
else:
ay = 0
py += sy
sy = (sy + ay + 1) * 0.98
player.y = py
if len(pipes) == 0 or pipes[len(pipes)-1].x < WIDTH - 200: #отображение труб
pipes.append(pygame.Rect(WIDTH, 0, 52, 200))
pipes.append(pygame.Rect(WIDTH, 400, 52, 200))
if player.top < 0 or player.bottom > HEIGHT:#Проверка столкновение с трубами
state = 'fall'
for pipe in pipes:
if player.colliderect(pipe):
state = 'fall'
for pipe in pipes:
if player > pipe:
scores += 1
elif state == 'fall':####Состояние когда игрок не может ничего делать
sy, ay = 0, 0
state = 'start'
timer = 60
else:
pass
for fon in bges: #Отображение заднего фона
window.blit(imgBG, fon)##########
for pipe in pipes:#Рисовка труб
if pipe.y == 0:
rect = imgPB.get_rect(bottomleft = pipe.bottomleft)
window.blit(imgPB, rect)
else:
rect = imgPT.get_rect(topleft = pipe.topleft)
window.blit(imgPT, rect)##########
window.blit(imgBIRD, player)#Рисовка игрока
text = font1.render('Очки: ' + str(scores), 1, pygame.Color('White')) #Текст очки
window.blit(text, (10, 10))
text = font1.render('Жизни: ' + str(lives), 1, pygame.Color('White'))#Текст жизни
window.blit(text, (110, 10))
pygame.display.update()#Обновление экрана
clock.tick(FPS)
pygame.quit()
Code scores
for pipe in pipes:
if player > pipe:
scores += 1
You should replace if player > pipe: with if pipe.x < player <= (pipe.x + 3): to fix the game adding a bunch of points (instead of adding 1 to the score for each pipe passed so far, it adds 1 if you're in a pipe).
Change the 3 of pipe + 3 by the speed of your pipes (in case of your program it's 3 so I put 3).
For the score not resetting, I suggest replacing this
elif state == 'fall'
sy, ay = 0, 0
state = 'start'
timer = 60
by this
elif state == 'fall'
sy, ay = 0, 0
state = 'start'
timer = 60
scores = 0
assuming this is the part that does stuff upon 'death'.
Not sure it'll work, but it may.
EDIT:
For any problems like TypeError, replace the pipe by pipe.x in the previous test (if pipe < player <= (pipe + 3):) so it gives if pipe.x < player <= (pipe.x + 3):. It should work now...
I've developed a Python code and am looking for improvements and how to add a pause option.
I repeat the exact same lines one after another although I don't know an easier way to do it.
import math, pygame, random, sys, turtle
from itertools import cycle
from datetime import datetime
from pygame import gfxdraw
from pygame.locals import *
def print_text(surface, font, text, surf_rect, x = 0, y = 0, center = False, color = (255,215,0)):
if not center:
textimage = font.render(text, True, color)
surface.blit(textimage, (x, y))
else:
textimage = font.render(text, True, color)
text_rect = textimage.get_rect()
x = (surf_rect.width // 2) - (text_rect.width // 2 )
surface.blit(textimage, (x, y))
def game_is_over(surface, font, ticks):
timer = ticks
surf_rect = surface.get_rect()
surf_height = surf_rect.height
surf_width = surf_rect.width
print_text(screen, font, "Y O U G O T Y E E T E D (Game Over)", surf_rect, y = 260,\
center = True)
pygame.display.update()
while True:
ticks = pygame.time.get_ticks()
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
if ticks > timer + 3000:
break
def next_level(level):
level += 1
if level > 6:
level = 6
return level
#The Level Creator
def load_level(level):
invaders, colors = [], []
start_intx, end_intx, increment_intx = 85, 725, 40
start_inty, end_inty, increment_inty = 60, 60, 30
end_inty = end_inty + level * 30 # 30 being the number of rows / intruders
color_val = 256 / end_inty #For Colour Repetition
for x in range(start_intx, end_intx, increment_intx):
for y in range(start_inty, end_inty, increment_inty):
invaders.append(pygame.Rect(x, y, 30, 15))
colors.append(((x * 0.35) % 256, (y * color_val) % 256))
return invaders, colors, len(invaders)
def draw_title_invader():
rect = Rect(285,247,230,115)#INVATOR
rect2 = Rect(0,0,230,115)
rect3 = Rect(340,120,120,128)#TOP OF HAT
rect4 = Rect(300,200,200,48)#BOT OF HAT
rect5 = Rect(340,182,120,18)#LINE IN HAT
rect_width = 230
a = 175
b = 55
pygame.draw.rect(backbuffer, MGOLD,rect)
#The Left Eye in Title Screen
pygame.draw.circle(backbuffer,(0,255,255), (rect.x+46,rect.y+30), 23)
#The Right Eye in Title Screen
pygame.draw.circle(backbuffer,(0,255,255),(rect.x+rect_width-46,rect.y+30)\
,23)
#The Left Side Mouth in Title Screen
pygame.draw.line(backbuffer, RED, (rect.x+46, rect.y+92),\
(rect.x + 115, rect.y + 61), 2)
#The Right Side Mouth in Title Screen
pygame.draw.line(backbuffer, RED, (rect.x+rect_width-46,\
rect.y+92), (rect.x+rect_width-115,\
rect.y+61), 2)
#The Right Eye
pygame.draw.circle(backbuffer,RED,(rect.x+rect_width-115,rect.y+65)\
,23)
#The Hat
pygame.draw.rect(backbuffer, DIMGRAY,(340,120,120,128))
pygame.draw.rect(backbuffer, DIMGRAY,(300,200,200,48))
pygame.draw.rect(backbuffer, WHITE,(340,182,120,18))
def draw_bonus_invader(i, bonus_color, bx, bonus_x):
x, y = bonus_invader.x, bonus_invader.y
pygame.draw.circle(backbuffer, bonus_color, (x+bx, y+7), 2)
if i == 0:
pygame.draw.circle(backbuffer, bonus_color,
(bonus_invader.x+bx,bonus_invader.y+7),2)
if i == 1:
pygame.draw.circle(backbuffer, bonus_color,
(bonus_invader.x+bx,bonus_invader.y+7),2)
if i == 2:
pygame.draw.circle(backbuffer, bonus_color,
(bonus_invader.x+bx,bonus_invader.y+7),2)
if i == 3:
pygame.draw.circle(backbuffer, bonus_color,
(bonus_invader.x+bx,bonus_invader.y+7),2)
if i == 4:
pygame.draw.circle(backbuffer, bonus_color,
(bonus_invader.x+bx,bonus_invader.y+7),2)
if i == 5:
bx = next(bonus_x)
def draw_invader(backbuffer, rect, a, b, animate_invaders, ticks,\
animation_time):
invader_width = 30
#THe Intruder In Game
pygame.draw.rect(backbuffer, MGOLD, rect)
#CONSOLE GRAY
pygame.draw.rect(backbuffer, DIMGRAY,(0,510,800,110))
#Left Eye in game
pygame.gfxdraw.filled_circle(backbuffer, rect.x + 6, rect.y + 4, 3, \
RED)
#Right EYe in game
pygame.gfxdraw.filled_circle(backbuffer, rect.x + invader_width - 7,\
rect.y + 4, 3, RED)
#The draw animation (if needed)
if animate_invaders:
pygame.gfxdraw.filled_trigon(backbuffer, rect.x+6, rect.y + 12,\
rect.x + 14, rect.y + 4, rect.x +\
invader_width - 7, rect.y + 12, RED)
else:
#The Left Side of the mouth
pygame.gfxdraw.line(backbuffer, rect.x + 6, rect.y + 12,\
rect.x + 15, rect.y + 8, RED)
#The Right Side of the mouth
pygame.gfxdraw.line(backbuffer, rect.x + invader_width - 7,\
rect.y + 12, rect.x + invader_width - 15,\
rect.y + 8, RED)
if ticks > animation_time + 200:
animate_invaders = False
return animate_invaders
pygame.init()
pygame.mixer.init() # not always called by pygame.init()
screen = pygame.display.set_mode((800, 600))
pygame.display.set_caption("Yeet The Intruders")
fpsclock = pygame.time.Clock()
#get screen metrics
the_screen = screen.get_rect()
screen_width = the_screen.width
screen_height = the_screen.height
backbuffer = pygame.Surface((the_screen.width, the_screen.height))
# fonts
font1 = pygame.font.SysFont(None, 30)
font2 = pygame.font.SysFont("Impact", 54)
font3 = pygame.font.SysFont("Impact", 36)
# User event frequencies
RELOAD_SPEED = 400
MOVE_SIDEWAYS = 1000
MOVE_DOWN = 1000
BONUS_FREQ = 10000
INV_SHOOT_FREQ = 500
# create user events
move_invaders_sideways = pygame.USEREVENT + 1
move_invaders_down = pygame.USEREVENT + 2
reload = pygame.USEREVENT + 3
invader_shoot = pygame.USEREVENT + 4
bonus = pygame.USEREVENT + 5
# event timers
pygame.time.set_timer(move_invaders_down, 0)
pygame.time.set_timer(move_invaders_sideways, MOVE_SIDEWAYS)
pygame.time.set_timer(reload, RELOAD_SPEED)
pygame.time.set_timer(invader_shoot, INV_SHOOT_FREQ)
pygame.time.set_timer(bonus, BONUS_FREQ)
#List of Colours used
BLACK = (0,0,0)
WHITE = (255,255,255)
RED = (255,0,0)
GREEN = (0,255,0)
BLUE = (0,0,255)
YELLOW = (255,255,0)
DIMGRAY = (105,105,105)
MGOLD = (212,175,55)
shots, invader_shots, inv_shot_colors, bonus_invaders = [], [], [], []
#MY Space Ship
player = Rect(380,578,42,20)
player_gun = Rect(player.x + 18,player.y - 4, 6, 4)
# make screen rect for purposes of text-centering etc
the_screen = screen.get_rect()
# invader animation variables
animation_time = 0
animate_invaders = False
invader_width = 30
invader_height = 15
# flashing text vars
the_text = cycle(["Press Enter To Play, Yeet Master...", ""])
insert = next(the_text)
flash_timer = 0
# flashing bonus item vars
y1,y2,y3,y4,y5,y6 = (255,255,0), (225,225,0), (195,195,0), (165,165,0),\
(135,135,0), (105,105,0)
bonus_colors = cycle([y1,y2,y3,y4,y5,y6])
bonus_color = next(bonus_colors)
bonus_x = cycle([4,11,18,25,32,39]) # change draw x coord
bonus_timer = 0 # used to control frequency of changes
# vars for moving invaders down
move_right, move_down, reloaded = True, True, True
vert_steps = 0
side_steps = 0
moved_down = False
invaders_paused = False
invaders = 0 # prevents error until list is created
initial_invaders = 0 # use to manage freq of inv shots as invaders removed
shoot_level = 1 # manage freq of shots
# various gameplay variables
game_over = True
score = 0
lives = 2
level = 0
playing = False
# event loop
while True:
ticks = pygame.time.get_ticks()
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
if event.type == KEYUP:
if event.key == pygame.K_1 and not game_over:
print("Next level")
if event.type == invader_shoot and not game_over:
i = random.randint(0, len(invaders)-1)
shot_from = invaders[i]
a, b = colors[i]
invader_fired = True
invader_shots.append(Rect(shot_from.x, shot_from.y, 5, 7))
inv_shot_colors.append(RED)
if event.type == reload and not game_over:
reloaded = True
pygame.time.set_timer(reload, 0)
if event.type == move_invaders_sideways and not game_over:
if move_right:
for invader in invaders: invader.move_ip(10,0)
side_steps += 1
else:
for invader in invaders: invader.move_ip(-10,0)
side_steps -= 1
if side_steps == 6 or side_steps == -6:
if vert_steps <= 31: # and not moved_down
pygame.time.set_timer(move_invaders_sideways, 0)
pygame.time.set_timer(move_invaders_down, MOVE_DOWN)
# keep invaders moving horizontally after 31 down movements
else: move_right = not move_right
if event.type == move_invaders_down and not game_over:
#for i in range(20): print("down event")
move_right = not move_right
animate_invaders = True
animation_time = ticks
# reset move_sideways timer
pygame.time.set_timer(move_invaders_sideways, MOVE_SIDEWAYS)
# cancel move_down timer
pygame.time.set_timer(move_invaders_down, 0)
for invader in invaders: invader.move_ip(0,10)
vert_steps += 1
if event.type == bonus and not game_over:
#a = Rect(769,20,45,15)
bonus_invaders.append(Rect(797,20,45,15))
# keyboard polling
pressed = pygame.key.get_pressed()
if pressed[K_ESCAPE]: pygame.quit(), sys.exit()
elif pressed[K_RETURN]:
if game_over: game_over = False
elif pressed[K_d] or pressed[K_RIGHT]:player.move_ip((8, 0))
#player_gun.move_ip((8,0))
elif pressed[K_a] or pressed[K_LEFT]: player.move_ip((-8, 0))
if pressed[K_SPACE]:
if reloaded:
reloaded = False
# create timeout of RELOAD_SPEED
pygame.time.set_timer(reload, RELOAD_SPEED)
# shrink copy of player rect to imitate a missile
missile = player.copy().inflate(-38, -10)
# spawn missile higher to ensure appears missile fired from 'gun'
# when the ship is moving horizontally
missile.y -= 9
shots.append(missile)
#missile_sound.play()
backbuffer.fill(BLACK)
if not game_over:
playing = True
if level == 0:
level = next_level(level)
invaders, colors, initial_invaders = load_level(level)
move_right, move_down, reloaded = True, True, True
vert_steps = 0
side_steps = 0
moved_down = False
invaders_paused = False
pygame.time.set_timer(invader_shoot, 500)
shoot_level = 1
for shot in invader_shots:
shot.move_ip((0,random.randint(5,11)))
if not backbuffer.get_rect().contains(shot):
i = invader_shots.index(shot)
del invader_shots[i]
del inv_shot_colors[i]
if shot.colliderect(player) and shot.y < the_screen.height -10:
lives -= 1
if lives < 0:
lives = 0
game_over = True
i = invader_shots.index(shot)
del invader_shots[i]
del inv_shot_colors[i]
for shot in shots:
shot.move_ip((0, -8))
for inv_shot in invader_shots:
if inv_shot.colliderect(shot):
shots.remove(shot)
i = invader_shots.index(inv_shot)
del invader_shots[i]
del inv_shot_colors[i]
for b_invader in bonus_invaders:
if b_invader.colliderect(shot):
shots.remove(shot)
i = bonus_invaders.index(b_invader)
del bonus_invaders[i]
score += 1
if not backbuffer.get_rect().contains(shot):
shots.remove(shot)
else:
hit = False
for invader in invaders:
if invader.colliderect(shot):
score += 1
hit = True
i = invaders.index(invader)
del invaders[i]
del colors[i]
if hit: shots.remove(shot)
# move bonus invader
for bonus_invader in bonus_invaders:
bonus_invader.move_ip((-4,0 ))
## if not screen.get_rect().contains(bonus_invader):
## bonus_invaders.remove(bonus_invader)
if bonus_invader.x < -55:
bonus_invaders.remove(bonus_invader)
# check if all invaders killed, if so, move to next level
if len(invaders) == 0:
level = next_level(level)
invaders, colors, initial_invaders = load_level(level)
move_right, move_down, reloaded = True, True, True
vert_steps = 0
side_steps = 0
moved_down = False
invaders_paused = False
pygame.time.set_timer(invader_shoot, 500)
shoot_level = 1
# adjust shot freq when invader numbers decrease
if len(invaders) < initial_invaders*.75 and shoot_level == 1:
pygame.time.set_timer(invader_shoot, 750)
shoot_level = 2
elif len(invaders) < initial_invaders*.5 and shoot_level == 2:
pygame.time.set_timer(invader_shoot, 1000)
shoot_level = 3
elif len(invaders) < initial_invaders*.25 and shoot_level == 3:
pygame.time.set_timer(invader_shoot, 1500)
shoot_level = 4
# draw invaders
for rect, (a, b) in zip(invaders, colors):
animate_invaders = draw_invader(backbuffer, rect, a, b,\
animate_invaders, ticks, \
animation_time)
# draw bonus invaders
if ticks > bonus_timer + 169:
bonus_timer = ticks # change colors every 169ms approx
for bonus_invader in bonus_invaders:
pygame.draw.rect(backbuffer, (0,0,0,0), bonus_invader)
pygame.draw.ellipse(backbuffer,MGOLD,bonus_invader)
for i in range(6):
bonus_color = next(bonus_colors)
bx = next(bonus_x)
draw_bonus_invader(i, bonus_color, bx, bonus_x)
# draw space ship shots
for shot in shots:
pygame.draw.rect(backbuffer, GREEN, shot)
# draw invader shots
for shot, color in zip(invader_shots, inv_shot_colors):
pygame.draw.rect(backbuffer, color, shot)
#update 'gun' position and draw ship/gun
#player_gun = Rect(player.x, player.y, 6, 4)
player_gun.x = player.x+18
pygame.draw.rect(backbuffer, (204,0,255), player)
pygame.draw.rect(backbuffer, (0,204,255), player_gun)
player.clamp_ip(backbuffer.get_rect())
print_text(backbuffer, font1, "Intruders Rekt#: {}".format(score),\
the_screen, x=0, y=520)
print_text(backbuffer, font1, "Hearts#: {}".format(lives), the_screen,\
x=0, y=550)
print_text(backbuffer, font1, "Round#: {}".format(level), the_screen,\
x=0, y=580)
if game_over:
if playing:
game_is_over(backbuffer, font2, ticks)
playing = False
level = 0
lives = 2
score = 0
shots, invader_shots, inv_shot_colors, bonus_invaders = [], [], [], []
print_text(backbuffer, font2, "_/¯Yeet The Intruders¯\_", the_screen, y=5,\
center=True)
draw_title_invader()
if ticks > flash_timer + 800: # "press to play" flashing text
insert = next(the_text)
flash_timer = ticks
print_text(backbuffer, font3, insert, the_screen, y =\
the_screen.height-40, center=True)
screen.blit(backbuffer, (0,0))
pygame.display.update()
fpsclock.tick(30)
Your code is quite large, but to pause the game is very general task:
Add a pause state.
Toggle the pause state on an certain event, e.g. when the p key is pressed.
Skip the game processing if pauseis stated.
e,.g.
pause = False # pause state
while True:
ticks = pygame.time.get_ticks()
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
if event.type == KEYUP:
if event.key == pygame.K_1 and not game_over:
print("Next level")
# toggle pause if "p" is pressed
if event.key == pygame.K_p:
pause = not pause
# [...]
if pause:
# [...] draw pause screen
pass
elif not game_over: # <--- elif is important
playing = True
# [...]
screen.blit(backbuffer, (0,0))
pygame.display.update()
fpsclock.tick(30)
I'm currently in the process of creating a Snake game and I want to create a food generator that generates an apple every 10 seconds based on my in-game timer. The timer counts down from 60 to 0(when the game ends) and I want an new apple to generate every 10 seconds, keeping the old one even if it hasn't been eaten. I don't know how to approach this and could use some help. Here is my full program.
Edit: this is a beginner Computer Science school project so the more basic the better.
import random
import pygame
pygame.init()
#---------------------------------------#
#
# window properties #
width = 640 #
height = 480
game_window=pygame.display.set_mode((width,height))
black = ( 0, 0, 0) #
#---------------------------------------#
# snake's properties
outline=0
body_size = 9
head_size = 10
apple_size = 8
speed_x = 8
speed_y = 8
dir_x = 0
dir_y = -speed_y
segx = [int(width/2.)]*3
segy = [height, height + speed_y, height + 2*speed_y]
segments = len(segx)
apple_counter = 0
grid_step = 8
regular_font = pygame.font.SysFont("Andina",18)
blue = [11, 90, 220]
clock = pygame.time.Clock()
time = 60
fps = 25
time = time + 1.0/fps
text = regular_font.render("Time from start: "+str(int(time)), 1, blue)
text2 = regular_font.render("Score: "+str(int(apple_counter)), 1, blue)
apple_x = random.randrange(0, 640, grid_step)
apple_y = random.randrange(0, 480, grid_step)
apple_colour = (255,0,0)
def redraw_game_window():
game_window.fill(black)
for i in range(segments):
segment_colour = (random.randint(1,50),random.randint(100,150),random.randint(1,50))
head_colour = (random.randint(180,220),random.randint(180,220),random.randint(1,15))
apple_colour = (255,0,0)
pygame.draw.circle(game_window, segment_colour, (segx[i], segy[i]), body_size, outline)
pygame.draw.circle(game_window, head_colour, (segx[0], segy[0]), head_size, outline)
game_window.blit(text, (530, 20))
game_window.blit(text2, (30, 20))
pygame.draw.circle(game_window, apple_colour, (apple_x, apple_y), apple_size, outline)
pygame.display.update()
exit_flag = False
print "Use the arrows and the space bar."
print "Hit ESC to end the program."
########################################################## TIMER/CONTROLS
while exit_flag == False:
redraw_game_window()
clock.tick(fps)
time = time - 1.00/fps
text = regular_font.render("Time: "+str(int(time)), 1, blue)
text2 = regular_font.render("Score: "+str(int(apple_counter)), 1, blue)
if time < 0.1:
print "Game Over"
exit_flag = True
pygame.event.get()
keys = pygame.key.get_pressed()
if time ==
if keys[pygame.K_ESCAPE]:
exit_flag = True
if keys[pygame.K_LEFT] and dir_x != speed_x:
dir_x = -speed_x
dir_y = 0
if keys[pygame.K_RIGHT] and dir_x != -speed_x:
dir_x = speed_x
dir_y = 0
if keys[pygame.K_UP] and dir_y != speed_x:
dir_x = 0
dir_y = -speed_y
if keys[pygame.K_DOWN] and dir_y != -speed_x:
dir_x = 0
dir_y = speed_y
############################################################ SNAKE MOVEMENT
for i in range(segments-1,0,-1):
segx[i]=segx[i-1]
segy[i]=segy[i-1]
segx[0] = segx[0] + dir_x
segy[0] = segy[0] + dir_y
############################################################ COLLISION
for i in range(segments-1, 3, -1):
if segments > 3:
if segx[0] == segx[i] and segy[0] == segy[i]:
print "You have collided into yourself, Game Over."
exit_flag = True
############################################################# BORDERS
if segx[0] > 640 or segx[0] < 0:
print "Game Over, you left the borders."
break
if segy[0] > 480 or segy[0] < 0:
print "Game Over, you left the borders."
break
############################################################# APPLE DETECT
for i in range (0 , 13):
if segx[0] == apple_x + i and segy[0] == apple_y + i:
segments = segments + 1
segx.append(segx[-1])
segy.append(segy[-1])
apple_counter = apple_counter + 1
if segx[0] == apple_x - i and segy[0] == apple_y - i:
segments = segments + 1
segx.append(segx[-1])
segy.append(segy[-1])
apple_counter = apple_counter + 1
#############################################################
pygame.quit()
You either
A) use pygame.time.set_timer to call a function every 10 seconds to spawn food, and every 60 seconds to end the round.
or
B) compare get_ticks()
def new_round():
last_apple = pygame.time.get_ticks() + 10*1000
while true:
now = pygame.time.get_ticks()
if now - last_apple >= 1000:
spawn_apple()
last_apple = now
if now - round_start >= 60*1000:
round_end()
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
In my game I have created a scoring system, but I am struggling to find a way to store a high score that doesn't reset when the gameloop is run again. Here is the code:
import pygame
import time
import random
import timeit
pygame.init()
display_width = 1600
display_height = 850
speed = [1, -1]
black = (0,0,0)
white = (255,255,255)
red = (255, 0, 0)
grey = (177,177,177)
blue = (0,0,255)
green = (0,255,0)
gameDisplay = pygame.display.set_mode((display_width,display_height))
pygame.display.set_caption('Kill hitler before he gets trump')
clock = pygame.time.Clock()
crosshairImg = pygame.image.load('crosshair.PNG')
hitlerImg = pygame.image.load('hitler.png')
donaldImg = pygame.image.load('donald.png')
def crosshair(x, y):
gameDisplay.blit(crosshairImg, (x,y))
def enemy(x, y):
gameDisplay.blit(hitlerImg, (x,y))
def friendly(x, y):
gameDisplay.blit(donaldImg, (x,y))
def message_display(text):
largeText = pygame.font.Font('freesansbold.ttf',45)
TextSurf, TextRect = text_objects(text, largeText)
TextRect.center = ((display_width/2),(display_height/2))
gameDisplay.blit(TextSurf, TextRect)
pygame.display.update()
def text_objects(text, font):
textSurface = font.render(text, True, red)
return textSurface, textSurface.get_rect()
def status(total, enemy_kills):
if total == 0:
status = 0
else:
status = round((enemy_kills/total)*100, 2)
font = pygame.font.SysFont(None, 25)
text = font.render('Status:'+str(status)+'%', True, blue)
gameDisplay.blit(text,(0,30))
def score(count):
font = pygame.font.SysFont(None,25)
text = font.render('Confirmed Enemy Kills:'+str(count), True, blue)
gameDisplay.blit(text,(0,0))
def timer(count):
count = round(count, 1)
font = pygame.font.SysFont(None,25)
text = font.render('time left:'+str(count), True, blue)
gameDisplay.blit(text,(0,45))
def friend_kill(count):
font = pygame.font.SysFont(None,25)
text = font.render('Confirmed Friendly Kills:'+str(count), True, blue)
gameDisplay.blit(text,(0,15))
I believe that the following part of the code needs editing. I showed you the previous to hopefully make the next part easier to read.
def gameloop():
thing_startx = (display_width/2)
thing_starty = (display_height/2)
thing_xspeed = 0
thing_yspeed = 0
enemy_startx = random.randrange(0, (display_width-20))
enemy_starty = random.randrange(0, (display_height-20))
enemy_xspeed = 0
enemy_yspeed = 0
friend_startx = random.randrange(0, (display_width-40))
friend_starty = random.randrange(0, (display_height-40))
friend_width = 40
friend_height = 40
friend_xspeed = 0
friend_yspeed = 0
ammo = 5
kills = 0
total_kills = 0
friendly_kills = 0
gameExit = False
start = time.time()
elapsed = 0
while not gameExit and elapsed < 30:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
if event.type == pygame.MOUSEMOTION:
thing_startx = event.pos[0]-37
thing_starty = event.pos[1]-37
thing_startx += thing_xspeed
thing_starty += thing_yspeed
gameDisplay.fill (grey)
score(kills)
status(total_kills, kills)
friend_kill(friendly_kills)
timer((30-elapsed))
enemy(enemy_startx, enemy_starty)
friendly(friend_startx, friend_starty)
crosshair(thing_startx, thing_starty)
pygame.display.update()
pygame.mouse.set_visible(0)
if event.type == pygame.MOUSEBUTTONDOWN:
if (event.pos[0] > enemy_startx and event.pos[0] < enemy_startx+45) and event.pos[1] > enemy_starty and event.pos[1] < enemy_starty+60:
enemy_startx = random.randrange(0, (display_width-45))
enemy_starty = random.randrange(0, (display_height-60))
friend_startx = random.randrange(0,(display_width-40))
friend_starty = random.randrange(0,(display_height-40))
kills += 1
total_kills += 1
if event.type == pygame.MOUSEBUTTONDOWN:
if (event.pos[0] > friend_startx and event.pos[0] < friend_startx+60) and event.pos[1] > friend_starty and event.pos[1] < friend_starty+80:
friend_startx = random.randrange(0,(display_width-40))
friend_starty = random.randrange(0,(display_height-40))
enemy_startx = random.randrange(0, (display_width-45))
enemy_starty = random.randrange(0, (display_height-60))
friendly_kills += 1
total_kills += 1
message_display('you killed a friendly')
time.sleep(1)
if (kills>=5 and kills<10) or (kills>=15 and kills<20):
if enemy_startx+45<display_width and enemy_xspeed not in (1, -1):
enemy_xspeed += 1
if friend_startx+60<display_width and friend_xspeed not in (1,-1):
friend_xspeed += 1
if enemy_startx>0 and enemy_xspeed not in (-1, 0):
enemy_xspeed = 1
if friend_startx>0 and friend_xspeed not in (-1, 0):
friend_xspeed = 1
elif kills>=10 and kills<20:
if enemy_starty+60<display_height and enemy_yspeed not in (1, -1):
enemy_yspeed += 1
if friend_starty+80<display_width and friend_yspeed not in (1,-1):
friend_yspeed += 1
if enemy_starty>0 and enemy_yspeed not in (-1, 0):
enemy_yspeed = 1
if friend_starty>0 and friend_yspeed not in (-1, 0):
friend_yspeed = 1
elif kills>=20:
if enemy_startx+45<display_height and enemy_xspeed not in (2, -2):
enemy_xspeed = 2
if friend_startx+60<display_height and friend_xspeed not in (2, -2):
friend_xspeed = 2
if enemy_starty>0 and enemy_yspeed not in (2, -2):
enemy_yspeed = -2
if friend_starty>0 and friend_yspeed not in (2, -2):
friend_yspeed = -2
else:
enemy_xspeed = 0
enemy_yspeed = 0
friend_xspeed = 0
friend_yspeed = 0
if enemy_startx+45>display_width or enemy_startx<0:
enemy_xspeed *= -1
if enemy_starty+60>display_height or enemy_starty<0:
enemy_yspeed *= -1
if friend_startx+40>display_width or friend_startx<0:
friend_xspeed *= -1
if friend_starty+40>display_height or friend_starty<0:
friend_yspeed *= -1
enemy_starty += enemy_yspeed
enemy_startx += enemy_xspeed
friend_startx += friend_xspeed
friend_starty += friend_yspeed
pygame.display.update()
clock.tick(100)
elapsed = time.time() - start
msg = 'you got',kills,'enemy kills amd',friendly_kills,'enemy kills'
message_display('you got '+str(kills)+' enemy kills and '+str(friendly_kills)+' friendly kills')
time.sleep(2)
gameloop()
gameloop()
Edit: previous answer failed to answer the question.
At the top of the file import the pickle module:
import pickle
At the start of the game_loop() function write the following piece of code:
try:
with open("var.pickle", "rb") as file:
high = pickle.load(file)
except (OSError, IOError) as e:
high = 0
with open("var.pickle", "wb") as file:
pickle.dump( high, file)
Finally before the line
message_display('you got '+str(kills)+' enemy kills and '+str(friendly_kills)+' friendly kills')
time.sleep(2)
Add the following:
if high < kills:
with open("var.pickle", "wb") as file:
pickle.dump(high, open("var.pickle", "wb"))
message_display("New High-score!")
What happens is that you get the high score stored if it exists or create it with a score of 0. Once you finish the game loop if the score is higher than the high-score you change the high-score to the new value.
Store the high score in a separate .txt file called highscore.txt. .txt files are files that can store strings but also be used as data that doesn't get deleted. Make sure your .txt file is in the same directory as your game file. To start it up, write '0' on the first line without apostrophes. Does not require downloads or extra imports. Make a .txt file and do this in the game loop:
File = open(highscore.txt, 'r') #Out of game Loop
HighScore = int(File.read())
if kills > HighScore: #In game loop
File.truncate()
File.close()
File = open(highscore.txt, 'w')
File.write(kills)
File.close()
File = open(highscore.txt, 'r')