This question already has answers here:
How can I make a sprite move when key is held down
(6 answers)
How to get keyboard input in pygame?
(11 answers)
How to get if a key is pressed pygame [duplicate]
(1 answer)
How to hold a 'key down' in Pygame?
(1 answer)
Closed 2 years ago.
Hey guys I'm trying to add movement to a sprite I have and I'm having some trouble, heres the code. I'm using the WASD keys to move the player around the place, I just can't seem to figure out why it won't move. Any help is appreciated.
import pygame
import math
from sys import exit
from pygame.locals import *
pygame.mixer.init
class Player(pygame.sprite.Sprite):
def __init__(self, screen):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load("ryu.png")
transColor = self.image.get_at((1, 1))
self.image.set_colorkey(transColor)
self.rect = self.image.get_rect()
self.dx = screen.get_width()/2
self.dy = screen.get_height()/2
self.rect.center = (self.dx, self.dy)
self.screen = screen
self.speed = 4
def update(self):
self.rect.center = (self.dx, self.dy)
def returnPosition(self):
return self.rect.center
def MoveLeft(self):
if self.rect.left < 0:
self.dx+=0
else:
self.dx-=self.speed
def MoveRight(self):
if self.rect.right >self.screen.get_width():
self.dx+=0
else:
self.dx+=self.speed
def MoveUp(self):
if self.rect.top <0:
self.dy+=0
else:
self.dy-=self.speed
def MoveDown(self):
if self.rect.bottom > self.screen.get_height():
self.dy+=0
else:
self.dy+=self.speed
def checkKeys(myData):
(event, player) = myData
keys = pygame.key.get_pressed()
if keys [K_a]:
print 'He turned left!!!'
player.MoveLeft()
if keys [K_s]:
print "He's going down!!!"
if keys [K_d]:
print "He turned right!!!"
if keys [K_w]:
print "He's going up!!!"
def main():
screen = pygame.display.set_mode((640, 480))
clock = pygame.time.Clock()
keepGoing = True
pygame.display.set_caption("Creating a sprite")
player = Player(screen)
background = pygame.Surface(screen.get_size())
background.fill((0, 0, 0))
allSprites = pygame.sprite.Group(player)
while keepGoing:
clock.tick(30)
for event in pygame.event.get():
if event.type == pygame.QUIT:
keepGoing = False
allSprites.clear(screen, background)
allSprites.update()
allSprites.draw(screen)
pygame.display.flip()
if __name__ == "__main__":
main()
Related
This question already has answers here:
How do I scale a PyGame image (Surface) with respect to its center?
(1 answer)
How to change an image size in Pygame?
(4 answers)
Closed 12 hours ago.
I am making a game where I am trying to have an enemy grow in the air then drop like a bomb. For the most part, everything works well. The only problem I have is that it is while it is growing, it is moving down and right.
Here is the code I am using
import pygame
class BloodyTear(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.sprite=pygame.image.load('image')
self.image = self.sprite
self.rect = self.image.get_rect()
self.rect.x =500
self.rect.y = 50
self.size1 = 10
self.size2 = 10
self.mask = pygame.mask.from_surface(self.image)
self.size = self.size1, self.size2
def update(self):
if self.size1 < 135:
self.size1 += 1
self.size2 += 1
self.size = self.size1, self.size2
self.image = pygame.transform.scale(self.sprite, self.size)
if self.size1 == 135:
self.rect.y += 3
self.mask = pygame.mask.from_surface(self.image)
if self.rect.y >= 500:
self.kill()
def collide(self, spriteGroup):
if pygame.sprite.spritecollide(self, spriteGroup, True, pygame.sprite.collide_mask):
pass
pygame.init()
blood = BloodyTear()
window = pygame.display.set_mode((800, 800))
clock = pygame.time.Clock()
bloddsprite = pygame.sprite.Group()
bloddsprite.add(blood)
run = True
while run:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
bloddsprite.update()
window.fill(0)
bloddsprite.draw(window)
pygame.display.flip()
pygame.quit()
exit()
I tried using get_bounding_rect() but it didn't seem to change anything. I'm not sure exactly how to fix this.
This question already has answers here:
How can I make a sprite move when key is held down
(6 answers)
How to get keyboard input in pygame?
(11 answers)
Closed 3 months ago.
I am new to Pygame and am facing issues getting the event handler to register my keystrokes to move my player when I call that class under the event handler in the main loop
I run this code and the level and player render correctly but not able to move my player. I've looked at various other answers such as adding pygame.event.pump() but this doesn't work and shouldn't be needed as it should be handled by the main event handler
import pygame, sys
# Settings
size = width, height = (800, 800)
FPS = 60
road_w = width//1.6
roadmark_w = width//80
right_lane = width/2 + road_w/4
left_lane = width/2 - road_w/4
speed = 5
player_start = right_lane, height*0.8
enemy_start = left_lane, height*0.2
# Create Player Class
class Player(pygame.sprite.Sprite):
def __init__(self,pos,groups):
super().__init__(groups)
self.image = pygame.image.load("car.png").convert_alpha()
self.rect = self.image.get_rect(center = pos)
self.direction = pygame.math.Vector2(0,0)
self.speed = 5
def input(self):
keys = pygame.key.get_pressed()
if keys[pygame.K_UP]:
self.direction.y = -1
elif keys[pygame.K_DOWN]:
self.direction.y = 1
else:
self.direction.y = 0
if keys[pygame.K_RIGHT]:
self.direction.x = 1
print(self.direction.x)
elif keys[pygame.K_LEFT]:
self.direction.x = -1
else:
self.direction.x = 0
def move(self, speed):
if self.direction.magnitude() != 0:
self.direction = self.direction.normalize()
self.rect.x += self.direction.x * speed
self.rect.y += self.direction.y * speed
def update(self):
self.input()
self.move(self.speed)
#Create Level Class
class Level:
def __init__(self):
# get display surface
self.display_surface = pygame.display.get_surface()
#Sprite group set up
self.player_sprite = pygame.sprite.Group()
def create_map(self):
pygame.draw.rect(self.display_surface,(50, 50, 50),\
(width/2-road_w/2, 0, road_w, height))
pygame.draw.rect(self.display_surface,(255, 240, 60),\
(width/2 - roadmark_w/2, 0, roadmark_w, height))
pygame.draw.rect(self.display_surface,(255, 255, 255),\
(width/2 - road_w/2 + roadmark_w*2, 0, roadmark_w, height))
pygame.draw.rect(self.display_surface,(255, 255, 255),\
(width/2 + road_w/2 - roadmark_w*3, 0, roadmark_w, height))
def run(self):
# Update and draw level
self.create_map()
self.player = Player(player_start,[self.player_sprite])
self.player_sprite.draw(self.display_surface)
self.player_sprite.update
# Create Game Class
class Game:
def __init__(self):
# Setup
pygame.init()
self.screen = pygame.display.set_mode(size)
pygame.display.set_caption('Car Game')
self.clock = pygame.time.Clock()
self.level = Level()
def run(self):
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
self.screen.fill((60,220,0))
self.level.run()
pygame.display.update()
self.clock.tick(FPS)
# Run Game
if __name__ == '__main__':
game = Game()
game.run()
Car.png
This question already has answers here:
Pygame doesn't let me use float for rect.move, but I need it
(2 answers)
Closed 1 year ago.
Hello Stackoverflow Community,
could someone help me with my problem.
When I move to the left I am quite fast but when I want to go to the right it takes way to lang. I deleted the dt from my move function and the went the same speed. I changed the buttons but the problem seems only to occure when I use the +=. Does one of you dealt with the problem before and could help me?
import pygame
import time
import random
#0 = Menu, 1 = Game, 2 = Quit
game_state = 1
WHITE = (255, 255, 255)
class Player(pygame.sprite.Sprite):
speed = 100
def __init__(self, WIDTH):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load("player.png")
self.rect = self.image.get_rect()
self.rect.center = (WIDTH / 2, 480)
def move(self, keys, dt):
if(keys[0]):
self.rect.x += self.speed * dt
print(self.speed)
print(dt)
print(self.rect.x)
if(keys[1]):
print(self.speed)
print(dt)
self.rect.x -= self.speed * dt
print(self.rect.x)
class Main():
prev_time = time.time()
dt = 0
#initalizing menu or game depending on variables
def __init__(self):
global game_state
while game_state !=2:
WIDTH, HEIGHT = 800, 600
screen = self.initialize_pygame("Alien Slaughter", WIDTH, HEIGHT)
self.all_sprites = pygame.sprite.Group()
self.player = Player(WIDTH)
self.all_sprites.add(self.player)
if(game_state == 1):
self.prev_time = time.time()
self.game(screen, WIDTH, HEIGHT)
#calculating deltatime
def calc_deltatime(self):
self.now = time.time()
self.dt = self.now - self.prev_time
self.prev_time = self.now
#initializing pygame and create window
def initialize_pygame(self, title, width, height):
screen = pygame.display.set_mode((width, height))
pygame.display.set_caption(title)
icon = pygame.image.load("icon.png")
pygame.display.set_icon(icon)
pygame.init()
return screen
def handle_inputs(self, keys, event):
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_d:
keys[0] = True
if event.key == pygame.K_a:
keys[1] = True
if event.type == pygame.KEYUP:
if event.key == pygame.K_d:
keys[0] = False
if event.key == pygame.K_a:
keys[1] = False
def game(self, screen, width, height):
global game_state
BLACK = (100, 100, 100)
keys = [False, False]
#Game loop
while game_state == 1:
#Process input (events)
for event in pygame.event.get():
#Check for Closing windows
if event.type == pygame.QUIT:
game_state = 2
self.handle_inputs(keys, event)
self.calc_deltatime()
self.player.move(keys, self.dt)
#Update
self.all_sprites.update()
#Draw / render
screen.fill(BLACK)
self.all_sprites.draw(screen)
pygame.display.update()
game = Main()
Since pygame.Rect is supposed to represent an area on the screen, a pygame.Rect object can only store integral data.
The coordinates for Rect objects are all integers. [...]
The fraction part of the coordinates gets lost when the movement is added to the coordinates of the Rect object. If this is done every frame, the position error will accumulate over time.
If you want to store object positions with floating point accuracy, you have to store the location of the object in separate variables respectively attributes and to synchronize the pygame.Rect object. round the coordinate and assign it to the location of the rectangle:
class Player(pygame.sprite.Sprite):
speed = 100
def __init__(self, WIDTH):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load("player.png")
self.rect = self.image.get_rect()
self.rect.center = (WIDTH / 2, 480)
self.x = self.rect.x
def move(self, keys, dt):
if keys[0]:
self.x += self.speed * dt
if keys[1]:
self.x -= self.speed * dt
self.rect.x = round(self.x)
This question already has answers here:
How to rotate an image(player) to the mouse direction?
(2 answers)
How do I rotate a sprite towards the mouse and move it?
(2 answers)
Closed 2 years ago.
I've been trying and trying, but basically I wanna make a tank game which has a tank that can turn itself by the mouse to fire bullets; when you turn your mouse to a direction, the sprite will follow exactly. the problem is, I can't turn the tank with any code, no matter what.
import os
import pygame
import math
pygame.init()
os.environ['SDL_VIDEO_WINDOW_POS'] = "%d,%d" % (0, 30)
icon = pygame.image.load('Sprite3.png')
pygame.display.set_icon((icon))
pygame.display.set_caption('DeMass.io')
class Tank(object): # represents the bird, not the game
def __init__(self):
""" The constructor of the class """
self.image = pygame.image.load('Sprite0.png')
# the bird's position
self.x = 0
self.y = 0
def handle_keys(self):
""" Handles Keys """
key = pygame.key.get_pressed()
dist = 1
if key[pygame.K_DOWN] or key[pygame.K_s]:
self.y += dist # move down
elif key[pygame.K_UP] or key[pygame.K_w]:
self.y -= dist # move up
if key[pygame.K_RIGHT] or key[pygame.K_d]:
self.x += dist # move right
elif key[pygame.K_LEFT] or key[pygame.K_a]:
self.x -= dist # move left
def draw(self, surface):
""" Draw on surface """
# blit yourself at your current position
surface.blit(self.image, (self.x, self.y))
w = 1900
h = 10000
screen = pygame.display.set_mode((w, h))
tank = Tank() # create an instance
clock = pygame.time.Clock()
connection_angle = 90
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit() # quit the screen
running = False
screen.fill((255, 255, 255))
tank.draw(screen)
pygame.display.update()
tank.handle_keys()
clock.tick(100)
You can use the atan2 function from the built-in math module to calcualte the angle between two coordinates,
and then rotate your sprite accordingly:
import pygame
from math import atan2, degrees
wn = pygame.display.set_mode((400, 400))
class Player(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface((30, 40), pygame.SRCALPHA)
self.image.fill((255, 0, 0))
self.rect = self.image.get_rect(topleft=(185, 180))
def point_at(self, x, y):
rotated_image = pygame.transform.rotate(self.image, degrees(atan2(x-self.rect.x, y-self.rect.y)))
new_rect = rotated_image.get_rect(center=self.rect.center)
wn.fill((0, 0, 0))
wn.blit(rotated_image, new_rect.topleft)
player = Player()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
elif event.type == pygame.MOUSEMOTION:
player.point_at(*pygame.mouse.get_pos())
pygame.display.update()
Output:
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.
so I was doing the exercise of python crash course 12-6. which places a ship on the left side of the screen and allows the player to move the ship up and down. Make the ship fire the bullet that travels right across the screen when the player presses the space-bar.
I've tried to print the length of the bullets, the animation runs which means it is recognizing that the button is being pressed and the bullets appear but don't move. The bullet appears but stays frozen. It seems the for loop has something to do with it.
I've tried to compare the Alian Invasion code three times which is explained in the chapter for this exercise, which sound stupid but i don't see anything obviously wrong to me.
I'm new to python and pygame and even to stackoverflow, any help will be highly appreciated.
The below is the main code to run the game.
import pygame
import sys
from sideways_shooter import SidewaysShooter
from stone import Stone
from settings import Settings
class SidewaysShooterGame:
def __init__(self):
pygame.init()
self.settings = Settings()
self.screen = pygame.display.set_mode(
(self.settings.screen_width, self.settings.screen_height))
pygame.display.set_caption("Sideways Shooter Game")
self.sideways_shooter = SidewaysShooter(self)
self.stones = pygame.sprite.Group()
def run_game(self):
while True:
self._check_events()
self.sideways_shooter.update()
self._stones_update()
self._update_screen()
def _stones_update(self):
self.stones.update()
for stone in self.stones.copy():
if stone.rect.left >= self.sideways_shooter.screen_rect.right:
self.stones.remove(stone)
def _check_events(self):
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
elif event.type == pygame.KEYDOWN:
self._check_keydown_events(event)
elif event.type == pygame.KEYUP:
self._check_keyup_events(event)
def _check_keydown_events(self, event):
if event.key == pygame.K_UP:
self.sideways_shooter.moving_up = True
elif event.key == pygame.K_DOWN:
self.sideways_shooter.moving_down = True
elif event.key == pygame.K_q:
sys.exit()
elif event.key == pygame.K_SPACE:
self._throw_stones()
def _check_keyup_events(self,event):
if event.key == pygame.K_UP:
self.sideways_shooter.moving_up = False
elif event.key == pygame.K_DOWN:
self.sideways_shooter.moving_down = False
def _throw_stones(self):
if len(self.stones) < self.settings.stones_allowed:
new_stone = Stone(self)
self.stones.add(new_stone)
def _update_screen(self):
self.screen.fill(self.settings.bg_color)
self.sideways_shooter.blitme()
for stone in self.stones:
stone.draw_stone()
pygame.display.flip()
if __name__ == '__main__':
ss_game = SidewaysShooterGame()
ss_game.run_game()
The below are the classes and methods that contains assets and attributes for the main code project.
sideway_shooter file
import pygame
class SidewaysShooter:
def __init__(self, ss_game):
self.screen = ss_game.screen
self.settings = ss_game.settings
self.screen_rect = ss_game.screen.get_rect()
self.image = pygame.image.load('images/resized_shooter_bmp_file.bmp')
self.rect = self.image.get_rect()
self.rect.midleft = self.screen_rect.midleft
self.y = float(self.rect.y)
self.moving_up = False
self.moving_down = False
def update(self):
if self.moving_up and self.rect.top > 0:
self.y -= self.settings.speed
if self.moving_down and self.rect.bottom < self.screen_rect.bottom:
self.y += self.settings.speed
self.rect.y = self.y
def blitme(self):
self.screen.blit(self.image, self.rect)
stone file
import pygame
from pygame.sprite import Sprite
class Stone(Sprite):
def __init__(self, ss_game):
super().__init__()
self.screen = ss_game.screen
self.settings = ss_game.settings
self.color = self.settings.stone_color
self.rect = pygame.Rect(0, 0, self.settings.stone_width,
self.settings.stone_height)
self.rect.midright = ss_game.sideways_shooter.rect.midright
self.x = float(self.rect.x)
def upate(self):
self.x += self.settings.stone_speed
self.rect.x = self.x
def draw_stone(self):
pygame.draw.rect(self.screen, self.color, self.rect)
settings file
class Settings:
def __init__(self):
self.screen_width = 1400
self.screen_height = 700
self.bg_color = (255, 255, 255)
self.speed = 1.5
self.stone_color = (60, 60, 60)
self.stone_width = 15
self.stone_height = 3
self.stone_speed = 1.0
self.stones_allowed = 3