My Python game is lagging a lot. I started making a new Python game and every time it came to testing it, it would always lag although I am not using any images.
import turtle
import random
#head orientation
h = [0]
#score
a = [0]
b = [0]
#food coord
fcoord = [0,0,0]
#position
pos = []
def home(x,y):
x = 0
y = 0
a[0] = 0
b[0] = 0
h[0] = 0
fcoord[2] = 0
pos[:] = []
turtle.hideturtle()
turtle.clear()
turtle.pu()
turtle.color("lime")
turtle.goto(0,0)
turtle.write("PLAY", align="center",font="Calibri")
turtle.title("Snake Game")
turtle.onscreenclick(start)
turtle.mainloop()
def level_1():
turtle.clear()
turtle.pu()
turtle.speed(0)
turtle.pensize(20)
turtle.color("grey")
turtle.goto(-220,220)
turtle.pd()
turtle.goto(220,220)
turtle.goto(220,-220)
turtle.goto(-220,-220)
turtle.goto(-220,220)
turtle.pu()
turtle.goto(0,0)
def start(x,y):
turtle.onscreenclick(None)
level_1()
tfood = turtle.Turtle()
tfood.hideturtle()
tfood.pu()
tfood.speed(0)
tfood.shape("square")
tfood.color("red")
tscore = turtle.Turtle()
tscore.hideturtle()
tscore.pu()
tscore.speed(0)
tscore.goto(100,-250)
tscore.write("Score:" + str(a[0]), align="center",font=(10))
while x > -210 and x < 210 and y > -210 and y <210:
if fcoord[2] == 0:
food(tfood)
fcoord[2] = 1
turtle.onkey(u,"Up")
turtle.onkey(l,"Left")
turtle.onkey(r,"Right")
turtle.onkey(d,"Down")
turtle.listen()
move()
x = turtle.xcor()
y = turtle.ycor()
if x > fcoord[0]*20-5 and x < fcoord[0]*20+5 and y > fcoord[1]*20-5 and y < fcoord[1]*20+5:
fcoord[2] = 0
tfood.clear()
a[0] += 1
tscore.clear()
tscore.write("Score:" + str(a[0]), align="center",font=(10))
if len(pos) > 1:
for i in range(1,len(pos)):
if x < pos[i][0]+5 and x > pos[i][0]-5 and y < pos[i][1]+5 and y > pos[i][1]-5:
tscore.clear()
tfood.clear()
gameover()
tscore.clear()
tfood.clear()
gameover()
#Food
def food(tfood):
x = random.randrange(-8,8,1)
y = random.randrange(-8,8,1)
fcoord[0] = x
fcoord[1] = y
tfood.hideturtle()
tfood.pu()
tfood.shape("circle")
tfood.color("red")
tfood.goto(x*20,y*20)
tfood.stamp()
#Up
def u():
if h[0] == 270:
pass
else:
h[0] = 90
#Down
def d():
if h[0] == 90:
pass
else:
h[0] = 270
#Left
def l():
if h[0] == 0:
pass
else:
h[0] = 180
#Right
def r():
if h[0] == 180:
pass
else:
h[0] = 0
def move():
turtle.pensize(1)
turtle.color("green")
turtle.pu()
turtle.speed(3)
turtle.setheading(h[0])
turtle.shape("square")
turtle.stamp()
turtle.fd(20)
x = turtle.xcor()
y = turtle.ycor()
if b[0] > a[0]:
turtle.clearstamps(1)
pos.insert(0,[round(x),round(y)])
pos.pop(-1)
else:
pos.insert(0,[round(x),round(y)])
b[0] += 1
def gameover():
turtle.onscreenclick(None)
turtle.speed(0)
turtle.pu()
turtle.goto(0,150)
turtle.color("red")
turtle.write("Game Over",align="center", font=(10))
turtle.goto(0,50)
turtle.write("Score:" + str(a[0]),align="center",font=(10))
turtle.goto(200,-200)
turtle.write("(Click anywhere to return to the main menu)",align="right",font=(0.0000001))
turtle.onscreenclick(home)
turtle.mainloop()
# # # # # # # # # # # # # # # # # # # # # #
# Main #
# # # # # # # # # # # # # # # # # # # # # #
if __name__ == '__main__':
home(0,0)
I'm not sure what you mean by lagging but I've addressed a couple of issues in my rewrite below. The first is that turtles are global entities that don't get garbage collected under normal circumstances so don't recreate them, reuse them instead. Second, when you have your own while loop to control the game, you potentially lock out events. I've eliminated your loop and modified the game to work with ontimer events so that turtle movement should be handled by the same event loop that's handing user input, making it slightly more responsive to the user:
from turtle import Turtle, Screen
from random import randint
FONT = ('Arial', 18, 'bold')
# Up
def u():
if h[0] != 270:
h[0] = 90
# Down
def d():
if h[0] != 90:
h[0] = 270
# Left
def l():
if h[0] != 0:
h[0] = 180
# Right
def r():
if h[0] != 180:
h[0] = 0
def gameover():
screen.onkey(None, "Up")
screen.onkey(None, "Left")
screen.onkey(None, "Right")
screen.onkey(None, "Down")
tscore.clear()
tfood.clear()
tplayer.clear()
tfood.hideturtle()
tplayer.hideturtle()
tscore.color("red")
tscore.goto(0, 150)
tscore.write("Game Over", align="center", font=FONT)
tscore.goto(0, 50)
tscore.write("Score:" + str(a[0]), align="center", font=FONT)
tscore.goto(0, -200)
tscore.write("(Click anywhere to return to the main menu)", align="center", font=FONT)
screen.onscreenclick(home)
def food(tfood):
x = randint(-160, 160)
y = randint(-160, 160)
tfood.goto(x, y)
tfood.showturtle()
def move():
x, y = tplayer.position()
if -210 < x < 210 and -210 < y < 210:
if not tfood.isvisible():
food(tfood)
tplayer.setheading(h[0])
tplayer.stamp()
tplayer.forward(20)
if b[0] > a[0]:
tplayer.clearstamps(1)
pos.insert(0, [round(x), round(y)])
pos.pop(-1)
else:
pos.insert(0, [round(x), round(y)])
b[0] += 1
if tplayer.distance(tfood) < 15:
tfood.hideturtle()
tfood.clear()
a[0] += 1
tscore.clear()
tscore.write("Score:" + str(a[0]), align="center", font=FONT)
flag = True
x, y = tplayer.position()
if len(pos) > 1:
for i in range(1, len(pos)):
if pos[i][0] - 5 < x < pos[i][0] + 5 and pos[i][1] - 5 < y < pos[i][1] + 5:
flag = False
break
if flag:
screen.ontimer(move, 25)
else:
screen.ontimer(gameover, 100)
def level_1():
tmarker.penup()
tmarker.goto(-220, 220)
tmarker.pendown()
tmarker.goto(220, 220)
tmarker.goto(220, -220)
tmarker.goto(-220, -220)
tmarker.goto(-220, 220)
tmarker.penup()
def start(x, y):
screen.onscreenclick(None)
tscore.clear()
level_1()
tplayer.home()
tplayer.setheading(h[0])
tscore.goto(100, -250)
tscore.write("Score:" + str(a[0]), align="center", font=FONT)
screen.onkey(u, "Up")
screen.onkey(l, "Left")
screen.onkey(r, "Right")
screen.onkey(d, "Down")
move()
def home(x=0, y=0):
screen.onscreenclick(None)
a[0] = 0
b[0] = 0
h[0] = 0
pos[:] = []
tscore.clear()
tscore.home()
tscore.color('lime')
tscore.write("PLAY", align="center", font=FONT)
screen.onscreenclick(start)
# head orientation
h = [0]
# score
a = [0]
b = [0]
# position
pos = []
# turtles
tfood = Turtle('circle', visible=False)
tfood.speed('fastest')
tfood.color('red')
tfood.penup()
tscore = Turtle(visible=False)
tscore.speed('fastest')
tscore.penup()
tplayer = Turtle("square", visible=False)
tplayer.speed('slow')
tplayer.color("green")
tplayer.penup()
tmarker = Turtle(visible=False)
tmarker.speed('fastest')
tmarker.pensize(20)
tmarker.color("grey")
# # # # # # # # # # # # # # # # # # # # # #
# Main #
# # # # # # # # # # # # # # # # # # # # # #
if __name__ == '__main__':
screen = Screen()
screen.title("Snake Game")
screen.listen()
home()
screen.mainloop()
Related
So, I have been working on this game called Space Invader. Everything is doing great except for one thing which is the sound. As in the below code, I've imported winsound module and it is not doing well. When I fire the bullet it makes the fire noise which I wanted but the problem is that I've also added background music, and whenever I hit fire it stops the background music and starts making fire noises until it hits the target. I want background music to run continuously. I've also seen many Youtube videos but couldn't get any help. Can anyone tell me the mistake which I've made in the below code?
import turtle
import random
import math
import winsound
score = 0
highscore = 0
targets = []
live_remaining = 3
screen = turtle.Screen()
screen.title("Space War")
screen.bgcolor("Black")
screen.setup(width=800, height=770)
screen.bgpic("Space.gif")
screen.addshape("Spaceship.gif")
screen.addshape("Missile.gif")
screen.addshape("ufo.gif")
screen.addshape("gameover.gif")
screen.addshape("youwin.gif")
screen.tracer(0)
winsound.PlaySound("bgmusic.wav", winsound.SND_ASYNC)
spaceship = turtle.Turtle()
spaceship.speed(0)
spaceship.shape("Spaceship.gif")
spaceship.penup()
spaceship.ht()
spaceship.goto(0, -320)
spaceship.st()
spaceship.direction = "stop"
spaceshipspeed = 15
num_of_targets = 50
for i in range(num_of_targets):
targets.append(turtle.Turtle())
target_start_x = -250
target_start_y = 275
target_number = 0
for target in targets:
target.shape("ufo.gif")
target.penup()
target.speed(0)
x=target_start_x + (50 * target_number)
y=target_start_y
target.goto(x, y)
target_number += 1
if target_number == 10:
target_start_y -= 20
target_number = 0
targetspeed = 0.5
fires=turtle.Turtle()
fires.shape("Missile.gif")
fires.penup()
fires.ht()
fires.speed(0)
fires.goto(0, -340)
fires.direction = "stop"
firesspeed=3
fire = turtle.Turtle()
fire.shape("Missile.gif")
fire.penup()
fire.ht()
fire.speed(0)
fire.goto(0, -340)
fire.direction = "stop"
firespeed = 4
firestate = "ready"
sb=turtle.Turtle()
sb.shape("square")
sb.color("white")
sb.ht()
sb.penup()
sb.goto(0,320)
sb.write("Score: 0 | High Score: 0", align="center", font=("courier", 30, "bold"))
life = turtle.Turtle()
life.shape("square")
life.ht()
life.penup()
life.goto(-350,-350)
life.color("white")
life.write("Life remaining: 3", font=("courier",10,"bold"))
def go_left():
x = spaceship.xcor()
x -= spaceshipspeed
if x < -340:
x = -340
spaceship.setx(x)
def go_right():
x = spaceship.xcor()
x += spaceshipspeed
if x > 340:
x = 340
spaceship.setx(x)
def go_forward():
global firestate
if firestate == "ready":
firestate = "fire"
x = spaceship.xcor()
y = spaceship.ycor()
fire.setposition(x, y)
fire.st()
winsound.PlaySound("fire.wav", winsound.SND_ASYNC)
def move():
pass
screen.listen()
screen.onkeypress(go_left, "a")
screen.onkeypress(go_right, "d")
screen.onkeypress(go_forward, "space")
while True:
screen.update()
for target in targets:
x = target.xcor()
x += targetspeed
target.setx(x)
if target.xcor() > 340:
targetspeed *= -1
for t in targets:
y = t.ycor()
y -= 20
t.sety(y)
if target.xcor() < -340:
targetspeed *= -1
for t in targets:
y = t.ycor()
y -= 20
t.sety(y)
if fire.distance(target) < 20:
fire.direction = "stop"
fire.ht()
fire.clear()
firestate = "ready"
fire.goto(10000000, 1000000)
target.goto(0, 10000000)
score += 10
winsound.PlaySound("explosion.wav", winsound.SND_ASYNC)
if score > highscore:
highscore = score
sb.clear()
sb.write("Score: {} | High Score: {}".format(score,highscore), align="center",
font=("courier", 30, "bold"))
if score == 500:
screen.clear()
screen.bgcolor("black")
gf = turtle.Turtle()
gf.shape("youwin.gif")
gf.goto(0, 0)
winsound.PlaySound("gamewin.wav",winsound.SND_ASYNC)
if spaceship.distance(target) < 60:
spaceship.goto(0, -320)
target.goto(-320, 300)
live_remaining -= 1
winsound.PlaySound("explosion.wav",winsound.SND_ASYNC)
life.clear()
life.write("Life remaining: {}".format(live_remaining), font=("courier",10,"bold"))
if live_remaining == 0:
screen.clear()
screen.bgcolor("black")
gover=turtle.Turtle()
gover.shape("gameover.gif")
gover.goto(0, 0)
winsound.PlaySound("gamelose.wav", winsound.SND_ASYNC)
replay = input("Press r to retry",)
y = fire.ycor()
y += firespeed
fire.sety(y)
if fire.ycor() > 300:
fire.ht()
firestate = "ready"
move()
screen.mainloop()
I'm really a beginner and I'm looking for a mistake.
This is a condition in the Game class in the "collision" method.
I need to detect a collision between a missile and an enemy.
Problem: When a missile is at the same coordinate as the enemy, a collision is detected. However, if one of the shots is outside the X coordinate, another collision is not detected until the shot outside the enemy's X coordinate disappears beyond the top edge of the screen.
import pygame
import os
import sys
import random
from pygame.locals import *
pygame.init()
pygame.font.init()
DIR = os.path.dirname(os.path.realpath(__file__)) # získání cesty k adresáři se soubory
OKNO_X = 1024
OKNO_Y = 768
CLOCK = pygame.time.Clock()
SCREEN = pygame.display.set_mode((OKNO_X, OKNO_Y))
BACKGROUND = pygame.image.load(os.path.join(DIR, "universe.jpg"))
DEBUGFONT = pygame.font.SysFont("Comic Sans MS", 20)
class Spaceship():
def __init__(self, x=510, y=OKNO_Y-50):
self.x = x
self.y = y
def vykresli(self):
ship = pygame.image.load(os.path.join(DIR, "spaceship.png"))
SCREEN.blit(ship, (self.x, self.y))
def pohyb(self, x, y):
self.x += x
self.y += y
if self.x < 0: self.x = 0
if self.x > OKNO_X - 50: self.x = OKNO_X - 54
if self.y < 0: self.y = 0
if self.y > OKNO_Y - 50: self.y = OKNO_Y - 54
class Enemies():
def __init__(self):
self.enem_x = []
self.enem_y = []
self.enem_invader = []
self.enem_speed = []
def vygeneruj(self):
#generování nepřátel
invader_green = pygame.image.load(os.path.join(DIR, "invader_green.png"))
invader_blue = pygame.image.load(os.path.join(DIR, "invader_blue.png"))
invader_yellow = pygame.image.load(os.path.join(DIR, "invader_yellow.png"))
invader_red = pygame.image.load(os.path.join(DIR, "invader_red.png"))
if random.randrange(0, 50) == 1:
#self.enem_x.append(random.randrange(50, 970))
self.enem_x.append(510)
self.enem_y.append(0)
self.enem_invader.append(random.choice([invader_green, invader_blue, invader_yellow, invader_red]))
self.enem_speed.append(random.randrange(1,5))
#self.enem_speed.append(10)
def vykresli(self):
#vykreslení nepřátel
for i in range(len(self.enem_invader)):
SCREEN.blit(self.enem_invader[i], (self.enem_x[i], self.enem_y[i]))
self.enem_y[i] += self.enem_speed[i]
##############DEBUG################x
label_d1 = DEBUGFONT.render(str(self.enem_x[i]), 1, (255,255,255))
SCREEN.blit(label_d1, (self.enem_x[i], self.enem_y[i]-10))
label_d1 = DEBUGFONT.render(str(self.enem_y[i]), 1, (255,255,255))
SCREEN.blit(label_d1, (self.enem_x[i]+30, self.enem_y[i]-10))
#smazání nepřátel, co přeletěly za hranu
e = 0
pocet_enemies = len(self.enem_invader)
while e < pocet_enemies:
if self.enem_y[e] > OKNO_Y:
del self.enem_x[e]
del self.enem_y[e]
del self.enem_invader[e]
del self.enem_speed[e]
pocet_enemies -= 1
e += 1
class Game():
def __init__(self):
self.sestreleno = 0
def kolize(self):
#vyhodnocuje střet střely s enemies
x, y = 0, 0
pocet_enemies = len(enemies.enem_x)
pocet_shots = len(shot.x)
while y < pocet_shots:
while x < pocet_enemies:
if (shot.y[y] - 23 > enemies.enem_y[x] and shot.y[y] - 23 < enemies.enem_y[x] + 50) and (shot.x[y] >= enemies.enem_x[x]-50 and shot.x[y] <= enemies.enem_x[x]+50):
del shot.x[y]
del shot.y[y]
del enemies.enem_x[x]
del enemies.enem_y[x]
del enemies.enem_invader[x]
del enemies.enem_speed[x]
pocet_enemies -= 1
pocet_shots -= 1
self.sestreleno += 1
break
x += 1
y += 1
def skore(self):
myfont_skore = pygame.font.SysFont("Comic Sans MS", 30)
label_skore = myfont_skore.render("Sestřeleno: " + str(self.sestreleno), 1, (100,100,100))
SCREEN.blit(label_skore, (10, 10))
class Shot():
def __init__(self):
self.x = []
self.y = []
self.missile = pygame.image.load(os.path.join(DIR, "missile.png"))
def vystrel(self, x, y):
#přidání střely do seznamu střel
self.x.append(x)
self.y.append(y)
def strela(self):
#vykreslení střely
for m in range(len(self.x)):
SCREEN.blit(self.missile, (self.x[m]+23, self.y[m]-50))
self.y[m] -= 5
##############DEBUG################x
label_d1 = DEBUGFONT.render(str(self.x[m]), 1, (255,255,255))
SCREEN.blit(label_d1, (self.x[m], self.y[m]-10))
label_d1 = DEBUGFONT.render(str(self.y[m]), 1, (255,255,255))
SCREEN.blit(label_d1, (self.x[m]+30, self.y[m]-10))
label_d1 = DEBUGFONT.render(str(m), 1, (255,255,255))
SCREEN.blit(label_d1, (self.x[m]+40, self.y[m]-20))
#smazání střely ze seznamu pokud vletí za hranu screenu
for s in range(len(self.y)):
if self.y[s] <= 0:
del self.x[s]
del self.y[s]
break
#print(self.x)
#instance
spaceship = Spaceship()
enemies = Enemies()
shot = Shot()
game = Game()
while True:
SCREEN.blit(BACKGROUND, (0, 0, OKNO_X, OKNO_Y)) # překreslení pozadí
KEY = pygame.key.get_pressed()
if KEY[pygame.K_LEFT]:
spaceship.pohyb(-10, 0)
if KEY[pygame.K_RIGHT]:
spaceship.pohyb(+10, 0)
if KEY[pygame.K_UP]:
spaceship.pohyb(0, -10)
if KEY[pygame.K_DOWN]:
spaceship.pohyb(0, +10)
if KEY[pygame.K_ESCAPE]:
pygame.quit()
sys.exit()
for event in pygame.event.get():
if event.type == KEYDOWN:
if event.key == K_SPACE:
shot.vystrel(spaceship.x, spaceship.y+30)
if event.type == KEYUP:
if event.key == K_p:
pygame.time.wait(5000)
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
spaceship.vykresli()
enemies.vygeneruj()
enemies.vykresli()
shot.strela()
game.kolize()
game.skore()
CLOCK.tick(30) # rychlost FPS
pygame.display.update() # obnovení obrazovky
Instead of a method,
def kolize(self):
#vyhodnocuje střet střely s enemies
x, y = 0, 0
pocet_enemies = len(enemies.enem_x)
pocet_shots = len(shot.x)
while y < pocet_shots:
while x < pocet_enemies:
if (shot.y[y] - 23 > enemies.enem_y[x] and shot.y[y] - 23 < enemies.enem_y[x] + 50) and (shot.x[y] >= enemies.enem_x[x]-50 and shot.x[y] <= enemies.enem_x[x]+50):
del shot.x[y]
del shot.y[y]
del enemies.enem_x[x]
del enemies.enem_y[x]
del enemies.enem_invader[x]
del enemies.enem_speed[x]
pocet_enemies -= 1
pocet_shots -= 1
self.sestreleno += 1
break
x += 1
y += 1
I had to use this method.
def kolize(self):
#vyhodnocuje střet střely s invaderem
myBreak = False
pocet_enemies = len(enemies.enem_x)
pocet_shots = len(shot.x)
for y in range(pocet_shots):
for x in range(pocet_enemies):
if (shot.y[y] - 23 > enemies.enem_y[x] and shot.y[y] - 23 < enemies.enem_y[x] + 50) and (shot.x[y]-23 >= enemies.enem_x[x]-50 and shot.x[y] <= enemies.enem_x[x]+27):
game.explosion(enemies.enem_x[x], enemies.enem_y[x]) # předání souřadnic výbuchu
game.delShots(y)
game.delEnem(x)
pocet_enemies -= 1
pocet_shots -= 1
self.sestreleno += 1
if spaceship.health < 50: spaceship.health += 1
myBreak = True
break
if myBreak == True:
myBreak = False
break
I needed to conditionally jump out of the nested loop and out of the main loop.
When I run my code and I move my turtle up with the space bar, all the obstacles, that are supposed to be moving, stop moving. What causes the problem and how do I fix this?
I have no idea what can cause this problem and I've tried Googling but can't find anything. Since this is my first week of trying out Python, or programming in general, I have no idea what I've done wrong.
import turtle
import math
import random
#starting conditions
player = turtle.Turtle()
player.hideturtle()
player.penup()
player.shape("turtle")
player.setheading(90)
player.setpos(-200,0)
player.speed(1)
player.color("yellow")
canvas = turtle.Screen()
canvas.bgcolor("black")
canvas.title("gamescreen")
gameover = turtle.Turtle()
gameover.penup()
gameover.hideturtle()
gameover.color("red")
gameover.speed(0)
gameover.setpos(-150, 330)
scoreboard = turtle.Turtle()
scoreboard.hideturtle()
scoreboard.color("blue")
scoreboard.penup()
scoreboard.setpos(-300,320)
#borders
box = turtle.Turtle()
box.speed(0)
box.hideturtle()
box.setheading(0)
box.color("blue")
box.pensize(3)
box.penup()
box.setpos(-300,-300)
for i in range(4):
box.pendown()
box.forward(600)
box.left(90)
player.showturtle()
#movement
spd = 50
def playerup():
player.sety(player.ycor()+ spd)
if (player.ycor()+ spd) > 287:
player.speed(0)
player.sety(287)
player.speed(1)
def playerdown():
player.sety(player.ycor()- spd)
if (player.ycor()+ spd) < -287:
player.speed(0)
player.sety(-287)
player.speed(1)
turtle.listen()
gravity = 3
obsspd = 3
#collision
def hit(t1, t2):
xdistance = t1.xcor()-t2.xcor()
ydistance = t1.ycor()-t2.ycor()
if (abs(xdistance) < 20) and (abs(ydistance) < 130):
return True
else:
return False
#obstacle list
number_obstacles = 2
obstacles = []
numberslistx = list(range(-100,280))
numberslisty = list(range(143,190))
for i in range(number_obstacles):
obstacles.append(turtle.Turtle())
for obstacle in obstacles:
obstacle.hideturtle()
obstacle.speed(0)
obstacle.color("green")
obstacle.penup()
obstacle.shape("square")
obstacle.turtlesize(12,3)
xobs = random.choice(numberslistx)
yobs = random.choice(numberslisty)
obstacle.setposition(xobs,yobs)
obstacle.showturtle()
#obstacle2 list
number_obstacles2 = 2
obstacles2 = []
numberslistx = list(range(-100,280))
numberslisty = list(range(160,190))
for i in range (number_obstacles2):
obstacles2.append(turtle.Turtle())
for obstacle2 in obstacles2:
obstacle2.hideturtle()
obstacle2.speed(0)
obstacle2.color("green")
obstacle2.penup()
obstacle2.shape("square")
xobs = random.choice(numberslistx)
yobs = random.choice(numberslisty)
obstacle2.turtlesize(12,3)
obstacle2.setposition(xobs,-yobs)
obstacle2.showturtle()
if(obstacle.xcor()-obstacle2.xcor())> 10:
obstacle.setposition(xobs,yobs)
obstacle2.setposition(xobs,-yobs)
#border
def fall():
if (player.ycor()< -300):
return True
def ceiling():
if (player.ycor() > 300):
return True
colors = ["red", "green","yellow","blue","purple","pink"]
points = 1
while True:
player.sety(player.ycor()-gravity)
xresetpos = random.choice(range(230,300))
yresetpos = random.choice(range(140,190))
for obstacle in obstacles:
obstacle.setx(obstacle.xcor()-obsspd)
if (obstacle.xcor()-obsspd) < -270:
obstacle.hideturtle()
obstacle.setx(xresetpos)
obstacle.sety(yresetpos)
obstacle.showturtle()
obsspd+=1
points += 1
display = points
scoreboard.clear()
scoreboard.write(display)
player.color(random.choice(colors))
obstacle.color(random.choice(colors))
for obstacle2 in obstacles2:
obstacle2.setx(obstacle2.xcor()-(obsspd))
if (obstacle2.xcor()-obsspd) < -270:
obstacle2.hideturtle()
obstacle2.setx(xresetpos)
obstacle2.sety(-(int(yresetpos))-15)
obstacle2.showturtle()
player.color(random.choice(colors))
obstacle2.color(random.choice(colors))
if hit(player, obstacle):
player.hideturtle()
player.setpos(400,0)
gameover.color("red")
gameover.setpos(-150,-20)
gameover.write("Game over",False,"left",("Arial",50,))
gameover.setpos(-160,-200)
gameover.write("Press x to play again",False,"left",("Arial",30,))
break
if hit(player, obstacle2):
player.hideturtle()
player.setpos(400,0)
gameover.setpos(-150,-20)
gameover.write("Game over",False,"left",("Arial",50,))
gameover.setpos(-160,-200)
gameover.write("Press x to play again",False,"left",("Arial",30,))
break
if fall():
player.hideturtle()
player.setpos(400,0)
gameover.setpos(-150,-20)
gameover.write("Game over",False,"left",("Arial",50,))
gameover.setpos(-160,-200)
gameover.write("Press x to play again",False,"left",("Arial",30,))
break
if ceiling():
player.setycor(280)
#if score(player,obstacle1):
# points += 1
# display = points
# scoreboard.clear()
# scoreboard.write(display)
turtle.onkeypress(playerup, "space")
#turtle.onkeypress(playerdown, "Down")
#if player.xcor() is obstacle1.xcor():
# points += 1
# scoreboard.clear()
# scoreboard.write(points)
#balken stoppen niet als jij beweegt
One problem is that your horizontal motion is controlled, out of sync, by a while True: loop but your vertical motion is controlled, in sync, by a keyboard event. We need to get both motions in sync using events via replacing your while True: with an ontimer() event. Here's my complete rework of your code along these lines with a few simplifications for example purposes:
from turtle import Screen, Turtle
from random import choice, randrange
COLORS = ["red", "green", "yellow", "blue", "purple", "pink"]
PLAYER_SPEED = 50
GRAVITY = 3
NUMBER_OBSTACLES_UPPER = 2
NUMBER_OBSTACLES_LOWER = 2
# movement
def playerup():
screen.onkeypress(None, 'space') # disable handler inside handler
player.sety(player.ycor() + PLAYER_SPEED)
if player.ycor() > 287:
player.speed('fastest')
player.sety(287)
player.speed('slowest')
screen.onkeypress(playerup, 'space')
# collision
def hit(t1, t2):
xdistance = abs(t1.xcor() - t2.xcor())
if xdistance >= 20:
return False
ydistance = abs(t1.ycor() - t2.ycor())
return ydistance < 130
# border
def fall():
return player.ycor() < -300
def ceiling():
return player.ycor() > 300
# main program loop
def move():
global points, obstacle_speed_upper, obstacle_speed_lower
player.sety(player.ycor() - GRAVITY)
for obstacle in obstacles_upper:
obstacle.setx(obstacle.xcor() - obstacle_speed_upper)
if obstacle.xcor() < -270:
obstacle.hideturtle()
obstacle.setposition(randrange(230, 300), randrange(140, 190))
obstacle.showturtle()
obstacle_speed_upper += 1
points += 1
scoreboard.clear()
scoreboard.write(points, font=('Arial', 30,))
if hit(player, obstacle):
player.hideturtle()
gameover.write("Game Over", align='center', font=('Arial', 50,))
return
for obstacle in obstacles_lower:
obstacle.setx(obstacle.xcor() - obstacle_speed_lower)
if obstacle.xcor() < -270:
obstacle.hideturtle()
obstacle.setposition(randrange(230, 300), - randrange(160, 190))
obstacle.showturtle()
obstacle_speed_lower += 1
points += 1
scoreboard.clear()
scoreboard.write(points, font=('Arial', 30,))
if hit(player, obstacle):
player.hideturtle()
gameover.write("Game Over", align='center', font=('Arial', 50,))
return
if ceiling() or fall():
player.hideturtle()
gameover.write("Game Over", align='center', font=('Arial', 50,))
return
screen.ontimer(move, 100)
# starting conditions
screen = Screen()
screen.setup(750, 750)
screen.bgcolor('black')
screen.title("Game Screen")
# borders
box = Turtle()
box.hideturtle()
box.color('blue')
box.speed('fastest')
box.pensize(3)
box.penup()
box.setpos(-300, -300)
box.pendown()
for _ in range(4):
box.forward(600)
box.left(90)
gameover = Turtle()
gameover.hideturtle()
gameover.color('red')
gameover.penup()
gameover.sety(-25)
points = 0
scoreboard = Turtle()
scoreboard.hideturtle()
scoreboard.color('blue')
scoreboard.penup()
scoreboard.setpos(-300, 320)
scoreboard.write(points, font=('Arial', 30,))
player = Turtle()
player.hideturtle()
player.shape('turtle')
player.speed('slowest')
player.color('yellow')
player.setheading(90)
player.penup()
player.setx(-200)
player.showturtle()
# obstacle list
obstacle_speed_upper = 3
obstacles_upper = []
for _ in range(NUMBER_OBSTACLES_UPPER):
obstacle = Turtle()
obstacle.hideturtle()
obstacle.shape('square')
obstacle.turtlesize(12, 3)
obstacle.speed('fastest')
obstacle.color(choice(COLORS))
obstacle.penup()
xobs = randrange(-100, 280)
yobs = randrange(145, 190)
obstacle.setposition(xobs, yobs)
obstacle.showturtle()
obstacles_upper.append(obstacle)
# lower obstacles list
obstacle_speed_lower = 3
obstacles_lower = []
for _ in range(NUMBER_OBSTACLES_LOWER):
obstacle = Turtle()
obstacle.hideturtle()
obstacle.shape('square')
obstacle.turtlesize(12, 3)
obstacle.speed('fastest')
obstacle.color(choice(COLORS))
obstacle.penup()
xobs = randrange(-100, 280)
yobs = randrange(160, 190)
obstacle.setposition(xobs, -yobs)
obstacle.showturtle()
obstacles_lower.append(obstacle)
screen.onkeypress(playerup, 'space')
screen.listen()
move()
screen.mainloop()
So I want it to count the score every time the snake eats a candy.
I haven't tried much, but I tried to find existing codes and adding them to mine but that just broke the game. I also tried to make my own score board by watching a tutorial, but I don't know where the code should go like at the beginning or end.
import pygame
import random
score = 0
welcome = ("Welcome to our snake game")
print(welcome)
class cube:
height = 20
w = 500
def __init__(movee,start,x=1,y=0,color=(0,0,0)):
movee.pos = start
movee.x = 1
movee.y = 0
movee.color = color
def move(movee, x, y):
movee.x = x
movee.y = y
movee.pos = (movee.pos[0] + movee.x, movee.pos[1] + movee.y)
def draw(movee, surface, eyes=False):
leng = movee.w // movee.height
i = movee.pos[0]
j = movee.pos[1]
pygame.draw.rect(surface, movee.color, (i*leng+1,j*leng+1, leng-2, leng-2))
class snake:
body = []
turns = {}
def __init__(movee, color, pos):
movee.color = color
movee.head = cube(pos)
movee.body.append(movee.head)
def move(movee):
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
keys = pygame.key.get_pressed()
for key in keys:
if keys[pygame.K_LEFT]:
movee.x = -1
movee.y = 0
movee.turns[movee.head.pos[:]] = [movee.x, movee.y]
elif keys[pygame.K_RIGHT]:
movee.x = 1
movee.y = 0
movee.turns[movee.head.pos[:]] = [movee.x, movee.y]
elif keys[pygame.K_UP]:
movee.x = 0
movee.y = -1
movee.turns[movee.head.pos[:]] = [movee.x, movee.y]
elif keys[pygame.K_DOWN]:
movee.x = 0
movee.y = 1
movee.turns[movee.head.pos[:]] = [movee.x, movee.y]
for i, c in enumerate(movee.body):
p = c.pos[:]
if p in movee.turns:
turn = movee.turns[p]
c.move(turn[0],turn[1])
if i == len(movee.body)-1:
movee.turns.pop(p)
else:
if c.x == -1 and c.pos[0] <= 0: c.pos = (c.height-1, c.pos[1])
elif c.x == 1 and c.pos[0] >= c.height-1: c.pos = (0,c.pos[1])
elif c.y == 1 and c.pos[1] >= c.height-1: c.pos = (c.pos[0], 0)
elif c.y == -1 and c.pos[1] <= 0: c.pos = (c.pos[0],c.height-1)
else: c.move(c.x,c.y)
def add(movee):
tail = movee.body[-1]
dx, dy = tail.x, tail.y
if dx == 1 and dy == 0:
movee.body.append(cube((tail.pos[0]-1,tail.pos[1])))
elif dx == -1 and dy == 0:
movee.body.append(cube((tail.pos[0]+1,tail.pos[1])))
elif dx == 0 and dy == 1:
movee.body.append(cube((tail.pos[0],tail.pos[1]-1)))
elif dx == 0 and dy == -1:
movee.body.append(cube((tail.pos[0],tail.pos[1]+1)))
movee.body[-1].x = dx
movee.body[-1].y = dy
def draw(movee, surface):
for i, c in enumerate(movee.body):
if i ==0:
c.draw(surface, True)
else:
c.draw(surface)
def drawingAGrid(w, height, surface):
sizein = w // height
x = 0
y = 0
for l in range(height):
x = x + sizein
y = y + sizein
def redrawGrid(surface):
global height, width, s, snack
surface.fill((255,255,255))
s.draw(surface)
snack.draw(surface)
drawingAGrid(width, height, surface)
pygame.display.update()
def Candy(height, item):
positions = item.body
while True:
x = random.randrange(height)
y = random.randrange(height)
if len(list(filter(lambda z:z.pos == (x,y), positions))) > 0:
continue
else:
break
return (x,y)
def gameloop():
global width, height, s, snack, x_pos, y_pos, reset
width = 500
height = 20
win = pygame.display.set_mode((width, width))
s = snake((255, 0, 0), (10, 10))
snack = cube(Candy(height, s), color=(0, 0, 0))
flag = True
clock = pygame.time.Clock()
x_pos, y_pos = s.body[0].pos
while flag:
pygame.time.delay(50)
clock.tick(7)
s.move()
x, y = s.body[0].pos
if not -1 <= x - x_pos <= 1 or not -1 <= y - y_pos <= 1:
movee.reset((10,10))
x_pos, y_pos = s.body[0].pos
if s.body[0].pos == snack.pos:
s.add()
snack = cube(Candy(height, s), color=(0, 0, 0))
redrawGrid(win)
gameloop()
I just want like a scoreboard in any of the corners counting the score.
Use pygame.freetype to render text. e,g, crated a pygame.freetype.SysFont object:
import pygame.freetype
pygame.init()
font = pygame.freetype.SysFont('Times New Roman', 30)
The score is the number of body parts. Use str to convert a number to a text and .render() to render a text to a pygame.Surface object:
score = len(s.body)
text_surf, text_rect = font.render(str(score), (255, 0, 0), size=30)
Define a margin to the border of the window, calculate the text position (e.g. bottom right) and .blit the text to the window surfrace:
margin = 10
text_pos = (width - text_rect.width - margin, width - text_rect.height - margin)
surface.blit(text_surf, text_pos)
Function redrawGrid:
def redrawGrid(surface):
global height, width, s, snack
surface.fill((255,255,255))
s.draw(surface)
snack.draw(surface)
drawingAGrid(width, height, surface)
score = len(s.body)
text_surf, text_rect = font.render(str(score), (255, 0, 0), size=30)
margin = 10
text_pos = (width - text_rect.width - margin, width - text_rect.height - margin)
surface.blit(text_surf, text_pos)
pygame.display.update()
I have no clue what to do here, I want to make it so that a turtle in Python will shoot a bullet and if it collides with the other turtle, the score goes up. Except if I run this code, the game will crash when I shoot the bullet. So far, I only tried it for one of the eight move commands.
#imports turtles
import turtle
import random
#Sets screen, turtle program, and colour group
turtle.setup(1000, 800)
screen = turtle.Screen()
wn = turtle.Screen()
wn.bgcolor("springgreen")
amir = turtle.Turtle()
amir.shape("arrow")
amir.shapesize(1)
amir.speed(10)
amir.pensize (2)
amir.color("blue")
amir.setheading(90)
amir.penup()
#bullet 1
jonafat = turtle.Turtle()
jonafat.shape("circle")
jonafat.shapesize(0.5)
jonafat.speed(2)
jonafat.pensize (1)
jonafat.color("black")
jonafat.penup()
jonafat.ht()
hossein = turtle.Turtle()
hossein.shape("arrow")
hossein.shapesize(1)
hossein.speed(10)
hossein.pensize (2)
hossein.color("gold")
hossein.setheading(90)
hossein.penup()
#bullet
jonafat2 = turtle.Turtle()
jonafat2.shape("circle")
jonafat2.shapesize(0.5)
jonafat2.speed(2)
jonafat2.pensize (1)
jonafat2.color("black")
jonafat2.penup()
jonafat2.ht()
#scoreboard
TT = turtle.Turtle()
TT.ht()
TT.penup()
TT.goto(-500,200)
TT.color("black")
TT.write("0", move = False, align = "center", font = ("Arial", 20, "normal"))
#second scoreboard
TT = turtle.Turtle()
TT.ht()
TT.penup()
TT.goto(-500,200)
TT.color("black")
TT.write("0", move = False, align = "center", font = ("Arial", 20, "normal"))
x = 0
y = 0
amirs = 2
hosseins = 2
auto = 15
vanguard = 15
trump = 0
time = 1
score = 0
panda = 295
def up():
global amir
global x
global amirs
global hosseins
amir.seth(90)
n = 1
for i in range(0, n):
amir.sety(amir.ycor()+10)
n + 1
def down():
global amir
global x
global amirs
global hosseins
amir.seth(270)
n = 1
for i in range(0, n):
amir.sety(amir.ycor()-10)
n + 1
def left():
global amir
global x
global amirs
global hosseins
amir.seth(180)
n = 1
for i in range(0, n):
amir.setx(amir.xcor()-10)
n + 1
def right():
global amir
global x
global amirs
global hosseins
amir.seth(0)
n = 1
for i in range(0, n):
amir.setx(amir.xcor()+10)
n + 1
def up2():
global hossein
global y
global hosseins
hossein.seth(90)
n = 1
for i in range(0, n):
hossein.sety(hossein.ycor()+10)
n + 1
def down2():
global hossein
global y
global hosseins
hossein.seth(270)
n = 1
for i in range(0, n):
hossein.sety(hossein.ycor()-10)
n + 1
def left2():
global hossein
global y
global hosseins
hossein.seth(180)
n = 1
for i in range(0, n):
hossein.setx(hossein.xcor()-10)
n + 1
def right2():
global hossein
global y
global hosseins
hossein.seth(0)
n = 1
for i in range(0, n):
hossein.setx(hossein.xcor()+10)
n + 1
def collisionCheck(jonafat, hossein):
crash = True
jonafat1X = jonafat.xcor()
jonafat1Y = jonafat.ycor()
hossein2X = hossein.xcor()
hossein2Y = hossein.ycor()
jonafatPos = (int(jonafat1X), int(jonafat1Y))
hosseinPos = (int(hossein2X), int(hossein2Y))
if jonafatPos != hosseinPos:
crash = False
if jonafatPos == hosseinPos:
crash = True
return crash
def clock():
global time
time = time-1
def move():
global auto
global vanguard
global score
global time
wn.ontimer(clock,1000)
angle = amir.heading()
jonafat.ht()
jonafat.speed(10)
jonafat.setpos(amir.xcor(), amir.ycor())
if angle == 0:
trump = 1.
time = time-1
jonafat.showturtle()
jonafat.speed(2)
n = 1
for i in range(0, n):
jonafat.goto(amir.xcor()+300, amir.ycor())
n + 1
infLoop = 1
while infLoop == 1:
if collisionCheck(jonafat, hossein) == True:
infLoop = 0
break
score = score + 1
TT.clear()
TT.write(score, move = False, align = "center", font = ("Arial", 20, "normal"))
if time == 0:
break
infLoop = 0
if angle == 90:
jonafat.showturtle()
jonafat.speed(2)
n = 1
for i in range(0, n):
jonafat.goto(amir.xcor(),amir.ycor()+300)
n + 1
if angle == 180:
jonafat.showturtle()
jonafat.speed(2)
n = 1
for i in range(0, n):
jonafat.goto(amir.xcor()-300, amir.ycor())
n + 1
if angle == 270:
jonafat.showturtle()
jonafat.speed(2)
n = 1
for i in range(0, n):
jonafat.goto(amir.xcor(), amir.ycor()-300)
n + 1
def move2():
angle2 = hossein.heading()
jonafat2.ht()
jonafat2.speed(10)
jonafat2.setpos(hossein.xcor(), hossein.ycor())
if angle2 == 0:
jonafat2.showturtle()
jonafat2.speed(2)
n = 1
for i in range(0, n):
jonafat2.goto(hossein.xcor()+300, hossein.ycor())
n + 1
if angle2 == 90:
jonafat2.showturtle()
jonafat2.speed(2)
n = 1
for i in range(0, n):
jonafat2.goto(hossein.xcor(), hossein.ycor()+300)
n + 1
if angle2 == 180:
jonafat2.showturtle()
jonafat2.speed(2)
n = 1
for i in range(0, n):
jonafat2.goto(hossein.xcor()-300, hossein.ycor())
n + 1
if angle2 == 270:
jonafat2.showturtle()
jonafat2.speed(2)
n = 1
for i in range(0, n):
jonafat2.goto(hossein.xcor(), hossein.ycor()-300)
n + 1
wn.onkeypress(up, "w")
wn.onkeypress(down, "s")
wn.onkeypress(left, "a")
wn.onkeypress(right, "d")
wn.onkeypress(up2, "Up")
wn.onkeypress(down2, "Down")
wn.onkeypress(left2, "Left")
wn.onkeypress(right2, "Right")
wn.onkeypress(move2, "Shift_R")
wn.onkeypress(move, "space")
wn.listen()
This is the part I have trouble with
def collisionCheck(jonafat, hossein):
crash = True
jonafat1X = jonafat.xcor()
jonafat1Y = jonafat.ycor()
hossein2X = hossein.xcor()
hossein2Y = hossein.ycor()
jonafatPos = (int(jonafat1X), int(jonafat1Y))
hosseinPos = (int(hossein2X), int(hossein2Y))
if jonafatPos != hosseinPos:
crash = False
if jonafatPos == hosseinPos:
crash = True
return crash
def clock():
global time
time = time-1
def move():
global auto
global vanguard
global score
global time
wn.ontimer(clock,1000)
angle = amir.heading()
jonafat.ht()
jonafat.speed(10)
jonafat.setpos(amir.xcor(), amir.ycor())
if angle == 0:
trump = 1.
time = time-1
jonafat.showturtle()
jonafat.speed(2)
n = 1
for i in range(0, n):
jonafat.goto(amir.xcor()+300, amir.ycor())
n + 1
infLoop = 1
while infLoop == 1:
if collisionCheck(jonafat, hossein) == True:
infLoop = 0
break
score = score + 1
TT.clear()
TT.write(score, move = False, align = "center", font = ("Arial", 20, "normal"))
if time == 0:
break
infLoop = 0
It appears your only checking if their position is the same, although two objects can pass close to each other so that they visually collide, but aren't on the exact same position as each other.
You'll want to take their dimensions into account to properly check for collisions. The easiest way to check if they collide is to take the distance between their positions and check if it's smaller than a certain value. Although better options exist.
Instead of all this:
def collisionCheck(jonafat, hossein):
crash = True
jonafat1X = jonafat.xcor()
jonafat1Y = jonafat.ycor()
hossein2X = hossein.xcor()
hossein2Y = hossein.ycor()
jonafatPos = (int(jonafat1X), int(jonafat1Y))
hosseinPos = (int(hossein2X), int(hossein2Y))
if jonafatPos != hosseinPos:
crash = False
if jonafatPos == hosseinPos:
crash = True
return crash
Let's take advantage of #JoshuaWaring's advice as well as turtle's distance() method and come up with something more like:
PERSONAL_SPACE = 10 # assign this to be how close is too close
def collisionCheck(jonafat, hossein):
return jonafat.distance(hossein) < PERSONAL_SPACE
Let's rework the rest of the code to produce a minimally playable game:
# imports turtles
from turtle import Turtle, Screen
PERSONAL_SPACE = 15 # assign this to be how close is too close
FIRE_DISTANCE = 300
FONT = ('Arial', 36, 'normal')
# Sets screen, turtle program, and color group
screen = Screen()
screen.setup(1000, 800)
screen.bgcolor('springgreen')
def collisionCheck(bullet, player):
return bullet.distance(player) < PERSONAL_SPACE
def up1():
player1.seth(90)
player1.forward(10)
def down1():
player1.seth(270)
player1.forward(10)
def left1():
player1.seth(180)
player1.forward(10)
def right1():
player1.seth(0)
player1.forward(10)
def clock1():
global time1, score1
if collisionCheck(bullet1, player2):
score1 += 1
TT1.undo()
TT1.write(score1, align='center', font=FONT)
time1 = 1
else:
bullet1.forward(1)
time1 -= 1
if time1:
screen.ontimer(clock1, 10)
else:
bullet1.hideturtle()
def fire1():
global time1
bullet1.setpos(player1.pos())
bullet1.setheading(player1.heading())
bullet1.showturtle()
time1 = FIRE_DISTANCE
screen.ontimer(clock1, 100)
screen.onkeypress(up1, 'w')
screen.onkeypress(down1, 's')
screen.onkeypress(left1, 'a')
screen.onkeypress(right1, 'd')
screen.onkeypress(fire1, 'space')
def up2():
player2.seth(90)
player2.forward(10)
def down2():
player2.seth(270)
player2.forward(10)
def left2():
player2.seth(180)
player2.forward(10)
def right2():
player2.seth(0)
player2.forward(10)
def clock2():
global time2, score2
if collisionCheck(bullet2, player1):
score2 += 1
TT2.undo()
TT2.write(score2, align='center', font=FONT)
time2 = 1
else:
bullet2.forward(1)
time2 -= 1
if time2:
screen.ontimer(clock2, 10)
else:
bullet2.hideturtle()
def fire2():
global time2
bullet2.setpos(player2.pos())
bullet2.setheading(player2.heading())
bullet2.showturtle()
time2 = FIRE_DISTANCE
screen.ontimer(clock2, 100)
screen.onkeypress(up2, 'Up')
screen.onkeypress(down2, 'Down')
screen.onkeypress(left2, 'Left')
screen.onkeypress(right2, 'Right')
screen.onkeypress(fire2, '0')
player1 = Turtle('arrow')
player1.speed('fastest')
player1.color('blue')
player1.setheading(180)
player1.penup()
player1.forward(10)
# bullet 1
bullet1 = Turtle('circle', visible=False)
bullet1.shapesize(0.5)
bullet1.speed('fastest')
bullet1.color('black', 'blue')
bullet1.penup()
player2 = Turtle('arrow')
player2.speed('fastest')
player2.color('gold')
player2.setheading(0)
player2.penup()
player2.forward(10)
# bullet 2
bullet2 = Turtle('circle', visible=False)
bullet2.shapesize(0.5)
bullet2.speed('fastest')
bullet2.color('black', 'gold')
bullet2.penup()
# scoreboard
TT1 = Turtle(visible=False)
TT1.penup()
TT1.goto(-450, 300)
TT1.color('blue')
TT1.write('0', align='center', font=FONT)
# second scoreboard
TT2 = Turtle(visible=False)
TT2.penup()
TT2.goto(450, 300)
TT2.color('gold')
TT2.write('0', align='center', font=FONT)
time1 = 0
score1 = 0
time2 = 0
score2 = 0
screen.listen()
screen.mainloop()
Still needs additional work, i.e. doesn't handle (or disable) multiple shots correctly, etc.