There is no error when running the code but the ship is unable to move left or right and I'm sure I did everything right so here's all the code. The ship displays correctly but does not move at all.
import pygame
from ship import Ship
import game_functions as gf
from settings import Settings
def run_game():
pygame.init()
game_settings = Settings()
screen = pygame.display.set_mode((game_settings.screen_width, game_settings.screen_height))
pygame.display.set_caption("Alien Invasion")
space_ship = Ship(screen)
while True:
gf.check_events(space_ship)
gf.update_screen(game_settings, screen, space_ship)
space_ship.update()
run_game()
settings.py
class Settings:
def __init__(self):
self.screen_width = 800
self.screen_height = 600
self.bg_colour = (0, 0, 255)
ship.py
import pygame
class Ship:
def __init__(self, screen):
# Initializing the ship
self.screen = screen
# Load the ship and get the rect attribute
self.image = pygame.image.load("spaceship.png")
self.rect = self.image.get_rect()
self.screen_rect = screen.get_rect()
# Start each new ship at the bottom of the screen
self.rect.centerx = self.screen_rect.centerx
self.rect.bottom = self.screen_rect.bottom
# Movement flag
self.moving_right = False
self.moving_left = False
def blitme(self):
self.screen.blit(self.image, self.rect)
def update(self):
if self.moving_right:
self.rect.centerx += 1
if self.moving_left:
self.rect.centerx -= 1
game_functions.py
import sys
import pygame
def check_events(spaceship):
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
elif event.type == pygame.KEYDOWN:
if event.type == pygame.K_RIGHT:
spaceship.moving_right = True
elif event.type == pygame.K_LEFT:
spaceship.moving_left = True
elif event.type == pygame.KEYUP:
if event.type == pygame.K_RIGHT:
spaceship.moving_right = False
elif event.type == pygame.K_LEFT:
spaceship.moving_left = False
def update_screen(game_settings, screen, spaceship):
screen.fill(game_settings.bg_colour)
spaceship.blitme()
pygame.display.flip()
That is all the code I have been able to do. Does anyone have a solution to this problem?
In pygame, use event.type to check for a key event. Use event.key to check which key is pressed.
def check_events(spaceship):
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
elif event.type == pygame.KEYDOWN: # event.type
if event.key == pygame.K_RIGHT: # event.key
spaceship.moving_right = True
elif event.key == pygame.K_LEFT:
spaceship.moving_left = True
elif event.type == pygame.KEYUP:
if event.key == pygame.K_RIGHT:
spaceship.moving_right = False
elif event.key == pygame.K_LEFT:
spaceship.moving_left = False
Related
The ball wont move unless I'm moving my mouse, or clicking one of the buttons I have that are supposed to do things. (i.e. the up and down buttons that are supposed to move the paddle.) Clicking buttons and moving the mouse don't control the direction the Ball moves in- it just gets it to move the way it's supposed to. It will stop moving entirely if I stop moving the mouse or clicking the buttons.
Here's some of the code:
while not x:
for event in pygame.event.get():
if event.type == pygame.QUIT:
x = True #quits the game when you press X
if event.type == pygame.KEYUP: #makes start screen go away
if event.key == pygame.K_RETURN:
gameScreen()
ball.startMoving() #makes the ball start moving
start = True
if start == True:
gameScreen()
ball.move() #controls the movement of the ball
ball.show() #makes the ball show up
p1Paddle.border()
p1Paddle.show() #make the paddles and ball show up vv
p2Paddle.border()
p2Paddle.show()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_w: #makes blue paddle go up
p1Paddle.state = 'up'
p1Paddle.move()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_s: #makes blue paddle go down
p1Paddle.state = 'down'
p1Paddle.move()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP: #makes red paddle go up
p2Paddle.state = 'up'
p2Paddle.move()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_DOWN: #makes red paddle go down
p2Paddle.state = 'down'
p2Paddle.move()
pygame.display.update() #updates the screen/window
clock.tick(30)
And here's the code for the ball class.
class Ball:
def __init__(self, screen, colour, posX, posY, radius):
self.screen = screen
self.colour = colour
self.posX = posX
self.posY = posY
self.radius = radius
self.dx = 0
self.dy = 0
self.show()
def show(self):
pygame.draw.circle(self.screen, self.colour, (self.posX, self.posY), self.radius)
def startMoving(self):
self.dx = 15
self.dy = 5
def move(self):
self.posX += self.dx
self.posY += self.dy
Here's how I would change this code - you'll have to see if it works but I think this is your intention. The comments I added explain my changes. I made it so that all the movement and drawing code for the ball, and the code for drawing the paddle, always runs, regardless of whether or not the user pressed a key or generated some other kind of event.
# -start of application loop-
while not x:
# -start of event loop-
for event in pygame.event.get():
if event.type == pygame.QUIT:
x = True
if event.type == pygame.KEYUP:
if event.key == pygame.K_RETURN:
gameScreen()
ball.startMoving()
start = True
# only move the paddle if the game is running and the user pressed a key:
if start == True:
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_w:
p1Paddle.state = 'up'
p1Paddle.move()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_s:
p1Paddle.state = 'down'
p1Paddle.move()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
p2Paddle.state = 'up'
p2Paddle.move()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_DOWN:
p2Paddle.state = 'down'
p2Paddle.move()
# -end of event loop-
# Move and draw everything once per application loop,
# regardless of if the event loop ran:
if start == True:
gameScreen()
ball.move()
ball.show()
p1Paddle.border()
p1Paddle.show()
p2Paddle.border()
p2Paddle.show()
pygame.display.update()
clock.tick(30)
# -end of application loop-
I use VIDEORESIZE to update the window and when i scale the window the background update to the new size.
Now when i put an ship into this windows then when i scale the window or fullsize the winodw the ship can't touch the bottom of the window, it can't update to the new screen size and the ship speed become very very slowly
How can i fix it?
Here's the codes:
#!/usr/bin/python
import sys
import pygame
class Setting():
'''set for the screen'''
def __init__(self,width,height):
self.w=width
self.h=height
self.flag=pygame.RESIZABLE
self.color=(255,255,255)
self.screen=pygame.display.set_mode((self.w,self.h),self.flag)
self_title=pygame.display.set_caption("Muhaha")
class Ship():
'''set for the background and ship'''
def __init__(self,screen,setting):
self.bk=pygame.image.load("/home/finals/python/alien/image/muha.png").convert()
self.bkg=pygame.transform.smoothscale(self.bk,(setting.w,setting.h))
temp=pygame.image.load("/home/finals/python/alien/image/title.jpg").convert_alpha()
self.ship=pygame.transform.smoothscale(temp,(200,200))
self.screen=screen
self.screen_rect=screen.get_rect()
self.ship_rect=self.ship.get_rect()
'''make the ship at the middle bottom of the screen'''
self.ship_rect.centerx=self.screen_rect.centerx
self.ship_rect.bottom=self.screen_rect.bottom
def blit(self):
self.screen.blit(self.bkg,(0,0))
self.screen.blit(self.ship,self.ship_rect)
class Check_event():
def __init__(self):
self.moving_up = False
self.moving_down = False
self.moving_left = False
self.moving_right = False
def event(self,ship,setting):
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
'''set for moving ship'''
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
self.moving_up=True
elif event.key == pygame.K_DOWN:
self.moving_down=True
elif event.key == pygame.K_LEFT:
self.moving_left=True
elif event.key == pygame.K_RIGHT:
self.moving_right=True
elif event.type == pygame.KEYUP:
if event.key == pygame.K_UP:
self.moving_up=False
elif event.key == pygame.K_DOWN:
self.moving_down=False
elif event.key == pygame.K_LEFT:
self.moving_left=False
elif event.key == pygame.K_RIGHT:
self.moving_right=False
'''set for scale the window'''
elif event.type == pygame.VIDEORESIZE:
w,h = event.w,event.h
setting.screen = pygame.display.set_mode((w,h),setting.flag,0)
ship.bkg=pygame.transform.smoothscale(ship.bk,(w,h))
'''set for the ship not move out of the screen'''
if self.moving_up == True and ship.ship_rect.top >= 0:
ship.ship_rect.centery -= 1
if self.moving_down == True and ship.ship_rect.bottom <= setting.h:
ship.ship_rect.centery += 1
if self.moving_left == True and ship.ship_rect.left >= 0:
ship.ship_rect.centerx -= 1
if self.moving_right == True and ship.ship_rect.right <= setting.w:
ship.ship_rect.centerx += 1
def game():
pygame.init()
setting=Setting(1200,800)
screen=setting.screen
ship=Ship(screen,setting)
check_event=Check_event()
while True:
check_event.event(ship,setting)
ship.blit()
pygame.display.flip()
game()
Update the ship.screen_rect and compute the scale factor of the window (scale_x, scale_y). Finally scale the position of the ship by the scale factor:
class Check_event():
# [...]
def event(self,ship,setting):
for event in pygame.event.get():
# [...]
elif event.type == pygame.VIDEORESIZE:
w,h = event.w,event.h
setting.screen = pygame.display.set_mode((w,h),setting.flag,0)
ship.bkg=pygame.transform.smoothscale(ship.bk,(w,h))
current_rect = ship.screen_rect
ship.screen_rect = ship.bkg.get_rect()
scale_x = ship.screen_rect.width / current_rect.width
scale_y = ship.screen_rect.height / current_rect.height
ship.ship_rect.centerx = round(ship.ship_rect.centerx * scale_x)
ship.ship_rect.bottom = round(ship.ship_rect.bottom * scale_y)
I'm doing a project for my Computer Science class where we're using pygame to move an object around the screen. I'm not using the pygame sprites, but rather images imported into pygame and using those to act as custom sprites. When i try to move the Bunny, or "Player" object across the screen it does seem to update the position. This is the Player object i'm trying to change position:
class Player(object):
def __init__(self, x, y, filename):
self.x = x
self.y = y
self.image = pygame.transform.scale(pygame.image.load(filename), (150, 200))
self.moving_left = False
self.moving_right = False
self.moving_up = False
self.moving_down = False
def moveUpdate(self):
if self.moving_left:
self.x -= 25
pygame.display.update()
if self.moving_right:
self.y += 25
pygame.display.update()
if self.moving_up:
self.y -= 25
pygame.display.update()
if self.moving_down:
self.y += 25
pygame.display.update()
def moveEvent(self, event):
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
self.moving_left = True
if event.key == pygame.K_RIGHT:
self.moving_right = True
if event.key == pygame.K_UP:
self.moving_up = True
if event.key == pygame.K_DOWN:
self.moving_down = True
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT:
self.moving_left = False
if event.key == pygame.K_RIGHT:
self.moving_right = False
if event.key == pygame.K_UP:
self.moving_up = False
if event.key == pygame.K_DOWN:
self.moving_down = False
def draw(self, screen):
screen.blit(self.image, (self.x, self.y))
And this is the class i'm using to run the game itself:
class Game(object):
def __init__(self):
self.screensize = [1000, 1000]
self.white = [255, 255, 255]
self.black = [0, 0, 0]
self.screen = pygame.display.set_mode(self.screensize)
#self.bunny = pygame.transform.scale(pygame.image.load('bunny.png'), (150, 200))
self.clock = pygame.time.Clock()
self.player = Player(500, 500, 'bunny.png')
def Run(self):
run = True
while run:
self.clock.tick(60)
self.screen.fill(self.white)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
pygame.quit()
exit()
elif event.type == pygame.K_ESCAPE:
run = False
pygame.quit()
exit()
# - Objects Event Handle -
self.player.moveEvent(event)
# - Updates -
#self.player.moveUpdate()
# - Draws -
self.player.draw(self.screen)
pygame.display.flip()
game = Game()
game.Run()
Remove the event loop from the Player.moveEvent:
class Player(object):
# [...]
def moveEvent(self, event):
# for event in pygame.event.get(): <----- to be removed
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
self.moving_left = True
if event.key == pygame.K_RIGHT:
self.moving_right = True
if event.key == pygame.K_UP:
self.moving_up = True
if event.key == pygame.K_DOWN:
self.moving_down = True
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT:
self.moving_left = False
if event.key == pygame.K_RIGHT:
self.moving_right = False
if event.key == pygame.K_UP:
self.moving_up = False
if event.key == pygame.K_DOWN:
self.moving_down = False
Note, the method is called in an event loop and the event is passed to the method. The method has to handle the input parameter event:
while run:
self.clock.tick(60)
self.screen.fill(self.white)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
pygame.quit()
exit()
elif event.type == pygame.K_ESCAPE:
run = False
pygame.quit()
exit()
# - Objects Event Handle -
self.player.moveEvent(event)
# - Updates -
self.player.moveUpdate()
So im trying the make my sprite move constantly when im holding my arrow keys, but i need to keep pressing it to move it. any idea why?
here's my code:
yes i have imported pygame and everything
class Block(pygame.sprite.Sprite):
def __init__(self, color = blue,widht = 64, height = 64):
super(Block, self).__init__()
self.image = pygame.Surface((widht, height))
self.image.fill(color)
self.rect = self.image.get_rect()
self.sound = pygame.mixer.Sound("2dSounds/Walk.wav")
self.hspeed = 0
self.vspeed = 0
to update the sprite, so it changes places depending what key i press
def update(self):
self.rect.x += self.hspeed
self.rect.y += self.vspeed
to change the speed using a_block.change_speed(...)
def change_speed(self, hspeed, vspeed):
self.hspeed += hspeed
self.vspeed += vspeed
to set the position of the sprite when i first create it
def set_position(self, x, y):
self.rect.x = x
self.rect.y = y
to set a image for my sprite i just created
def set_image(self, filename = None):
if(filename != None):
self.image = pygame.image.load(filename)
self.rect = self.image.get_rect()
to play a sound
def play_sound():
self.sound.play()
the gameloop
def game_loop():
a_block = Block()
global event
gameDisplay.fill(white)
#Quit
gameExit = False
while not gameExit:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
the controls that dont work
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
a_block.change_speed(-20, 0)
if event.key == pygame.K_RIGHT:
a_block.change_speed(20, 0)
if event.key == pygame.K_UP:
a_block.change_speed(0, -20)
if event.key == pygame.K_DOWN:
a_block.change_speed(0, 20)
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT:
a_block.change_speed(0, 0)
if event.key == pygame.K_RIGHT:
a_block.change_speed(0, 0)
if event.key == pygame.K_UP:
a_block.change_speed(0, 0)
if event.key == pygame.K_DOWN:
a_block.change_speed(0, 0)
To draw a_block and other things
block_group = pygame.sprite.Group()
gameDisplay.fill(white)
a_block.set_image('2dImages/brick.png')
a_block.set_position(display_width/2, display_height/2)
a_block.update()
block_group.add(a_block)
block_group.draw(gameDisplay)
update display
pygame.display.update()
clock.tick(60)
thanks alot in advance!!
At the beginning of your code (but after you call pygame.init()), add the following line of code:
pygame.key.set_repeat(10)
This will post keyboard events to the event queue every 10 milliseconds even if the key was already pressed.
So I have been working on making a sprite for a game. My goal is to make my picture of a square to move. However I am facing difficulties in actually moving the square. Any help for as to what is wrong with the key event part of my code would be very much so appreciated.
import pygame
import sys
import time
from time import sleep
import random
from pygame.locals import *
image1 = pygame.image.load('square.png')
class sprite(pygame.sprite.Sprite):
def __init__(self):
self.image = pygame.image.load('square.png')
self.image = self.image.convert_alpha()
self.rect=self.image.get_rect()
self.x = 100
self.y = 100
self.dx=50
self.dy=50
def update(self):
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
self.x -= self.dx
if event.key == pygame.K_DOWN:
self.x += self.dx
if event.key == pygame.K_LEFT:
self.x -= self.dx
if event.key == pygame.K_RIGHT:
self.x += self.dx
self.rect.center=(self.x,self.y)
if event.type == pygame.KEYUP:
if event.key == pygame.K_UP or event.key == pygame.K_DOWN:
sprite.dy = 0
if event.key == pygame.K_RIGHT or event.key == pygame.K_LEFT:
sprite.dx = 0
def background(self, surface):
self.image2 = pygame.image.load(white.png)
screen.blit(self.image2, (0,0))
def draw(self, surface):
surface.blit(self.image, (self.x, self.y))
screen = pygame.display.set_mode((1250, 500))
screen.fill((255,255,255))
my_sprite=sprite()
while True:
pygame.init()
pygame.event.get()
pygame.event.pump
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
my_sprite.draw(screen)
pygame.display.update()
First of all, don't put pygame.init() in your loop.
I have a feeling that your problem is because in your update() method of the sprite, event is not even defined. Add the line for event in pygame.event.get(): at the start of the method and indent the rest under it.
def update(self):
for event in pygame.event.get():
... # Rest of the method