so I have been trying to make this game in python using only standard libraries because I don't know how to link libraries (I am an absolute beginner) but whenever I run the program, it doesn't respond. This is the code:
import turtle
import random
import math
import time
import os
play = True
#window
window = turtle.Screen()
window.bgcolor("#4287f5")
window.title("Box Grab!")
#border
outer = turtle.Turtle()
outer.speed(0)
outer.color("#000000","#000000")
outer.up()
outer.goto(250, 250)
outer.down
outer.begin_fill()
for i in range(4):
outer.rt(90)
outer.fd(500)
outer.ht()
#boxes
box1 = turtle.Turtle()
box2 = turtle.Turtle()
box3 = turtle.Turtle()
box4 = turtle.Turtle()
box5 = turtle.Turtle()
box6 = turtle.Turtle()
box1n = 2
box2n = 2
box3n = 2
box4n = 2
box5n = 2
box6n = 2
box1.penup()
box1.speed(0)
box1.color("darkorange")
box1.shape("square")
box2.penup()
box2.speed(0)
box2.color("darkorange")
box2.shape("square")
box3.penup()
box3.speed(0)
box3.color("darkorange")
box3.shape("square")
box4.penup()
box4.speed(0)
box4.color("darkorange")
box4.shape("square")
box5.penup()
box5.speed(0)
box5.color("darkorange")
box5.shape("square")
box6.penup()
box6.speed(0)
box6.color("darkorange")
box6.shape("square")
box1.setpos(random.randint(-250, 250), random.randint(-250, 250))
box2.setpos(random.randint(-250, 250), random.randint(-250, 250))
box3.setpos(random.randint(-250, 250), random.randint(-250, 250))
box4.setpos(random.randint(-250, 250), random.randint(-250, 250))
box5.setpos(random.randint(-250, 250), random.randint(-250, 250))
box6.setpos(random.randint(-250, 250), random.randint(-250, 250))
#player
player = turtle.Turtle()
player.penup()
player.color("blue")
player.shape("circle")
#defining movement
def down():
player.setheading(270)
player.forward(20)
def right():
player.setheading(0)
player.forward(20)
def left():
player.setheading(180)
player.forward(20)
def up():
player.setheading(90)
player.forward(20)
#collision
def isCollision(t1, t2):
d = math.sqrt(math.pow(t1.xcor()-t2.xcor(),2) + math.pow(t1.ycor()-t2.ycor(),2))
if d < 20:
return True
else:
return False
if isCollision(player, box1):
box1.hideturtle()
box1n - 1
if isCollision(player, box2):
box2.hideturtle()
box2n - 1
if isCollision(player, box3):
box3.hideturtle()
box3n - 1
if isCollision(player, box4):
box4.hideturtle()
box4n - 1
if isCollision(player, box5):
box5.hideturtle()
box5n - 1
if isCollision(player, box6):
box6.hideturtle()
box6n - 1
#movement
turtle.listen()
turtle.onkey(up,"w")
turtle.onkey(down,"s")
turtle.onkey(right,"d")
turtle.onkey(left,"a")
#time
def mainTime():
x = 60
for i in range(60 + 1):
time.sleep(1)
print(formatTime(x))
x -= 1
def formatTime(x):
minutes = int(x / 60)
seconds_rem = int(x % 60)
if (seconds_rem < 10):
return(str(minutes) + ":0" + str(seconds_rem))
else:
return(str(minutes) + ":" + str(seconds_rem))
if x == 0:
play = false
mainTime()
#score
def score():
score = 0
for s in range(60):
t = 60
time.sleep(1)
t -= 1
if box1 or box2 or box3 or box4 or box5 or box6 == 1:
score = score + (seconds_rem * 100)
score()
#game over
if play == false:
print("GAME OVER. ")
restart = input("RESTART? Y/N")
if restart == "y":
os.system('python "C:\\Users\\lyons\\AppData\\Local\\Programs\\Python\\Python37-32\\Projects\\failing to make a game.py"')
Also, when it used to work, the boxes wouldn't dissapear after the player hit them. How do I fix this?
Related
I was trying to make this snake game (no food yet) by using turtle. At length of 1 it still fast but as it goes longer it runs slower and slower.
from turtle import Turtle, Screen
SIZE = 500
GRID_NUM = 20
GRID_SIZE = SIZE // GRID_NUM
screen = Screen()
screen.setup(SIZE, SIZE)
screen.bgcolor('black')
screen.setworldcoordinates(10, 8, SIZE + 2, SIZE)
class Snake:
def __init__(self):
self.head = init_turtle()
self.head.setpos((GRID_SIZE // 2 + GRID_SIZE * 9, GRID_SIZE // 2 + GRID_SIZE * 10))
self.body = []
self.direction = 0 # 0 = left, 1 = up, 2 = right, 3 = down
self.speed = 100 * len(self.body) if len(self.body) > 0 else 100
def levelup(self):
if len(self.body) == 0:
self.body.append(self.head.clone())
else:
self.body.append(self.body[len(self.body) - 1].clone())
def update(self):
for i in range(len(self.body) - 1, -1 , -1):
if i == 0:
self.body[i].setpos(self.head.pos())
else:
self.body[i].setpos(self.body[i - 1].pos())
def init_turtle():
turtle = Turtle()
turtle.shape('square')
turtle.shapesize(1.25)
turtle.color('red')
turtle.pencolor('#404040')
turtle.speed('fastest')
turtle.up()
return turtle
def init_border():
def border():
turtle = init_turtle()
for _ in range(4):
turtle.down()
turtle.forward(SIZE)
turtle.left(90)
yield(0)
turtle.penup()
turtle.hideturtle()
def horizontal():
turtle = init_turtle()
for x in range(GRID_SIZE, SIZE, GRID_SIZE):
turtle.goto(x, 0)
turtle.pendown()
turtle.goto(x, SIZE)
turtle.penup()
yield(0)
turtle.hideturtle()
def vertical():
turtle = init_turtle()
for y in range(GRID_SIZE, SIZE, GRID_SIZE):
turtle.goto(0, y)
turtle.pendown()
turtle.goto(SIZE, y)
turtle.penup()
yield(0)
turtle.hideturtle()
generator1 = border()
generator2 = horizontal()
generator3 = vertical()
while(next(generator1, 1) + next(generator2, 1) + next(generator3, 1) < 3):
pass
def start_game():
snake = Snake()
def pop():
snake.body.pop()
def right():
snake.direction = 0
def up():
snake.direction = 1
def left():
snake.direction = 2
def down():
snake.direction = 3
def exit():
screen.bye()
screen.onkey(pop, 'q')
screen.onkey(left, 'Left')
screen.onkey(up, 'Up')
screen.onkey(right, 'Right')
screen.onkey(down, 'Down')
screen.onkey(exit, 'Escape')
screen.onkey(snake.levelup, 'Return')
screen.listen()
while True:
snake.update()
snake.head.setheading(snake.direction * 90)
snake.head.forward(GRID_SIZE)
print('snake', snake.head.pos())
init_border()
start_game()
screen.mainloop()
At first i think the cause of the problem was defines a lot of function but i don't know. Also i am new to python so i don't know any kind of optimizing methods.
Any ideas to optimize this program?
We can speed up long snakes by doing the drawing off screen and sending explicit updates. Below is a rework of your code that does just that and includes a temporary patch to make the snake move in a square so you can just hit to see how much the snake is affected by additional body segments:
from turtle import Turtle, Screen
SIZE = 525
GRID_NUM = 20
GRID_SIZE = SIZE // GRID_NUM
RIGHT, UP, LEFT, DOWN = range(4)
class Snake:
def __init__(self):
self.head = init_turtle()
self.head.setpos(GRID_NUM//2, GRID_NUM//2)
self.direction = LEFT
self.body = []
def levelup(self):
if self.body:
self.body.append(self.body[-1].clone())
else:
self.body.append(self.head.clone())
def update(self):
for i in range(len(self.body) - 1, -1, -1):
if i == 0:
self.body[i].setposition(self.head.position())
else:
self.body[i].setposition(self.body[i - 1].position())
def init_turtle():
turtle = Turtle()
turtle.shape('square')
print(GRID_SIZE)
turtle.shapesize((GRID_SIZE - 1) / 20)
turtle.color('#404040', 'red')
turtle.speed('fastest')
turtle.penup()
return turtle
def init_border():
def border():
turtle = init_turtle()
turtle.goto(-0.5, -0.5)
for _ in range(4):
turtle.pendown()
turtle.forward(GRID_NUM)
turtle.left(90)
turtle.penup()
turtle.hideturtle()
def vertical():
turtle = init_turtle()
for x in range(GRID_NUM):
turtle.goto(x - 0.5, -0.5)
turtle.pendown()
turtle.goto(x - 0.5, GRID_NUM - 0.5)
turtle.penup()
yield 0
turtle.hideturtle()
def horizontal():
turtle = init_turtle()
for y in range(GRID_NUM):
turtle.goto(-0.5, y + 0.5)
turtle.pendown()
turtle.goto(GRID_NUM - 0.5, y + 0.5)
turtle.penup()
yield 0
turtle.hideturtle()
border()
generator1 = horizontal()
generator2 = vertical()
while next(generator1, 1) + next(generator2, 1) < 2:
pass
def start_game():
snake = Snake()
def right():
snake.direction = RIGHT
def up():
snake.direction = UP
def left():
snake.direction = LEFT
def down():
snake.direction = DOWN
screen.onkey(snake.body.pop, 'q')
screen.onkey(left, 'Left')
screen.onkey(up, 'Up')
screen.onkey(right, 'Right')
screen.onkey(down, 'Down')
screen.onkey(screen.bye, 'Escape')
screen.onkey(snake.levelup, 'Return')
screen.listen()
while True:
snake.update()
snake.head.setheading(snake.direction * 90)
snake.head.forward(1)
# Run snake around in a square for testing purposes
x, y = snake.head.position()
if round(x) == 1 and snake.direction == LEFT:
up()
elif round(y) == GRID_NUM - 2 and snake.direction == UP:
right()
elif round(x) == GRID_NUM - 2 and snake.direction == RIGHT:
down()
elif round(y) == 1 and snake.direction == DOWN:
left()
screen.update()
screen = Screen()
screen.setup(SIZE, SIZE)
screen.bgcolor('black')
screen.setworldcoordinates(-0.75, -0.75, GRID_NUM + 0.25, GRID_NUM + 0.25)
init_border()
screen.tracer(False)
start_game()
screen.mainloop() # never reached!
I'd recommend both approaches as the main loop will only get more complicated (slower) as you add food and border detection.
I changed your coordinate system to make it snake centric. That is, forward(1) moves one square on the grid rather than having to do the math. If you're going to mess with the coordinates anyway, why not tweak them to your best advantage.
How can I make a score system, that increases by one, when I hit square1. A score system, that restart back to 0, when I hit square2. And also loop back to the beginning position, when I hit square2. So loop back and restart the score to 0, when I hit square 2.
import turtle
import math
from time import sleep
wn = 0
player = turtle.Turtle()
square1 = turtle.Turtle()
square2 = turtle.Turtle()
speed = 1
def init():
wn = turtle.Screen()
wn.bgcolor("blue")
wn.tracer(3)
turtle.listen()
turtle.onkey(turnLeft, "Left")
turtle.onkey(turnRight, "Right")
def initCharacters():
player.color("red")
player.shape("circle")
player.penup()
player.speed(0)
player.setposition(25, 20)
square1.color("white")
square1.shape("square")
square1.penup()
square1.speed(0)
square1.setposition(100, 100)
square2.color("yellow")
square2.shape("square")
square2.penup()
square2.speed(0)
square2.setposition(150, 50)
def distanceIsLessThan(p, q, distance):
return math.pow(p.xcor() - q.xcor(), 2) + math.pow(p.ycor() - q.ycor(), 2) < math.pow(distance, 2)
def turnLeft():
player.left(90)
def turnRight():
player.right(90)
def main():
init()
initCharacters()
while True:
player.forward(speed)
if distanceIsLessThan(player, square1, 20) or \
distanceIsLessThan(player, square2, 20):
# print("Touch")
initCharacters()
sleep(0.02)
if __name__ == "__main__":
main()
This is basically what you want:
import turtle
import math
from time import sleep
#Adding the integer for the score
score=0
wn = 0
player = turtle.Turtle()
square1 = turtle.Turtle()
square2 = turtle.Turtle()
speed = 1
#Here Im making a new turtle for showing the score
turtle_score=turtle.Turtle()
turtle_score.penup()
turtle_score.hideturtle()
turtle_score.goto(-300.00,-245.00)
turtle_score.write("")
def init():
wn = turtle.Screen()
wn.bgcolor("blue")
wn.tracer(3)
turtle.listen()
turtle.onkey(turnLeft, "Left")
turtle.onkey(turnRight, "Right")
def initCharacters():
player.color("red")
player.shape("circle")
player.penup()
player.speed(0)
player.setposition(25, 20)
square1.color("white")
square1.shape("square")
square1.penup()
square1.speed(0)
square1.setposition(100, 100)
square2.color("yellow")
square2.shape("square")
square2.penup()
square2.speed(0)
square2.setposition(150, 50)
def distanceIsLessThan(p, q, distance):
return math.pow(p.xcor() - q.xcor(), 2) + math.pow(p.ycor() - q.ycor(), 2) < math.pow(distance, 2)
def turnLeft():
player.left(90)
def turnRight():
player.right(90)
def main():
init()
initCharacters()
global score
while True:
player.forward(speed)
#Checking which square the player collided with and updating the score.
if distanceIsLessThan(player, square1, 20):
score=score+1
player.fd(40)
turtle_score.undo()
turtle_score.write(str(score))
if distanceIsLessThan(player, square2, 20):
score=0
turtle_score.undo()
turtle_score.write(str(score))
# print("Touch")
initCharacters()
sleep(0.02)
if __name__ == "__main__":
main()
The score shows up at the bottom left corner of the screen.
I need help figuring out how to visibly show a scoreboard for the amount of times player X has won, player O has won, and how many draws or ties there has been. Here is the code I am using, I just can't figure out how to add a scoreboard.
I added a # that says where my scoreboard is going to go and I started it, but don't think its correct and need help with the entire scoreboard.
from tkinter import *
#screen dimensions
winsize = 500
gridwidth = 2
symbol = winsize/12
symsize = 0.5
#colors of players
player_x = 'black'
player_o = 'gray'
#screen colors
screencolor = 'red'
gridcolor = 'black'
bg_color = 'white'
player_one = 1
sizeof_cell = winsize / 3
screen_title = 0
turn_x = 1
turn_o = 2
gameover = 3
score_x = 0
score_o = 0
zero = 0
X = 1
O = 2
class Game(Tk):
def __init__(self):
Tk.__init__(self)
self.canvas = Canvas(
height=winsize, width=winsize,
bg=bg_color)
self.canvas.pack()
self.bind('<x>', self.exit)
self.canvas.bind('<Button-1>', self.mouse)
self.gamestate = screen_title
self.title_screen()
self.board = [
[zero, zero, zero],
[zero, zero, zero],
[zero, zero, zero]]
#ADD HIGH SCORE
def display_score(score):
score = 0
if score(grid):
score += 1
#creating title screen
def title_screen(self):
self.canvas.delete('all')
self.canvas.create_rectangle(
0, 0,
winsize, winsize,
fill='black',
outline='black')
self.canvas.create_rectangle(
int(winsize/15), int(winsize/15),
int(winsize*14/15), int(winsize*14/15),
width=int(winsize/20),
outline='black')
self.canvas.create_rectangle(
int(winsize/10), int(winsize/10),
int(winsize*9/10), int(winsize*9/10),
fill='black',
outline='black')
#adding names, R number, intructions
self.canvas.create_text(
winsize/2,
winsize/3,
text='TIC TAC TOE', fill='white',
font=('Calibri', int(-winsize/10), 'bold'))
self.canvas.create_text(
winsize/2,
winsize/2,
text='Game By: Yanely Ramos (R11529473)', fill='white',
font=('Arial', int(-winsize/25)))
self.canvas.create_text(
winsize/2,
winsize/1.8,
text='& Maria Tan de Castro (R11512696)', fill='white',
font=('Arial', int(-winsize/25)))
self.canvas.create_text(
winsize/2,
winsize/1.3,
text='Directions: Players take turn putting marks on empty' + '\n' + 'squares first player to get 3 in a row is a winner.' + "\n" + 'If all 9 squares are full and there is no winner, it is a draw.', fill='white',
font=('Times New Roman', int(-winsize/35)))
self.canvas.create_text(
int(winsize/2),
int(winsize/2.5),
text='[Click here to play]', fill='white',
font=('Arial', int(-winsize/25)))
#clicking of the game using the mouse
def mouse(self, event):
x = self.pixel_grid(event.x)
y = self.pixel_grid(event.y)
if self.gamestate == screen_title:
self.new_gameboard()
self.gamestate = player_one
elif (self.gamestate == turn_x and
self.board[y][x] == zero):
self.next_shift(X, x, y)
if self.winner(X):
self.gamestate = gameover
self.gameover_title('X WINS')
elif self.game_draw():
self.gamestate = gameover
self.gameover_title('DRAW')
else:
self.gamestate = turn_o
elif (self.gamestate == turn_o and
self.board[y][x] == zero):
self.next_shift(O, x, y)
if self.winner(O):
self.gamestate = gameover
self.gameover_title('O WINS')
elif self.game_draw():
self.gamestate = gameover
self.gameover_title('DRAW')
else:
self.gamestate = turn_x
elif self.gamestate == gameover:
self.new_gameboard()
self.gamestate = player_one
#starting new game
def new_gameboard(self):
self.canvas.delete('all')
self.board = [
[zero, zero, zero],
[zero, zero, zero],
[zero, zero, zero]]
for n in range(1, 3):
self.canvas.create_line(
sizeof_cell*n, 0,
sizeof_cell*n, winsize,
width=gridwidth, fill=gridcolor)
self.canvas.create_line(
0, sizeof_cell*n,
winsize, sizeof_cell*n,
width=gridwidth, fill=gridcolor)
#what pops up when the game ends
def gameover_title(self, outcome):
self.canvas.delete('all')
if outcome == 'X WINS':
wintext = 'X wins'
wincolor = player_x
elif outcome == 'O WINS':
wintext = 'O wins'
wincolor = player_o
elif outcome == 'DRAW':
wintext = 'Draw'
wincolor = screencolor
self.canvas.create_rectangle(
0, 0,
winsize, winsize,
fill=wincolor, outline='')
self.canvas.create_text(
int(winsize/2), int(winsize/2),
text=wintext, fill='white',
font=('Calibri', int(-winsize/6), 'bold'))
self.canvas.create_text(
int(winsize/2), int(winsize/1.65),
text='[click to play again]', fill='white',
font=('Arial', int(-winsize/25)))
#next players turn
def next_shift(self, player, grid_x, grid_y):
if player == X:
self.drawx(grid_x, grid_y)
self.board[grid_y][grid_x] = X
elif player == O:
self.drawo(grid_x, grid_y)
self.board[grid_y][grid_x] = O
#creating X player
def drawx(self, grid_x, grid_y):
x = self.grid_pixel(grid_x)
y = self.grid_pixel(grid_y)
delta = sizeof_cell/1.5*symsize
self.canvas.create_line(
x-delta, y-delta,
x+delta, y+delta,
width=symbol, fill='red')
self.canvas.create_line(
x+delta, y-delta,
x-delta, y+delta,
width=symbol, fill='red')
#creating O player
def drawo(self, grid_x, grid_y):
x = self.grid_pixel(grid_x)
y = self.grid_pixel(grid_y)
delta = sizeof_cell/1.5*symsize
self.canvas.create_oval(
x-delta, y-delta,
x+delta, y+delta,
width=symbol, outline='black')
#how to win
def winner(self, symbol):
for y in range(3):
if self.board[y] == [symbol, symbol, symbol]:
return True
for x in range(3):
if self.board[0][x] == self.board[1][x] == self.board[2][x] == symbol:
return True
if self.board[0][0] == self.board[1][1] == self.board[2][2] == symbol:
return True
elif self.board[0][2] == self.board[1][1] == self.board[2][0] == symbol:
return True
return False
#if 9 squares fill up, go to draw screen
def game_draw(self):
for row in self.board:
if zero in row:
return False
return True
def grid_pixel(self, grid_coord):
pixel_coord = grid_coord * sizeof_cell + sizeof_cell / 2
return pixel_coord
def pixel_grid(self, pixel_coord):
if pixel_coord >= winsize:
pixel_coord = winsize - 1
grid_coord = int(pixel_coord / sizeof_cell)
return grid_coord
def exit(self, event):
self.destroy()
def main():
root = Game()
root.mainloop()
root.title('TIC TAC TOE')
You can save players statistics in the mouse method and show them when you need them.
Try the following example
Add self.stats = {'X': 0, 'O': 0, 'DRAW': 0} in Game init method.
In mouse method:
When self.winner(X) increment X (self.stats['X']+=1)
When self.winner(O) increment O
When self.game_draw() increment DRAW
Add a simple text in gameover_title showing stats on screen:
self.canvas.create_text(
int(winsize/2), int(winsize-20),
text='X: {X} O: {O} DRAW: {DRAW}'.format(**self.stats),
fill='white',
font=('Arial', int(-winsize/25)))
I wanted to make a snake game in turtle but I can't seem to get the tail segments to follow the leader. As if to say I can't get the first body part to follow the head, and then the second body part to follow the first body, etc.
I tried using what maths I have but I can't seem to get it to calculate where the head just was or where the body in front of it just was.
here is my code:
#libraries
import turtle
import random
import math
#screen
the_screen = turtle.Screen()
the_screen.bgcolor("lightgreen")
the_screen.title("Catapillar")
#border
border_writer = turtle.Turtle()
border_writer.speed(0)
border_writer.color("green")
border_writer.penup()
border_writer.setposition(-275, -275)
border_writer.pendown()
border_writer.pensize(7)
for side in range(4):
border_writer.fd(550)
border_writer.lt(90)
border_writer.hideturtle()
#player
player = turtle.Turtle()
player.color("yellow")
player.shape("circle")
player.penup()
player.speed(0)
player.setposition(0,0)
player.setheading(0)
playerspeed = 2
#fruit
fruit = 1
fruit = turtle.Turtle()
fruit.color("red")
fruit.shape("circle")
fruit.penup()
fruit.speed(0)
fruit.shapesize(0.6, 0.6)
x = random.randint(-200, 200)
y = random.randint(100, 250)
fruit.setposition(x, y)
#moving and collision checker
def turnleft():
player.left(24.5)
def turnright():
player.right(24.5)
def increasespeed():
global playerspeed
playerspeed += 1
def isCollision(t1, t2):
distance = math.sqrt(math.pow(t1.xcor()-t2.xcor(), 2) + math.pow(t1.ycor()-t2.ycor(), 2))
if distance < 24:
return True
else:
return False
#making the tail(s) and hiding them
tail1 = turtle.Turtle()
tail1.hideturtle()
tail1.color("yellow")
tail1.shape("circle")
tail1.penup()
tail1.speed(0)
tail1.setposition(+700,700)
tail1.shapesize(0.6, 0.6)
tail1state = 'off'
#key presses
turtle.listen()
turtle.onkeypress(turnleft, "Left")
turtle.onkeypress(turnright, "Right")
turtle.onkeypress(increasespeed, "Up")
#main loop player always moves forward, out of bound set, reset fruit
#randomly when collided, create tail1...
while True:
player.forward(playerspeed)
#gameovers'
if (player.xcor() > 275) or (player.xcor() < -275):
playerspeed += 7
print("GAME OVER")
if (player.ycor() > 275) or (player.ycor() < -275):
playerspeed += 7
print("GAME OVER")
#collision check between fruit and head
if isCollision(player, fruit):
#resets the fruit, moves it randomly
fruit.hideturtle()
if tail1state == 'off':
uuu = player.xcor()
vvv = player.ycor()
tail1.setposition(uuu,vvv)
tail1.showturtle()
tail1state = 'on'
#reset the fruit
x = random.randint(-200, 200)
y = random.randint(-100, 250)
fruit.setposition(x, y)
fruit.showturtle()
#playerspeed +=1
If you have any idea on how you think I should approach it, please let me know what you think.
Thank you.
Since this comes up over and over (but effort to effect it is rarely shown) here's my minimal, generic, slithering around a screen effect that you should be able to adapt for your own purposes:
from turtle import Turtle, Screen
SNAKE_LENGTH = 10
SNAKE_SIZE = 15
WIDTH, HEIGHT = 375, 375
CURSOR_SIZE = 20
def slither():
segment = snake[-1].clone() if len(snake) < SNAKE_LENGTH else snake.pop(0)
screen.tracer(False) # segment.hideturtle()
segment.setposition(snake[-1].position())
segment.setheading(snake[-1].heading())
segment.forward(SNAKE_SIZE)
while not -WIDTH/2 < segment.xcor() < WIDTH/2 or not -HEIGHT/2 < segment.ycor() < HEIGHT/2:
segment.undo()
segment.right(95)
segment.forward(SNAKE_SIZE)
screen.tracer(True) # segment.showturtle()
snake.append(segment)
screen.ontimer(slither, 100)
boundary = Turtle(shape='square', visible=False)
boundary.shapesize(HEIGHT / CURSOR_SIZE, WIDTH / CURSOR_SIZE)
boundary.fillcolor("white")
boundary.stamp()
head = Turtle("circle")
head.shapesize(SNAKE_SIZE / CURSOR_SIZE)
head.penup()
snake = [head]
screen = Screen()
slither()
screen.exitonclick()
I'm trying to create a shooter-like game in Python turtle (it's basically a copy of the game Boom dots). But I'm having a lot of issues, because I'm kind of new to programming. This time the command onkey() doesn't work. I tried everything but nothing seems to be of help.
I don't get any traceback errors. It's just that defined command doesn't work when I press the button which is assigned to the command.
Part of code in which I suspect the problem is:
def cannon_left():
cannon_x = cannon_x - 10
cannon.goto(cannon_x, 0)
def cannon_right():
cannon_x = cannon_x + 10
cannon.goto(cannon_x, 0)
def reset1():
live_score = 0
The whole code:
import random
import turtle
#images
image_coconut = "Coconut.png"
image_banana = "Banana.png"
image_pineapple = "Pineapple.png"
image_cannon = "Cannon.png"
#definitions
live_score = 0
screen = turtle.Screen()
wn = turtle.Screen()
cannon = turtle.Turtle()
enemy = turtle.Turtle()
score = turtle.Turtle()
background = turtle.Turtle()
reset = turtle.Turtle()
bullet = turtle.Turtle()
enemy_x = enemy.xcor()
enemy_y = enemy.ycor()
cannon_x = 0
move_speed = 2
enemy1 = 0
def cannon_shooting(x, y):
bullet.showturtle()
bullet.forward(280)
if bullet.ycor() == enemy_y - 10:
if not bullet.xcor() == enemy_x - 10:
if live_score == 0:
live_score = 0
else:
live_score = live_score + 1
if bullet.xcor() == enemy_x - 10:
live_score = live_score + 1
enemy1 = random.randint(1, 3)
bullet.hideturtle()
#image adding
screen.addshape(image_coconut)
screen.addshape(image_banana)
screen.addshape(image_pineapple)
screen.addshape(image_cannon)
def cannon_left():
cannon_x = cannon_x - 10
cannon.goto(cannon_x, 0)
def cannon_right():
cannon_x = cannon_x + 10
cannon.goto(cannon_x, 0)
def reset1():
live_score = 0
#setup
bullet.hideturtle()
bullet.speed(50)
bullet.penup()
bullet.shape('circle')
bullet.goto(0, -140)
bullet.left(90)
enemy.speed(0)
enemy.penup()
enemy.hideturtle()
enemy.goto(0, 140)
screen.addshape(image_coconut)
enemy.shape(image_coconut)
enemy.showturtle()
cannon.speed(0)
cannon.penup()
cannon.hideturtle()
cannon.goto(0, -140)
screen.addshape(image_cannon)
cannon.shape(image_cannon)
cannon.showturtle()
cannon.left(90)
score.speed(0)
score.penup()
score.hideturtle()
score.goto(90, -190)
score.color('white')
score.write("Your score: %s" % live_score, font=(None, 11, "bold"))
reset.speed(0)
reset.penup()
reset.hideturtle()
reset.goto(-185, -190)
reset.color('white')
reset.write("Reset (R)", font=(None, 11, "bold"))
#movement
while True:
enemy.forward(move_speed)
if enemy.xcor() == 140:
enemy.left(180)
enemy.forward(move_speed)
if enemy.xcor() == -140:
enemy.right(180)
enemy.forward(move_speed)
if enemy1 == 1:
screen.addshape(image_banana)
enemy.shape(image_banana)
if enemy1 == 2:
screen.addshape(image_pineapple)
enemy.shape(image_pineapple)
if enemy1 == 3:
enemy.shape(image_coconut)
#key presses
wn.onkey(cannon_right, "D")
wn.onkey(cannon_left, "A")
wn.onkey(cannon_right, "Right")
wn.onkey(cannon_left, "Left")
wn.onkey(cannon_shooting, "SPACE")
wn.onkey(reset1, "R")
#others
wn.listen()
wn.mainloop()
Note: I'm creating the game in Trinket.io. Click here to go to the Trinket.io version.
Python is an imperative programming language. This means that order matters. What appears to be the main logic of your game is declared before the onkey initialization part as an infinite loop:
#movement
while True:
enemy.forward(move_speed)
...
As this loop runs forever, it means that will start executing and the code will never reach the part where you set up the key mapping.
You need the code that is in the loop put this code in a function, and decide when exactly it needs to be called by Turtle. You should not put the while True as part of the function, as there already exists a main loop managed by Turtle.