I'm quite new to python and have recently started game dev with pygame. I wanted to know why my game just freezes and the exitcode -805306369 (0xCFFFFFFF) appears. Do i have errors in my programm? It looks like this:
import pygame
import random
import math
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
run = True
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))
def iscollision(targetedX, targetedY, aim_sightX, aim_sightY):
distance = math.sqrt((math.pow(targetedX - aim_sightX, 2)) + (math.pow(targetedY - aim_sightY, 2)))
if distance < 70:
return True
else:
return False
while run:
window.fill((255, 255, 255))
random_target()
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = 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
score = 0
while score < 10:
collision = iscollision(targetedX, targetedY, aim_sightX, aim_sightY)
if collision and event.key == pygame.K_SPACE:
print("HIT") # Just for me to acknowledge that collision is true and space bar was pressed in the right spot
score = score + 1
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 think there is a mistake in this area as my program runs well without it.
while score < 10:
collision = iscollision(targetedX, targetedY, aim_sightX, aim_sightY)
if collision and event.key == pygame.K_SPACE:
print("HIT") # Just for me to acknowledge that collision is true and space bar was pressed in the right spot
score = score + 1
I've checked other questions but they are mostly for java and other languages.
You have an application loop. You do not need an additional loop to control the game. The loop that increments the score is an infinite loop. Change the loop to a selection (change while to if).
Furthermore, the score has to be initialized before the application loop:
score = 0
while run:
# [...]
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = 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:
# [...]
elif event.key == pygame.K_SPACE:
if score < 10:
collision = iscollision(targetedX, targetedY, aim_sightX, aim_sightY)
if collision:
print("HIT")
score = score + 1
I have been creating a game where an image moves according to player input with Keydown and Keyup methods. I want to add boundaries so that the user cannot move the image/character out of the display (I dont want a game over kind of thing if boundary is hit, just that the image/character wont be able to move past that boundary)
import pygame
pygame.init()#initiate pygame
black = (0,0,0)
white = (255,255,255)
red = (255,0,0)
display_width = 1200
display_height = 800
display = pygame.display.set_mode((display_width,display_height))
characterimg_left = pygame.image.load(r'/Users/ye57324/Desktop/Make/coding/python/characterimg_left.png')
characterimg_right = pygame.image.load(r'/Users/ye57324/Desktop/Make/coding/python/characterimg_right.png')
characterimg = characterimg_left
def soldier(x,y):
display.blit(characterimg, (x,y))
x = (display_width * 0.30)
y = (display_height * 0.2)
pygame.display.set_caption('No U')
clock = pygame.time.Clock()#game clock
flip_right = False
x_change = 0
y_change = 0
bg_x = 0
start = True
bg = pygame.image.load(r'/Users/ye57324/Desktop/Make/coding/python/bg.png').convert()
class player:
def __init__(self, x, y):
self.jumping = False
p = player(x, y)
while start:
for event in pygame.event.get():
if event.type == pygame.QUIT or (event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE):
start = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
x_change += -4
if flip_right == True:
characterimg = characterimg_left
flip_right = False
x += -150
elif event.key == pygame.K_RIGHT:
x_change += 4
if flip_right == False:
characterimg = characterimg_right
flip_right = True
x += 150
elif event.key == pygame.K_UP:
y_change += -4
elif event.key == pygame.K_DOWN:
y_change += 4
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT:
x_change += 4
elif event.key == pygame.K_RIGHT:
x_change += -4
elif event.key == pygame.K_UP:
y_change += 4
elif event.key == pygame.K_DOWN:
y_change += -4
x += x_change
y += y_change
display.fill(white)
soldier(x,y)
pygame.display.update()
clock.tick(120)#fps
pygame.quit()
I have tried several times including switching to the key pressed method but they all failed. Help please, thank you.
Basically you want to limit the player's movement.
So everytime you want to "move" the player (I'm guessing this is "x_change" / "y_change") you need to check whether they would still be inside your boundaries after the move.
Example: Your display x boundary is 0 pixels on the left of your screen and 500 to the right. I only allow the actual movement if the result of the movement is within my boundaries.
boundary_x_lower = 0
boundary_x_upper = 500
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
if boundary_x_lower < (x_change - 4):
# I allow the movement if I'm still above the lower boundary after the move.
x_change -= 4
elif event.key == pygame.K_RIGHT:
if boundary_x_upper > (x_change +4):
# I allow the movement if I'm still below the upper boundary after the move.
x_change += 4
PS: I am confused by your code as you subtract when you move to the right... I am used to 2D games where you increment the player's position if you move to the right... and subtract if you go to the left.
Feel free to adapt the code to fit your project. The basic principle applies also to the y-axis movement: with boundary_y_lower & _y_upper. if you have further questions, just ask!
Just clamp the x and y values between 0 and the display width and height.
# In the main while loop after the movement.
if x < 0:
x = 0
elif x + image_width > display_width:
x = display_width - image_width
if y < 0:
y = 0
elif y + image_height > display_height:
y = display_height - image_height
I also recommend checking out how pygame.Rects work. You could define a rect with the size of the display,
display_rect = display.get_rect()
and a rect for the character which will be used as the blit position:
rect = characterimg_left.get_rect(center=(x, y))
Then move and clamp the rect in this way:
rect.move_ip((x_change, y_change))
rect.clamp_ip(display_rect)
display.fill(white)
# Blit the image at the `rect.topleft` coordinates.
display.blit(characterimg, rect)
I've been working with Pygame and I encountered this problem.
I have made 2 animation lists. One called rightImages which contains images of my character walking to the right, and one called leftImages which is the opposite. The animation works when I press the D key over (My program's controls are A is left, D is right, etc) and over again, but when I hold it down the animations do not run. Hopefully, you understand and if you don't please run the program and then maybe you will get what I am saying. Here is my code:
def Main():
x_change = 0
y_change = 0
x = 400
y = 400
counter = 0
counter2 = 0
player = pygame.image.load('knight_left.png')
while True:
rightImages = ['knight_right.png','knight_right1.png','knight_right2.png']
leftImages =['knight_left.png', 'knight_left1.png', 'knight_left2.png']
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_d:
x_change += 5
counter += 1
if counter >= len(rightImages):
counter = 0
player = pygame.image.load(rightImages[counter])
elif event.key == pygame.K_a:
x_change -= 5
counter2 += 1
if counter2 >= len(leftImages):
counter2 = 0
player = pygame.image.load(leftImages[counter2])
elif event.key == pygame.K_w:
y_change -= 5
elif event.key == pygame.K_s:
y_change += 5
elif event.type == pygame.KEYUP:
x_change = 0
y_change = 0
x = x+x_change
y = y+y_change
gameDisplay.fill(white)
gameDisplay.blit(player,(x,y))
pygame.display.update()
clock.tick(30)
Main()
This is the code that runs through the animation loop when walking to the right.
counter += 1
if counter >= len(rightImages):
counter = 0
player = pygame.image.load(rightImages[counter])
This is for when walking to the left.
counter2 += 1
if counter2 >= len(rightImages):
counter2 = 0
player = pygame.image.load(rightImages[counter2])
If you could please tell me how to cycle through the animation lists even when the key is held down that would be awesome!
Note: I did not include all of my code.
I usually do something similar to this: First load the images before the main loop starts, because reading from the hard disk is slow.
Assign the currently selected images to a variable active_images and swap them out if the player presses a key, e.g. active_images = right_images.
In the main loop you just have to check if the player moves and then increment the counter (or a timer variable) and assign the current image to the player variable: player = active_images[counter].
import pygame as pg
def main():
screen = pg.display.set_mode((640, 480))
clock = pg.time.Clock()
white = pg.Color('white')
x_change = 0
y_change = 0
x = 400
y = 400
# Load the images before the main loop starts. You could also
# do this in the global scope.
right_images = []
for img_name in ['knight_right.png','knight_right1.png','knight_right2.png']:
right_images.append(pg.image.load(img_name).convert_alpha())
left_images = []
for img_name in ['knight_left.png', 'knight_left1.png', 'knight_left2.png']:
left_images.append(pg.image.load(img_name).convert_alpha())
# This variable refers to the currently selected image list.
active_images = left_images
counter = 0 # There's no need for a second counter.
player = active_images[counter] # Currently active animation frame.
while True:
for event in pg.event.get():
if event.type == pg.QUIT:
return
elif event.type == pg.KEYDOWN:
if event.key == pg.K_d:
x_change = 5
active_images = right_images # Swap the image list.
elif event.key == pg.K_a:
x_change = -5
active_images = left_images # Swap the image list.
elif event.key == pg.K_w:
y_change -= 5
elif event.key == pg.K_s:
y_change += 5
elif event.type == pg.KEYUP:
if event.key == pg.K_d and x_change > 0:
x_change = 0
counter = 0 # Switch to idle pose.
player = active_images[counter]
elif event.key == pg.K_a and x_change < 0:
x_change = 0
counter = 0 # Switch to idle pose.
player = active_images[counter]
elif event.key == pg.K_w and y_change < 0:
y_change = 0
elif event.key == pg.K_s and y_change > 0:
y_change = 0
if x_change != 0: # If moving.
# Increment the counter and keep it in the correct range.
counter = (counter+1) % len(active_images)
player = active_images[counter] # Swap the image.
x += x_change
y += y_change
screen.fill(white)
screen.blit(player, (x, y))
pg.display.flip()
clock.tick(30)
if __name__ == '__main__':
pg.init()
main()
pg.quit()
Try the following code.
def Main():
x = 400
y = 400
counter = 0
counter2 = 0
player = pygame.image.load('knight_left.png')
rightImages = ['knight_right.png','knight_right1.png','knight_right2.png']
leftImages =['knight_left.png', 'knight_left1.png', 'knight_left2.png']
while True:
x_change = 0
y_change = 0
keys = pygame.key.get_pressed() #checking pressed keys
if keys[pygame.K_d]:
x_change += 5
counter += 1
if counter >= len(rightImages):
counter = 0
player = pygame.image.load(rightImages[counter])
if keys[pygame.K_a]:
x_change -= 5
counter2 += 1
if counter2 >= len(leftImages):
counter2 = 0
player = pygame.image.load(leftImages[counter2])
x = x+x_change
gameDisplay.fill(white)
gameDisplay.blit(player,(x,y))
pygame.display.update()
clock.tick(30)
Main()
I'm trying to create a bird's-eye-view game (e.g. hotline miami) in pygame. I've gotten stuck at the collision detection. I'm trying to to see if the player hits a block on the left, right, in front or behind . I've gotten only to doing the 'in front' collision but that doesn't work; the player will hit the block 'head first', stop, but is then able to move through the block if he spams the arrow key. I know what the problem is (in the if else statement in the collision detection) but I can't for the life of me find the solution. Everything I tried doesn't seem to work. Help! Any help would be greatly appreciated, thanks in advance! (btw this is my first time on stack overflow, so sorry if I'm not asking the question well) (I removed some of the unnecessary code like the pygame.init() and variables)
def drawBlock(block_width,block_height,x,y):
pygame.draw.rect(gameDisplay, red, [x,y,block_width,block_height])
def gameLoop(x,y):
while not gameExit:
level = ["W","W","W","W","W","W","W","W","W","W","W","W",
"N","N","N","N","N","N","N","N","N","N","N","N","L",
"N","N","N","N","N","N","N","N","N","N","N","N","L",
"N","N","N","N","P","N","N","N","N","N","N","N","L",
"N","N","N","N","N","N","N","N","N","N","N","N","L",
"N","N","N","N","N","N","N","N","N","N","N","N","L",
"N","N","N","N","N","N","N","N","N","N","N","N","L",
"N","N","N","N","N","N","N","N","N","N","N","N","L",
"N","N","N","N","N","N","N","N","N","P","N","N","L",
"N","N","N","N","P","N","N","N","N","N","N","N","L",
"N","N","N","N","N","N","N","N","N","N","N","N","L","S"]
#EVENT HANDLING
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if canMoveUp:
if event.key == pygame.K_UP:
y_change = -player_movement
if canMoveDown:
if event.key == pygame.K_DOWN:
y_change = player_movement
if event.key == pygame.K_LEFT:
x_change = -player_movement
if event.key == pygame.K_RIGHT:
x_change = player_movement
if event.type == pygame.KEYUP:
if event.key == pygame.K_UP or event.key == pygame.K_DOWN:
y_change = 0
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
x_change = 0
pX += x_change
pY += y_change
gameDisplay.fill(black)
#CALCULATING THE SIZE OF THE BLOCKS SO THEY FIT W/ A VARIETY OF RESOLUTIONS
if calculateBlockX:
for element in level:
if element == "W":
W_count += 1
if element == "S":
block_width = (display_width/W_count)
calculateBlockX = False
if calculateBlockY:
for element in level:
if element == "L":
L_count += 1
if element == "S":
block_height = (display_height/L_count)
calculateBlockY = False
#COUNTING HOW MANY BLOCKS THERE ARE IN THE LEVEL ARRAY (P)
if P_countFunction:
for element in level:
if element == "P":
P_count += 1
if element == "S":
print(P_count)
P_countFunction = False
#ALL THE X AND Ys OF ALL THE BLOCKS IN THE LEVEL, AND ACTUALLY DRAWING THEM
blockXY = []
for element in level:
if element == "N":
x += block_width
if element == "L":
y += block_height
x = 0
if element == "P":
drawBlock(block_width,block_height,x,y)
blockXY.append(x)
blockXY.append(y)
if appendBlockXY:
if len(collisionArray) > P_count:
del(collisionArray[P_count])
print(collisionArray)
appendBlockXY = False
collisionArray.append(blockXY)
blockXY = []
x += block_width
if element == "S":
y = 0
#COLLISION DETECTION
for XnY in collisionArray:
if pX >= XnY[0] and pX <= XnY[0] + block_width and pY + playerSize <= XnY[1] or pX + playerSize >= XnY[0] and pX <= XnY[0] + block_width:
if pY - block_height == XnY[1]:
canMoveUp = False
y_change = 0
if pY - block_height != XnY[1]:
canMoveUp = True
else:
if pY - block_height >= XnY[1]:
canMoveUp = True
#gameDisplay.blit(img,[pX,pY])
pygame.draw.rect(gameDisplay, green, [pX,pY,playerSize,playerSize])
clock.tick(60)
pygame.display.update()
pygame.quit()
quit()
gameLoop(x,y)
pygame.display.update()
Your collision detection is written in a way that allows the last iteration to override all earlier checks. Instead of that, have canMoveUp set to True before the loop, and the loop should only set it to False or leave it alone.
So with pygame you have a while loop that loops continuously, then your event handlers in a for loop, then the code you want to execute continuously.
I need to handle an event after i execute a line of code inside the while loop though beacuse they impact each other, but I also need to handle a different event before the line.
How, inside my main while loop, handle a set of events, execute some code, and then handle another set of events?
Solved.
I set a variable equal to 1 in the user event handler, and then down where i needed to execute the code, i check if the variable was equal to 1, and if it was, i executed my code and set the variable back to 0.
Good stuff.
Here is my code if anyone wants to help me find a better solution ;) (kinda long):
uif = "images/userGray.png"
bif = "images/bg.jpg"
cif = "images/chair3.png"
i = 0
playerX = 1
playerY = 1
pX = 1
pY = 1
bX = 0
bY = 0
moveX = 0
moveY = 0
windowX = 640
windowY = 480
lowerY = 1024
lowerX = 1024
bullets = []
x = 0
y = 0
rotate = False
objects = []
objects.append([256,260,410,511])
import pygame, sys
from pygame.locals import *
pygame.init()
screen = pygame.display.set_mode((640,480),0,32)
background = pygame.image.load(bif).convert()
user = pygame.image.load(uif).convert_alpha()
chair = pygame.image.load(cif).convert_alpha()
chair1 = pygame.image.load(cif).convert_alpha()
pygame.time.set_timer(USEREVENT + 1, 100)
def shoot(inLoc, clLoc, weapon):
bulletId = len(bullets)
bullets[bulletId] = [inLoc, clLoc, 200, 3]
moveSpeed = .1
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
if event.type == USEREVENT + 1:
rotate = True;
if event.type == KEYDOWN:
if event.key == K_LEFT or event.key == K_a:
moveX = -1*moveSpeed
elif event.key == K_RIGHT or event.key == K_d:
moveX = moveSpeed
if event.key == K_DOWN or event.key == K_s:
moveY = moveSpeed
elif event.key == K_UP or event.key == K_w:
moveY = -1*moveSpeed
if event.type == KEYUP:
if event.key == K_LEFT or event.key == K_a or event.key == K_RIGHT or event.key == K_d:
moveX = 0
if event.key == K_DOWN or event.key == K_s or event.key == K_UP or event.key == K_w:
moveY = 0
dontMoveX = 0
dontMoveY = 0
for obj in objects:
if playerX + moveX > obj[0]-user.get_width() and playerX + moveX < obj[1] and playerY + moveY > obj[2]-user.get_height() and playerY + moveY < obj[3]:
if playerY + moveY == obj[2]-user.get_height()-1 or playerY + moveY == obj[3]+1:
dontMoveX = 0
else:
dontMoveX = 1
if playerX + moveX > obj[0]-user.get_width() and playerX + moveX < obj[1] and playerY + moveY > obj[2]-user.get_height() and playerY + moveY < obj[3]:
if playerX + moveX == obj[0]-user.get_width()-1 or playerX + moveX == obj[1]+1:
dontMoveY = 0
else:
dontMoveY = 1
if dontMoveX == 0:
playerX += moveX
if (playerX >= 0 and playerX <= windowX/2) or (playerX >= lowerX-(windowX/2) and playerX <= lowerX-user.get_width()):
pX+=moveX
if playerX > windowX/2 and playerX < lowerX-(windowX/2):
bX+=-1*moveX
if dontMoveY == 0:
playerY += moveY
if (playerY >= 0 and playerY <= windowY/2) or (playerY >= lowerY-(windowY/2) and playerY <= lowerY-user.get_width()):
pY+=moveY
if playerY > windowY/2 and playerY < lowerY-(windowY/2):
bY+=-1*moveY
screen.blit(background,(bX,bY))
screen.blit(user,(pX,pY))
pygame.mouse.set_visible(False);
if rotate == True:
if i < 360:
i = i + 18
else:
i = 0
orig_chair_rect = chair.get_rect()
chair1 = pygame.transform.rotate(chair, i);
rot_chair_rect = orig_chair_rect.copy()
rot_chair_rect.center = chair1.get_rect().center
chair1 = chair1.subsurface(rot_chair_rect).copy()
rotate = False
x,y = pygame.mouse.get_pos()
x -= chair.get_width()/2
y -= chair.get_height()/2
screen.blit(chair1,(x,y))
pygame.display.update()