Thanks to the help of people on this site i have manages to get some bullets firing on a level on my platform game. The fire continuously and travel vertical until the hit the floor and then they disappear. However, i wanted to add horizontal firing bullets in that level and i have done the exact same code as my vertical bullets and yet it only fires one and doesn't fire any other horizontal bullets. It fires one horizontal bullet, goes to the boundary of my screen and after that no other bullets come after it. Any help would be aprreciated!
class VerticalBullets(pygame.sprite.Sprite):
def __init__(self,x,y):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load("Images/bullet.png")
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
def update(self):
self.rect.y += 7
if self.rect.y > 520:
bullet_list_v.empty()
class HorizontalBullets(pygame.sprite.Sprite):
def __init__(self,x,y):
pygame.sprite.Sprite.__init__(self)
bullet_image = pygame.image.load("Images/bullet.png")
self.image = pygame.transform.rotate(bullet_image,-90)
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
def update(self):
self.rect.x -= 5
if self.rect.x < 30:
bullet_list_h.empty()
def main3():
TrapList.empty()
TrapList.add(trap4)
player.hspeed = 0
player.rect.x,player.rect.y = 50,0
bullet_list_v.empty()
bullet_list_h.empty()
FiringBullet = pygame.USEREVENT + 1
pygame.time.set_timer(FiringBullet, 1500)
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)
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)
if event.type == FiringBullet:
bullet = VerticalBullets(400,200)
bullet2 = VerticalBullets(500,200)
bullet3 = VerticalBullets(625,200)
hbullet = HorizontalBullets(700,400)
bullet_list_v.add(bullet)
bullet_list_v.add(bullet2)
bullet_list_v.add(bullet3)
bullet_list_h.add(h_bullet)
screen.fill(BLACK)
level3.update()
for eachbullet in bullet_list_v:
bullet_list_v.draw(screen)
bullet_list_v.update()
for eachbullet in bullet_list_h:
bullet_list_h.draw(screen)
bullet_list_h.update()
if player.rect.y < 0:
NextLevel3()
TrapList.draw(screen)
trampoline.render()
playergroup.update()
playergroup.draw(screen)
player.level_3_collisions(BlockListDirt2)
pygame.display.update()
clock.tick(60)
Try changing:
bullet_list_h.add(h_bullet)
To:
bullet_list_h.add(hbullet)
To make sure that you're adding the horizontal bullet that you just created instead of one that's not declared.
Related
I implemented a pause feature in my game in the while loop at the end of my code, but the problem is that only my car sprite pauses. I have tried a bunch of different ways setting up my pause code but none of the ways I arrange it seems to pause the whole game.
I want to be able to pause my whole game when I press the p key on my keyboard, not just my car sprite. Can someone please tell me how I can fix this code? The code that will pause the whole game will be nice. Please, the rearranged code that will pause the whole game will help. Also I don't just want the answer, I want a quick explanation of why only my car sprite would pause instead of the whole game.
My code:
import random
import pygame
import pygame.freetype
pygame.init()
#screen settings
WIDTH = 1000
HEIGHT = 400
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("AutoPilot")
screen.fill((255, 255, 255))
#fps
FPS = 120
clock = pygame.time.Clock()
#load images
bg = pygame.image.load('background/street.png').convert_alpha() # background
bullets = pygame.image.load('car/bullet.png').convert_alpha()
debris_img = pygame.image.load('debris/cement.png')
#define game variables
shoot = False
#player class
class Player(pygame.sprite.Sprite):
def __init__(self, scale, speed):
pygame.sprite.Sprite.__init__(self)
self.bullet = pygame.image.load('car/bullet.png').convert_alpha()
self.bullet_list = []
self.speed = speed
#self.x = x
#self.y = y
self.moving = True
self.frame = 0
self.flip = False
self.direction = 0
self.score = 0
#load car
self.images = []
img = pygame.image.load('car/car.png').convert_alpha()
img = pygame.transform.scale(img, (int(img.get_width()) * scale, (int(img.get_height()) * scale)))
self.images.append(img)
self.image = self.images[0]
self.rect = self.image.get_rect()
self.update_time = pygame.time.get_ticks()
self.movingLeft = False
self.movingRight = False
self.rect.x = 465
self.rect.y = 325
#draw car to screen
def draw(self):
screen.blit(self.image, (self.rect.centerx, self.rect.centery))
#move car
def move(self):
#reset the movement variables
dx = 0
dy = 0
#moving variables
if self.movingLeft and self.rect.x > 33:
dx -= self.speed
self.flip = True
self.direction = -1
if self.movingRight and self.rect.x < 900:
dx += self.speed
self.flip = False
self.direction = 1
#update rectangle position
self.rect.x += dx
self.rect.y += dy
#shoot
def shoot(self):
bullet = Bullet(self.rect.centerx + 18, self.rect.y + 30, self.direction)
bullet_group.add(bullet)
#check collision
def collision(self, debris_group):
for debris in debris_group:
if debris.health > 0 and pygame.sprite.spritecollide(debris, bullet_group, True):
debris.health -= 1
if debris.health <= 0:
self.score += 1
#player stats/score
def stats(self):
myfont = pygame.font.SysFont('comicsans', 30)
scoretext = myfont.render("Score: " + str(self.score), 1, (0,0,0))
screen.blit(scoretext, (100,10))
#bullet class
class Bullet(pygame.sprite.Sprite):
def __init__(self, x, y, direction):
pygame.sprite.Sprite.__init__(self)
self.speed = 5
self.image = bullets
self.rect = self.image.get_rect()
self.rect.center = (x,y)
self.direction = direction
def update(self):
self.rect.centery -= self.speed
#check if bullet has gone off screen
if self.rect.centery < 1:
self.kill()
#debris class
class Debris(pygame.sprite.Sprite):
def __init__(self,scale,speed):
pygame.sprite.Sprite.__init__(self)
self.scale = scale
self.x = random.randrange(100,800)
self.speed_y = 10
self.y = 15
self.speed = speed
self.vy = 0
self.on_ground = True
self.move = True
self.health = 4
self.max_health = self.health
self.alive = True
self.velocity = random.randrange(1,2)
self.speed_x = random.randrange(-3,3)
self.moving_down = True
self.is_destroyed = False
#load debris
self.image = debris_img
self.rect = self.image.get_rect()
self.rect.x = random.randrange(100, 800)
self.rect.y = random.randrange(-150, -100)
self.rect.center = (self.x,self.y)
#load explosion
self.img_explosion_00 = pygame.image.load('explosion/0.png').convert_alpha()
self.img_explosion_00 = pygame.transform.scale(self.img_explosion_00, (self.img_explosion_00.get_width() * 2,
self.img_explosion_00.get_height() * 2))
self.img_explosion_01 = pygame.image.load('explosion/1.png').convert_alpha()
self.img_explosion_01 = pygame.transform.scale(self.img_explosion_01, (self.img_explosion_01.get_width() * 2,
self.img_explosion_01.get_height() * 2))
self.img_explosion_02 = pygame.image.load('explosion/2.png').convert_alpha()
self.img_explosion_02 = pygame.transform.scale(self.img_explosion_02, (self.img_explosion_02.get_width() * 2,
self.img_explosion_02.get_height() * 2))
self.img_explosion_03 = pygame.image.load('explosion/3.png').convert_alpha()
self.img_explosion_03 = pygame.transform.scale(self.img_explosion_03, (self.img_explosion_03.get_width() * 2,
self.img_explosion_03.get_height() * 2))
#explosion list
self.anim_explosion = [self.img_explosion_00,
self.img_explosion_01,
self.img_explosion_02,
self.img_explosion_03]
self.anim_index = 0
self.frame_len = 20 #frames before explosion animation disappears
#spawn new debris
def spawn_new_debris(self):
self.rect.x = random.randrange(100, 800)
self.rect.y = random.randrange(-150, -100)
self.velocity = random.randrange(1, 2)
self.speed_x = random.randrange(-3, 3)
#respawn debris when they go of the screen
def boundaries(self):
if self.rect.left > WIDTH + 10 or self.rect.right < -10 or self.rect.top > HEIGHT + 10:
self.spawn_new_debris()
#update image
def update(self):
self.rect.y += self.velocity
self.rect.x += self.speed_x
self.boundaries()
if self.health <= 0:
max_index = len(self.anim_explosion) - 1
if self.anim_index > max_index:
self.kill()
else:
if self.frame_len == 0:
self.image = self.anim_explosion[self.anim_index]
self.anim_index += 1
self.frame_len = 20
else:
self.frame_len -= 1
#make debris fall down
def falldown(self):
self.rect.centery += self.velocity
if self.moving_down and self.rect.y > 350:
self.kill()
######################CAR/DEBRIS##########################
player = Player(1,5)
##########################################################
#groups
bullet_group = pygame.sprite.Group()
debris_group = pygame.sprite.Group()
all_sprites = pygame.sprite.Group()
for x in range(100):
d = Debris(1, 5)
debris_group.add(d)
all_sprites.add(d)
#game runs here
run = True
paused = False
while run:
#draw street
screen.blit(bg, [0, 0])
#update groups
bullet_group.update()
bullet_group.draw(screen)
debris_group.update()
debris_group.draw(screen)
#draw car
player.draw()
player.move()
player.collision(debris_group)
player.stats()
#update all sprites
all_sprites.update()
all_sprites.draw(screen)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
#pause game
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_p:
paused = not paused
if paused == True:
continue
#check if key is down
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
run = False
if event.key == pygame.K_a:
player.movingLeft = True
if event.key == pygame.K_d:
player.movingRight = True
if event.key == pygame.K_SPACE:
player.shoot()
shoot = True
#check if key is up
if event.type == pygame.KEYUP:
if event.key == pygame.K_a:
player.movingLeft = False
if event.key == pygame.K_d:
player.movingRight = False
#update the display
pygame.display.update()
pygame.display.flip()
clock.tick(FPS)
pygame.quit()
Move your
for event in pygame.event.get():
right below the while loop, and move your
if paused:
continue
below the for loop, like so:
run = True
paused = False
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
#pause game
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_p:
paused = not paused
#check if key is down
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
run = False
if event.key == pygame.K_a:
player.movingLeft = True
if event.key == pygame.K_d:
player.movingRight = True
if event.key == pygame.K_SPACE:
player.shoot()
shoot = True
#check if key is up
if event.type == pygame.KEYUP:
if event.key == pygame.K_a:
player.movingLeft = False
if event.key == pygame.K_d:
player.movingRight = False
if paused:
continue
#draw street
screen.blit(bg, [0, 0])
#update groups
bullet_group.update()
bullet_group.draw(screen)
debris_group.update()
debris_group.draw(screen)
#draw car
player.draw()
player.move()
player.collision(debris_group)
player.stats()
#update all sprites
all_sprites.update()
all_sprites.draw(screen)
#update the display
pygame.display.update()
pygame.display.flip()
clock.tick(FPS)
pygame.quit()
The reason only your car sprite paused when you pressed the q key is because, as you can see in your original code here:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
#pause game
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_p:
paused = not paused
if paused == True:
continue
you put the
if paused == True:
continue
inside the for loop, not the while loop, so the lines that move the car would be blocked, but the rest of the code within the while loop will still get executed.
I'm trying to use time.Time() to control the fire rate of my projectiles, but after putting in the time logic, my player can no longer shoot any projectiles at all. How can I make it so that my player only fires once every half a second or so?
The following is a workable example;
main game module
import pygame
from constants import *
from player import Player
from Projectile import Projectiles
import time
pygame.init()
screen = pygame.display.set_mode([500, 500])
pygame.display.set_caption('Labyrinth')
# Spawn player
player = Player(50, 50)
all_sprites_list = pygame.sprite.Group()
all_sprites_list.add(player)
projectile_list = pygame.sprite.Group()
clock = pygame.time.Clock()
done = False
# ----- Event Loop
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
elif event.type == pygame.KEYDOWN:
if event.key == ord('a'):
player.changespeed(-3, 0)
elif event.key == ord('d'):
player.changespeed(3, 0)
elif event.key == ord('w'):
player.changespeed(0, -3)
elif event.key == ord('s'):
player.changespeed(0, 3)
elif event.key == pygame.K_LEFT:
projectile = Projectiles(player.rect.x, player.rect.y, -5, 0)
elif event.key == pygame.K_RIGHT:
projectile = Projectiles(player.rect.x, player.rect.y, 5, 0)
elif event.key == pygame.K_UP:
projectile = Projectiles(player.rect.x, player.rect.y, 0, -5)
elif event.key == pygame.K_DOWN:
projectile = Projectiles(player.rect.x, player.rect.y, 0, 5)
try:
if projectile:
if time.Time() - last_shot > player.fire_rate:
projectile_list.add(projectile)
last_shot = time.Time()
except:
pass
elif event.type == pygame.KEYUP:
if event.key == ord('a'):
player.changespeed(3, 0)
elif event.key == ord('d'):
player.changespeed(-3, 0)
elif event.key == ord('w'):
player.changespeed(0, 3)
elif event.key == ord('s'):
player.changespeed(0, -3)
# ----- Game Logic
all_sprites_list.update()
projectile_list.update()
screen.fill(GREEN)
all_sprites_list.draw(screen)
projectile_list.draw(screen)
pygame.display.flip()
clock.tick(60)
pygame.quit()
player module
from constants import *
import pygame
import time
from datetime import datetime, timedelta
class Player(pygame.sprite.Sprite):
def __init__(self, x, y):
super().__init__()
self.image = pygame.Surface([15, 15])
self.image.fill(BLACK)
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
self.fire_rate = 1
self.change_x = 0
self.change_y = 0
def changespeed(self, x, y):
self.change_x += x
self.change_y += y
def update(self):
self.rect.x += self.change_x
self.rect.y += self.change_y
projectile module
import pygame
from constants import *
class Projectiles(pygame.sprite.Sprite):
def __init__(self, x, y, x_speed, y_speed):
super().__init__()
self.image = pygame.Surface([4, 4])
self.image.fill(RED)
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
self.x_speed = x_speed
self.y_speed = y_speed
def update(self):
self.rect.x += self.x_speed
self.rect.y += self.y_speed
constants module defines a few colours. Any help is much appreciated!
Well, strictly speaking, the answer is that you have time.Time() in a try block, and it should be time.time() (all lowercase). This throws an exception, so any time time.Time() - last_shot > player.fire_rate is evaluated, the try block isn't run. This would have been more apparent if you had caught the exception and thrown an error message rather than just passing.
There likely are further issues, but a more in-depth analysis of your code is difficult, as I don't see you initializing last_shot anywhere, nor player.fire_rate. The "minimal complete example" standard isn't just for the answerers, but for the asker as well. Basic debugging in isolating the issue as much as possible.
As another note, your while loop appears to contain nothing but a for loop, making it redundant. If you're doing that to just have the program run through the loop over and over again until the appropriate time, then time.sleep() would be probably be a better way to do that.
A try with a bare except is an anti-pattern and should almost never be used, because it hides all errors in the try clause and makes the code hard to debug. I'd remove it and rearrange the event handling code.
When an arrow key gets pressed, only change the velocity vector depending on the key instead of creating new projectile instances. Then check again if any of the arrow keys were pressed and if the timer is finished, create a projectile instance and pass the current velocity vector.
import pygame as pg
from pygame.math import Vector2
BULLET_IMG = pg.Surface((9, 9))
BULLET_IMG.fill(pg.Color('aquamarine2'))
class Projectile(pg.sprite.Sprite):
def __init__(self, pos, vel):
super().__init__()
self.image = BULLET_IMG
self.rect = self.image.get_rect(center=pos)
self.vel = Vector2(vel)
def update(self):
self.rect.move_ip(self.vel)
def main():
pg.init()
screen = pg.display.set_mode((640, 480))
clock = pg.time.Clock()
projectiles = pg.sprite.Group()
previous_time = pg.time.get_ticks()
speed = 12
vel = Vector2(speed, 0)
done = False
while not done:
for event in pg.event.get():
if event.type == pg.QUIT:
done = True
elif event.type == pg.KEYDOWN:
# Only change the velocity vector.
if event.key == pg.K_LEFT:
vel = Vector2(-speed, 0)
elif event.key == pg.K_RIGHT:
vel = Vector2(speed, 0)
elif event.key == pg.K_UP:
vel = Vector2(0, -speed)
elif event.key == pg.K_DOWN:
vel = Vector2(0, speed)
# If an arrow keys was pressed, create a new projectile.
if event.key in (pg.K_LEFT, pg.K_RIGHT, pg.K_UP, pg.K_DOWN):
current_time = pg.time.get_ticks()
# We're ready to fire when 500 ms have passed.
if current_time - previous_time > 500:
previous_time = current_time
# Now create the projectile instance and pass
# the position and the velocity.
projectiles.add(Projectile(pg.mouse.get_pos(), vel))
projectiles.update()
screen.fill((30, 30, 30))
projectiles.draw(screen)
pg.display.update()
clock.tick(60)
if __name__ == '__main__':
main()
pg.quit()
I've been at it for a while, and I cannot seem to figure out why my sprite is not moving up or down when the program is run.
Player Sprite Class
def __init__(self,name,x,y):
pygame.sprite.Sprite.__init__(self)
self.name = str(name)
self.speed = 5
self.image = pygame.image.load(name+'.png').convert_alpha()
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
def move_up(self):
self.rect.y -= self.speed
def move_down(self):
self.rect.y += self.speed
def move_left(self):
self.rect.x -= self.speed
def move_right(self):
self.rect.x += self.speed
def update(self):
self.screen.blit(self.image,(self.rect))
Main File / Loop
class Console:
def __init__(self,width,height):
pygame.init()
self.w = width
self.h = height
self.clock = pygame.time.Clock()
self.screen = pygame.display.set_mode((self.w,self.h))
self.screenName = pygame.display.set_caption("Star's Labyrinth")
class Background(pygame.sprite.Sprite):
def __init__(self,image_file,x,y):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load(image_file)
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
def main():
gameExit = False
game_display = Console(1024,576)
game_display.screen
starboy = Player("starboy",200,200)
background = Background("background.png",0,0)
while not gameExit:
for event in pygame.event.get():
if event.type == pygame.QUIT:
gameExit = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_a:
starboy.move_left()
elif event.key == pygame.K_d:
starboy.move_right()
elif event.type == pygame.K_w:
starboy.move_up()
elif event.type == pygame.K_s:
starboy.move_down()
print(pygame.event.get())
game_display.screen.blit(background.image,background.rect)
starboy.update
game_display.screen.blit(starboy.image,(starboy.rect.x,starboy.rect.y))
pygame.display.update()
game_display.clock.tick(30)
I have tried different types of commands trying to figure out whether it's a variable or function problem. Also is there a way I can make it move without having to tap the key.
In the event loop you're checking if the event.type is pygame.K_w or pygame.K_s, but you have to check if the event.key is equal to these constants. Change
elif event.type == pygame.K_w:
starboy.move_up()
elif event.type == pygame.K_s:
starboy.move_down()
to:
elif event.key == pygame.K_w:
starboy.move_up()
elif event.key == pygame.K_s:
starboy.move_down()
You also forgot the parentheses behind starboy.update.
I cant seem to get my sprite to move left or right after moving it to a class. I am using pygame. I have a velocity variable and add to that to my x for my shape yet it still doesnt move. Any help would be really appreciated. Movement was working before i decided to put all my the things to do with the player into a class.
import pygame
import Constants
from pygame.locals import *
pygame.init()
pygame.display.set_caption("Platformer")
window = pygame.display.set_mode((Constants.SCREEN_WIDTH, Constants.SCREEN_HEIGHT))
clock = pygame.time.Clock()
all_sprite_list = pygame.sprite.Group()
class player:
def __init__(self,velocity):
self.velocity = velocity
def location(self,x,y):
self.x = x
self.y = y
self.xVel = 0
def keys(self):
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
self.xVel = - self.velocity
elif event.key == pygame.K_RIGHT:
self.xVel = self.velocity
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
self.xVel = 0
def move(self):
self.x = + self.xVel
def draw(self):
display = pygame.display.get_surface()
pygame.draw.rect(window,(255,255,255),[self.x,self.y,20,40])
def do(self):
self.keys()
self.move()
self.draw()
P = player(10)
P.location(Constants.SCREEN_WIDTH/2,0)
#Map
def draw_map():
window.fill(Constants.BLUE)
#sprites
def draw_player():
player = Player(50,50)
all_sprite_list.add(player)
#Game loop
def game_loop():
GameQuit = False
while not GameQuit:
for event in pygame.event.get():
if event.type == pygame.QUIT:
GameQuit = True
draw_map()
P.do()
pygame.display.update()
clock.tick(30)
#game initialisation
game_loop()
pygame.quit()
quit()
`
The problem is that pygame.event.get() clears all events from the event queue, so when your player calls it, all events are already gone. From the docs
This will get all the messages and remove them from the queue. If a type or sequence of types is given only those messages will be removed from the queue.
You can solve this by specifying which events should be removed from the event queue e.g.
for event in pygame.event.get(QUIT):
GameQuit = True
The other events should still be in the queue for your player to use
Leon Z. has already explained that pygame.event.get() empties the event queue. I usually pass the events from the event loop to the objects that need the events. You could also assign the list that pygame.event.get() returns to a variable and then pass this variable to the player instance: events = pygame.event.get().
BTW, there was a little mistake in the move method: = + instead of +=.
import pygame
from pygame.locals import *
pygame.init()
pygame.display.set_caption("Platformer")
window = pygame.display.set_mode((640, 480))
clock = pygame.time.Clock()
all_sprite_list = pygame.sprite.Group()
class player:
def __init__(self,velocity):
self.velocity = velocity
def location(self,x,y):
self.x = x
self.y = y
self.xVel = 0
def keys(self, event):
"""Handle the events that get passed from the event loop."""
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
self.xVel = -self.velocity
elif event.key == pygame.K_RIGHT:
self.xVel = self.velocity
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
self.xVel = 0
def move(self):
self.x += self.xVel # Add the self.xVel to self.x.
def draw(self):
display = pygame.display.get_surface()
pygame.draw.rect(display, (255,255,255), [self.x, self.y, 20, 40])
def do(self):
self.move()
self.draw()
P = player(10)
P.location(window.get_width()/2, 0)
def draw_map():
window.fill(pygame.Color('blue'))
def draw_player():
player = Player(50,50)
all_sprite_list.add(player)
def game_loop():
GameQuit = False
while not GameQuit:
for event in pygame.event.get():
if event.type == pygame.QUIT:
GameQuit = True
# Pass the event to all objects that need it.
P.keys(event)
draw_map()
P.do()
pygame.display.update()
clock.tick(30)
game_loop()
pygame.quit()
I am trying to move this rectangle to make Pong. I had it working before but I messed up the code.
Could anyone help me make it move and possibly make my code look cleaner?
Again, I made it move, but the problem seems to be in the Update method.
Possibly the ScreenSide parameter???...
import pygame, sys, random
from pygame.locals import *
pygame.init()
screen_width = 800
screen_height = 600
screen = pygame.display.set_mode((800, 600))
rectImg1 = 'Rect.jpg'
rectImg2 = 'Rect2.jpg'
RIGHT = "RIGHT"
LEFT = "LEFT"
WHITE = (255,255,255)
FPS = 30
PADDLE_SPEED = 5
BALL_SPEED = 10
fpsClock = pygame.time.Clock()
xPos = 0
yPos = 0
leftY = 20
rightY = 20
class Paddle(pygame.sprite.Sprite):
def __init__(self, screenSide):
pygame.sprite.Sprite.__init__(self)
self.screenSide = screenSide
if self.screenSide == LEFT:
self.image = pygame.image.load(rectImg1).convert_alpha()
self.rect = self.image.get_rect()
self.rect.x = 20
self.rect.y = 20
def update(self):
if self.screenSide == LEFT:
self.y = leftY
allSpritesGroup = pygame.sprite.Group()
paddle = Paddle(LEFT)
allSpritesGroup.add(paddle)
#code to make it move
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
if paddle.screenSide == LEFT:
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_s:
paddle.y += PADDLE_SPEED
elif event.key == pygame.K_w:
paddle.y -= PADDLE_SPEED
elif event.type == pygame.KEYUP:
if event.key == pygame.K_s or event.key == pygame.K_w:
paddle.y == 0
screen.fill((255,255,255))
allSpritesGroup.draw(screen)
allSpritesGroup.update()
pygame.display.flip()
fpsClock.tick(FPS)
pygame.quit()
Just a guess but your problem might be in:
elif event.type == pygame.KEYUP:
if event.key == pygame.K_s or event.key == pygame.K_w:
paddle.y == 0
This looks more like a comparison and if not then you're setting the y to 0 whenever you let go of a key.
Also, You're right about the update function:
def update(self):
if self.screenSide == LEFT:
self.y = leftY
You're constantly setting the y to 20 so it won't move since every time it updates its moved to 20.
Your event handling is broken. The KEYDOWN and KEYUP events are outside of the event loop because of this line if paddle.screenSide == LEFT:. You also need to update paddle.rect.y not paddle.y and you should do that in the class not with global variables. I'd give the paddles a self.y_speed attribute which you set in the event loop and then use it to update the self.rect.y position each frame in the update method. And remove the screenSide checks and just pass the image and position to the sprites during the instantiation.
import sys
import pygame
pygame.init()
screen = pygame.display.set_mode((800, 600))
screen_rect = screen.get_rect()
rectImg1 = pygame.Surface((30, 50))
rectImg1.fill((20, 20, 120))
rectImg2 = pygame.Surface((30, 50))
rectImg2.fill((120, 10, 20))
WHITE = (255,255,255)
FPS = 30
PADDLE_SPEED = 5
fpsClock = pygame.time.Clock()
class Paddle(pygame.sprite.Sprite):
def __init__(self, image, pos):
pygame.sprite.Sprite.__init__(self)
self.image = image
self.rect = self.image.get_rect(topleft=pos)
self.y_speed = 0
def update(self):
self.rect.y += self.y_speed
allSpritesGroup = pygame.sprite.Group()
paddle = Paddle(rectImg1, (20, 20))
paddle2 = Paddle(rectImg2, (750, 20))
allSpritesGroup.add(paddle, paddle2)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_s:
paddle.y_speed = PADDLE_SPEED
elif event.key == pygame.K_w:
paddle.y_speed = -PADDLE_SPEED
elif event.type == pygame.KEYUP:
if event.key == pygame.K_s or event.key == pygame.K_w:
paddle.y_speed = 0
allSpritesGroup.update()
screen.fill(WHITE)
allSpritesGroup.draw(screen)
pygame.display.flip()
fpsClock.tick(FPS)