Trying to make a simple maze game in Python Turtle. Using the stamp method I have made the outline of the first level, and it loads perfectly. I want to add a second level and access it, but I don't know how. Any help will be appreciated.
P.S - I am quite new to stack overflow so idk how much code I should put here, but expecting help, I am posting the full code. Thank in advance
import turtle
import math
wn = turtle.Screen()
wn.bgcolor("black")
wn.title("A maze game")
wn.setup(700,700)
class Pen(turtle.Turtle):
def __init__(self):
turtle.Turtle.__init__(self)
self.shape("square")
self.color("white")
self.penup()
self.speed(0)
class Treasure(turtle.Turtle):
def __init__(self, x, y):
turtle.Turtle.__init__(self)
self.shape("square")
self.color(color_1)
self.penup()
self.speed(0)
self.gold = 100
self.goto(x, y)
def destroy(self):
self.goto(2000, 2000)
self.hideturtle()
def change_color(self):
self.color(color_2)
color_1 = ("white")
color_2 = ("gold")
class Player(turtle.Turtle):
def __init__(self):
turtle.Turtle.__init__(self)
self.shape("circle")
self.color("red")
self.penup()
self.speed(0)
self.gold = 0
def go_up(self):
move_to_x = player.xcor()
move_to_y = player.ycor() + 24
if (move_to_x, move_to_y) not in walls:
self.goto(move_to_x, move_to_y)
def go_down(self):
move_to_x = player.xcor()
move_to_y = player.ycor() - 24
if (move_to_x, move_to_y) not in walls:
self.goto(move_to_x, move_to_y)
def go_left(self):
move_to_x = player.xcor() - 24
move_to_y = player.ycor()
if (move_to_x, move_to_y) not in walls:
self.goto(move_to_x, move_to_y)
def go_right(self):
move_to_x = player.xcor() + 24
move_to_y = player.ycor()
if (move_to_x, move_to_y) not in walls:
self.goto(move_to_x, move_to_y)
def is_close_to(self, other):
a = self.xcor()-other.xcor()
b = self.ycor()-other.ycor()
distance = math.sqrt((a ** 2) + (b ** 2))
if distance < 50:
return True
else:
return False
levels = [""]
level_1 = [
"XXXXXXXXXXXXXXXXXXXXXXXXX",
"X P T X",
"XXXXXXXXXXXXXXXXXXXXXXXXX"
]
treasures = []
levels.append(level_1)
def setup_maze(level):
for y in range(len(level)):
for x in range(len(level[y])):
character = level[y][x]
screen_x = -288 + (x * 24)
screen_y = 288 - (y * 24)
if character == "X":
pen.goto(screen_x, screen_y)
pen.stamp()
walls.append((screen_x, screen_y))
if character == "P":
player.goto(screen_x, screen_y)
if character == "T":
treasures.append(Treasure(screen_x, screen_y))
pen = Pen()
player = Player()
walls = []
setup_maze(levels[1])
turtle.listen()
turtle.onkey(player.go_left,"Left")
turtle.onkey(player.go_right,"Right")
turtle.onkey(player.go_up,"Up")
turtle.onkey(player.go_down,"Down")
wn.tracer(0)
while True:
for treasure in treasures:
if player.is_close_to(treasure):
treasure.change_color()
wn.update()
To load a new level, you need to reset the current state of the world to a known base state, then setup the new level. You seem to have figured out the latter, and the former involves clearing the screen, re-initializing its properties, and clearing the game state.
First, you need to clear the window. As this answer tells us, this can be done by calling turtle.Screen().reset(), or in your case wm.reset().
After that's done, you need to reinitialize all the properties of the screen, like setting the bgcolor and title and other things like this. Right now these happen at the beginning of the file, but you'll need to do them multiple times through your program's lifecycle, so you should place them in a separate function, like init_screen, so that you can call it once you've reset it.
Finally, you need to reset the game state. In your case, this would be your treasures and walls lists, but as you add more features this may include any other data that does not need to persist between one level and the next. This data actually becomes invalid as soon as you call setup_maze, so it would make sense to first clear them and then setup the new level in the inner loops.
Related
cant move the character at the same time the obstacle is moving, pirincipal is the name of the image that works as the player
def move():
def left(event):
x = -5
y = 0
canvasGame.update()
edgeReached()
canvasGame.move(principal,x, y)
collision()
def right(event):
x = 5
y = 0
canvasGame.update()
edgeReached()
canvasGame.move(principal,x, y)
collision()
canvasGame.bind_all("<Left>", left)
canvasGame.bind_all("<Right>", right
move()
class Barrel:
def __init__(self, canvas):
self.canvas = canvas
self.obs = canvasGame.create_image(125, 500, image=nuevoObs, anchor=tk.NW)
self.x = 16
self.y = 0
def movement(self):
while True:
coords = canvasGame.coords(self.obs)
if (coords[0] >= 1000):
self.x = -10
self.y = 0
elif (coords[0] < 0):
self.x = 10
self.y = 0
self.canvas.move(self.obs, self.x,self.y)
canvasGame.update()
time.sleep(0.05)
def createBarrel():
barrel = Barrel(canvasGame)
circle_thread = Thread(target=barrel.movement())
circle_thread.daemon = True
circle_thread.start()
createBarrel()
def plzmove():
moveplz = Thread(target=move())
moveplz.daemon = True
moveplz.start()
plzmove()
I tried creating threads but the problem continues, if there is a barrel moving, the player cant move (if there is nothing else moving, the player can move with freedom), also, the player movement is just an image being moved, any tip is appreciated, much love.
Right now I am creating a maze path finding algorithm using breadth first search. The algorithm to find the 'best path' seems to work. The problem however is that I am not sure how to make the sprite (turtle) move through that best path.
Here is code:
import turtle
import time
import sys
from collections import deque
bs = turtle.Screen()
bs.bgcolor("black")
bs.setup(1300,700)
class Building(turtle.Turtle): # Define building class
def __init__(self):
turtle.Turtle.__init__(self)
self.shape("square") # Shape of the building
self.color("grey") # Colour of the building
self.penup() # Lift the pen up so it does not leave a trail
self.speed('fast') # Sets the speed that the building is drawn on the screen
class Road(turtle.Turtle): # Define road class
def __init__(self):
turtle.Turtle.__init__(self)
self.shape("square") # Shape of the road
self.color("white") # Colour of the road
self.penup() # Lift the pen up so it does not leave a trail
self.hideturtle()
self.speed('fast') # Sets the speed that the road is drawn on the screen
class Start(turtle.Turtle): # Define start class
def __init__(self):
turtle.Turtle.__init__(self)
self.shape("square") # Shape of the start point
self.color('green') # Colour of the start point
self.penup() # Lift the pen up so it does not leave a trail
self.hideturtle()
self.speed('fast')
class Route(turtle.Turtle):
def __init__(self):
turtle.Turtle.__init__(self)
self.shape("square")
self.color("yellow")
self.penup()
self.hideturtle()
self.speed('fast')
class End(turtle.Turtle): # Define end class
def __init__(self):
turtle.Turtle.__init__(self)
self.shape("square") # Shape of the end point
self.color("red") # Colour of the end point
self.penup() # Lift the pen up so it does not leave a trail
self.hideturtle()
self.speed('fast')
class Searcher(turtle.Turtle):
def __init__(self):
turtle.Turtle.__init__(self)
self.shape("square")
self.color("white")
self.penup()
self.hideturtle()
self.speed('fast')
class sprite(turtle.Turtle): # Define sprite class
noOfSteps = 0 # Declare variable noOfSteps and instantiate it as 0
def __init__(self):
turtle.Turtle.__init__(self)
self.shape("turtle") # Shape of the sprite
self.color("purple") # Colour of the sprite
self.penup() # Lift the pen up so it does not leave a trail
self.hideturtle()
self.speed('fast')
def moveSprite(self):
start.color('green')
start.stamp()
searcher.color('red')
searcher.stamp()
self.goto(start_x, start_y)
self.showturtle()
# self.goto(solution[x,y])
# Read maze txt file
def readMaze(mazeSet, filename):
mazeFile = open(filename, "r")
lines = mazeFile.readlines()
for line in lines:
line = line.strip()
row = [c for c in line]
mazeSet.append(row)
mazeSet = [] # This declares the maze as an empty list
readMaze(mazeSet, "CA1_Map.txt") # This reads the maze into the list
# Setting up of maze
def setupMaze(mazeSet):
global start_x, start_y, end_x, end_y
m_height, m_width = len(mazeSet), len(mazeSet[0]) # Define maze height and maze width
for y in range(m_height): # Select each line in the maze
for x in range(m_width): # Identify each character in the line
character = mazeSet[y][x] # Assign the maze reference to the variable 'character'
screen_x = ((x - m_width) * 24) + 150 # Assign screen_x to screen starting position for x coords
screen_y = ((m_width - y) * 24) - 200 # Assign screen_y to screen starting position for y coords
if character == "X":
building.goto(screen_x, screen_y)
building.stamp()
walls.append((screen_x, screen_y))
if character == "." or character == 'e':
path.append((screen_x, screen_y))
if character == "e":
end_x, end_y = screen_x, screen_y
searcher.color('red')
searcher.goto(screen_x, screen_y)
searcher.stamp()
searcher.color('white')
finish.append((screen_x, screen_y))
if character == "s":
start_x, start_y = screen_x, screen_y
start.goto(screen_x,screen_y)
start.stamp()
def search(x,y):
frontier.append((x, y))
solution[x,y] = x,y
while len(frontier) > 0:
time.sleep(0)
x, y = frontier.popleft()
if(x - 24, y) in path and (x - 24, y) not in visited:
cell = (x - 24, y)
solution[cell] = x, y
frontier.append(cell)
visited.add((x-24, y))
if (x, y - 24) in path and (x, y - 24) not in visited:
cell = (x, y - 24)
solution[cell] = x, y
frontier.append(cell)
visited.add((x, y - 24))
if(x + 24, y) in path and (x + 24, y) not in visited:
cell = (x + 24, y)
solution[cell] = x, y
frontier.append(cell)
visited.add((x + 24, y))
if(x, y + 24) in path and (x, y + 24) not in visited:
cell = (x, y + 24)
solution[cell] = x, y
frontier.append(cell)
visited.add((x, y + 24))
searcher.goto(x,y)
searcher.stamp()
def correctRoute(x, y):
route.goto(x, y)
route.stamp()
while (x, y) != (start_x, start_y):
route.goto(solution[x, y])
route.stamp()
x, y = solution[x, y]
def endProgram():
bs.exitonclick()
sys.exit()
# Main program
# Setting up classes
building = Building()
road = Road()
start = Start()
end = End()
searcher = Searcher()
route = Route()
sprite = sprite()
# Setting up lists
walls = []
path = []
finish = []
visited = set()
frontier = deque()
solution = {}
setupMaze(mazeSet)
search(start_x, start_y)
correctRoute(end_x, end_y)
while True:
sprite.moveSprite()
The image of the maze currently looks like this:
So what I need to do is make the purple turtle (kind of hard to see) move from the green square to red square through the best path (yellow squares).
Step 1: At the function where the program determines the correct route,
record each coordinate into a list,
and return the list (inverted) so it can be accessed outside the function:
def correctRoute(x, y):
routes = [(x, y)]
route.goto(x, y)
route.stamp()
while (x, y) != (start_x, start_y):
route.goto(solution[x, y])
route.stamp()
x, y = solution[x, y]
routes.append((x, y))
return routes[::-1]
Step 2: Give the moveSprite function another parameter, and the parameter will be the list of coordinates.
the list will then be split into two parts: the starting coordinates and the path. Before calling self.showturtle(),
make sure that the turtle is in its proper starting position first.
Using a for loop, loop through the path list with time.sleep and make the turtle go to each of the coordinates:
def moveSprite(self, routes):
starting, path = routes[0], routes[1:]
start.color('green')
start.stamp()
searcher.color('red')
searcher.stamp()
self.goto(starting)
self.showturtle()
for path in path:
time.sleep(0.3)
self.goto(path)
Step 3: At the very bottom of your code, assign the correctRoute call to a variable to retrive the coordinates.
Remove the while loop, and put the list of coordinates into the moveSprite function:
routes = correctRoute(end_x, end_y)
sprite.moveSprite(routes)
All together:
import turtle
import time
import sys
from collections import deque
bs = turtle.Screen()
bs.bgcolor("black")
bs.setup(1300,700)
class Building(turtle.Turtle): # Define building class
def __init__(self):
turtle.Turtle.__init__(self)
self.shape("square") # Shape of the building
self.color("grey") # Colour of the building
self.penup() # Lift the pen up so it does not leave a trail
self.speed('fast') # Sets the speed that the building is drawn on the screen
class Road(turtle.Turtle): # Define road class
def __init__(self):
turtle.Turtle.__init__(self)
self.shape("square") # Shape of the road
self.color("white") # Colour of the road
self.penup() # Lift the pen up so it does not leave a trail
self.hideturtle()
self.speed('fast') # Sets the speed that the road is drawn on the screen
class Start(turtle.Turtle): # Define start class
def __init__(self):
turtle.Turtle.__init__(self)
self.shape("square") # Shape of the start point
self.color('green') # Colour of the start point
self.penup() # Lift the pen up so it does not leave a trail
self.hideturtle()
self.speed('fast')
class Route(turtle.Turtle):
def __init__(self):
turtle.Turtle.__init__(self)
self.shape("square")
self.color("yellow")
self.penup()
self.hideturtle()
self.speed('fast')
class End(turtle.Turtle): # Define end class
def __init__(self):
turtle.Turtle.__init__(self)
self.shape("square") # Shape of the end point
self.color("red") # Colour of the end point
self.penup() # Lift the pen up so it does not leave a trail
self.hideturtle()
self.speed('fast')
class Searcher(turtle.Turtle):
def __init__(self):
turtle.Turtle.__init__(self)
self.shape("square")
self.color("white")
self.penup()
self.hideturtle()
self.speed('fast')
class sprite(turtle.Turtle): # Define sprite class
noOfSteps = 0 # Declare variable noOfSteps and instantiate it as 0
def __init__(self):
turtle.Turtle.__init__(self)
self.shape("turtle") # Shape of the sprite
self.color("purple") # Colour of the sprite
self.penup() # Lift the pen up so it does not leave a trail
self.hideturtle()
self.speed('fast')
def moveSprite(self, routes):
starting, path = routes[0], routes[1:]
start.color('green')
start.stamp()
searcher.color('red')
searcher.stamp()
self.goto(starting)
self.showturtle()
for path in path:
time.sleep(0.3)
self.goto(path)
# Read maze txt file
def readMaze(mazeSet, filename):
mazeFile = open(filename, "r")
lines = mazeFile.readlines()
for line in lines:
line = line.strip()
row = [c for c in line]
mazeSet.append(row)
mazeSet = [] # This declares the maze as an empty list
readMaze(mazeSet, "CA1_Map.txt") # This reads the maze into the list
# Setting up of maze
def setupMaze(mazeSet):
global start_x, start_y, end_x, end_y
m_height, m_width = len(mazeSet), len(mazeSet[0]) # Define maze height and maze width
for y in range(m_height): # Select each line in the maze
for x in range(m_width): # Identify each character in the line
character = mazeSet[y][x] # Assign the maze reference to the variable 'character'
screen_x = ((x - m_width) * 24) + 150 # Assign screen_x to screen starting position for x coords
screen_y = ((m_width - y) * 24) - 200 # Assign screen_y to screen starting position for y coords
if character == "X":
building.goto(screen_x, screen_y)
building.stamp()
walls.append((screen_x, screen_y))
if character == "." or character == 'e':
path.append((screen_x, screen_y))
if character == "e":
end_x, end_y = screen_x, screen_y
searcher.color('red')
searcher.goto(screen_x, screen_y)
searcher.stamp()
searcher.color('white')
finish.append((screen_x, screen_y))
if character == "s":
start_x, start_y = screen_x, screen_y
start.goto(screen_x,screen_y)
start.stamp()
def search(x,y):
frontier.append((x, y))
solution[x,y] = x,y
while len(frontier) > 0:
time.sleep(0)
x, y = frontier.popleft()
if(x - 24, y) in path and (x - 24, y) not in visited:
cell = (x - 24, y)
solution[cell] = x, y
frontier.append(cell)
visited.add((x-24, y))
if (x, y - 24) in path and (x, y - 24) not in visited:
cell = (x, y - 24)
solution[cell] = x, y
frontier.append(cell)
visited.add((x, y - 24))
if(x + 24, y) in path and (x + 24, y) not in visited:
cell = (x + 24, y)
solution[cell] = x, y
frontier.append(cell)
visited.add((x + 24, y))
if(x, y + 24) in path and (x, y + 24) not in visited:
cell = (x, y + 24)
solution[cell] = x, y
frontier.append(cell)
visited.add((x, y + 24))
searcher.goto(x,y)
searcher.stamp()
def correctRoute(x, y):
routes = [(x, y)]
route.goto(x, y)
route.stamp()
while (x, y) != (start_x, start_y):
route.goto(solution[x, y])
route.stamp()
x, y = solution[x, y]
routes.append((x, y))
return routes[::-1]
def endProgram():
bs.exitonclick()
sys.exit()
# Main program
# Setting up classes
building = Building()
road = Road()
start = Start()
end = End()
searcher = Searcher()
route = Route()
sprite = sprite()
# Setting up lists
walls = []
path = []
finish = []
visited = set()
frontier = deque()
solution = {}
setupMaze(mazeSet)
search(start_x, start_y)
routes = correctRoute(end_x, end_y)
sprite.moveSprite(routes)
If you want the turtle to change its direction at each turn, use this as the moveSprite function:
def moveSprite(self, routes):
starting, routes = routes[0], routes[1:]
start.color('green')
start.stamp()
searcher.color('red')
searcher.stamp()
self.goto(starting)
self.showturtle()
for path1, path2 in zip(routes, routes[1:]):
self.goto(path1)
time.sleep(0.3)
if path1[0] == path2[0]: # If the x coordinates of two consecutive moves are equal, that means that the turtle is moving along the `y` axis
if path1[1] > path2[1]:
self.setheading(270)
else:
self.setheading(90)
else: # If the x coordinates of two consecutive moves aren't equal, that means that the turtle is moving along the `x` axis
if path1[0] > path2[0]:
self.setheading(180)
else:
self.setheading(0)
self.goto(path2)
I am new to Python. I'm trying to create a space game where two space ships fight each other. The user controls one and the other will fly and fire randomly. The user has to protect their self and fire on the other ship. If either ship can sucessefully hit the other 10 times, then that ship wins.
Problem: I can not see both ships at the same time. When I control one turtle, then the other turtle does not show. Please help.
from turtle import *
import random
import pygame
class Application:
space_ship = Turtle()
window = Screen()
window_X = 640
window_Y = 640
ship_x = space_ship.xcor()
Clock = pygame.time.Clock()
def __init__(self):
self.game_config()
self.enemy_config()
def enemy_config(self):
enemy = Turtle()
enemy.penup()
enemy.speed(0)
enemy.shapesize(2)
enemy.setposition(0,-250)
while True:
self.Clock.tick(20)
enemy.fd(10)
if enemy.ycor() >= 340:
enemy.right(50)
enemy.sety(-320)
elif enemy.ycor() <= -340:
enemy.right(50)
enemy.sety(320)
elif enemy.xcor() >= 340:
enemy.right(50)
enemy.setx(-320)
elif enemy.xcor() <= -340:
enemy.right(50)
enemy.setx(320)
def movefd(self):
while True:
self.Clock.tick(20)
self.space_ship.fd(10)
if self.space_ship.ycor() >= 340:
self.space_ship.sety(-320)
elif self.space_ship.ycor() <= -340:
self.space_ship.sety(320)
elif self.space_ship.xcor() >= 340:
self.space_ship.setx(-320)
elif self.space_ship.xcor() <= -340:
self.space_ship.setx(320)
def moverg(self):
self.space_ship.right(15)
def movelf(self):
self.space_ship.left(15)
def game_config (self):
bgcolor("white")
self.space_ship.shapesize(2)
self.space_ship.speed(0)
self.space_ship.color("green")
self.window.setup(self.window_X,self.window_Y)
self.space_ship.left(90)
self.space_ship.penup()
onkeypress(self.moverg, "Right")
onkeypress(self.movelf, "Left")
onkeypress(self.movefd, "Up")
listen()
done()
if __name__ == '__main__':
Application()
Problem: can not see both ship same time. when use control one turtle
then another turtle does not show.
For me, the bigger problem is you've completely missed the point of object-oriented programming. Let's address both our problems with a complete rework of your code. But before we do, repeat over and over, "while True: has no business in an event-driven world like turtle."
from turtle import Screen, Turtle
class SpaceShip(Turtle):
def __init__(self):
super().__init__()
self.shapesize(2)
self.color("green")
self.speed('fastest')
self.penup()
self.setheading(90)
def movefd(self):
self.forward(10)
if self.ycor() >= 340:
self.sety(-320)
elif self.ycor() <= -340:
self.sety(320)
if self.xcor() >= 340:
self.setx(-320)
elif self.xcor() <= -340:
self.setx(320)
def moverg(self):
self.right(15)
def movelf(self):
self.left(15)
class EnemyShip(SpaceShip):
def __init__(self):
super().__init__()
self.hideturtle()
self.color("black")
self.setheading(-50)
self.sety(-250)
self.showturtle()
class Application:
SCREEN_X = 640
SCREEN_Y = 640
def __init__(self):
self.screen = Screen()
self.screen.setup(self.SCREEN_X, self.SCREEN_Y)
self.space_ship = SpaceShip()
self.enemy = EnemyShip()
self.screen.onkeypress(self.space_ship.moverg, "Right")
self.screen.onkeypress(self.space_ship.movelf, "Left")
self.screen.onkeypress(self.space_ship.movefd, "Up")
self.screen.listen()
self.movefd()
self.screen.mainloop()
def movefd(self):
self.enemy.movefd()
self.screen.ontimer(self.movefd, 100)
if __name__ == '__main__':
Application()
The Point of the game is to make all the circles disappear when they Collide but for some reason some circles aren't disappearing? - Thank you for your help in advance!
import turtle
import random
import math
import time
# Setting up the Screen
ms = turtle.Screen()
ms.bgcolor("red")
ms.title("Space Rocket Minigame #Rafa94")
# Using class functions/Methods
# subclass
class Border(turtle.Turtle):
def __init__(self): # class constrcutor
turtle.Turtle.__init__(self) # adding our Objects attributes all starting with "self"
self.penup()
self.hideturtle()
self.speed(0)
self.color("silver")
self.pensize(5)
def draw_border(self):
self.penup()# getting our pen to start drawing
self.goto(-300, -300)
self.pendown()
self.goto(-300, 300)
self.goto(300, 300)
self.goto(300, -300)
self.goto(-300, -300)
class Player(turtle.Turtle): # since it got inherited this class becomes a Superclass
def __init__(self): # self is our only argument here but it will have multiple attributes
turtle.Turtle.__init__(self) # since we are using the Turtle module, we are able to use it's built in functions
self.penup()# our attributes
self.speed(0)
self.shape("triangle")
self.color("black")
self.velocity = 0.1
def move(self):
self.forward(self.velocity)
# Border Checking
if self.xcor() > 290 or self.xcor() < -290: # Left side is -290 Right side is 290 we also want the coordinates x and y to be below 300 to not go over our border
self.left(60)
if self.ycor() > 290 or self.ycor() < -290:
self.left(60)
def turnleft(self):
self.left(30)
def turnright(self):
self.right(30)
def increasespeed(self):
self.velocity += 1
class Goal(turtle.Turtle): # Sub Class
def __init__(self):
# since we are using the Turtle module we are able to use it's built in functions
turtle.Turtle.__init__(self)
self.penup() # our attributes
self.speed(0)
self.shape("circle")
self.color("green")
self.velocity = 3 #xcor #ycor
self.goto(random.randint(-250, 250), random.randint(-250, 250)) # we are making our turtle "go to" X & Y coordinates by -250 and 250 only randomly. We also have our random module here aswell
self.setheading(random.randint(0, 360)) # setting the heading to see in which direction i want it to go
def jump(self): # Jump = Collidee
self.goto(random.randint(-250, 250), random.randint(-250, 250)) # "jump" stands for Collidee so if the circle "jumps" with player it will move to random postion by 250 and -25
self.setheading(random.randint(0, 360)) # from where it collidee's it goes 360 moves location 360 Right
def move(self): # we copyed the same method cause it will be doing the same movements as the player we want it to go "forward" with our set "speed" & also check for our borders we set
self.forward(self.velocity)
# Border Checking
if self.xcor() > 290 or self.xcor() < -290: # Left side is -290 Right side is 290 we also want the coordinates x and y to be below 300 to not go over our border
self.left(60)
if self.ycor() > 290 or self.ycor() < -290:
self.left(60)
# Collision checking function/Method
# Uses the Pythgorean Theorem to measure the distance between two objects
def isCollision(t1, t2): # t1 = turtle1 t2 = turtle also when a function starts with "is" isCollision most likely it will be a Boolean of True or False
a = t1.xcor()-t2.xcor() # xcor = Right -xcor = Left/ when they collide the xcor is 0
b = t1.ycor()-t2.ycor() # ycor = Right -ycor = Left/ when they collide the ycor is 0
distance = math.sqrt((a ** 2) + (b ** 2))
if distance < 30:
return True
else:
return False
# Create class instances
player = Player() # after creating a class must make instances to call it in other words make an Object of the class
border = Border() # sub class
#goal = Goal() #sub class
# Draw our border
border.draw_border()
#create multiple goals
goals = [] # Creating a list of goals
for count in range(6): # We are making the code repeat 6 times
goals.append(Goal()) # each time the code runs it puts a goal the end 6 times
# Set keyboard bindings
ms.listen()
ms.onkey(player.turnleft, "Left")
ms.onkey(player.turnright, "Right")
ms.onkey(player.increasespeed, "Up")
# speed game up
ms.tracer(0.1)
# main loop
while True:
ms.update()
player.move() # these two are class methods
#goal.move() # the reason we copyed like we said is cause it's gunna have the exact same movements as our player!
# we want the goal to be True to in our while loop in order for the code to be excuted
for goal in goals:
# Basically saying If there is a collision between the player and goal we the want the goal to "jump" / Function in our while True loop
goal.move()
if isCollision(player, goal):
goal.jump() # baiscally saying if the goal collide's move or "jump" to other location
time.sleep(0.005)
As far as I can tell, your circles (goals) disappear and reappear elsewhere as you designed them to do. One possibiliy is that since you move the circles to a random location, that location can be close to where they disappeared from, making it appear that nothing happened.
Generally, your code is a mess. Below is my rewrite of it to bring some structure and style to it. As well as take more advantage of what turtle offers:
from turtle import Screen, Turtle
from random import randint
WIDTH, HEIGHT = 600, 600
CURSOR_SIZE = 20
class Border(Turtle):
def __init__(self): # class initializer
super().__init__(visible=False)
self.penup()
self.color("silver")
self.pensize(5)
def draw_border(self):
self.goto(-WIDTH/2, -HEIGHT/2)
self.pendown()
for _ in range(2):
self.forward(WIDTH)
self.left(90)
self.forward(HEIGHT)
self.left(90)
class Player(Turtle):
def __init__(self):
super().__init__(shape="triangle")
self.color("black")
self.penup()
self.velocity = 0.1
def move(self):
self.forward(self.velocity)
if not (CURSOR_SIZE - WIDTH/2 < self.xcor() < WIDTH/2 - CURSOR_SIZE and CURSOR_SIZE - HEIGHT/2 < self.ycor() < HEIGHT/2 - CURSOR_SIZE):
self.undo() # undo forward motion
self.left(60)
self.forward(self.velocity) # redo forward motion in new heading
def turn_left(self):
self.left(30)
def turn_right(self):
self.right(30)
def increase_speed(self):
self.velocity += 1
class Goal(Turtle):
def __init__(self):
super().__init__(shape="circle")
self.color("green")
self.penup()
self.velocity = 3
self.jump()
def jump(self):
while self.distance(player) < CURSOR_SIZE * 10: # make sure we move far away from player
self.goto(randint(CURSOR_SIZE - WIDTH/2, WIDTH/2 - CURSOR_SIZE), randint(CURSOR_SIZE - HEIGHT/2, HEIGHT/2 - CURSOR_SIZE))
self.setheading(randint(0, 360))
def move(self):
self.forward(self.velocity)
if not (CURSOR_SIZE - WIDTH/2 < self.xcor() < WIDTH/2 - CURSOR_SIZE and CURSOR_SIZE - HEIGHT/2 < self.ycor() < HEIGHT/2 - CURSOR_SIZE):
self.undo() # undo forward motion
self.left(60)
self.forward(self.velocity) # redo forward motion in new heading
def isCollision(t1, t2):
return t1.distance(t2) < CURSOR_SIZE
def move():
player.move()
for goal in goals:
goal.move()
if isCollision(player, goal):
goal.jump()
screen.update()
screen.ontimer(move, 10)
# Setting up the Screen
screen = Screen()
screen.bgcolor("red")
screen.title("Space Rocket Minigame #cdlane")
screen.tracer(False)
# Create class instances
Border().draw_border()
player = Player()
# Create multiple goals
goals = [Goal() for _ in range(6)]
# Set keyboard bindings
screen.onkey(player.turn_left, "Left")
screen.onkey(player.turn_right, "Right")
screen.onkey(player.increase_speed, "Up")
screen.listen()
move()
screen.mainloop()
i am trying to make a game where you can shoot bullets to kill emojis. However, i can't manage to figure out how to stop spamming the space key to shoot bullets. If you keep on spamming, the game would be too easy. I am not exactly sure if I should use the sleep command or something else.Please help! thanks!
Here is my code:
# import everything from turtle
from turtle import *
import random
import math
#create a link to the object (creates the environment)
screen = Screen()
speed1 = 1.3
ht()
amountOfEmojis = 11
#set a boundary for screen, if touches end, goes to the other side
screenMinX = -screen.window_width()/2
screenMinY = -screen.window_height()/2
screenMaxX = screen.window_width()/2
screenMaxY = screen.window_height()/2
#establish important data for screen environment
screen.setworldcoordinates(screenMinX,screenMinY,screenMaxX,screenMaxY)
screen.bgcolor("black")
#turtle setup
penup()
ht()
speed(0)
goto(0, screenMaxY - 50)
color('white')
write("Welcome to Emoji Run!", align="center", font=("Courier New",26))
goto(0, screenMaxY - 70)
write("Use the arrow keys to move and space to fire. The point of the game is to kill the emojis", align="center")
goto(0, 0)
color("red")
emojis = ["Poop_Emoji_7b204f05-eec6-4496-91b1-351acc03d2c7_grande.png", "1200px-Noto_Emoji_KitKat_263a.svg.png",
"annoyningface.png", "Emoji_Icon_-_Sunglasses_cool_emoji_large.png"]
class Bullet(Turtle):
#constructor, object for a class, pass in information
def __init__(self,screen,x,y,heading):
#create a bullet
Turtle.__init__(self)#clones bullet
self.speed(0)
self.penup()
self.goto(x,y)
self.seth(heading)#pointing to itself
self.screen = screen
self.color('yellow')
self.max_distance = 500
self.distance = 0
self.delta = 20
self.shape("bullet")
#logic to move bullet
def move(self):
self.distance = self.distance + self.delta#how fast it's going to move
self.forward(self.delta)
if self.done():
self.reset()
def getRadius(self):
return 4#collision detection helper function
def blowUp(self):
self.goto(-300,0)#function that makes something go off the screen
def done(self):
return self.distance >= self.max_distance # append to list
class Asteroid(Turtle):
def __init__(self,screen,dx,dy,x,y,size,emoji):#spawn asteroid randomly
Turtle.__init__(self)#clone itself
self.speed(0)
self.penup()
self.goto(x,y)
self.color('lightgrey')
self.size = size
self.screen = screen
self.dx = dx
self.dy = dy
r = random.randint(0, len(emoji) - 1)
screen.addshape(emojis[r])
self.shape(emojis[r])
#self.shape("rock" + str(size)) #sets size and shape for asteroid
def getSize(self):#part of collision detection
return self.size
#getter and setter functions
def getDX(self):
return self.dx
def getDY(self):
return self.dy
def setDX(self,dx):
self.dx = dx
def setDY(self,dy):
self.dy = dy
def move(self):
x = self.xcor()
y = self.ycor()
#if on edge of screen. go to opposite side
x = (self.dx + x - screenMinX) % (screenMaxX - screenMinX) + screenMinX
y = (self.dy + y - screenMinY) % (screenMaxY - screenMinY) + screenMinY
self.goto(x,y)
def blowUp(self):
self.goto(-300,0)#function that makes something go off the screen
def getRadius(self):
return self.size * 10 - 5
class SpaceShip(Turtle):
def __init__(self,screen,dx,dy,x,y):
Turtle.__init__(self)
self.speed(0)
self.penup()
self.color("white")
self.goto(x,y)
self.dx = dx
self.dy = dy
self.screen = screen
self.bullets = []
self.shape("turtle")
def move(self):
x = self.xcor()
y = self.ycor()
x = (self.dx + x - screenMinX) % (screenMaxX - screenMinX) + screenMinX
y = (self.dy + y - screenMinY) % (screenMaxY - screenMinY) + screenMinY
self.goto(x,y)
#logic for collision
def powPow(self, asteroids):
dasBullets = []
for bullet in self.bullets:
bullet.move()
hit = False
for asteroid in asteroids:
if intersect(asteroid, bullet):#counts every asteroid to see if it hits
asteroids.remove(asteroid)
asteroid.blowUp()
bullet.blowUp()
hit = True
if (not bullet.done() and not hit):
dasBullets.append(bullet)
self.bullets = dasBullets
def fireBullet(self):
self.bullets.append(Bullet(self.screen, self.xcor(), self.ycor(), self.heading()))
def fireEngine(self):#how turtle moves
angle = self.heading()
x = math.cos(math.radians(angle))
y = math.sin(math.radians(angle))
self.dx = self.dx + x#how it rotates
self.dy = self.dy + y
self.dx = self.dx / speed1
self.dy = self.dy / speed1
#extra function
def turnTowards(self,x,y):
if x < self.xcor():
self.left(7)
if x > self.xcor():
self.right(7)
def getRadius(self):
return 10
def getDX(self):
return self.dx
def getDY(self):
return self.dy
#collision detection
def intersect(object1,object2):
dist = math.sqrt((object1.xcor() - object2.xcor())**2 + (object1.ycor() - object2.ycor())**2)
radius1 = object1.getRadius()
radius2 = object2.getRadius()
# The following if statement could be written as
# return dist <= radius1+radius2
if dist <= radius1+radius2:
return True
else:
return False
#adds object to screen
screen.register_shape("rock3",((-20, -16),(-21, 0), (-20,18),(0,27),(17,15),(25,0),(16,-15),(0,-21)))
screen.register_shape("rock2",((-15, -10),(-16, 0), (-13,12),(0,19),(12,10),(20,0),(12,-10),(0,-13)))
screen.register_shape("rock1",((-10,-5),(-12,0),(-8,8),(0,13),(8,6),(14,0),(12,0),(8,-6),(0,-7)))
screen.register_shape("ship",((-10,-10),(0,-5),(10,-10),(0,10)))
screen.register_shape("bullet",((-2,-4),(-2,4),(2,4),(2,-4)))
#ship spawn exactly the middle everytime
ship = SpaceShip(screen,0,0,(screenMaxX-screenMinX)/2+screenMinX,(screenMaxY-screenMinY)/2 + screenMinY)
#randomize where they spawn
asteroids = []
for k in range(amountOfEmojis):
dx = random.random() * 6 - 3
dy = random.random() * 6 - 3
x = random.randrange(10) * (screenMaxX - screenMinX) + screenMinX
y = random.random() * (screenMaxY - screenMinY) + screenMinY
asteroid = Asteroid(screen,dx,dy,x,y,random.randint(1,3), emojis)
asteroids.append(asteroid)
def play():
# Tell all the elements of the game to move
ship.move()
gameover = False
for asteroid in asteroids:
r = random.randint(0, 1)
if r == 1:
asteroid.right(50)
else:
asteroid.left(20)
asteroid.move()
if intersect(ship,asteroid):
write("You Got Killed :(",font=("Verdana",25),align="center")
gameover = True
ship.powPow(asteroids)
screen.update()
if not asteroids:
color('green')
write("You Killed the Emojis!!",font=("Arial",30),align="center")
ht()
if not gameover:
screen.ontimer(play, 30)
bullets = []
#controls
def turnLeft():
ship.left(7)
def turnRight():
ship.right(7)
def go():
ship.fireEngine()
def fire():
ship.fireBullet()
ht()
screen.tracer(0);
screen.onkey(turnLeft, 'left')
screen.onkey(turnRight, 'right')
screen.onkey(go, 'up')
screen.onkey(fire, 'space')
screen.listen()
play()
Thanks!
You could try something like this:
import time
FIRE_DELAY = 0.1 # number of seconds between bullets
LAST_FIRE = 0
def fire():
t = time.time()
if t - LAST_FIRE > FIRE_DELAY:
LAST_FIRE = t
ship.fireBullet()