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

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.

Related

K_SPACE bug pygame [duplicate]

This question already has answers here:
How to get keyboard input in pygame?
(11 answers)
Closed 1 year ago.
from pygame.locals import *
import random
import pygame
from pygame.constants import K_RIGHT
# Initialize the pygame
pygame.init
# create the screen
screen = pygame.display.set_mode((800, 600))
# background
background = pygame.image.load('bg.png')
# Title and Icon
pygame.display.set_caption("Space Invaders")
icon = pygame.image.load('ufo.png')
pygame.display.set_icon(icon)
# Player
playerImg = pygame.image.load('player.png')
playerX = 370
playerY = 480
playerX_change = 0
def player(x, y):
screen.blit(playerImg, (x, y))
# Enemy
enemyImg = pygame.image.load('alien.png')
enemyX = random.randint(0, 736)
enemyY = 50
enemyX_change = 1
enemyY_change = 40
def enemy(x, y):
screen.blit(enemyImg, (x, y))
# Bullet
# ready - you can't see bullet
# fire - you can see bullet and it's moving
bulletImg = pygame.image.load('bullet.png')
bulletX = 0
bulletY = 480
bulletX_change = 1
bulletY_change = 10
bullet_state = "ready"
def fire_bullet(x, y):
global bullet_state
bullet_state = "fire"
screen.blit(bulletImg, (x+16, y+10))
# Game Loop
running = True
while running:
# Changing RGB of background
screen.fill((0, 0, 0))
# Background image
screen.blit(background, (0, 0))
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# if keystroke is pressed check wheter its right or left
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
fire_bullet(playerX, bulletY)
if event.key == pygame.K_LEFT:
playerX_change = -3
if event.key == pygame.K_RIGHT:
playerX_change = 3
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
playerX_change = 0
# bounds
playerX += playerX_change
if playerX <= 0:
playerX = 0
elif playerX >= 736:
playerX = 736
# enemy movement
enemyX += enemyX_change
if enemyX <= 0:
enemyX_change = 1
enemyY += enemyY_change
elif enemyX >= 736:
enemyX_change = -1
enemyY += enemyY_change
# bullet movement
if bullet_state is "fire":
fire_bullet(playerX, bulletY)
bulletY -= bulletY_change
player(playerX, playerY)
enemy(enemyX, enemyY)
pygame.display.update()
I'm working on a tutorial project for begginers in PyGame. It is a copy of Space Inviders. When i'm pressing space nothing is happening, but when i press ctrl + shift + space it reacts as space, also after changing K_SPACE to K_LSHIFT or K_UP it is working but with other buttons it is not, I've tried changing "fire" and "ready" to True or False but it didn't fixed my problem
It is a matter of Indentation. You have to evaluate the events in the event loop instead of the application loop:
#Game Loop
running = True
while running:
# Changing RGB of background
screen.fill((0, 0, 0))
# Background image
screen.blit(background, (0, 0))
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# INDENTATION
#-->|
# if keystroke is pressed check wheter its right or left
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
fire_bullet(playerX, bulletY)
if event.key == pygame.K_LEFT:
playerX_change = -3
if event.key == pygame.K_RIGHT:
playerX_change = 3
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
playerX_change = 0

How to fix enemy glitching at top of screen pygame [duplicate]

This question already has an answer here:
How to make enemies fall at random on pygame?
(1 answer)
Closed 2 years ago.
my enemy in my game is supposed to move up and down and every time it reaches the bottom of the screen it is supposed to re spawn in a different spot and go down again. Here it is explained in a video.
pygame.init()
screen_width = 800
screen_height = 600
window = pygame.display.set_mode((screen_width, screen_height))
pygame.display.set_caption('Test')
time = pygame.time.Clock()
bg_color1 = (135, 142, 142) # MAIN BG COLOR
bg_color2 = (255, 0, 0) # red
bg_color3 = (255, 255, 0) # yellow
UFO = pygame.image.load('ufo.png')
bg_pic = pygame.image.load('Letsgo.jpg')
clock = pygame.time.Clock()
playerImg = pygame.image.load('enemy.png')
playerX = random.randrange(0, screen_width)
playerY = -50
playerX_change = 0
player_speed = 5
def player(x, y):
window.blit(playerImg, (playerX, playerY))
crashed = False
rect = UFO.get_rect()
obstacle = pygame.Rect(400, 200, 80, 80)
menu = True
playerY = playerY + player_speed
if playerY > screen_height:
playerX = random.randrange(0,screen_width)
playerY = -25
def ufo(x, y):
window.blit(UFO, (x, y))
while menu:
for event in pygame.event.get():
if event.type == pygame.QUIT:
quit()
elif event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1:
menu = False
window.fill((0, 0, 0))
time.tick(30)
window.blit(bg_pic, (0, 0))
pygame.display.update()
x = (screen_width * 0.45)
y = (screen_height * 0.8)
x_change = 0
car_speed = 0
y_change = 0
while not crashed:
x += x_change
if x < 0:
x = 0
elif x > screen_width - UFO.get_width():
x = screen_width - UFO.get_width()
y += y_change
if y < 0:
y = 0
elif y > screen_height - UFO.get_height():
y = screen_height - UFO.get_height()
for event in pygame.event.get():
if event.type == pygame.QUIT:
crashed = True
############SIDE TO SIDE################
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
x_change = -5
elif event.key == pygame.K_RIGHT:
x_change = 5
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
x_change = 0
###########UP AND DOWN#################
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
y_change = -5
elif event.key == pygame.K_DOWN:
y_change = 5
if event.type == pygame.KEYUP:
if event.key == pygame.K_UP or event.key == pygame.K_DOWN:
y_change = 0
## if playerY > screen_height:
playerX = random.randrange(0,screen_width)
playerY = -10
x += x_change
y += y_change
##
window.fill(bg_color1)
ufo(x, y)
player(playerX, playerY)
pygame.display.update()
clock.tick(100)
pygame.quit()
quit()
this is my full code and the code i used to make it move up and down was this.
playerX = random.randrange(0,screen_width)
playerY = -10
Thanks for any help!...........................................................................
What you are doing at the moment seems to be setting the Y once, you need to create a loop to constantly update the Y
The line with the condition if playerY > screen_height: is actually a comment:
## if playerY > screen_height:
so you're setting playerX every frame. It should look more like this:
if playerY > screen_height: # when out of screen
playerX = random.randrange(0,screen_width) # new random X
playerY = 0 # also reset y back to top
playerY += 10 # move

How to collide two images in Pygame module [duplicate]

This question already has an answer here:
How to detect collisions between two rectangular objects or images in pygame
(1 answer)
Closed 2 years ago.
I’m new to programming and know the basics of Python and wanted to ask how I can perform an action if two images overlap a little bit and then a specific button is pressed in pygame.
The game looks like following:
import pygame
import random
pygame.init()
window = pygame.display.set_mode((1000, 600))
caption = pygame.display.set_caption(
'Test your reaction speed. Shoot the target game!') # sets a caption for the window
game_running = True # this is the gameloop so the window stays open
PlayerImg = pygame.image.load('F:\PythonPortable\oscn.png')
PlayerX = 370
PlayerY = 420
PlayerX_change = 0
PlayerY_change = 0
def player():
window.blit(PlayerImg, (PlayerX, PlayerY))
aim_sight = pygame.image.load('F:\PythonPortable\ktarget.png')
aim_sightX = 460
aim_sightY = 300
aim_sight_changeX = 0
aim_sight_changeY = 0
def aim_sight_function(x, y):
window.blit(aim_sight, (x, y))
targetedImg = pygame.image.load('F:\PythonPortable\ktargetedperson.png')
targetedX = random.randint(0, 872)
targetedY = random.randint(0, 200)
def random_target():
window.blit(targetedImg, (targetedX, targetedY))
while game_running:
window.fill((255, 255, 255))
random_target()
for event in pygame.event.get():
if event.type == pygame.QUIT:
game_running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
aim_sight_changeX = -2
PlayerX_change = -2
elif event.key == pygame.K_RIGHT:
aim_sight_changeX = 2
PlayerX_change = 2
elif event.key == pygame.K_UP:
aim_sight_changeY = -2
PlayerY_change = -2
elif event.key == pygame.K_DOWN:
aim_sight_changeY = 2
PlayerY_change = 2
elif event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
aim_sight_changeX = 0
PlayerX_change = 0
elif event.key == pygame.K_UP or event.key == pygame.K_DOWN:
aim_sight_changeY = 0
PlayerY_change = 0
aim_sightX += aim_sight_changeX
if aim_sightX <= 46.5:
aim_sight_changeX = 0
elif aim_sightX >= 936:
aim_sight_changeX = 0
aim_sightY += aim_sight_changeY
if aim_sightY <= 0:
aim_sight_changeY = 0
elif aim_sightY >= 400:
aim_sight_changeY = 0
PlayerX += PlayerX_change
if PlayerX <= -50:
PlayerX_change = 0
elif PlayerX >= 850:
PlayerX_change = 0
player()
aim_sight_function(aim_sightX, aim_sightY)
pygame.display.update()
I would like to know how a do what I want. I thought maybe:
if event.type == pygame.K_SPACE and targetedX == targetedX in range(aim_sightX - 100, aim_sightY + 100) or targetedY == targetedY in range (aim_sightY - 100, aim_sightY + 100):
...
It seems as though none of the tutorials I watched cover this topic and would like to recieve recommendations for tutorials that cover this problem or a direct answer.
I recommend to use a pygame.Rect objects and colliderect() to find a collision between two Surface objects. pygame.Surface.get_rect.get_rect() returns a rectangle with the size of the Surface object, that always starts at (0, 0) since a Surface object has no position. The position of the rectangle can be specified by a keyword argument:
PlayerImg_rect = PlayerImg.get_rect(topleft = (PlayerX, PlayerY))
targetedImg_rect = targetedImg .get_rect(topleft = (targetedX, targetedX))
if PlayerImg_rect.colliderect(targetedImg_rect):
print("hit")

Can you make the game display appear in the centre of your screen once the run is pressed. If yes how?

#enable pygame mode
import pygame
pygame.init()
#create screen
screen = pygame.display.set_mode((1000,600))
#Title + Logo
pygame.display.set_caption("Space Invader")
icon = pygame.image.load("chicken.png")
pygame.display.set_icon(icon)
#Player icon
player_icon = pygame.image.load("spaceship.png")
playerX = 400
playerY = 500
player_changeX = 0
player_changeY = 0
def player(x, y):
screen.blit(player_icon, (x, y))
surface.blit(image,((1920/2)-(image.get_width()/2),(1080/2)-
(image.get_height()/2)))
#game loop
running = True
while running:
# backround colour RGB
screen.fill((0, 0, 0))
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
#If key pressed check wether its right or left
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
player_changeX = -1
if event.key == pygame.K_RIGHT:
player_changeX = 1
if event.key == pygame.K_UP:
player_changeY = -1
if event.key == pygame.K_DOWN:
player_changeY = 1
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key ==pygame.K_RIGHT:
player_changeX = 0
if event.key == pygame.K_UP or event.key == pygame.K_DOWN:
player_changeY = 0
# If player reaches boarder
if playerX >= 936:
player_changeX = -1
if playerX <= 0:
player_changeX = 1
if playerY <= 0:
player_changeY = 1
if playerY >= 550:
player_changeY = -1
#Player change in coordinates
playerX += player_changeX
playerY += player_changeY
player(playerX, playerY)
pygame.display.update()
I am creating a simple game as i just got into programing and I was wondering if you could make the game screen appear in the centre of your own screen as when I run it it keeps appearing on the bottom of my screen and I then have to manually move it into the centre. If you can please tell me how. Hope my question was formated good enough. Thank you for any help.
It depends; if it's a image you can do:
surface.blit(image,((screenwidth/2)-(image.get_width()/2),(screenheight/2)-(image.get_height()/2)))
Please tell me it it's different

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