NameError: name 'height' is not defined on line 10 - python

I'm currently creating a game for a school project on Python. This is what I have so far and Python's telling me NameError: name 'height' is not defined on line 10. What does this mean? I've done lots of research, but I still can't figure it out. Can someone help me?
import turtle
enter code here`import random
def main():
wn=turtle.Screen();
Gameturtle=turtle.Turtle()
Setupuser(Gameturtle,wn)
Setupcontrols(Gameturtle,wn)
Randomanglegenerator(turtle,len,height)
li = []
InsertEnemyturtleintolist(li)
while (True):
Hitchecker(Gameturtle, li)
def Setupuser(myTurtle,window):
window.bgcolor("white")
#width=x height=y
window.setup (width=400, height=400, startx=100, starty=100)
myTurtle.speed(2)
myTurtle.shape('turtle')
myTurtle.penup()
myTurtle.delay(0)
myTurtle.left(90)
myTurtle.mainloop()
window.exitonclick ()
def Hitchecker(myTurtle, enemyTurtles):
for eturtle in enemyTurtles:
distance=myTurtle.distance(eturtle)
if distance <= 1:
print("You lost a life >:^D")
def InsertEnemyturtleintolist(list):
Enemy=turtle.Turtle()
Enemy.shape=("triangle")
Enemy.speed(5)
Enemy.penup()
Enemy.left(90)
Enemy.showturtle()
list.append(Enemy)
def Setupcontrols(turtle, window):
window.onkey(lambda: turtle.goto(turtle.xcor(), turtle.ycor()+15), 'w')
window.onkey(lambda: turtle.goto(turtle.xcor()-15, turtle.ycor()), 'a')
window.onkey(lambda: turtle.goto(turtle.xcor()+15, turtle.ycor()), 'd')
window.onkey(lambda: turtle.goto(turtle.xcor(), turtle.ycor()-15), 's')
window.listen()
def Randomanglegenerator(turtle,len,height):
XYcord = random.randrange(1,5)
print(XYcord)
if XYcord==2 or 4:
Enemy.setheading(90)
main()

There are several problems with your program. First, invalid or questionable Python syntax:
if XYcord==2 or 4:
wn=turtle.Screen();
Should be something like:
if XYcord == 2 or XYcord == 4:
wn = turtle.Screen()
These are equivalent methods and you should use one or the other, not both. And mainloop() is a method of the screen or a function in the package 'turtle', not a method of a turtle instance:
myTurtle.mainloop()
window.exitonclick()
Instead do:
window.mainloop()
or:
window.exitonclick()
Redefining Python built-ins like list is a bad idea:
def InsertEnemyturtleintolist(list):
...
list.append(Enemy)
instead do:
def InsertEnemyturtleintolist(myEnemiesList):
...
myEnemiesList.append(Enemy)
Finally, an infinite loop like this has no place in an event-driven world like turtle:
while (True):
we need to replace it with a timer event. Below is my rewrite of your code to address the above issues and get it to basically function:
from turtle import Screen, Turtle
from random import randrange
def main():
screen = Screen()
turtle = Turtle()
SetupUser(turtle, screen)
SetupControls(turtle, screen)
RandomAngleGenerator(turtle)
enemies = []
for _ in range(5):
InsertEnemyTurtleIntoList(enemies, turtle)
HitChecker(turtle, screen, enemies)
screen.mainloop()
def SetupUser(myTurtle, myScreen):
myScreen.bgcolor('white')
myScreen.setup(width=400, height=400, startx=100, starty=100)
myTurtle.speed('slow')
myTurtle.shape('turtle')
myTurtle.penup()
def SetupControls(myTurtle, myScreen):
myScreen.onkey(lambda: myTurtle.sety(myTurtle.ycor() + 15), 'w')
myScreen.onkey(lambda: myTurtle.setx(myTurtle.xcor() - 15), 'a')
myScreen.onkey(lambda: myTurtle.setx(myTurtle.xcor() + 15), 'd')
myScreen.onkey(lambda: myTurtle.sety(myTurtle.ycor() - 15), 's')
myScreen.listen()
def HitChecker(myTurtle, myScreen, enemyTurtles):
dead = False
for myEnemy in enemyTurtles:
if myTurtle.distance(myEnemy) <= 10:
print("You lost a life >:^D")
dead = True
break
if dead:
myScreen.onkey(None, 'w')
myScreen.onkey(None, 'a')
myScreen.onkey(None, 'd')
myScreen.onkey(None, 's')
else:
myScreen.ontimer(lambda: HitChecker(myTurtle, myScreen, enemyTurtles), 100)
def InsertEnemyTurtleIntoList(array, myTurtle):
enemy = Turtle()
enemy.hideturtle()
enemy.shape('triangle')
enemy.speed('normal')
enemy.penup()
enemy.left(90)
enemy.showturtle()
while enemy.distance(myTurtle) < 30:
enemy.setposition(randrange(-190, 190), randrange(-190, 190))
array.append(enemy)
def RandomAngleGenerator(myTurtle):
turns = randrange(1, 3)
for _ in range(turns):
myTurtle.left(90)
main()
I'm sure it doesn't do everything you want it to do yet, but this should give you a workable starting point to finish your program.

Related

Python Turtle Issue

I am tryig to create a turtle game where two players can chase around a "goal" shape. I am struggling to get the program to recognize that two shapes are close to each other and therefore that one player should receive a point and then the goal should move. I have pasted my code below, any help would be greatly appreciated.
import turtle as trtl
import random as rand
#initialization / game setup
wn = trtl.Screen()
player1 = trtl.Turtle()
player1.shape('turtle')
player1.fillcolor('red')
player1.penup()
player1.goto(rand.randint(-100,100),rand.randint(-100,100))
player2 = trtl.Turtle()
player2.shape('triangle')
player2.fillcolor('blue')
player2.penup()
player2.goto(rand.randint(-100,100),rand.randint(-100,100))
goal = trtl.Turtle()
goal.shape('circle')
goal.fillcolor('yellow')
goal.penup()
goal.goto(rand.randint(-200,200),rand.randint(-150,-150))
player1_score = 0
player2_score = 0
def player1_up():
player1.setheading(90)
player1.forward(10)
def player2_up():
player2.setheading(90)
player2.forward(10)
def player1_down():
player1.setheading(270)
player1.forward(10)
def player2_down():
player2.setheading(270)
player2.forward(10)
def player1_right():
player1.setheading(0)
player1.forward(10)
def player2_right():
player2.setheading(0)
player2.forward(10)
def player1_left():
player1.setheading(180)
player1.forward(10)
def player2_left():
player2.setheading(180)
player2.forward(10)
if (abs(player1.xcor() - goal.xcor())<5):
if (abs(player1.ycor() - goal.ycor())<5):
player1_score+=1
goal.goto(rand.randint(-200,200),rand.randint(-150,150))
print(player1_score)
#events
wn.onkeypress(player1_up, "w")
wn.onkeypress(player2_up, "i")
wn.onkeypress(player1_down, "s")
wn.onkeypress(player2_down, "k")
wn.onkeypress(player1_right, "d")
wn.onkeypress(player2_right, "l")
wn.onkeypress(player1_left, "a")
wn.onkeypress(player2_left, "j")
wn.listen()
wn.mainloop()
I tried to simplify the code and I have seen this work in other programs. However, I cannot get it to work here!

Where to put closing for Pygame

I've made a game using Pygame module and Tkinter module using mostly messagebox part. I don't know where should I put code for closing Pygame window because I can't close the window.
for e in event.get():
if e.type == QUIT:
pygame_quit()
sys_exit()
This is the code where I need to put it:
def main(playing=True):
turn = 0
characters = sorted(['cruise', 'car', 'cap', 'derby', 'cat', 'cloud', 'tractor', 'tomato'])
for index in range(1, 5):
try:
characters.remove(settings[f'player_{index}_character'])
except ValueError:
pass
players_count = settings['players_number']
if players_count == 0:
players_count = 2
for player_index in range(1, players_count + 1):
with open('resources/players.json', 'r') as f:
players_info = load(f)
player_name = settings[f'player_{player_index}_username']
player_character = settings[f'player_{player_index}_character']
if player_name == '':
player_name = f'guest_{player_index}'
if player_character == '':
player_character = choice(characters)
characters.remove(player_character)
players_info['username'] = player_name
players_info['character'] = player_character
players[f'player_{player_index}'] = players_info
PygameClass.players_start()
while playing:
for e in event.get():
if e.type == QUIT:
pygame_quit()
sys_exit()
turn += 1
if turn > players_count:
turn = 1
player_name = players[f'player_{turn}']['username']
player_character = players[f'player_{turn}']['character']
messagebox.showinfo('Monopoly', f'It\'s {player_name}\'s turn. ({player_character.upper()})')
if players[f'player_{turn}']['in_jail']:
messagebox.showinfo('Monopoly', 'You paid $50. You are out of Jail!')
players[f'player_{turn}']['in_jail'] = False
players[f'player_{turn}']['money'] -= 50
players[f'player_{turn}']['plot_index'] = 10
PygameClass.move_player(turn)
PygameClass.money.play()
else:
move(dice(), turn)
main()
mainloop()
In the code calling move() function many more code is getting executed tho.
You are using pygame loop wrong.
def main():
# something
while playing:
for e in event.get():
if e.type == QUIT:
pygame_quit()
playing = False
main()
Mixing tkinter and pygame is a bad idea, pygame is a great module for making games and it's not that hard to learn so spend a bit more time learning it instead of mixing it with tkinter.

Seconds Counter and score keeper in with python tkinter

im a beginner in python and i have a big trouble for this code. im making a small match making game and this game made me hate python.
simply, user should match the photos together and try to do it as fast as possible for getting less time.
however, the timer is never working or giving me recursion limit error.
i want a simple second counter and a way to count the score.
so far, this is what i have and the timer is happening only once. so the label just becoming 1
import mycanvas as mc
import tkinter as tk
import random as r
import time
clickedimages=[]
score = 0
seconds=0
def main():
root=tk.Tk()
root.geometry("550x800")
root.resizable(0,0)
coverimg=tk.PhotoImage(file="pics\\qs.png")
name=""
images=[]
coppyimages=[]
allcanvas=[]
lbl=tk.Label(root,text="0",font=('robot',20))
lbl2=tk.Label(root,text=str(score),font=('robot',20))
lbl.place(x=100,y=750)
lbl2.place(x=400,y=750)
#making images
for x in range(1,11):
name="pics\\p"+str(x)+".png"
images.append(tk.PhotoImage(file=name))
coppyimages.append(tk.PhotoImage(file=name))
coppyimages.append(tk.PhotoImage(file=name))
#5x4
#positioning
tx=50
ty=150
counter=1
for x in range(0,5):
for y in range (0,4):
choice=r.randint(0,len(coppyimages)-1)
allcanvas.append(mc.myconvas(root,counter,coppyimages.pop(choice),tx,ty,coverimg))
tx+=120
counter+=1
tx=50
ty+=120
root.after(1000,timer(lbl))
root.mainloop()
def timer(lbl):
global seconds
seconds+=1
lbl.configure(text=str(seconds))
def clicked(event):
if(len(clickedimages)==0):
event.widget.showorhide()
clickedimages.append(event.widget)
elif((len(clickedimages)>0) and (event.widget != clickedimages[0])):
event.widget.showorhide()
clickedimages.append(event.widget)
matchchecker()
def matchchecker():
global clickedimages,score
time.sleep(0.5)
if(clickedimages[0].nameofimage==clickedimages[1].nameofimage):
print("Its a match")
clickedimages[0].place_forget()
clickedimages[1].place_forget()
score+=1
else:
print("wrong :(")
clickedimages[0].showorhide()
clickedimages[1].showorhide()
clickedimages.clear()
gamechecker()
def gamechecker():
global score
if(score==10):
print("Game over")
if __name__ == '__main__':
main()
the class is :
import tkinter as tk
import main
class myconvas(tk.Canvas):
number=0
myimage=None
nameofimage=""
coverimg=None
show=True
def __init__(self, root,n,img,px,py,dfault):
super().__init__()
self["width"] = 100
self["height"] = 100
self.number=n
self.myimage=img
self.maketheimage(dfault,px,py)
self.nameofimage = img.cget('file')
# self.setimagename()
self.coverimg=dfault;
self.bind("<Button-1>",main.clicked)
# root.after(500,self.showorhide())
def maketheimage(self,img,px,py):
self.create_image(50,50,image=img,anchor='center')
self.place(x=px,y=py)
def setimagename(self):
self.nameofimage=self.myimage.cget('file')
def showorhide(self):
if(self.show):
self.create_image(50,50,image=self.myimage,anchor='center')
self.show=False
else:
self.create_image(50,50,image=self.coverimg,anchor='center')
self.show=True
thank you in advance

Python-turtle: From math library: dist() causing loop to exit/freeze

I am trying to make a game using Python (with turtle)
the aim of the game is to shoot the other person
The problem comes with the collision code. I am checking collisions with bullets using dist(), but that seems to cause the loop to exit/freeze (I don't really know which).
I've tried using distance formula instead of the function but that didn't change anything
Here is my code:
bullet.forward(10)
distancetop1 = dist(player1.pos(),bullet.pos())
if self != player1 and distancetop1 < 2:
bullet.clear()
print("orange won!")
exit()
distancetop2 = dist(player1.pos(),bullet.pos())
if self != player2 and distancetop2 < 2:
bullet.clear()
print("blue won!")
exit()
My full code, if needed, is here
With turtle don't put your key checks in a loop. Set them once then call listen. Use mainloop to keep the game running.
Try this code:
import turtle,random, math
sc = turtle.Screen()
sc.bgcolor("#000")
player1 = turtle.Turtle()
player1.color("#00f")
player1.speed(0)
player1.up()
player1.goto(-256,0)
player2 = turtle.Turtle()
player2.color("#ffa500")
player2.speed(0)
player2.up()
player2.goto(256,0)
player2.seth(180)
bullet1 = turtle.Turtle()
bullet1.color("#fff")
bullet1.speed(0)
bullet1.ht()
bullet1.up()
bullet1.active = False
def dist(c1,c2):
return math.sqrt((c1[0]-c2[0])**2 + (c1[1]-c2[1])**2)
def shoot(self):
bullet = bullet1.clone()
bullet.active = True
bullet.goto(self.xcor(),self.ycor())
bullet.down()
bullet.seth(self.heading())
while (bullet.xcor() < 600 and bullet.xcor() > -600) and (bullet.ycor() < 256 and bullet.ycor() > -256):
bullet.forward(10)
distancetop1 = dist(player1.pos(),bullet.pos())
if self != player1 and distancetop1 < 5:
bullet.clear()
print("orange won!")
exit()
distancetop2 = dist(player2.pos(),bullet.pos())
if self != player2 and distancetop2 < 5:
bullet.clear()
print("blue won!")
exit()
bullet.clear()
def p1right():
player1.seth(0)
player1.forward(4)
def p1left():
player1.seth(180)
player1.forward(4)
def p1up():
player1.seth(90)
player1.forward(4)
def p1down():
player1.seth(270)
player1.forward(4)
def p1shoot():
shoot(player1)
def p2right():
player2.seth(0)
player2.forward(4)
def p2left():
player2.seth(180)
player2.forward(4)
def p2up():
player2.seth(90)
player2.forward(4)
def p2down():
player2.seth(270)
player2.forward(4)
def p2shoot():
shoot(player2)
#while True:
sc.onkey(p1right,"D")
sc.onkey(p1left,"A")
sc.onkey(p1up,"W")
sc.onkey(p1down,"S")
sc.onkey(p1shoot,"space")
sc.onkey(p2right,"Right")
sc.onkey(p2left,"Left")
sc.onkey(p2up,"Up")
sc.onkey(p2down,"Down")
sc.onkey(p2shoot,"Return")
sc.listen()
sc.mainloop()

Python code not working: does not print winner

I was wondering why my code keeps printing 'tan', I can't seem to get it to print the actual winner.
import turtle
import random
turtles = []
def setup():
global turtles
startline = -610
screen = turtle.Screen()
screen.bgpic('pavement.gif')
screen.setup(1290, 720)
turtle_ycor = [-40, -20, 0, 20, 40]
turtle_color = ['pink', 'skyblue', 'indigo', 'turquoise', 'tan']
for i in range(0, len(turtle_ycor)):
new_turtle = turtle.Turtle()
new_turtle.shape('turtle')
new_turtle.penup()
new_turtle.setpos(startline, turtle_ycor[i])
new_turtle.color(turtle_color[i])
new_turtle.pendown()
turtles.append(new_turtle)
def race():
global turtles
winner = False
finishline = 550
while not winner:
for current_turtle in turtles:
move = random.randint(0, 10)
current_turtle.forward(move)
xcor = current_turtle.xcor()
if (xcor >= finishline):
winner = True
current_turtle.forward(0)
turtle.forward(0)
winner_color = current_turtle.color()
print('The winner is', winner_color[1])
setup()
race()
turtle.mainloop()
I tried winner_color[0].
I think I may have found the error in this code.
I found out that with your code the last string value in the list turtle_color always wins.
This is because of this part of your code:
while not winner:
for current_turtle in turtles:
move = random.randint(0, 10)
current_turtle.forward(move)
xcor = current_turtle.xcor() #this should be indented, or itll only run this code
#for the last color in the list, in this case, tan
if (xcor >= finishline): #and all of this code should be indented too
winner = True #so it checks all colors, not just tan
current_turtle.forward(0)
turtle.forward(0)
winner_color = current_turtle.color()
print('The winner is', winner_color[1])
So, the correct code (in full) is:
import turtle
import random
turtles = []
def setup():
global turtles
startline = -610
screen = turtle.Screen()
screen.bgpic('pavement.gif')
screen.setup(1290, 720)
turtle_ycor = [-40, -20, 0, 20, 40]
turtle_color = ['pink', 'skyblue', 'indigo', 'turquoise', 'tan']
for i in range(0, len(turtle_ycor)):
new_turtle = turtle.Turtle()
new_turtle.shape('turtle')
new_turtle.penup()
new_turtle.setpos(startline, turtle_ycor[i])
new_turtle.color(turtle_color[i])
new_turtle.pendown()
turtles.append(new_turtle)
def race():
global turtles
winner = False
finishline = 550
while not winner:
for current_turtle in turtles:
move = random.randint(0, 10)
current_turtle.forward(move)
xcor = current_turtle.xcor()
if (xcor >= finishline):
winner = True
current_turtle.forward(0)
turtle.forward(0)
winner_color = current_turtle.color()
print('The winner is', winner_color[1])
setup()
race()
Tell me if there are still any errors (etc)!
It is possible the winner is in fact 'tan' at the end of every race.
The cause of this can be that random.seed is not called yet. Therefore, the code will initialize with the same seed every time it is run, causing the same sequence of random numbers generated every time having the same winner as result. You can increase randomization by for instance initializing the seed before every call, or only at the top of your code.
Adding this line:
random.seed() # initializes seed using current system time
anywhere in your code should randomize the outcomes.
On the note of reading out the winner_color: I'm assuming
winner_color = current_turtle.color() # gets the color of the current turtle
is now a string containing the color 'tan'. In this case, the index [0] will work on a string, and not a list. See for example
>>> a = 'tan'
>>> a[0]
't'
>>> a[1]
'a'
>>> a[2]
'n'
>>> a[:]
'tan'
>>> a[::-1]
'nat'
Also, have a look at how to present your question in a nice way (the stackoverflow text editor also shows tooltips on styling). This will increase the chances of your question being answered and studied.
Welcome to stackoverflow, I hoped this helps you get your code to work!

Categories