import pygame
import random
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
# enemy Player
enemy_icon = pygame.image.load("space-invaders.png")
enemyX = random.randint(0, 936)
enemyY = random.randint(-100, -50)
enemy_changeX = random.randint (0.1, 0.5)
enemy_changeY = random.randint (0.1, 0.5)
if enemyY >= 500:
print("Game over")
exit()
def player(x, y):
screen.blit(player_icon, (x, y))
def enemy(x, y):
screen.blit(enemy_icon, (x, y))
# 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 whether 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:
playerX = 20
if playerX <= 0:
playerX = 936
if playerY <= 0:
playerY = 0
if playerY >= 550:
playerY = 550
# enemy control
if enemyX >= 936:
enemyX = 20
if enemyX <= 0:
enemyX = 936
if enemyY <= 0:
enemyY = 0
if enemyY >= 550:
enemyY = random.randint(-100, -50)
# Player change in coordinates
playerX += player_changeX
playerY += player_changeY
#enemy change in coordinates
enemyX += enemy_changeX
enemyY += enemy_changeY
#Results
player(playerX, playerY)
enemy(enemyX, enemyY)
pygame.display.update()
I just got into programing, I am creating a little game. It's not finished yet but I am running into a problem I want to use float numbers instead of integers but it doesn't let me. Can you change this? and if yes how. The flaot number i want to use is in enemy_changeX and Y.
The error it's giving me is ,
line 212, in randrange
raise ValueError("non-integer arg 1 for randrange()")
ValueError: non-integer arg 1 for randrange()
even though I don't have a line 212
I hope the question was accurate enough.
First of all, you are requesting an integer between 0.1 and 0.5, which is not possible for obvious reasons.
To get a float you can use random.uniform(0.1, 0.5).
Although I have to note here, that pixels can't be float values, because there are no half pixels. Thus you have to think whether you really need a float value for a pixel change value.
Related
This question already has answers here:
How to detect collisions between two rectangular objects or images in pygame
(1 answer)
Why is my collision test always returning 'true' and why is the position of the rectangle of the image always wrong (0, 0)?
(1 answer)
How do I detect collision in pygame?
(5 answers)
Closed 2 years ago.
I want to make it kind of like a life system so that if it collides with the enemy 3 times it will quit
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 = 0
playerY += 10
##
window.fill(bg_color1)
ufo(x, y)
player(playerX, playerY)
pygame.display.update()
clock.tick(100)
pygame.quit()
quit()
im thinking of using a collide.rect but cant figure it out any help is appreciated
I want the "playerImg" to be the enemy ...................................................................................
Create a variable that stores the number of lives. Create pygme.Rect objects of the player and the UFO with the method get_rect. Set the location of the rectangles by keyword arguments. Use colliderect to test the collision and decrease the number of lives when a collision is detected and create a new random starting position:
lives = 3
while not crashed:
# [...]
player_rect = playerImg.get_rect(topleft = (playerX, playerY))
ufo_rect = UFO.get_rect(topleft = (x, y))
if player_rect.colliderect(ufo_rect):
lives -= 1
print(lives)
playerX = random.randrange(0, screen_width)
playerY = 0
if lives == 0:
crashed = True
# [...]
i am still learning on how to use pygame and i just created a space invader inspired game. but one issue that i have right now is that the bullet does not come out accordingly to my object's location. instead it only comes out from the bottom of the screen. i want my bullet to come out accordingly to my object no matter if its moving up, down, right or left. thank you in advance!!
import pygame
import random
import math
#intialize the pygame
pygame.init()
#create the screen
screen = pygame.display.set_mode((700,583))
#Caption and icon
pygame.display.set_caption("Yoshi & Fruits")
icon = pygame.image.load("Yoshi_icon.png")
pygame.display.set_icon(icon)
#Player
playerImg = pygame.image.load("YoshiMario.png")
playerX = 370
playerY = 480
playerX_change = 0
playerY_change = 0
#Enemy
enemyImg = pygame.image.load('msh1.png')
enemyX = random.randint(0,735)
enemyY = random.randint(50,150)
enemyX_change = 2
enemyY_change = 30
#Knife
# ready - you cant see the knife on the screen
# fire - the knife is currently moving
knifeImg = pygame.image.load('diamondsword3.png')
knifeX = 0
knifeY = 480
knifeX_change = 0
knifeY_change = 10
knife_state = "ready"
score = 0
def player(x,y):
screen.blit(playerImg, (x, y))
def enemy(x,y):
screen.blit(enemyImg, (x, y))
def fire_knife(x,y):
global knife_state
knife_state = "fire"
screen.blit(knifeImg,(x + 16, y + 10))
def isCollision(enemyX,enemyY,knifeX,knifeY):
distance = math.sqrt((math.pow(enemyX - knifeX,2)) + (math.pow(enemyY - knifeY,2)))
if distance < 27:
return True
else:
return False
#game loop
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
#if keystroke is pressed check whether its right or left
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.key == pygame.K_SPACE:
if knife_state is "ready":
# get the current x coordinate of yoshi
knifeX = playerX
fire_knife(playerX,knifeY)
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT:
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
# RGB - Red, Green, Blue
screen.fill((0, 255, 0))
#add a wallpaper
bgimage=pygame.image.load("Background.png")
screen.blit(bgimage, (0, 0))
# 5 = 5 + -0.1 ->5 = 5 - 0.1
# 5 = 5 + 0.1
# checking for boundaries of yoshi/mushroom so it doesnt go out of bounds
playerX += playerX_change
if playerX < 0:
playerX = 0
elif playerX > 645:
playerX = 645
playerY += playerY_change
if playerY < 0:
playerY = 0
elif playerY > 500:
playerY = 500
# enemy movement
enemyX += enemyX_change
if enemyX <= 0:
enemyX_change = 2
enemyY += enemyY_change
elif enemyX > 645:
enemyX_change = -2
enemyY += enemyY_change
# knife movement
if knifeY <= 0:
knifeY = 480
knife_state = "ready"
if knife_state is "fire":
fire_knife(knifeX,knifeY)
knifeY -= knifeY_change
# collision
collision = isCollision(enemyX,enemyY,knifeX,knifeY)
if collision:
knifeY = 480
knife_state = "ready"
score += 1
print(score)
enemyX = random.randint(0,735)
enemyY = random.randint(50,150)
player(playerX,playerY)
enemy(enemyX,enemyY)
pygame.display.update()
I assume by "bullet" you are referring to "knife" in the code.
The code is not tracking the change in the knife's co-ordinates. Sure it's created at the player's X co-ordinate, but nothing remembers this change. So let's modify fire_knife() to simply remember the changes in the state of the knife, including the new X & Y.
def fire_knife( x, y ):
""" Start a knife flying upwards from the player """
global knife_state, knifeX, knifeY
knifeX = x + 16
knifeY = y + 10
knife_state = "fire"
And create a collision handler that automatically resets the knife back to "ready":
def knife_hits( enemyX, enemyY ):
""" Return True if the knife hits the enemy at the given (x,y).
If so, prepare the knife for firing again. """
global knife_state, knifeX, knifeY
collision_result = False
if ( knife_state == "fire" and isCollision( enemyX, enemyY, knifeX, knifeY ) ):
knife_state = "ready"
collision_result = True
return collision_result
Then create another function to separately draw the knife, if it's in the correct state.
def draw_knife( screen ):
""" If the knife is flying, draw it to the screen """
global knife_state, knifeImg, knifeX, knifeY
if ( knife_state == "fire" ):
screen.blit( knifeImg, ( knifeX, knifeY ) )
And, for the sake of completeness, a function to update the knife's position, and reset the knife_state when it goes off-screen.
def update_knife():
""" Make any knife fly up the screen, resetting at the top """
global knife_state, knifeX, knifeY, knifeY_change
# if the knife is already flying, move it
if ( knife_state == "fire" ):
knifeY -= knifeY_change
if ( knifeY <= 0 ):
knife_state = "ready" # went off-screen
So that gives a new main loop calling these functions:
#game loop
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
#if keystroke is pressed check whether its right or left
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.key == pygame.K_SPACE:
if knife_state is "ready":
# Fire the knife at the coordinates of yoshi
fire_knife( playerX, playerY ) # create a new flying knife
# ...
# enemy movement
enemyX += enemyX_change
if enemyX <= 0:
enemyX_change = 2
enemyY += enemyY_change
elif enemyX > 645:
enemyX_change = -2
enemyY += enemyY_change
update_knife() # move the flying knife (if any)
if ( knife_hits( enemyX, enemyY ) ): # is there a knife-enemy-collision?
score += 1
print(score)
enemyX = random.randint(0,735)
enemyY = random.randint(50,150)
else:
draw_knife( screen ) # paint the flying knife (if any)
player(playerX,playerY)
enemy(enemyX,enemyY)
pygame.display.update()
Putting all the modifications to the knife position into functions makes your main loop simpler, and keeps most knife-code contained into a single group of functions. It would probably be better again to make a Knife class with these functions, but this is a simple start.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
Here is a source code of my space-arcade pygame. It's a quite simple one and doesn't shoots bullets. Only that we can move the player with the obstacles being moved as well. However, the limit for the spaceship (player) to move in the screen has been set from x = 0 to x = 765 and from y = 200 to y = 480. But the spaceship somehow cross the limit for y-axis i.e it can move beyond y = 0 and y = 600, but only at some specific x-axis like when x is 10 and 590 something. How can i fix this gap in the following python code:
import random
pygame.init()
screen = pygame.display.set_mode((800, 600))
pygame.display.set_caption("Space Invader")
icon = pygame.image.load("space-invaders.png")
pygame.display.set_icon(icon)
background = pygame.image.load("background.png")
player_image = pygame.image.load("space-invaders.png")
playerX = 370
playerY = 480
playerX_change = 0
playerY_change = 0
def player(x, y):
screen.blit(player_image, (x, y))
obs_image = pygame.image.load("cave-painting (1).png")
obsX = random.randint(0, 800)
obsY = random.randint(0, 100)
obsX_change = 2
obsY_change = 0.3
def obstacle(x, y):
screen.blit(obs_image, (x, y))
running = True
while running:
screen.fill( (0, 0,0) )
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_LEFT:
playerX_change = -4
if event.key == pygame.K_RIGHT:
playerX_change = 4
if event.key == pygame.K_UP:
playerY_change = -4
if event.key == pygame.K_DOWN:
playerY_change = 4
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
# Stopping our player beyond screen:
if playerX <= 0:
playerX = 0
elif playerX >= 765:
playerX = 765
elif playerY <= 200:
playerY = 200
elif playerY >= 480:
playerY = 480
obsX += obsX_change
obsY += obsY_change
# Movement mechanics for obstacles:
if obsX <= 0:
obsX_change = 3
obsY += obsY_change
elif obsX >= 736:
obsX_change = -3
obsY += obsY_change
player(playerX, playerY)
obstacle(obsX, obsY)
pygame.display.update()```
Here are the source pictures used in the aforementioned code:
[background][1]
[cave-painting (1)][2]
[space-invaders][3]
[1]: https://i.stack.imgur.com/EZFLs.png
[2]: https://i.stack.imgur.com/CxNs4.png
[3]: https://i.stack.imgur.com/Z97n7.png
Don't use elif. You're code says (pseudocode):
If x is beyond or equal to 0 then go back to zero
If x is not beyond or equal to 0 but x is beyond or equal to 765 then go back to 765
If none of the above are true but y is beyond or equal to 200 then go back to 200
Do you see the problem? If x is equal to 0, then the y-checks never occur. Change the third elif to if to fix this issue. Here's the fixed code:
if playerX <= 0:
playerX = 0
elif playerX >= 765:
playerX = 765
if playerY <= 200:
playerY = 200
elif playerY >= 480:
playerY = 480
These comparisons should be independent from each other.
By chaining then in a single if/elif/elif/... block, the checks
beyond the first only take place if the first check fails, and so on.
Given the nature of your problem, this is likely the cause.
Just replace the elif statements by plain ifs: each check will
run independently and fix the limits it should guard:
# Stopping our player beyond screen:
if playerX <= 0:
playerX = 0
elif playerX >= 765:
playerX = 765
elif playerY <= 200:
playerY = 200
elif playerY >= 480:
playerY = 480
You can simplify you code. Use pygame.key.get_pressed() to move the player smoothly, rather than the keyboard events KEYDOWN and KEYDUP. pygame.key.get_pressed() returns a list with the state of each key. If a key is held down, the state for the key is True, otherwise False:
keys = pygame.key.get_pressed()
playerX += (keys[pygame.K_RIGHT] - keys[pygame.K_LEFT]) * 4
playerY += (keys[pygame.K_DOWN] - keys[pygame.K_UP]) * 4
Use pygame.Rect objects and pygame.Rect.clamp() respectively pygame.Rect.clamp_ip() to limit the position of the player to a rectangular area.
border_rect = pygame.Rect(0, 200, 800, 312)
player_rect = player_image.get_rect(topleft = (playerX, playerY))
player_rect.clamp_ip(border_rect)
playerX, playerY = player_rect.topleft
Or even shorter:
keys = pygame.key.get_pressed()
playerX, playerY = player_image.get_rect(topleft = (playerX, playerY)) \
.move((keys[pygame.K_RIGHT] - keys[pygame.K_LEFT]) * 4, \
(keys[pygame.K_DOWN] - keys[pygame.K_UP]) * 4) \
.clamp((0, 200, 800, 312)).topleft
Example code:
running = True
while running:
screen.blit(background, (0, 0))
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
keys = pygame.key.get_pressed()
playerX += (keys[pygame.K_RIGHT] - keys[pygame.K_LEFT]) * 4
playerY += (keys[pygame.K_DOWN] - keys[pygame.K_UP]) * 4
border_rect = pygame.Rect(0, 200, 800, 312)
player_rect = player_image.get_rect(topleft = (playerX, playerY))
player_rect.clamp_ip(border_rect)
playerX, playerY = player_rect.topleft
obsX += obsX_change
obsY += obsY_change
# Movement mechanics for obstacles:
if obsX <= 0:
obsX_change = 3
obsY += obsY_change
elif obsX >= 736:
obsX_change = -3
obsY += obsY_change
player(playerX, playerY)
obstacle(obsX, obsY)
pygame.display.update()
This question already has answers here:
How can i shoot a bullet with space bar?
(1 answer)
How do I stop more than 1 bullet firing at once?
(1 answer)
Closed 2 years ago.
Here is a source code of my space-arcade pygame. It's a quite simple one and does shoots bullets as well but for now these bullets do not affect the obstacles coming in the screen.
Question: How can I shoot multiple bullets just after firing the first bullet and otherwise not waiting for the first bullet to pass y <= 0 to fire another bullet?
Please help me with this issue and if possible re-write this code with some adjustments made
import random
pygame.init()
screen = pygame.display.set_mode((800, 600))
pygame.display.set_caption("Space Invader")
icon = pygame.image.load("space-invaders.png")
pygame.display.set_icon(icon)
background = pygame.image.load("background.png")
player_image = pygame.image.load("space-invaders.png")
playerX = 370
playerY = 480
playerX_change = 0
playerY_change = 0
def player(x, y):
screen.blit(player_image, (x, y))
obs_image = pygame.image.load("cave-painting (1).png")
obsX = random.randint(0, 800)
obsY = random.randint(0, 100)
obsX_change = 2
obsY_change = 0.3
def obstacle(x, y):
screen.blit(obs_image, (x, y))
bullet_image = pygame.image.load("bullet.png")
bulletX = 0
bulletY = 0
bulletX_change = 0
bulletY_change = 10
bullet_state = "ready"
def fire_bullet(x, y):
global bullet_state # Globaling it, inorder to access it inside this func.
bullet_state = "fire"
screen.blit(bullet_image, (x,y))
running = True
while running:
screen.fill( (0, 0,0) )
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_LEFT:
playerX_change = -4
if event.key == pygame.K_RIGHT:
playerX_change = 4
if event.key == pygame.K_UP:
playerY_change = -4
if event.key == pygame.K_DOWN:
playerY_change = 4
if event.key == pygame.K_SPACE:
if bullet_state is "ready":
bulletX = playerX
bulletY = playerY
fire_bullet(bulletX, bulletY)
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
# Stopping our player beyond screen:
if playerX <= 0:
playerX = 0
elif playerX >= 765:
playerX = 765
elif playerY <= 200:
playerY = 200
elif playerY >= 480:
playerY = 480
obsX += obsX_change
obsY += obsY_change
# Movement mechanics for obstacles:
if obsX <= 0:
obsX_change = 3
obsY += obsY_change
elif obsX >= 736:
obsX_change = -3
obsY += obsY_change
if bulletY <= 0:
bulletY = 480
bullet_state = "ready"
if bullet_state is "fire":
fire_bullet(bulletX, bulletY)
bulletY -= bulletY_change
player(playerX, playerY)
obstacle(obsX, obsY)
pygame.display.update()
Also Here are the source pictures used in the aforementioned code:
background
cave-painting (1)
space-invaders
bullet
You have to add a list of bullets:
bullet_list = []
When a new bullet spawns then add a new position to the head of the bullet list:
if event.key == pygame.K_SPACE:
bullet_list.insert(0, [playerX, playerY])
Move and draw the bullets in a loop. Delete the bullets which are out of the window from the list:
while running:
# [...]
for i in range(len(bullet_list)):
bullet_list[i][1] -= bulletY_change
if bullet_list[i][1] < 0:
del bullet_list[i:]
break
# [...]
for bullet in bullet_list:
screen.blit(bullet_image, bullet)
Complete example:
import pygame
import random
pygame.init()
screen = pygame.display.set_mode((800, 600))
clock = pygame.time.Clock()
pygame.display.set_caption("Space Invader")
icon = pygame.image.load("space-invaders.png")
pygame.display.set_icon(icon)
background = pygame.image.load("background.png")
player_image = pygame.image.load("space-invaders.png")
playerX = 370
playerY = 480
playerX_change = 0
playerY_change = 0
def player(x, y):
screen.blit(player_image, (x, y))
obs_image = pygame.image.load("cave-painting (1).png")
obsX = random.randint(0, 800)
obsY = random.randint(0, 100)
obsX_change = 2
obsY_change = 0.3
def obstacle(x, y):
screen.blit(obs_image, (x, y))
bullet_image = pygame.image.load("bullet.png")
bulletX_change = 0
bulletY_change = 10
bullet_list = []
def draw_bullets(bullets):
for bullet in bullets:
screen.blit(bullet_image, bullet)
running = True
while running:
clock.tick(60)
screen.fill( (0, 0,0) )
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_LEFT:
playerX_change = -4
if event.key == pygame.K_RIGHT:
playerX_change = 4
if event.key == pygame.K_UP:
playerY_change = -4
if event.key == pygame.K_DOWN:
playerY_change = 4
if event.key == pygame.K_SPACE:
bullet_list.insert(0, [playerX, playerY])
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
# Stopping our player beyond screen:
if playerX <= 0:
playerX = 0
elif playerX >= 765:
playerX = 765
elif playerY <= 200:
playerY = 200
elif playerY >= 480:
playerY = 480
obsX += obsX_change
obsY += obsY_change
# Movement mechanics for obstacles:
if obsX <= 0:
obsX_change = 3
obsY += obsY_change
elif obsX >= 736:
obsX_change = -3
obsY += obsY_change
for i in range(len(bullet_list)):
bullet_list[i][1] -= bulletY_change
if bullet_list[i][1] < 0:
del bullet_list[i:]
break
player(playerX, playerY)
obstacle(obsX, obsY)
draw_bullets(bullet_list)
pygame.display.update()
I made a loop to keep the "enemy" character moving to left and right, but for some reason that I really can't tell why, he just goes to the right and when he hits the border limit that I defined, he "teleports" to the left border and keeps going to the right forever. I even tried to make the "enemyX_change" beeing negative, but he just goes to the left, hit the border and stops. I'm using Python 3.8.
import pygame
import random
# Initiate pygame
pygame.init()
# Display the game window
screen = pygame.display.set_mode((800, 600))
# Title and Icon
pygame.display.set_caption('Space Invaders')
icon = pygame.image.load('icon.png')
pygame.display.set_icon(icon)
# Player
playerSprite = pygame.image.load('player.png')
playerX = 370
playerY = 480
playerX_change = 0
# Enemy
enemySprite = pygame.image.load('enemy.png')
enemyX = random.randint(0, 736)
enemyY = random.randint(50, 150)
enemyX_change = 0.3
enemyY_change = 0
def player(x, y):
screen.blit(playerSprite, (x, y))
def enemy(x, y):
screen.blit(enemySprite, (x, y))
# Game Loop
running = True
while running:
# Background color (RGB)
screen.fill((0, 0, 0))
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# If a key is pressed, check if it's the right or left arrow key
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
playerX_change = -0.3
if event.key == pygame.K_RIGHT:
playerX_change = 0.3
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
playerX_change = 0
# Move the spaceship to the left or right
playerX += playerX_change
# Prevents the player from going off the border
if playerX <= 0:
playerX = 0
elif playerX >= 736:
playerX = 736
# Moves the enemy
enemyX += enemyX_change
# Prevents the enemy from going off the border
if enemyX <= 0:
enemyX = 0.3
elif enemyX >= 736:
enemyX = -0.3
player(playerX, playerY)
enemy(enemyX, enemyY)
pygame.display.update()
When the enemy goes out of bounds, then you have to change the movement direction (enemyX_change) rather than the position of the player (enemyX):
enemyX = -0.3
enemyX_change *= -1
Invert enemyX_change when it is less than 0 or greater than the width of the window:
# Moves the enemy
enemyX += enemyX_change
# Prevents the enemy from going off the border
if enemyX <= 0 or enemyX >= 736:
enemyX_change *= -1