Why does my game keep on freezing when the player collides with the enemy in pygame - pygame

My game is basically space invaders but with tanks. I already put in all of the important bits like moving and firing the bullets and stuff but whenever the player tank is within a small distance from an enemy tank the game freezes, and the same happens with the bullets when I fire them, sometimes it randomly works but that's very rare.
Here's the code:
import pygame
import random
WIDTH=600
HEIGHT=600
FPS = 60
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
BLUE = (255, 0, 0)
GREEN = (48, 69, 48)
pygame.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
clock = pygame.time.Clock()
player_img = pygame.image.load('transparentplayer.png')
player = player_img.get_rect()
player.centerx = WIDTH // 2
player.bottom = HEIGHT - 50
enemy_img = pygame.image.load('transparent.png')
enemies = []
for i in range(3):
enemy = enemy_img.get_rect()
enemy.x = random.randint(0, WIDTH - 103)
enemy.y = -50
enemies.append(enemy)
bullet_img = pygame.image.load('transparentbullet.png')
bullets = []
direction = 'none'
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
pygame.quit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
direction = 'left'
if event.key == pygame.K_RIGHT:
direction = 'right'
if event.key == pygame.K_UP:
direction = 'up'
if event.key == pygame.K_DOWN:
direction = 'down'
if event.key == pygame.K_SPACE:
bullet = bullet_img.get_rect()
bullet.centerx = player.centerx
bullet.y = player.top
bullets.append(bullet)
if event.type == pygame.KEYUP and event.key != pygame.K_SPACE:
direction = 'none'
screen.fill(GREEN)
if direction == 'left':
if player.x > 0:
player.x -= 4
if direction == 'right':
if player.right < WIDTH:
player.x += 4
if direction == 'up':
if player.y > 0:
player.y -= 4
if direction == 'down':
if player.bottom < HEIGHT:
player.y += 4
for enemy in enemies:
enemy.y += 3
if enemy.top > HEIGHT:
enemy.y = -70
enemy.x = random.randint(0, WIDTH - 103)
for enemy in enemies:
screen.blit(enemy_img, (enemy.x, enemy.y))
for bullet in bullets:
bullet.y -= 3
for bullet in bullets:
screen.blit(bullet_img, (bullet.x, bullet.y))
temp = []
for i in range(len(bullets)):
if bullets[i].y < 0:
temp.append(i)
temp.sort(reverse=True)
for i in temp:
del bullets[i]
temp1 = []
temp2 = []
for i in range(len(bullets)):
for j in range(len(enemies)):
if bullets[i].colliderect(enemies[j]):
temp1.append(i)
temp2.append(j)
temp1.sort(reverse=True)
temp2.sort(reverse=True)
for i in temp1:
del bullets[i]
for i in temp2:
del enemies[i]
for enemy in enemies:
if player.colliderect(enemy):
pygame.image.load("gameover.PNG")
running = False
for i in range(len(temp)):
del temp[0]
for i in range(len(temp1)):
del temp1[0]
for i in range(len(temp2)):
del temp2[0]
screen.blit(player_img, (player.x, player.y))
pygame.display.update()
clock.tick(FPS)

Looking your code it looks like your game is supposed to end when you collide with an enemy. The only problem is only that you are not displaying the gameover image properly.
Try to replace this:
for enemy in enemies:
if player.colliderect(enemy):
pygame.image.load("gameover.PNG")
running = False
with this:
for enemy in enemies:
if player.colliderect(enemy):
gameover = pygame.image.load("gameover.png")
screen.blit(gameover,(WIDTH/2 - gameover.get_width()/2, HEIGHT/2 - gameover.get_height()/2))
running = False
Also, I suggest you to load the gameover image before the game loop starts

Related

Pygame - How to make mouse gesture movement smoother?

I wanted to be able to "scroll" around a pygame window using just mouse gestures, or in this case, "two fingers scrolling" (don't know the right term for this).
I managed to make an example implementation:
import pygame
pygame.init()
size = (width, height) = (800, 600)
screen = pygame.display.set_mode(size)
class SceneElement:
def __init__(self, x, y, width, height, color):
self.x = x
self.y = y
self.width = width
self.height = height
self.color = color
class Scene:
def __init__(self):
self.elements = [
SceneElement(150, 150, 200, 200, (55, 55, 10, 0.3)),
SceneElement(250, 300, 200, 200, (155, 200, 10, 0.5)),
]
def render(self, offset):
screen.fill((255, 255, 255))
for element in self.elements:
x = element.x + offset[0]
y = element.y + offset[1]
pygame.draw.rect(screen, element.color, (x, y, element.width, element.height))
scene = Scene()
offset = [0, 0]
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == 1027:
if event.x == 0 and event.y == -1:
print(event.x, event.y)
offset[1] -= 10
elif event.x == -1 and event.y == 0:
offset[0] += 10
print(event.x, event.y)
elif event.x == 1 and event.y == 0:
offset[0] -= 10
print(event.x, event.y)
elif event.x == 0 and event.y == 1:
offset[1] += 10
print(event.x, event.y)
scene.render(offset)
pygame.display.flip()
pygame.quit()
The above works. Here is a gif showing that it works.
Now problem is, I don't think this is how this is supposed to be implemented. I didn't see any example or existing code online that did this.
So while the above works, it doesn't feel "smooth". Trying to move in a circle or diagonally feels very unnatural (as can be seen in the gif near the end). Is there a better way to do the above (moving around using mouse gestures) or is this the right implementation?
Mainly what you have to deal with here is that your diagonal movement is not normalized, to fix this the easiest would be to just use pygame.Vector2 for positions and such, it also has a normalized method that will do the normalizing for you:
scene = Scene()
offset = pygame.Vector2()
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.MOUSEWHEEL:
direction = pygame.Vector2(event.x, event.y).normalize()
offset += direction * 10
scene.render(offset)
pygame.display.flip()
This won't affect functionality of the rest of the code as vectors can be indexed just like lists, however, I'd suggest you use pygame.Vector2 for positions and velocities and accelerations and other physics related things in general as they are faster and far more convenient.
Also use constants instead of some arbitrary integer values for event types and other stuff as it makes reading the code a lot easier.
Thanks to Matiiss's answer, I managed to find a clue on how to do this:
import pygame
pygame.init()
size = (width, height) = (800, 600)
screen = pygame.display.set_mode(size)
class SceneElement:
def __init__(self, x, y, width, height, color):
self.x = x
self.y = y
self.width = width
self.height = height
self.color = color
class Scene:
def __init__(self):
self.elements = [
SceneElement(150, 150, 200, 200, (55, 55, 10, 0.3)),
SceneElement(250, 300, 200, 200, (155, 200, 10, 0.5)),
]
def render(self, offset):
screen.fill((255, 255, 255))
for element in self.elements:
x = element.x + offset[0]
y = element.y + offset[1]
pygame.draw.rect(screen, element.color, (x, y, element.width, element.height))
scene = Scene()
offset = pygame.Vector2()
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.MOUSEWHEEL:
print(event.x, event.y)
if event.x == 0 and event.y == 1:
direction = pygame.Vector2(event.x, event.y).normalize()
offset += direction * 10
elif event.x == 0 and event.y == -1:
direction = pygame.Vector2(event.x, event.y).normalize()
offset += direction * 10
elif event.x == -1 and event.y == 0:
direction = pygame.Vector2(1, event.y).normalize()
offset += direction * 10
elif event.x == 1 and event.y == 0:
direction = pygame.Vector2(-1, event.y).normalize()
offset += direction * 10
scene.render(offset)
pygame.display.flip()
pygame.quit()
This seems to work much more smoothly, but I feel like this could be improved still: https://imgur.com/a/7WNNQIl
EDIT: Based on Matiiss's comment, using their answer and replacing event.x with -event.x seems to work like the above without if/elif:
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.MOUSEWHEEL:
direction = pygame.Vector2(-event.x, event.y).normalize()
offset += direction * 10
scene.render(offset)
pygame.display.flip()

Why does my player disappears when pressed jump? All indentations wrong or right? [duplicate]

I want to make my character jump. In my current attempt, the player moves up as long as I hold down SPACEv and falls down when I release SPACE.
import pygame
pygame.init()
window = pygame.display.set_mode((300, 300))
clock = pygame.time.Clock()
rect = pygame.Rect(135, 220, 30, 30)
vel = 5
run = True
while run:
clock.tick(100)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
keys = pygame.key.get_pressed()
rect.centerx = (rect.centerx + (keys[pygame.K_RIGHT] - keys[pygame.K_LEFT]) * vel) % 300
if keys[pygame.K_SPACE]:
rect.y -= 1
elif rect.y < 220:
rect.y += 1
window.fill((0, 0, 64))
pygame.draw.rect(window, (64, 64, 64), (0, 250, 300, 100))
pygame.draw.circle(window, (255, 0, 0), rect.center, 15)
pygame.display.flip()
pygame.quit()
exit()
However, I want the character to jump if I hit the SPACE once. I want a smooth jump animation to start when SPACE is pressed once.
How would I go about this step by step?
To make a character jump you have to use the KEYDOWN event, but not pygame.key.get_pressed(). pygame.key.get_pressed () is for continuous movement when a key is held down. The keyboard events are used to trigger a single action or to start an animation such as a jump. See alos How to get keyboard input in pygame?
pygame.key.get_pressed() returns a sequence with the state of each key. If a key is held down, the state for the key is True, otherwise False. Use pygame.key.get_pressed() to evaluate the current state of a button and get continuous movement.
while True:
for event in pygame.event.get():
if event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE:
jump = True
Use pygame.time.Clock ("This method should be called once per frame.") you control the frames per second and thus the game speed and the duration of the jump.
clock = pygame.time.Clock()
while True:
clock.tick(100)
The jumping should be independent of the player's movement or the general flow of control of the game. Therefore, the jump animation in the application loop must be executed in parallel to the running game.
When you throw a ball or something jumps, the object makes a parabolic curve. The object gains height quickly at the beginning, but this slows down until the object begins to fall faster and faster again. The change in height of a jumping object can be described with the following sequence:
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, -1, -2, -3, -4, -5, -6, -7, -8, -9, -10]
Such a series can be generated with the following algorithm (y is the y coordinate of the object):
jumpMax = 10
if jump:
y -= jumpCount
if jumpCount > -jumpMax:
jumpCount -= 1
else:
jump = False
A more sophisticated approach is to define constants for the gravity and player's acceleration as the player jumps:
acceleration = 10
gravity = 0.5
The acceleration exerted on the player in each frame is the gravity constant, if the player jumps then the acceleration changes to the "jump" acceleration for a single frame:
acc_y = gravity
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if vel_y == 0 and event.key == pygame.K_SPACE:
acc_y = -acceleration
In each frame the vertical velocity is changed depending on the acceleration and the y-coordinate is changed depending on the velocity. When the player touches the ground, the vertical movement will stop:
vel_y += acc_y
y += vel_y
if y > ground_y:
y = ground_y
vel_y = 0
acc_y = 0
See also Jump
Example 1: replit.com/#Rabbid76/PyGame-Jump
import pygame
pygame.init()
window = pygame.display.set_mode((300, 300))
clock = pygame.time.Clock()
rect = pygame.Rect(135, 220, 30, 30)
vel = 5
jump = False
jumpCount = 0
jumpMax = 15
run = True
while run:
clock.tick(50)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.KEYDOWN:
if not jump and event.key == pygame.K_SPACE:
jump = True
jumpCount = jumpMax
keys = pygame.key.get_pressed()
rect.centerx = (rect.centerx + (keys[pygame.K_RIGHT] - keys[pygame.K_LEFT]) * vel) % 300
if jump:
rect.y -= jumpCount
if jumpCount > -jumpMax:
jumpCount -= 1
else:
jump = False
window.fill((0, 0, 64))
pygame.draw.rect(window, (64, 64, 64), (0, 250, 300, 100))
pygame.draw.circle(window, (255, 0, 0), rect.center, 15)
pygame.display.flip()
pygame.quit()
exit()
Example 2: replit.com/#Rabbid76/PyGame-JumpAcceleration
import pygame
pygame.init()
window = pygame.display.set_mode((300, 300))
clock = pygame.time.Clock()
player = pygame.sprite.Sprite()
player.image = pygame.Surface((30, 30), pygame.SRCALPHA)
pygame.draw.circle(player.image, (255, 0, 0), (15, 15), 15)
player.rect = player.image.get_rect(center = (150, 235))
all_sprites = pygame.sprite.Group([player])
y, vel_y = player.rect.bottom, 0
vel = 5
ground_y = 250
acceleration = 10
gravity = 0.5
run = True
while run:
clock.tick(100)
acc_y = gravity
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.KEYDOWN:
if vel_y == 0 and event.key == pygame.K_SPACE:
acc_y = -acceleration
keys = pygame.key.get_pressed()
player.rect.centerx = (player.rect.centerx + (keys[pygame.K_RIGHT] - keys[pygame.K_LEFT]) * vel) % 300
vel_y += acc_y
y += vel_y
if y > ground_y:
y = ground_y
vel_y = 0
acc_y = 0
player.rect.bottom = round(y)
window.fill((0, 0, 64))
pygame.draw.rect(window, (64, 64, 64), (0, 250, 300, 100))
all_sprites.draw(window)
pygame.display.flip()
pygame.quit()
exit()

How do i stop an image from moving by the edges of the screen in Pygame?

I just started with pygame and want to make a minigame with a weapon (pixelart). I made it move by arrow keys on the keyboard, but the image moves by the edges, how do I block it from going further than the edges? The dimensions of my "character" is 220x116 pixels
#!/usr/bin/env python
import pygame
from pygame.locals import *
from sys import exit
background_image = 'mario bg.png'
weapon = 'scar.png'
pygame.init()
SCREEN_SIZE = (800, 800)
screen = pygame.display.set_mode(SCREEN_SIZE, 0, 32)
pygame.display.set_caption("SCAR MINIGAME")
background = pygame.image.load(background_image).convert()
player = pygame.image.load(weapon).convert_alpha()
x, y = 150, 353
MOVE_RIGHT = x=+10
MOVE_LEFT = x=-10
MOVE_UP = y=-10
MOVE_DOWN = y=+10
direction = 0
while True:
for event in pygame.event.get():
if event.type == QUIT:
exit()
if event.type == KEYDOWN:
if event.key == K_LEFT:
MOVE_LEFT = False
elif event.key == K_RIGHT:
MOVE_RIGHT = False
elif event.key == K_DOWN:
MOVE_DOWN = False
elif event.key == K_UP:
MOVE_UP = False
elif event.type == KEYUP:
if event.key == K_LEFT:
MOVE_LEFT = True
elif event.key == K_RIGHT:
MOVE_RIGHT = True
elif event.key == K_UP:
MOVE_UP = True
elif event.key == K_DOWN:
MOVE_DOWN = True
if(direction == MOVE_LEFT):
x-=0.4
elif(direction == MOVE_RIGHT):
x+=0.4
elif(direction == MOVE_UP):
y-=0.4
elif(direction == MOVE_DOWN):
y+=0.4
screen.blit(background, (0, 0))
screen.blit(player, (x, y))
pygame.display.update()
You simply need to check the co-ordinates of the player, and restrict them to on-screen, or make them wrap around.
I find it's handy to keep the window dimensions in global variables, and use these in setup functions, and later calculations:
WINDOW_WIDTH=800
WINDOW_HEIGHT=800
screen = pygame.display.set_mode( (WINDOW_WIDTH,WINDOW_HEIGHT) , 0, 32)
So when you update the position of player:
# Check player is on-screen
if (player.x < 0):
player.x = 0
elif (player.x > WINDOW_WIDTH):
player.x = WINDOW_WIDTH
if (player.y < 0):
player.y = 0
elif (player.y > WINDOW_HEIGHT):
player.y = WINDOW_HEIGHT
screen.blit(background, (0, 0))
screen.blit(player, (x, y))
It would be a more complete answer to include the width of the sprite for the > WINDOW_WIDTH-sprite_width check so it still shows on-screen, but that exercise is left for the reader.
So back to the code. The new function keepPointOnScreen() takes a co-ordinate and checks that it's on the screen, modifying it if not. Calling this function each time the player position is updated keeps the sprite on-screen. Since the sprite is painted from the left-side, it's still possible to "hide" the sprite on the right & bottom. To fix this, the keeper function needs to take into account the bitmap width.
#!/usr/bin/env python
import pygame
from pygame.locals import *
from sys import exit
background_image = 'mario bg.png'
weapon = 'scar.png'
# Keep these as variables for checking later on the code
WINDOW_WIDTH=800
WINDOW_HEIGHT=800
# Setup the window
pygame.init()
SCREEN_SIZE = (WINDOW_WIDTH, WINDOW_HEIGHT)
screen = pygame.display.set_mode(SCREEN_SIZE, 0, 32)
pygame.display.set_caption("SCAR MINIGAME")
# load images & set starting positions
background = pygame.image.load(background_image).convert()
player = pygame.image.load(weapon).convert_alpha()
player_width = player.get_width()
player_height = player.get_height()
print("Player image is [%u x %u]" % (player_width, player_height))
x, y = 150, 353
direction = 0
clock = pygame.time.Clock()
###
### Given a co-ordinate, ensure the co-ordinate is inside the screen
### bounds. If it's outside the screen area, reduce it to inside,
### or wrap it to the other side
###
### The code uses the WINDOW_WIDTH and WINDOW_HEIGHT globals,
### Assuming the window is 0 to WIDTH-1 in pixels, and similiarly for height
####
def keepPointOnScreen(x,y, bm_width, bm_height, wrap=False):
global WINDOW_WIDTH, WINDOW_HEIGHT
if ( wrap == False ):
# Block on the edges of the screen (no wrapping)
if ( x < 0 ):
x = 0
elif ( x >= WINDOW_WIDTH-bm_width ):
x = WINDOW_WIDTH-bm_width-1
if ( y < 0 ):
y = 0
elif ( y >= WINDOW_HEIGHT-bm_height ):
y = WINDOW_HEIGHT-bm_height-1
else:
# Wrap-around from side to side and top to bottom
if ( x < 0 ):
x = WINDOW_WIDTH-bm_width-1
elif ( x >= WINDOW_WIDTH-bm_width ):
x = 0
if ( y < 0 ):
y = WINDOW_HEIGHT-bm_height-1
elif ( y >= WINDOW_HEIGHT-bm_width ):
y = 0
return x, y
while True:
for event in pygame.event.get():
if ( event.type == QUIT ):
exit()
# Movement keys
keys = pygame.key.get_pressed()
if ( keys[pygame.K_LEFT] ):
x -= 1
elif ( keys[pygame.K_RIGHT] ):
x += 1
elif ( keys[pygame.K_UP] ):
y -= 1
elif ( keys[pygame.K_DOWN] ):
y += 1
# make sure the point is still on-screen
x,y = keepPointOnScreen( x, y, player_width, player_height )
# re-paint the window
screen.blit(background, (0, 0))
screen.blit(player, (x, y))
pygame.display.update()
clock.tick(60) # no more than 60 FPS

Automatically quits

I'm trying to write a snake game in python but my game automatically quites after inputing out of boundaries code.
I don't understand how the coordinates of my rect are >= than the width of my game, because in the screen they are not. I think that's what happens because the game automatically quits.
I'll post my code, below, to be even more clearer
import pygame
from random import randint
pygame.init()
black = (0, 0, 0)
white = (255, 255, 255)
red = (255, 0, 0)
class Game():
width, height = 800, 600
screen = pygame.display.set_mode((width, height))
pygame.display.set_caption("Second snake game.")
def __init__(self):
pass
game = Game()
class Player(pygame.sprite.Sprite):
lead_x = game.width/2
lead_y = game.height/2
lead_x_change = 0
lead_y_change = 0
velocity = 0.2
block_size = 10
def __init__(self):
pygame.sprite.Sprite.__init__(self)
def draw_character(self):
self.cube = pygame.draw.rect(game.screen, black, [self.lead_x, self.lead_y, self.block_size, self.block_size])
def change_x_right(self):
self.lead_x_change += -self.velocity
def change_x_left(self):
self.lead_x_change += self.velocity
def change_y_up(self):
self.lead_y_change += -self.velocity
def change_y_down(self):
self.lead_y_change += self.velocity
def move_x(self):
self.lead_x += self.lead_x_change
def move_y(self):
self.lead_y += self.lead_y_change
def stop_moving_x(self):
self.lead_x_change = 0
def stop_moving_y(self):
self.lead_y_change = 0
class Apple():
lead_x = randint(100, 700)
lead_y = randint(100, 500)
block_size = 10
def __init__(self):
pass
def spawn_apple_after_eaten(self):
self.lead_x = randint(100, 700)
self.lead_y = randint(100, 500)
self.apple = pygame.draw.rect(game.screen, red, [self.lead_x, self.lead_y, self.block_size, self.block_size])
def spawn_apple(self):
self.apple = pygame.draw.rect(game.screen, red, [self.lead_x, self.lead_y, self.block_size, self.block_size])
apple = Apple()
player = Player()
gameExit = False
while not gameExit:
game.screen.fill(white)
apple.spawn_apple()
for event in pygame.event.get():
if event.type == pygame.QUIT:
gameExit = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_d:
player.change_x_left()
player.stop_moving_y()
if event.key == pygame.K_a:
player.change_x_right()
player.stop_moving_y()
if event.key == pygame.K_w:
player.change_y_up()
player.stop_moving_x()
if event.key == pygame.K_s:
player.change_y_down()
player.stop_moving_x()
if event.type == pygame.KEYUP:
if event.key == pygame.K_w or event.key == pygame.K_s:
player.stop_moving_y()
if event.key == pygame.K_a or event.key == pygame.K_d:
player.stop_moving_x()
player.move_x()
player.move_y()
player.draw_character()
if player.cube.colliderect(apple.apple):
apple.spawn_apple_after_eaten()
if player.lead_x + player.block_size >= game.width or player.lead_x <= game.width:
gameExit = True
pygame.display.update()
pygame.quit()
quit()
You're setting gameExit to True if the x-coordinate is greater than or equal to game.width or if it's less than or equal to game.width, so it's always True. The second part of the conditional statement should be or player.lead_x <= 0.
if player.lead_x + player.block_size >= game.width or player.lead_x <= 0:
gameExit = True

Powerup variables in a platform game

I've made a platform game that has powerups in it. One of the powerups is a lightning bolt that is meant to increase your speed. However, when I tell it to increase the speed it increases it but makes my player move without use of pressing down my arrow keys. Any help? And I know you can't see it but I have included player.update, etc. in main, but I didn't show it, so the code would be shortened.
Thanks
class Player(pygame.sprite.Sprite):
def __init__(self,x,y,width = 65, height = 35):
pygame.sprite.Sprite.__init__(self)
self.x = x
self.y = y
self.hspeed,self.vspeed = 0,0
self.speed = 2
self.Jump = 10
self.images=[]
r0 = pygame.image.load("Images\Player\i1.png")
r1 = pygame.image.load("Images\Player\i2.png")
r2 = pygame.image.load("Images\Player\i3.png")
r3 = pygame.image.load("Images\Player\i4.png")
self.hurt = pygame.image.load("Images\Player\Hurt.png")
self.images.append(r0)
self.images.append(r1)
self.images.append(r2)
self.images.append(r3)
self.rotatedimages = []
rr0 = pygame.transform.flip(r0 ,True, False)
rr1 = pygame.transform.flip(r1 ,True, False)
rr2 = pygame.transform.flip(r2 ,True, False)
rr3 = pygame.transform.flip(r3 ,True, False)
self.rotatedimages.append(rr0)
self.rotatedimages.append(rr1)
self.rotatedimages.append(rr2)
self.rotatedimages.append(rr3)
self.deadimages = [self.hurt]
self.gravity = 0.35
self.index = 0
self.image = self.images[self.index]
self.rect = pygame.Rect(self.x,self.y,width,height)
self.TimeNum=0
self.TimeTarget=10
self.Timer = 0
def update(self, event = None):
self.calcgravity()
self.rect.x += self.hspeed
self.rect.y += self.vspeed
#Walking animation of animation when left or right key is pressed.
key = pygame.key.get_pressed()
if self.Timer >= 0:
if key[pygame.K_RIGHT]:
self.TimeNum+=1
if self.TimeNum == self.TimeTarget:
self.index +=1
if self.index >= len(self.images):
self.index = 0
self.image = self.images[self.index]
self.TimeNum = 0
if key[pygame.K_LEFT]:
self.TimeNum+=1
if self.TimeNum == self.TimeTarget:
self.index +=1
if self.index >= len(self.rotatedimages):
self.index = 0
self.image = self.rotatedimages[self.index]
self.TimeNum = 0
# if you go outside the boundaries of the game.
if player.rect.x < 0:
GameOver()
def move(self, hspeed, vspeed):
self.hspeed += hspeed
self.vspeed += vspeed
def Level1Coll(self,PowerUps):
PowerUpsCollision = pygame.sprite.spritecollide(self,PowerUps,True )
for speedboost in PowerUpsCollision:
self.speed = 3
def main()
GameExit = False
while GameExit==False:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
player.move(-player.speed,0)
if event.key == pygame.K_RIGHT:
player.move(player.speed,0)
if event.key == pygame.K_UP:
player.move(0,-player.Jump)
JumpSound.play()
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT:
player.move(player.speed,0)
if event.key == pygame.K_RIGHT:
player.move(-player.speed,0)
if event.key == pygame.K_UP:
player.move(0,0)
You set self.speed to be equal to 3, which usually means that the sprite will move on its own with a speed of 3. Instead create a new variable:
extra_speed = 0
and apply that to the increase of speed of the sprite:
self.rect.y += (self.vspeed + extra_speed)
Now when the sprite doesn't have the power-up, nothing changes as the speed increases by nothing. But when the sprite does get the powerup, simply change extra_speed to 3 and reset back to 0 when the sprite is finished with the power-up. To meet the problem of instant running, use another variable to determine when to run and use it before you check to run.
running = False
#A few lines later into your update function
if running:
self.rect.x += self.hspeed
self.rect.y += (self.vspeed + extra_speed)
The above code means that if running is True, then move the sprite appropriately. Otherwise, don't move the sprite.