Window boundaries in Pygame are not working - python

I have recently optimized the enemies in my game goblin() to work through an OOP approach, however, the boundaries that I set for movement() are not working. In this simple game, I have to get the knight aka player() to the princess without hitting the goblin(). When I did this without using an OOP approach, it worked perfectly and the goblin would bounce left and right across the screen. Now, it just goes to the right and keeps on going forever! Super frustrating because before I start adding all of my enemies, I want to have a class that is functional! Thanks!
import pygame
# Initialize the pygame
pygame.init()
# Setting up the screen and background
screen = pygame.display.set_mode((800,600))
# Title and Icon of window
pygame.display.set_caption("Get Princess")
icon = pygame.image.load('icon.png')
pygame.display.set_icon(icon)
#Player Image
playerImg = pygame.image.load('knight.png')
playerImg = pygame.transform.scale(playerImg, (50,50))
playerX = 360
playerY = 520
playerX_change = 0
playerY_change = 0
#Princess Image
princessImg = pygame.image.load('princess.png')
princessImg = pygame.transform.scale(princessImg, (50,50))
princessX = 360
princessY = 20
def player(x,y):
screen.blit(playerImg, (x, y))
def princess(x,y):
screen.blit(princessImg, (x, y))
class goblin():
def __init__(self, goblinX, goblinY):
self.goblinX = goblinX
self.goblinY = goblinY
self.goblinImg = pygame.image.load('goblin.png')
self.goblinImg = pygame.transform.scale(self.goblinImg,(50,50))
def draw(self):
screen.blit(self.goblinImg, (self.goblinX, self.goblinY))
def movement(self, goblinX_change):
self.goblinX_change = goblinX_change
self.goblinX += self.goblinX_change
if self.goblinX <= 0:
self.goblinX_change += 0.3
elif self.goblinX >= 750:
self.goblinX_change = -0.3
g = goblin(360,250)
running = True
while running:
screen.fill((50,0,0))
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
playerY_change = -0.4
if event.key == pygame.K_DOWN:
playerY_change = 0.4
if event.key == pygame.K_LEFT:
playerX_change = -0.4
if event.key == pygame.K_RIGHT:
playerX_change = 0.4
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
playerX_change = 0
elif event.key == pygame.K_UP or event.key == pygame.K_DOWN:
playerY_change = 0
playerX += playerX_change
playerY += playerY_change
if playerX <= 0:
playerX = 0
elif playerX >= 750:
playerX = 750
if playerY <= 0:
playerY = 0
elif playerY >= 550:
playerY = 550
player(playerX,playerY)
princess(princessX, princessY)
g.movement(0.3)
g.draw()
pygame.display.update()

goblinX_change is an attribute of goblin. movement is continuously called in the application loop. This sets the attribute to the initial value in each frame. The initial value has to be set in the constructor and not in the movement method:
class goblin():
def __init__(self, goblinX, goblinY, goblinX_change):
self.goblinX = goblinX
self.goblinY = goblinY
self.goblinX_change = 0.3
self.goblinImg = pygame.image.load('goblin.png')
self.goblinImg = pygame.transform.scale(self.goblinImg,(50,50))
def draw(self):
screen.blit(self.goblinImg, (self.goblinX, self.goblinY))
def movement(self):
self.goblinX += self.goblinX_change
if self.goblinX <= 0:
self.goblinX_change += 0.3
elif self.goblinX >= 750:
self.goblinX_change = -0.3
g = goblin(360, 250, 0.3)
running = True
while running:
# [...]
g.movement()
g.draw()
pygame.display.update()

Related

How do I make the bullets to shoot towards my mouse when I leftclick in this code? [duplicate]

This question already has answers here:
How can you rotate the sprite and shoot the bullets towards the mouse position?
(1 answer)
calculating direction of the player to shoot pygame
(1 answer)
Shooting a bullet in pygame in the direction of mouse
(2 answers)
Closed 2 years ago.
import pygame
import random
import math
from pygame import mixer
pygame.init()
screen = pygame.display.set_mode((1280, 720))
background = pygame.image.load('1264.jpg')
background = pygame.transform.scale(background, (1290, 720))
pygame.display.set_caption("FlySwapper")
icon = pygame.image.load('logo.png')
pygame.display.set_icon(icon)
playerImg = pygame.image.load('Frosk.png')
playerX = 580
playerY = 550
playerX_change = 0
playerY_change = 0
enemyImg = []
enemyX = []
enemyY = []
enemyX_change = []
enemyY_change = []
num_of_enemies = 6
for i in range(num_of_enemies):
enemyImg.append(pygame.image.load('flue.png'))
enemyX.append(random.randint(0, 1290))
enemyY.append(random.randint(0, 310))
enemyX_change.append(0.5)
enemyY_change.append(0.5)
bulletImg = pygame.image.load('skudd.png')
bulletX = 0
bulletY = 0
bulletX_change = 2
bulletY_change = 2
bullet_state = "ready"
def player(x, y):
screen.blit(playerImg, (x, y))
def enemy(x, y, i):
screen.blit(enemyImg[i], (x, y))
def fire_bullet(x, y):
global bullet_state
bullet_state = "fire"
screen.blit(bulletImg, (x + 35, y + 10))
running = True
while running:
screen.blit(background, (0, 0))
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_a:
playerX_change = -1
if event.key == pygame.K_d:
playerX_change = 1
if event.key == pygame.K_w:
playerY_change = -1
if event.key == pygame.K_s:
playerY_change = 1
if event.type == pygame.KEYUP:
if event.key == pygame.K_a or event.key == pygame.K_d:
playerX_change = 0
if event.type == pygame.KEYUP:
if event.key == pygame.K_w or event.key == pygame.K_s:
playerY_change = 0
LEFT = 1
RIGHT = 3
if event.type == pygame.MOUSEBUTTONUP and event.button == LEFT:
if bullet_state == "ready":
#bullet_Sound = mixer.Sound('.wav')
#bullet_Sound.play()
bulletX = playerX
bulletY = playerY
fire_bullet(bulletX, bulletY)
playerX += playerX_change
playerY += playerY_change
if playerX <= 0:
playerX = 0
elif playerX >= 1150:
playerX = 1150
if playerY <= 310:
playerY = 310
elif playerY >= 590:
playerY = 590
player(playerX, playerY)
for i in range(num_of_enemies):
enemyX[i] += enemyX_change[i]
enemyY[i] += enemyY_change[i]
if enemyX[i] <= 0:
enemyX_change[i] = 0.5
elif enemyX[i] >= 1150:
enemyX_change[i] = -0.5
if enemyY[i] <= 0:
enemyY_change[i] = 0.5
elif enemyY[i] >= 590:
enemyY_change[i] = -0.5
enemy(enemyX[i], enemyY[i], i)
if bulletY <= 0:
bullet_state = "ready"
if bullet_state == "fire":
fire_bullet(bulletX, bulletY)
bulletY -= bulletY_change
pygame.display.update()
I have been trying to make the bullet go towards my mouse on left click for weeks, my teacher can't help me apparantly and I am pretty new to python.
I know that I have made the bullet to only go forward in this code, but I was planning on changing it to go towards the mouse click later.
I'm sorry if this was a bad explanation of my problem.
When you click the mouse, you need to calculate the normalized direction vector (Unit vector) from the start position of the bullet to the mouse position. Define the speed of the bullet and multiply the direction vector by the speed:
dx = event.pos[0] - bulletX
dy = event.pos[1] - bulletY
dist = math.sqrt(dx*dx + dy*dy)
bulletX_change = bullet_speed * dx/dist
bulletY_change = bullet_speed * dy/dist
relevant changes:
def fire_bullet(x, y):
screen.blit(bulletImg, (x + 35, y + 10))
running = True
while running:
# [...]
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# [...]
if event.type == pygame.MOUSEBUTTONUP and event.button == LEFT:
if bullet_state == "ready":
#bullet_Sound = mixer.Sound('.wav')
#bullet_Sound.play()
bulletX = playerX
bulletY = playerY
bullet_state = "fire"
dx = event.pos[0] - bulletX
dy = event.pos[1] - bulletY
dist = math.sqrt(dx*dx + dy*dy)
bulletX_change = bullet_speed * dx/dist
bulletY_change = bullet_speed * dy/dist
# [...]
if playerX < 0 or bulletY < 0 or playerX > 1280 or bulletY > 720:
bullet_state = "ready"
if bullet_state == "fire":
bulletX += bulletX_change
bulletY += bulletY_change
fire_bullet(bulletX, bulletY)
pygame.display.update()

TypeError: Invalid destination position for blit, Pygame

So my code here has 2 goblins()'s bouncing left and right on the game window, and I have to try to get player() to the princess() without touching a goblin(). However, when I create instances of goblin(), they go to the right and bounce off the window given that goblinX_change is set to 0.3, but when they make it to the left side of the window the game crashes and I get TypeError: Invalif destination position for blit.
import pygame
# Initialize the pygame
pygame.init()
# Setting up the screen and background
screen = pygame.display.set_mode((800,600))
# Title and Icon of window
pygame.display.set_caption("Get Princess")
icon = pygame.image.load('knight.png')
pygame.display.set_icon(icon)
#Player Image
playerImg = pygame.image.load('knight.png')
playerImg = pygame.transform.scale(playerImg, (50,50))
playerX = 360
playerY = 520
playerX_change = 0
playerY_change = 0
#Princess Image
princessImg = pygame.image.load('princess.png')
princessImg = pygame.transform.scale(princessImg, (50,50))
princessX = 360
princessY = 20
def player(x,y):
screen.blit(playerImg, (x, y))
def princess(x,y):
screen.blit(princessImg, (x, y))
class goblin():
def __init__(self, goblinX, goblinY, goblinX_change):
self.goblinX = goblinX
self.goblinY = goblinY
self.goblinX_change = goblinX_change
self.goblinImg = pygame.image.load('goblin.png')
self.goblinImg = pygame.transform.scale(self.goblinImg,(50,50))
def draw(self):
screen.blit(self.goblinImg, (self.goblinX, self.goblinY))
def movement(self):
self.goblinX += self.goblinX_change
if self.goblinX <= 0:
self.goblinX_change += self.goblinX_change
elif self.goblinX >= 750:
self.goblinX_change = -self.goblinX_change
g = goblin(360,250, 0.3)
g1 = goblin(360, 280, 0.3)
running = True
while running:
screen.fill((50,0,0))
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
playerY_change = -0.4
if event.key == pygame.K_DOWN:
playerY_change = 0.4
if event.key == pygame.K_LEFT:
playerX_change = -0.4
if event.key == pygame.K_RIGHT:
playerX_change = 0.4
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
playerX_change = 0
elif event.key == pygame.K_UP or event.key == pygame.K_DOWN:
playerY_change = 0
playerX += playerX_change
playerY += playerY_change
if playerX <= 0:
playerX = 0
elif playerX >= 750:
playerX = 750
if playerY <= 0:
playerY = 0
elif playerY >= 550:
playerY = 550
player(playerX,playerY)
princess(princessX, princessY)
g.movement()
g.draw()
g1.movement()
g1.draw()
pygame.display.update()
When the goblinX reaches 0, you need to reverse the direction:
def movement(self):
self.goblinX += self.goblinX_change
if self.goblinX <= 0:
self.goblinX_change = -self.goblinX_change # update this line
self.goblinX = 0
elif self.goblinX >= 750:
self.goblinX_change = -self.goblinX_change
When the goblin is at the left border, the movement must become positive (abs(self.goblinX_change)) and when the goblin is at the right border, the movement must become negative (-abs(self.goblinX_change)):
class goblin():
# [...]
def movement(self):
self.goblinX += self.goblinX_change
if self.goblinX <= 0:
self.goblinX_change = abs(self.goblinX_change)
elif self.goblinX >= 750:
self.goblinX_change = -abs(self.goblinX_change)
Alternatively you can change the direction, if the goblin is at the left border and moves to the left, or is at the right border and moves to the right:
class goblin():
# [...]
def movement(self):
self.goblinX += self.goblinX_change
if (self.goblinX <= 0 and self.goblinX_change < 0) or \
(self.goblinX >= 750 and self.goblinX_change > 0):
self.goblinX_change *= -1

Collision detection in pygame not working

So I am trying to implement some collision detection in a little pygame game I am making. However, my code does not seem to be working right. Or I probably just don't know how to implement it. In this game, I have to get the player to the princess without running to goblin. Everything works right but I cannot seem to implement collision detection between player and goblin. Ideally, I would like player to go back to starting position if it hits a goblin. You can see I do have a isCollision function but when I try to call it, I get "NameError: name 'playerX' is not defined"
import pygame
import math
# Initialize the pygame
pygame.init()
# Setting up the screen and background
screen = pygame.display.set_mode((800,600))
# Title and Icon of window
pygame.display.set_caption("Get Princess")
icon = pygame.image.load('knight.png')
pygame.display.set_icon(icon)
#Princess Image
princessImg = pygame.image.load('princess.png')
princessImg = pygame.transform.scale(princessImg, (50,50))
princessX = 360
princessY = 20
princessX_change = 0
princessY_change = 0
class player():
def __init__(self, playerX, playerY, playerX_change, playerY_change):
self.playerX = playerX
self.playerY = playerY
self.playerX_change = playerX_change
self.playerY_change = playerY
self.playerImg = pygame.image.load('knight.png')
self.playerImg = pygame.transform.scale(self.playerImg, (50,50))
self.rect = pygame.Rect(32,32,16,16)
def pdraw(self):
screen.blit(self.playerImg, (self.playerX, self.playerY))
def pmovement(self):
self.playerX += self.playerX_change
self.playerY += self.playerY_change
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
self.playerY_change = -0.4
if event.key == pygame.K_DOWN:
self.playerY_change = 0.4
if event.key == pygame.K_LEFT:
self.playerX_change = -0.4
if event.key == pygame.K_RIGHT:
self.playerX_change = 0.4
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
self.playerX_change = 0
elif event.key == pygame.K_UP or event.key == pygame.K_DOWN:
self.playerY_change = 0
if self.playerX <= 0:
self.playerX = 0
elif self.playerX >= 750:
self.playerX = 750
if self.playerY <= 0:
self.playerY = 0
elif self.playerY >= 550:
self.playerY = 550
class goblin():
def __init__(self, goblinX, goblinY, goblinX_change):
self.goblinX = goblinX
self.goblinY = goblinY
self.goblinX_change = goblinX_change
self.goblinImg = pygame.image.load('goblin.png')
self.goblinImg = pygame.transform.scale(self.goblinImg,(50,50))
def draw(self):
screen.blit(self.goblinImg, (self.goblinX, self.goblinY))
def movement(self):
self.goblinX += self.goblinX_change
if self.goblinX <= 0 or self.goblinX >= 750:
self.goblinX_change = self.goblinX_change * -1
def princess(x,y):
screen.blit(princessImg, (x, y))
p = player(360, 520, 0, 0)
g = goblin(360,250, 0.10)
g1 = goblin(360, 280, 0.5)
g2 = goblin(360, 200, 0.7)
g3 = goblin(360, 160, 0.4)
goblinlist = [g, g1, g2, g3]
def isCollision(playerX, playerY, goblinX, goblinY):
dx = playerX - goblinY
dy = playerY - goblinY
distance = math.sqrt(math.pow(dx,2) + math.pow(dy,2))
if distance < 27:
p = player(360, 520, 0,0)
running = True
while running:
screen.fill((50,0,0))
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
princess(princessX, princessY)
g.movement()
g.draw()
g1.movement()
g1.draw()
g2.movement()
g2.draw()
g3.movement()
g3.draw()
p.pmovement()
p.pdraw()
isCollision(p.playerX, p.playerY, g1.goblinX, g1.goblinY)
pygame.display.update()
isCollision is a function and playerX, playerY, goblinX, goblinY are the arguments of the function. You don't have a self argument. Usually self is the object in Methods.
Remove all the self. form the function isCollision:
def isCollision(playerX, playerY, goblinX, goblinY):
dx = playerX - goblinX
dy = playerY - goblinY
distance = math.sqrt(math.pow(dx, 2) + math.pow(dy, 2))
return distance < 27
Pass the coordinates of the player (p) and a goblin (g, g1, g2 or g3) to the function:
For instance:
if isCollision(p.playerX, p.playerY, g.goblinX, g.goblinY):
# do something
# [...]
Note, you can create a list of goblins and do the collision test in a loop:
goblin_list = [g, g1, g2, g3]
for gob in goblin_list:
if isCollision(p.playerX, p.playerY, gob.goblinX, gob.goblinY):
# [...]
You can even move and draw the goblins in a loop:
for gob in goblin_list:
gob.movement()
gob.draw()
You need to use the global statement, if you want to change a variable in global namespace:
def isCollision(playerX, playerY, goblinX, goblinY):
global p
dx = playerX - goblinX
dy = playerY - goblinY
distance = math.sqrt(math.pow(dx, 2) + math.pow(dy,2))
if distance < 27:
p = player(360, 520, 0,0)

How to add a boundary on areas inside the screen in pygame

I've been trying to create a game screen but I can't seem to add a boundary around the houses on the screen so that the player doesn't walk over them. Below is my code
import pygame
import sys
from pygame import mixer
pygame.init()
playerImg = pygame.image.load('player.png')
WalkFront = [pygame.image.load('B1.png'), pygame.image.load('B2.png'),pygame.image.load('B3.png'),
pygame.image.load('B4.png')]
WalkBack = [pygame.image.load('F1.png'), pygame.image.load('F2.png'), pygame.image.load('F3.png'),
pygame.image.load('F4.png')]
WalkRight = [pygame.image.load('R1.png'), pygame.image.load('R2.png'), pygame.image.load('R3.png'),
pygame.image.load('R4.png')]
WalkLeft = [pygame.image.load('L1.png'), pygame.image.load('L2.png'), pygame.image.load('L3.png'),
pygame.image.load('L4.png')]
walkcount = 0
clock = pygame.time.Clock()
scr = pygame.display.set_mode((800, 600))
pygame.display.set_caption('Pokemon: Red')
logo = pygame.image.load('logo.png')
pygame.display.set_icon(logo)
background = pygame.image.load('BG.png')
pallet = pygame.image.load('pallet town.png')
mixer.music.load('Start menu.mp3')
mixer.music.play(100, 0, 0)
playerX = 200
playerY = 200
up = False
down = False
left = False
right = False
def redrawgamewindow():
global walkcount
scr.fill((0, 0, 0))
scr.blit(pallet, (60, 0))
if walkcount + 1 >= 29:
walkcount = 0
if up:
scr.blit(WalkFront[walkcount // 7], (playerX, playerY))
walkcount += 1
elif down:
scr.blit(WalkBack[walkcount // 7], (playerX, playerY))
walkcount += 1
elif left:
scr.blit(WalkLeft[walkcount // 7], (playerX, playerY))
walkcount += 1
elif right:
scr.blit(WalkRight[walkcount // 7], (playerX, playerY))
walkcount += 1
else:
player(playerX, playerY)
pygame.display.update()
def player(x, y):
scr.blit(playerImg, (x, y))
def start_menu():
while True:
scr.fill((255, 255, 255))
scr.blit(background, (0, 0))
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
game()
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
pygame.quit()
sys.exit()
pygame.display.update()
def game():
global playerX
global playerY
clock.tick(12)
mixer.music.pause()
mixer.music.load('pallet_music.mp3')
mixer.music.play(100)
playerX_change = 0
playerY_change = 0
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
global up
global down
global left
global right
up = True
down = False
playerY_change = -0.8
elif event.key == pygame.K_DOWN:
up = False
down = True
playerY_change = 0.8
else:
up = False
down = False
walkcount = 0
if event.key == pygame.K_LEFT:
playerX_change = -1
left = True
right = False
elif event.key == pygame.K_RIGHT:
playerX_change = 1
right = True
left = False
else:
left = False
right = False
walkcount = 0
if event.type == pygame.KEYUP:
if event.key == pygame.K_UP or event.key == pygame.K_DOWN:
playerY_change = 0
up = False
down = False
left = False
right = False
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
playerX_change = 0
up = False
down = False
left = False
right = False
playerX += playerX_change
playerY += playerY_change
if playerX <= 90:
playerX = 90
elif playerX >= 670:
playerX = 670
if playerY <= 40:
playerY = 40
elif playerY >= 540:
playerY = 540
redrawgamewindow()
start_menu()
the background image has an area on it with a house in the top left. See the background image below so you can get a better idea. what I want is for the player to not be able to walk on the house so he gets blocked at the edge.
I recommend to define a rectangular area for the house. Use pygame.Rect. You have to find the values for hx, hy, hw and hh:
house_rect = pygame.Rect(hx, hy, hw, hh)
Create a rectangle for the player after the position of the player is changed. The size of the rectangle can be get from the pygame.Surface object which represents the player by get_rect(). The position has to be set by an keyword argument (topleft = (playerX, playerY)).
Use pygame.Rect.colliderect to evaluate if the player collides with the house and restrict the position of the player to the area outside the house:
playerX += playerX_change
player_rect = playerImg.get_rect(topleft = (playerX, playerY))
if player_rect.colliderect(house_rect):
if playerX_change > 0:
player_rect.right = house_rect.left
elif playerX_change < 0:
player_rect.left = house_rect.right
playerX = player_rect.x
playerY += playerY_change
player_rect = playerImg.get_rect(topleft = (playerX, playerY))
if player_rect.colliderect(house_rect):
if playerY_change < 0:
player_rect.top = house_rect.bottom
elif playerY_change > 0:
player_rect.bottom = house_rect.top
playerY = player_rect.y
I guess you have to patiently make the boundaries with x and y like this:
if x > boundaryX and y > boundaryY:
xOfThePlayer -= moving
It is an example you have to change this according to your needs.

How to fix unwanted character acceleration in a Pygame game?

I made a game where a character has to get coins on a 2D map (when you get a coin, it respawns on a random place), while running away form a spongebob-type character who moves randomly. If you touch the spongebob, you die.
The problem I am having is that my character sometimes goes slow, but then sometimes randomly goes fast when I am controlling it with my arrow keys. My changing in the values in the code is constant, so can someone explain to me this doesn't work?
Github Link
Here is the code if you don't want to open the link:
import pygame
import random
import math
import time
pygame.init()
screen = pygame.display.set_mode((800,600))
pygame.display.set_caption("Survive the Spongey Boi")
#Sounds
game_over_sound = pygame.mixer.Sound("Game_Over.wav")
pygame.mixer.music.load("background.wav")
pygame.mixer.music.play(-1)
#Score
coins_collected = 0
font = pygame.font.Font('freesansbold.ttf', 32)
#coinfont = pygame.font.Font('freesansbold.ttf', 16)
#Positions of the text.
coin_textX = 10
coin_textY = 10
def show_coin_score(x,y):
coins_text = font.render("Coins: " + str(coins_collected), True, (0,0,0))
screen.blit(coins_text, (x,y))
#Player
playerImg = pygame.image.load('monster.png')
playerX = 370
playerY = 480
playerX_change = 0
playerY_change = 0
#Spongebob
enemyImg = pygame.image.load('sponge.png')
enemyX = random.randint(0,735)
enemyY = random.randint(10,400)
enemyX_change = 0
enemyY_change = 0
#Coin
coinImg = pygame.image.load('coin.png')
coinX = random.randint(0,735)
coinY = random.randint(0,535)
#Font for Game Over
over_font = pygame.font.Font('freesansbold.ttf', 64)
def player(x,y):
screen.blit(playerImg, (x,y))
def enemy(x,y):
screen.blit(enemyImg, (x,y))
def coin(x,y):
screen.blit(coinImg, (x,y))
def isCollision(enemyX, enemyY, playerX, playerY):
#Distance formula in Python
distance = math.sqrt((math.pow(enemyX - playerX,2)) + (math.pow(enemyY - playerY,2)))
if distance < 27:
return True
else:
return False
def coin_collision(coinX, coinY, playerX, playerY):
distance = math.sqrt((math.pow(coinX - playerX,2)) + (math.pow(coinY - playerY,2)))
if distance < 29:
return True
else:
return False
def game_over_text():
over_text = over_font.render("GAME OVER", True, (0, 0, 0))
screen.blit(over_text, (200,250))
#Game loop
running = True
while running:
screen.fill((255,255,206))
#Do the for loop here.
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
#Do the keydown
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
playerX_change = -2
if event.key == pygame.K_RIGHT:
playerX_change = 2
if event.key == pygame.K_UP:
playerY_change = -2
if event.key == pygame.K_DOWN:
playerY_change = 2
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
playerX_change = 0
if event.key == pygame.K_UP or event.key == pygame.K_DOWN:
playerY_change = 0
playerX += playerX_change
playerY += playerY_change
enemyX += enemyX_change
enemyY += enemyY_change
#Boundaries
if playerX <= 0:
playerX = 0
elif playerX > 736:
playerX = 736
if playerY <= 0:
playerY = 0
elif playerY > 536:
playerY = 536
if enemyX <= 0:
enemyX = 0
elif enemyX > 736:
enemyX = 736
if enemyY <= 0:
enemyY = 0
elif enemyY > 536:
enemyY = 536
if isCollision(enemyX, enemyY, playerX, playerY):
game_over_text()
playerX = 10000
enemyX = 10000
pygame.mixer.Sound.play(game_over_sound)
time.sleep(3.5)
break
if coin_collision(coinX, coinY, playerX, playerY):
coins_collected += 1
#time.sleep(0.00001)
coinX = random.randint(0,735)
coinY = random.randint(0,535)
#CHANGE THIS LATER
enemyX_change = random.randint(-15,15)
enemyY_change = random.randint(-15,15)
#score_value = score_value//1
show_coin_score(coin_textX, coin_textY)
coin(coinX, coinY)
enemy(enemyX, enemyY)
player(playerX, playerY)
pygame.display.update()
Nice game! The issue seems to be cause, because you use the KEYDOW and KEYUP event. That may lead to ans issue when you change the direction between left and right respectively up and down, because the movement is canceled in on KEYUP.
I recommend to use the pygame.key.get_pressed to get the current states of the key. Set playerX_change respectively playerY_change dependent on the state of the keys:
while running:
# [...]
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
keys = pygame.key.get_pressed()
playerX_change, playerY_change = 0, 0
if keys[pygame.K_LEFT]:
playerX_change -= 2
if keys[pygame.K_RIGHT]:
playerX_change += 2
if keys[pygame.K_UP]:
playerY_change -= 2
if keys[pygame.K_DOWN]:
playerY_change += 2
Side note, use min and max to simplify the limitation to the bounderys:
while running:
# [...]
#Boundaries
playerX = max(0, min(736, playerX))
playerY = max(0, min(536, playerY))
enemyX = max(0, min(736, enemyX))
enemyY = max(0, min(536, enemyY))

Categories