Collisions in Visual Python - python

I'm currently doing a school project that wants 2D pong made in Visual Python. Right now, I've set my current collisions of the 2 paddles at the bottom of the code. When it runs, it decides to go through it and hit the green walls (Which I will change to clear walls later). Even with the paddle no where near the ball, it still detects a "wall" present and bounces off, which I'm pretty sure its creating a massive skinny wall on the x axis where the paddle is, but is stretched vertically. I do not know any other way my teacher taught other than this way. Any help would be greatly appreciated!
from visual import *
# Title Screen
def TitleScreen():
# Display
sceneTest = display(title='Pong', x=0, y=0, width=950,
height=950, center=(5,0,0), background=(1,1,1))
#autoscale
sceneTest.autoscale = False
#Back Wall
wallBack = box(pos = vector(2,0,-2), size=(50,50,0.2), color = color.black)
#Ball
ballPong = box(pos = vector(5,1,0), size=(0.5,0.5,0.01), color = color.white)
#Left Stick
stick1 = box(pos = vector(-6,0,0), size=(0.5, 5, 0.2), color = color.white)
#Right Stick
stick2 = box(pos = vector(16,0,0), size=(0.5, 5, 0.2), color = color.white)
# Title Text
titleScreenText = text(text = "Pong", pos = (5,9, 0), align = "center",
depth = 0.01, height = 1.5, width = 1.5,
color = color.white)
# Start Game
titleScreenText = text(text = "Press E to Start", pos = (-1.5,-8.5, 0),
depth = 0.01, height = 1.5, width = 1.5,
color = color.white)
# Main Loop for starting game
while True:
rate(30)
if sceneTest.kb.keys:
key = sceneTest.kb.getkey()
if key == "e":
sceneTest.delete()
pongGame()
# Main Game Loop
def pongGame():
# Game Display
newDisplay = display(title='Pong', x=0, y=0,width=950,
height=950, center=(5,0,0), background=(1,1,1))
newDisplay.autoscale = False
# BlackWall
wallBack = box(pos = vector(2.5,0,-2), size=(50,50,0.2), color = color.black)
ball2 = box(pos = vector(5,0,0), size=(0.5,0.5,0.5), color = color.white)
# Stick Paddle 1
stick1New = box(pos = vector(-6,0,0), size=(0.5, 5, 0.2), color = color.white)
# Stick Paddle 2
stick2New = box(pos = vector(16,0,0), size=(0.5, 5, 0.2), color = color.white)
#Clear Wall Left Boundary color = color.green) opacity= 0.01
wallClear1 = box(pos=vector(-6.5,0,0), size=(0.2,22,0.3), color = color.green)
#Clear Wall Right Boundary
wallClear2 = box(pos=vector(16.5,0,0), size=(0.2,22,0.3), color = color.green)
# Clear Wall Top Boundary
wallClear3 = box(pos=vector(5,11,0), size=(23,0.2,0.3), color = color.green)
# Clear Bottom Boudary
wallClear4 = box(pos=vector(5,-11,0), size=(23,0.2,0.3), color = color.green)
# Ball Velocity Initial
ball2.velocity = vector(11,0)
deltaT = 0.005
t = 0.0
# Scoreboard
player1Score = 0
player2Score = 0
scoreText = ("{} : {}".format(player1Score, player2Score))
scoreTextDisplay = text(text = scoreText, pos = (5,9, 0), align = "center", depth = 0.1, height = 1.5, width = 1.5, color = color.white)
while True:
# Refresh
rate(100)
# Ball Velocity while Running
t = t + deltaT
ball2.pos = ball2.pos + ball2.velocity*deltaT
##
## # Literal Aimbot
## stick2New.velocity = vector(0,3)
## stick2New.pos = stick2New.pos + stick2New.velocity*deltaT
## stick2New.pos.y = ball2.pos.y
##
# Player 1 Input/Controls
if newDisplay.kb.keys:
keyNew = newDisplay.kb.getkey()
# Moving Up
if keyNew == "w":
stick1New.pos.y = stick1New.pos.y + 0.25
# Moving Down
if keyNew == "s":
stick1New.pos.y = stick1New.pos.y - 0.25
# If ball hits Right wall
if ball2.pos.x > wallClear2.pos.x:
ball2.velocity.x = ball2.velocity.x
player1Score = player1Score + 1
ball2.pos = (5,0,0)
# If ball hits Left wall
if ball2.pos.x < wallClear1.pos.x:
ball2.velocity.x = ball2.velocity.x
player2Score = player2Score + 1
ball2.pos = (5,0,0)
# If the Ball hits the top of the Wall
if ball2.pos.y > wallClear3.pos.y:
ball2.velocity.y = -ball2.velocity.y
# If the Ball hits the bottom of the Wall
if ball2.pos.y < wallClear4.pos.y:
ball2.velocity.y = -ball2.velocity.y
# Collisions Check OLD
# if ball hits right paddle
## if ball2.pos.x < stick2New.pos.x: #or ball2.pos.x > stick2New.pos.x:
## ball2.velocity.x = -ball2.velocity.x
## if ball2.pos.x > (stick2New.pos.x == -6) or ball2.pos.x < (stick2New.pos.x > -6):
## ball2.velocity.x = -ball2.velocity.x
# if ball hits left paddle
if ball2.pos.x < stick1New.pos.x:
ball2.velocity.x = -ball2.velocity.x
if ball2.pos.x > stick2New.pos.x:
ball2.velocity.x = -ball2.velocity.x
TitleScreen()

You do not have any code to check the y coordinate of the ball when checking collisions with the paddles. This will make the paddles appear infinitely tall. You can incorporate some code like if (ball2.pos.x < stick1New.pos.x) and abs(ball2.pos.y-stick1New.pos.y) < 2.5: ball2.velocity.x*=-1; ball2.velocity.y *=-1;

Related

PacMan Ghost Movement

So I've been trying to recreate the PacMan Game, I have been stuck on how to approach the idea of the Ghosts moving around the maze, I've heard of A* and Dijkstra's Algorithms, but is there a simpler way to implement ghosts moving around the maze? Aside from figuring out the different modes they can go into, Frightened, Chase, and Scatter, I just want to be able to understand whats the best way to get them to move randomly in the maze with the wall detection function in place.
import pygame
import time
#import random
import pickle
import math
pygame.init()
pygame.mixer.init()
pygame.display.set_caption("Pac-Man")
# Sets the size of the screen via (WIDTH, HEIGHT)
SCREEN_WIDTH = 478
SCREEN_HEIGHT = 608
# Speed of Characters
SPEED = 1
# Frames per second, how fast the game runs
FPS = 50
# Colors (RED,GREEN,BLUE)
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
YELLOW = (255, 255, 0)
BLUE = (0, 0, 255)
# Sets the WIDTH and HEIGHT of the window
WINDOW = (SCREEN_WIDTH, SCREEN_HEIGHT)
# Displays the screen
SCREEN = pygame.display.set_mode(WINDOW)
CLOCK = pygame.time.Clock()
PacManStartSurface = pygame.transform.scale(pygame.image.load
("PacManStart.png"), (23, 23))
PacManStartSurface.convert()
PacManStartRect = PacManStartSurface.get_rect(topleft =
(((SCREEN_WIDTH - 25) // 2),
(SCREEN_HEIGHT + 144) // 2))
PacManSurface = pygame.transform.scale(pygame.image.load
("PacManRight.png"), (23, 23))
PacManSurface.convert()
PacManRect = PacManStartSurface.get_rect(topleft =
(((SCREEN_WIDTH - 125) // 2),
(SCREEN_HEIGHT + 144) // 2))
CurrentSurface = PacManStartSurface
CurrentRect = PacManStartRect
BackgroundSurface = pygame.image.load("Background.png").convert()
PinkGhostSurface = pygame.transform.scale(pygame.image.load("PinkGhost.png")
.convert(), (23, 23))
PinkGhostRect = PinkGhostSurface.get_rect()
YellowGhostSurface = pygame.transform.scale(pygame.image.load
("YellowGhost.png")
.convert(), (23, 23))
YellowGhostRect = YellowGhostSurface.get_rect()
RedGhostSurface = pygame.transform.scale(pygame.image.load("RedGhost.png")
.convert(), (23, 23))
RedGhostRect = RedGhostSurface.get_rect()
BlueGhostSurface = pygame.transform.scale(pygame.image.load("BlueGhost.png")
.convert(), (23, 23))
BlueGhostRect = BlueGhostSurface.get_rect()
pygame.mixer.music.load('power_pellet.wav')
Font = pygame.font.Font("emulogic.ttf", 15)
class PacMan():
def __init__(self):
self.LIVES = 3
class Maze():
def __init__(self):
self.DOTS = []
self.WALLS = []
self.ENERGIZER = []
self.GHOSTS = []
self.DECISION_NODES = []
self.BLOCK_WIDTH = 25
self.BLOCK_HEIGHT = 25
self.MAZE_OFFSET_X = 0
self.MAZE_OFFSET_Y = 50
self.MARGIN = 3
# 0 - Dots
# 1 - Walls
# 2 - Energizers
# 3 - Empty Spaces
# 4 - Ghosts
# 5 - Decision Nodes & will be added for intersections in maze
self.MATRIX = [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1], \
[1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1], \
[1,2,1,1,0,1,1,1,0,1,0,1,1,1,0,1,1,2,1], \
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1], \
[1,0,1,1,0,1,0,1,1,1,1,1,0,1,0,1,1,0,1], \
[1,0,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,0,1], \
[1,1,1,1,0,1,1,1,3,1,3,1,1,1,0,1,1,1,1], \
[3,3,3,1,0,1,3,3,5,4,5,3,3,1,0,1,3,3,3], \
[1,1,1,1,0,1,3,1,1,1,1,1,3,1,0,1,1,1,1], \
[0,0,0,0,0,3,5,1,4,4,4,1,5,3,0,0,0,0,0], \
[1,1,1,1,0,1,3,1,1,1,1,1,3,1,0,1,1,1,1], \
[3,3,3,1,0,1,5,3,3,3,3,3,5,1,0,1,3,3,3], \
[1,1,1,1,0,1,3,1,1,1,1,1,3,1,0,1,1,1,1], \
[1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1], \
[1,2,1,1,0,1,1,1,0,1,0,1,1,1,0,1,1,2,1], \
[1,0,0,1,0,0,0,0,0,3,0,0,0,0,0,1,0,0,1], \
[1,1,0,1,0,1,0,1,1,1,1,1,0,1,0,1,0,1,1], \
[1,0,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,0,1], \
[1,0,1,1,1,1,1,1,0,1,0,1,1,1,1,1,1,0,1], \
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1], \
[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]
# BackgroundImage(X, Y, WIDTH, HEIGHT)
self.MAZE_X = self.BLOCK_WIDTH * (len(self.MATRIX[0])
+ self.MAZE_OFFSET_X)
self.MAZE_Y = self.BLOCK_HEIGHT * (len(self.MATRIX)
+ self.MAZE_OFFSET_Y)
self.MAZE_WIDTH = self.BLOCK_WIDTH * len(self.MATRIX[0])
self.MAZE_HEIGHT = self.BLOCK_HEIGHT * len(self.MATRIX)
def DrawMaze(self, MazeSurface):
for ROW in range(len(self.MATRIX)):
for COLUMN in range(len(self.MATRIX[0])):
# Only saves the position of each dot
if self.MATRIX[ROW][COLUMN] == 0:
self.DOTS.append([(self.BLOCK_WIDTH * COLUMN),
(self.BLOCK_HEIGHT * ROW), 4, 4])
if self.MATRIX[ROW][COLUMN] == 1:
self.WALLS.append(pygame.draw.rect(MazeSurface, WHITE,
[((self.BLOCK_WIDTH) * COLUMN),
((self.BLOCK_HEIGHT) * ROW),
self.BLOCK_WIDTH, self.BLOCK_HEIGHT]))
if self.MATRIX[ROW][COLUMN] == 2:
self.ENERGIZER.append([(self.BLOCK_WIDTH * COLUMN),
(self.BLOCK_HEIGHT * ROW), 14, 14])
if self.MATRIX[ROW][COLUMN] == 4:
self.GHOSTS.append([(self.BLOCK_WIDTH * COLUMN),
(self.BLOCK_HEIGHT * ROW), 23, 23])
if self.MATRIX[ROW][COLUMN] == 5:
self.DECISION_NODES.append([(self.BLOCK_WIDTH * COLUMN),
(self.BLOCK_HEIGHT * ROW), 4, 4])
class Main(Maze):
def __init__(self):
# Inherits Maze class
Maze.__init__(self)
self.TimeBetweenBites = 0.1
self.LastBiteTime = time.time()
self.MouthOpen = False
self.PacManDirection = ""
self.GhostDirection = ""
self.PreviousGhostDirection = ""
self.SCORE = 0
self.HIGH_SCORE = 0
def PacManMovement(self):
key = pygame.key.get_pressed()
if key[pygame.K_LEFT] and not key[pygame.K_UP] \
and not key[pygame.K_DOWN]:
self.PacManDirection = "LEFT"
elif key[pygame.K_RIGHT] and not key[pygame.K_UP] \
and not key[pygame.K_DOWN]:
self.PacManDirection = "RIGHT"
elif key[pygame.K_UP] and not key[pygame.K_LEFT] \
and not key[pygame.K_RIGHT]:
self.PacManDirection = "UP"
elif key[pygame.K_DOWN] and not key[pygame.K_LEFT] \
and not key[pygame.K_RIGHT]:
self.PacManDirection = "DOWN"
def ContinuePacManMovement(self):
if self.PacManDirection == "LEFT":
CurrentRect.x -= SPEED
self.PacManWallDetection(-1, 0, CurrentRect)
if self.PacManDirection == "RIGHT":
CurrentRect.x += SPEED
self.PacManWallDetection(1, 0, CurrentRect)
if self.PacManDirection == "UP":
CurrentRect.y -= SPEED
self.PacManWallDetection(0, -1, CurrentRect)
if self.PacManDirection == "DOWN":
CurrentRect.y += SPEED
self.PacManWallDetection(0, 1, CurrentRect)
def PacManTeleport(self):
if CurrentRect.right < 0:
CurrentRect.right = SCREEN_WIDTH + 20
if CurrentRect.left > SCREEN_WIDTH:
CurrentRect.right = 0
def GhostTeleport(self):
if PinkGhostRect.right < 0:
PinkGhostRect.right = SCREEN_WIDTH + 20
if PinkGhostRect.left > SCREEN_WIDTH:
PinkGhostRect.right = 0
def PacManWallDetection(self, x, y, CurrentRect):
CurrentRect.right += x
for WALL in self.WALLS:
COLLIDE = CurrentRect.colliderect(WALL)
if COLLIDE:
if x < 0:
CurrentRect.left = WALL.right
CurrentSurface = pygame.transform.rotate(PacManSurface, 180)
MazeSurface.blit(CurrentSurface, CurrentRect)
if x > 0:
CurrentRect.right = WALL.left
break
CurrentRect.top += y
for WALL in self.WALLS:
COLLIDE = CurrentRect.colliderect(WALL)
if COLLIDE:
if y < 0:
CurrentRect.top = WALL.bottom
if y > 0:
CurrentRect.bottom = WALL.top
break
def GhostWallDetection(self, x, y, PinkGhostRect):
PinkGhostRect.right += x
for WALL in self.WALLS:
COLLIDE = PinkGhostRect.colliderect(WALL)
if COLLIDE:
if x < 0:
PinkGhostRect.left = WALL.right
if x > 0:
PinkGhostRect.right = WALL.left
break
PinkGhostRect.top += y
for WALL in self.WALLS:
COLLIDE = PinkGhostRect.colliderect(WALL)
if COLLIDE:
if y < 0:
PinkGhostRect.top = WALL.bottom
if y > 0:
PinkGhostRect.bottom = WALL.top
break
def EatDots(self):
for ROW in range(len(self.MATRIX)):
for COLUMN in range(len(self.MATRIX[0])):
for DOT in self.DOTS:
CHOMP = CurrentRect.colliderect(DOT)
if CHOMP:
Main.PlaySound(self, 0)
self.DOTS.remove(DOT)
self.MATRIX[ROW][COLUMN] = 3
self.SCORE += 10
if self.SCORE > self.HIGH_SCORE:
self.HIGH_SCORE = self.SCORE
return str(self.SCORE), str(self.HIGH_SCORE)
def EatEnergizer(self):
for ROW in range(len(self.MATRIX)):
for COLUMN in range(len(self.MATRIX[0])):
for POWERUP in self.ENERGIZER:
CHOMP = CurrentRect.colliderect(POWERUP)
if CHOMP:
self.ENERGIZER.remove(POWERUP)
self.MATRIX[ROW][COLUMN] = 3
self.SCORE += 50
Main.PlaySound(self, 1)
if self.SCORE > self.HIGH_SCORE:
self.HIGH_SCORE = self.SCORE
return str(self.SCORE), str(self.HIGH_SCORE)
def EatGhosts(self):
pass
def DrawDots(self):
for POSITION in self.DOTS:
X = POSITION[0] + 13
Y = POSITION[1] + 13
WIDTH = POSITION[2]
HEIGHT = POSITION[3]
pygame.draw.circle(MazeSurface, YELLOW, (X, Y),
WIDTH // 2, HEIGHT // 2)
def DrawEnergizer(self):
for POSITION in self.ENERGIZER:
X = POSITION[0] + 13
Y = POSITION[1] + 13
WIDTH = POSITION[2]
HEIGHT = POSITION[3]
pygame.draw.circle(MazeSurface, YELLOW, (X, Y),
WIDTH // 2, HEIGHT // 2)
def DrawGhosts(self):
MazeSurface.blit(PinkGhostSurface, PinkGhostRect)
MazeSurface.blit(YellowGhostSurface, YellowGhostRect)
MazeSurface.blit(RedGhostSurface, RedGhostRect)
MazeSurface.blit(BlueGhostSurface, BlueGhostRect)
def GhostPosition(self):
X, Y, WIDTH, HEIGHT = self.GHOSTS[0]
PinkGhostRect.x = X
PinkGhostRect.y = Y
PinkGhostRect.width = WIDTH
PinkGhostRect.height = HEIGHT
X, Y, WIDTH, HEIGHT = self.GHOSTS[1]
YellowGhostRect.x = X
YellowGhostRect.y = Y
YellowGhostRect.width = WIDTH
YellowGhostRect.height = HEIGHT
X, Y, WIDTH, HEIGHT = self.GHOSTS[2]
RedGhostRect.x = X
RedGhostRect.y = Y
RedGhostRect.width = WIDTH
RedGhostRect.height = HEIGHT
X, Y, WIDTH, HEIGHT = self.GHOSTS[3]
BlueGhostRect.x = X
BlueGhostRect.y = Y
BlueGhostRect.width = WIDTH
BlueGhostRect.height = HEIGHT
def ChaseMode(self):
self.GhostDirection = "LEFT"
self.GhostWallDetection(-1, 0, PinkGhostRect)
if PinkGhostRect.x < CurrentRect.x:
self.GhostDirection = "RIGHT"
self.GhostWallDetection(1, 0, PinkGhostRect)
if PinkGhostRect.y > CurrentRect.y:
self.GhostDirection = "UP"
self.GhostWallDetection(0, -1, PinkGhostRect)
if PinkGhostRect.y < CurrentRect.y:
self.GhostDirection = "DOWN"
self.GhostWallDetection(0, 1, PinkGhostRect)
def ScatterMode(self):
pass
def FrightenedMode(self):
pass
def PlaySound(self, Track):
if Track == 0:
Eat = pygame.mixer.Sound("pacman_chomp.wav")
Eat.play()
pygame.mixer.fadeout(400)
if Track == 1:
EatPellet = pygame.mixer.Sound("pacman_eatghost.wav")
EatPellet.play()
pygame.mixer.music.play(7)
pygame.mixer.fadeout(400)
def ShowScore(self):
global Font
OneUpText = Font.render("1UP", True, WHITE)
OneUpTextRect = OneUpText.get_rect(center = (70, 10))
# Displays current score
OneUpScoreText = Font.render(str(self.SCORE), True, WHITE)
OneUpScoreRect = OneUpScoreText.get_rect(center =
((SCREEN_WIDTH - 290)
// 2, 26))
HighScoreText = Font.render("High Score", True, WHITE)
HighScoreTextRect = HighScoreText.get_rect(center =
(SCREEN_WIDTH // 2, 10))
# Displays High Score
HighScoreNumber = Font.render(str(self.HIGH_SCORE), True, WHITE)
HighScoreNumberRect = HighScoreNumber.get_rect(center =
((SCREEN_WIDTH + 90)
// 2, 26))
SCREEN.blit(OneUpText, OneUpTextRect)
SCREEN.blit(OneUpScoreText, OneUpScoreRect)
SCREEN.blit(HighScoreText, HighScoreTextRect)
SCREEN.blit(HighScoreNumber, HighScoreNumberRect)
def PacManBite(self):
global CurrentSurface
CurrentTime = time.time()
if CurrentTime - self.LastBiteTime >= self.TimeBetweenBites:
self.LastBiteTime = CurrentTime
if self.MouthOpen:
CurrentSurface = PacManStartSurface
else:
CurrentSurface = PacManSurface
self.MouthOpen = not self.MouthOpen
if self.PacManDirection == "LEFT":
CurrentSurface = pygame.transform.rotate(CurrentSurface, 180)
if self.PacManDirection == "RIGHT":
CurrentSurface = CurrentSurface
if self.PacManDirection == "UP":
CurrentSurface = pygame.transform.rotate(CurrentSurface, 90)
if self.PacManDirection == "DOWN":
CurrentSurface = pygame.transform.rotate(CurrentSurface, 270)
def PacManLives(self):
pass
Player = Main()
BackgroundSurface = pygame.transform.scale(BackgroundSurface,
(Player.MAZE_WIDTH,
Player.MAZE_HEIGHT))
BackgroundRect = BackgroundSurface.get_rect()
MazeSurface = pygame.Surface((Player.MAZE_WIDTH, Player.MAZE_HEIGHT))
MazeRect = MazeSurface.get_rect(topleft = (Player.MAZE_OFFSET_X,
Player.MAZE_OFFSET_Y))
Player.DrawMaze(MazeSurface)
Player.GhostPosition()
#Player.GhostMovement()
'''
Before the game starts ...
pregame = True
while pregame:
if key button pressed:
pregame = False
run = True
'''
run = True
while run:
SCREEN.fill(BLACK)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.KEYDOWN:
Player.PacManMovement()
Player.PacManTeleport()
Player.ContinuePacManMovement()
MazeSurface.blit(BackgroundSurface, BackgroundRect)
Player.DrawDots()
Player.DrawEnergizer()
Player.DrawGhosts()
Player.GhostTeleport()
Player.EatDots()
Player.EatEnergizer()
Player.ChaseMode()
MazeSurface.blit(CurrentSurface, CurrentRect)
Player.PacManBite()
SCREEN.blit(MazeSurface, MazeRect)
Player.ShowScore()
pygame.display.update()
CLOCK.tick(FPS)
pygame.quit()
An easy algorithm for moving is simply looking at the available exits from this position and choose where to go.
Watching Pacman for a few minutes leads to a few movement rules:
The direction is only changed on exact map-grid boundaries (true for all entities).
Ghosts do not stop
Ghosts do not reverse direction
... unless becoming edible (out of scope for now)
So I implemented this in a simple heuristic:
Unless in a dead-end, do not reverse
Always move forward, but if we can turn, still prefer forward (60% of the time)
To code this, the GhostSprite simply remembers its current direction in self.direction, which is a compass bearing North, East, South, West. North is toward the top of the window (-Y), West to the left (-X).
This makes the Ghost's direction control reduce down to a single algorithm:
By consulting the map, list the available exits
Is the only available direction in reverse?
Yes: turn around
No:
60% of the time continue forward
40% of the time, choose a random direction for what's available
In my implementation the ghosts jump whole grid co-ordinates. In versions with per-pixel movement, the ghost needs only check that it on an exact grid-boundary before bothering to check for direction changes. Something like a self.rect.x % GRID_SIZE == 0 would achieve that quickly.
** Code **
import pygame
import random
# Window size
WINDOW_WIDTH = 420
WINDOW_HEIGHT = 465
GRID_SIZE = WINDOW_HEIGHT // 21
MAP_WIDTH = 19
MAP_HEIGHT = 21
MAP = [ "###################",
"# # #",
"# ## ### # ### ## #",
"# #",
"# ## # ##### # ## #",
"# # # # #",
"#### ### # ### ####",
"#### # # ####",
"#### # ## ## # ####",
"< # # >",
"#### # ##### # ####",
"#### # c # ####",
"#### # ##### # ####",
"# # #",
"# ## ### # ### ## #",
"# # # #",
"## # # ##### # # ##",
"# # # # #",
"# ###### # ###### #",
"# #",
"###################" ]
BLACK = ( 0, 0, 0)
YELLOW = (255, 255, 0)
BLUE = ( 0, 0, 254)
RED = (255, 0, 0)
LIGHTBLUE= (161, 255, 254)
PINK = (255, 192, 203)
ORANGE = (255, 165, 0)
def pixelPosToGridPos( pixel_x, pixel_y ):
""" Map a window-pixel position to a map-grid position """
return ( pixel_x // GRID_SIZE, pixel_y // GRID_SIZE )
def gridPosToPixelPos( grid_x, grid_y ):
""" Map a grid position to a window-position position """
return ( grid_x * GRID_SIZE, grid_y * GRID_SIZE )
def getMapColour( x, y ):
""" Convert map symbols into colours """
symbol = MAP[y][x]
if ( symbol == '#' ):
return BLUE
elif ( symbol == 'c' ):
return YELLOW
elif ( symbol == 'b' ): # "Shadow" / "Blinky"
return RED
elif ( symbol == 'p' ): # "Speedy" / "Pinky"
return PINK
elif ( symbol == 'i' ): # "Bashful" / "Inky"
return LIGHTBLUE
elif ( symbol == 'o' ): # "Pokey" / "Clyde"
return ORANGE
return BLACK
class GhostSprite( pygame.sprite.Sprite ):
""" A pacman-like ghost sprite """
def __init__( self, grid_x, grid_y, colour ):
super().__init__()
self.image = pygame.Surface( ( GRID_SIZE, GRID_SIZE), pygame.SRCALPHA )
self.image.fill( colour )
self.rect = self.image.get_rect()
self.rect.topleft = gridPosToPixelPos( grid_x, grid_y )
self.direction = random.choice( [ 'N', 'S', 'E', 'W' ] )
def moveToGrid( self, grid_x, grid_y ):
""" Allow position to be reset """
self.rect.topleft = gridPosToPixelPos( grid_x, grid_y )
def availableMoves( self ):
""" Consult the map to see where is good to go from here.
We only consider walls, not other NPCs """
map_x, map_y = pixelPosToGridPos( self.rect.x, self.rect.y )
exits = []
# handle wrap-around, where it's possible to go "off grid"
if ( map_x <= 0 or map_x >= MAP_WIDTH-1 ):
exits = [ 'E', 'W' ]
else:
# otherwise consult the map
if ( MAP[ map_y-1 ][ map_x ] != '#' ):
exits.append( 'N' )
if ( MAP[ map_y ][ map_x+1 ] != '#' ):
exits.append( 'E' )
if ( MAP[ map_y+1 ][ map_x ] != '#' ):
exits.append( 'S' )
if ( MAP[ map_y ][ map_x-1 ] != '#' ):
exits.append( 'W' )
return exits
def getOppositeDirection( self ):
""" Return the compass-opposite of our current movement direction """
opposites = { 'N':'S', 'S':'N', 'E':'W', 'W':'E' };
return opposites[ self.direction ]
def moveForward( self ):
""" Move in the current direction. Generally we use the map
to keep us in-bounds, but on the wrap-around we can get
close to the edge of the map, so use special handling for
warping """
# handle wrap-around avenue
map_x, map_y = pixelPosToGridPos( self.rect.x, self.rect.y )
if ( MAP[ map_y ][ map_x ] == '<' ):
self.direction = 'W'
self.rect.x = (MAP_WIDTH-1) * GRID_SIZE
elif ( MAP[ map_y ][ map_x ] == '>' ):
self.direction = 'E'
self.rect.x = 0
# Whichever direction we're moving in, go forward
if ( self.direction == 'N' ):
self.rect.y -= GRID_SIZE
elif ( self.direction == 'E' ):
self.rect.x += GRID_SIZE
elif ( self.direction == 'S' ):
self.rect.y += GRID_SIZE
else: # W
self.rect.x -= GRID_SIZE
def update( self ):
""" Move the ghost, mostly forward, never backwards (unless dead-end)
At an intersection, possibly turn """
exits = self.availableMoves()
# Generally: Keep moving in current direction, never u-turn
opposite = self.getOppositeDirection()
# 60% change of continuing forward at an intersection
if ( self.direction in exits and ( len( exits ) == 1 or random.randrange( 0,100 ) <= 60 ) ):
pass
elif ( self.direction not in exits and len( exits ) == 1 ):
self.direction = exits[0] # maybe u-turn
else: # more than 1 exit
if ( opposite in exits ):
exits.remove( opposite )
self.direction = random.choice( exits )
# Move-it- Move-it
self.moveForward()
###
### MAIN
###
pygame.init()
window = pygame.display.set_mode( ( WINDOW_WIDTH, WINDOW_HEIGHT ), pygame.HWSURFACE )
pygame.display.set_caption("Pac Algorithm")
# Make background image of map
background = pygame.Surface( ( WINDOW_WIDTH, WINDOW_HEIGHT ), pygame.SRCALPHA )
for y in range( MAP_HEIGHT ):
for x in range( MAP_WIDTH ):
rect = pygame.Rect( x * GRID_SIZE, y * GRID_SIZE, GRID_SIZE, GRID_SIZE )
pygame.draw.rect( background, getMapColour( x, y ), rect )
# Make the Ghosts
blinky = GhostSprite( 9, 7, RED )
inky = GhostSprite( 8, 9, LIGHTBLUE )
pinky = GhostSprite( 9, 9, PINK )
pokey = GhostSprite(10, 9, ORANGE )
ghosts = pygame.sprite.Group()
ghosts.add( [ blinky, inky, pinky, pokey ] )
# Ghosts move periodically
next_ghost_movement = pygame.time.get_ticks() + 1000
# Main loop
clock = pygame.time.Clock()
running = True
while running:
time_now = pygame.time.get_ticks()
# Handle user-input
for event in pygame.event.get():
if ( event.type == pygame.QUIT ):
running = False
# Movement keys
keys = pygame.key.get_pressed()
if ( keys[pygame.K_UP] ):
print("up")
elif ( keys[pygame.K_DOWN] ):
print("down")
elif ( keys[pygame.K_LEFT] ):
print("left")
elif ( keys[pygame.K_RIGHT] ):
print("right")
elif ( keys[pygame.K_ESCAPE] ):
# Reset the ghosts home
blinky.moveToGrid( 9, 7 )
inky.moveToGrid( 8, 9 )
pinky.moveToGrid( 9, 9 )
pokey.moveToGrid( 10, 9 )
next_ghost_movement = time_now + 1000
# move the ghosts
if ( time_now > next_ghost_movement ):
ghosts.update()
next_ghost_movement = time_now + 100
# Update the window, but not more than 60fps
window.blit( background, ( 0, 0 ) )
ghosts.draw( window )
pygame.display.flip()
# Clamp FPS
clock.tick(30)
pygame.quit()

Making a main screen in Ursina

I am currently making a game with Ursina and i've been struggling to find a code to make a Main-Starting-Screen to start the game or show controlls.
Here is my game code:
game = Ursina()
ground = Entity(model = "untitled.blend", texture = "Soul Sand.jpg", scale = 400, collider = "mesh")
player = FirstPersonController(model = "player.blend", position = (-6.39844, 148.284, 62.5471),jump_height = 7, jump_duration = 0.5, speed = 10, texture = "Player Texture.jpg", collider = "mesh")
camera.z = None
health_bar = HealthBar(bar_color=color.lime.tint(-.25), roundness=.5, value=100)
def input(key):
if key == "shift":
player.speed = 25
elif key == "control":
player.speed = 10
house = Entity(model = "House.blend", texture = "Tree Texture.jpg", scale = 2, collider = "mesh", position = (0, 146.3, 15))
tree = Entity(model = "Tree.blend", scale = 15, texture = "Tree Texture.jpg", collider = "mesh", position = (15.5488, 140, 55.0674))
game.run()
You could try just displaying a quad model which is a 2d square
Menuback=Entity(model="quad"scale=(10,10))
and just make
Allother entities to .enabled=False
And the menu to true
Create a button
And onclick menuback.enabled =False
And the rest od entities set on true
Here is the ursina docs if u need to look at some stuff
https://www.ursinaengine.org/api_reference.html

enemy collision in ursina

i'm making a game in ursina and want to know how i can output something that says its true or false(like in a boolean). because the game that i am making needs collision with entity's. i have looked for a solution but i can't find anything. so people that use ursina please help me here is the code:
from ursina import *
import random
#variables
speed = 0.05
number_of_pokemon = 10
app = Ursina()
#textures
player_texture = load_texture('pokemon orange assets/player.png')
pokemon_texture1 = load_texture('pokemon orange assets/pokemon.png')
pokemon_texture2 = load_texture('pokemon orange assets/pokemon2.png')
pokemon_texture3 = load_texture('pokemon orange assets/pokemon3.png')
grass_texture = load_texture('pokemon orange assets/grass.png')
textbox_texture = load_texture('pokemon orange assets/textbox.png')
missingno_texture = load_texture('pokemon orange assets/missingno.png')
pokemontextures = [pokemon_texture1, pokemon_texture2, pokemon_texture3]
#entitys: pokemon(s), player, textbox, battles
player = Entity(model = 'cube', texture = player_texture, scale = (1,1,0), position =
(0,0,-0.1))
#textbox = Entity(model ='cube', texture = textbox_texture, scale = (5,1,0), position =
(0,-3,0))
#spawns pokemon
number = random.uniform(0,100)
if(number == 100):
for i in range (100):
pokemon = Entity(model ='cube', texture = missingno_texture, scale = (1,2,0),
position = (random.uniform(-10,10),random.uniform(-10,10),random.uniform(-10,10)))
else:
for i in range(number_of_pokemon):
pokemon = Entity(model ='cube', texture = random.choice(pokemontextures), scale = (1.5,1.5,0), position = (random.uniform(-5,5),random.uniform(-4,4),-0.1))
#spawns grass
for y in range(20):
for x in range(20):
grass = Entity(model ='cube', texture = grass_texture, scale = (1,1,0), position = (x - 10,y - 10,0))
#movement
def update():
player.x += held_keys['d'] * speed
player.x -= held_keys['a'] * speed
player.y += held_keys['w'] * speed
player.y -= held_keys['s'] * speed
app.run()
Set a Collider and check if your entity intersects with another one:
player = Entity(model='cube',
texture=player_texture,
scale=(1, 1, 0),
position=(0, 0, -0.1),
collider='box') # <-- do the same for all pokemon entities
hit_info = player.intersects()
if hit_info.hit:
print(hit_info.entity)

Problem with animating a sprite in pygame

i have a problem with this code, i am a new person with programming and been using the book "how to think like a computer scientist 3rd edition" and he did not solve exercise 2 of chapter 17 this given: "he deliberately left a mistake in the code to animate Duke. If you click on one of the checkerboard squares to the right of Duke, he salutes anyway. Why? Find a one-line solution to the error ", I've tried many forms but I have not succeeded, I leave you all the code and the images that I have used
PS: images must have the name: ball.png and duke_spritesheet.png
import pygame
gravity = 0.025
my_clock = pygame.time.Clock()
class QueenSprite:
def __init__(self, img, target_posn):
self.image = img
self.target_posn = target_posn
(x, y) = target_posn
self.posn = (x, 0) # Start ball at top of its column
self.y_velocity = 0 # with zero initial velocity
def update(self):
self.y_velocity += gravity
(x, y) = self.posn
new_y_pos = y + self.y_velocity
(target_x, target_y) = self.target_posn # Unpack the position
dist_to_go = target_y - new_y_pos # How far to our floor?
if dist_to_go < 0: # Are we under floor?
self.y_velocity = -0.65 * self.y_velocity # Bounce
new_y_pos = target_y + dist_to_go # Move back above floor
self.posn = (x, new_y_pos) # Set our new position.
def draw(self, target_surface): # Same as before.
target_surface.blit(self.image, self.posn)
def contains_point(self, pt):
""" Return True if my sprite rectangle contains point pt """
(my_x, my_y) = self.posn
my_width = self.image.get_width()
my_height = self.image.get_height()
(x, y) = pt
return ( x >= my_x and x < my_x + my_width and
y >= my_y and y < my_y + my_height)
def handle_click(self):
self.y_velocity += -2 # Kick it up
class DukeSprite:
def __init__(self, img, target_posn):
self.image = img
self.posn = target_posn
self.anim_frame_count = 0
self.curr_patch_num = 0
def update(self):
if self.anim_frame_count > 0:
self.anim_frame_count = (self.anim_frame_count + 1 ) % 60
self.curr_patch_num = self.anim_frame_count // 6
def draw(self, target_surface):
patch_rect = (self.curr_patch_num * 50, 0,
50, self.image.get_width())
target_surface.blit(self.image, self.posn, patch_rect)
def contains_point(self, pt):
""" Return True if my sprite rectangle contains pt """
(my_x, my_y) = self.posn
my_width = self.image.get_width()
my_height = self.image.get_height()
(x, y) = pt
return ( x >= my_x and x < my_x + my_width and
y >= my_y and y < my_y + my_height)
def handle_click(self):
if self.anim_frame_count == 0:
self.anim_frame_count = 5
def draw_board(the_board):
""" Draw a chess board with queens, as determined by the the_board. """
pygame.init()
colors = [(255,0,0), (0,0,0)] # Set up colors [red, black]
n = len(the_board) # This is an NxN chess board.
surface_sz = 480 # Proposed physical surface size.
sq_sz = surface_sz // n # sq_sz is length of a square.
surface_sz = n * sq_sz # Adjust to exactly fit n squares.
# Create the surface of (width, height), and its window.
surface = pygame.display.set_mode((surface_sz, surface_sz))
ball = pygame.image.load("ball.png")
# Use an extra offset to centre the ball in its square.
# If the square is too small, offset becomes negative,
# but it will still be centered :-)
ball_offset = (sq_sz-ball.get_width()) // 2
all_sprites = [] # Keep a list of all sprites in the game
# Create a sprite object for each queen, and populate our list.
for (col, row) in enumerate(the_board):
a_queen = QueenSprite(ball,
(col*sq_sz+ball_offset, row*sq_sz+ball_offset))
all_sprites.append(a_queen)
# Load the sprite sheet
duke_sprite_sheet = pygame.image.load("duke_spritesheet.png")
# Instantiate two duke instances, put them on the chessboard
duke1 = DukeSprite(duke_sprite_sheet,(sq_sz*2, 0))
duke2 = DukeSprite(duke_sprite_sheet,(sq_sz*5, sq_sz))
# Add them to the list of sprites which our game loop manages
all_sprites.append(duke1)
all_sprites.append(duke2)
while True:
# Look for an event from keyboard, mouse, etc.
ev = pygame.event.poll()
if ev.type == pygame.QUIT:
break;
if ev.type == pygame.KEYDOWN:
key = ev.dict["key"]
if key == 27: # On Escape key ...
break # leave the game loop.
if key == ord("r"):
colors[0] = (255, 0, 0) # Change to red + black.
elif key == ord("g"):
colors[0] = (0, 255, 0) # Change to green + black.
elif key == ord("b"):
colors[0] = (0, 0, 255) # Change to blue + black.
if ev.type == pygame.MOUSEBUTTONDOWN: # Mouse gone down?
posn_of_click = ev.dict["pos"] # Get the coordinates.
for sprite in all_sprites:
if sprite.contains_point(posn_of_click):
sprite.handle_click()
break
for sprite in all_sprites:
sprite.update()
# Draw a fresh background (a blank chess board)
for row in range(n): # Draw each row of the board.
c_indx = row % 2 # Alternate starting color
for col in range(n): # Run through cols drawing squares
the_square = (col*sq_sz, row*sq_sz, sq_sz, sq_sz)
surface.fill(colors[c_indx], the_square)
# Now flip the color index for the next square
c_indx = (c_indx + 1) % 2
# Ask every sprite to draw itself.
for sprite in all_sprites:
sprite.draw(surface)
my_clock.tick(60) # Waste time so that frame rate becomes 60 fps
pygame.display.flip()
pygame.quit()
if __name__ == "__main__":
draw_board([0, 5, 3, 1, 6, 4, 2]) # 7 x 7 to test window size
PS: I think the error is here but it did not succeed
return ( x >= my_x and x + my_width and y >= my_y and y < my_y + my_height)
The issue is caused by the face, that "duke_spritesheet.png" is a sprite sheet. When you define the rectangular region which is covered by the object, then you have to use the width of a single image, rather than the width of the entire sprite sheet:
my_width = self.image.get_width()
my_width = 50
Change this in the method contains_point of the class DukeSprite:
class DukeSprite:
# [...]
def contains_point(self, pt):
""" Return True if my sprite rectangle contains pt """
(my_x, my_y) = self.posn
my_width = 50
my_height = self.image.get_height()
(x, y) = pt
return ( x >= my_x and x < my_x + my_width and
y >= my_y and y < my_y + my_height)

When press a key to move the turtle up, my other turtles freeze

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()

Categories

Resources