Here is my code. How can I move my class Player sprite? Would I add an x,y to my def __init__? like def __init__(self, x, y)? Thanks for the answers,
import pygame as pg
WIDTH = 800
HEIGHT = 600
CLOCK = pg.time.Clock()
FPS = 60
GREEN = (0, 255, 0)
LIGHTBLUE = (20, 130, 230)
BGCOLOR = LIGHTBLUE
class Player(pg.sprite.Sprite):
def __init__(self, x, y):
pg.sprite.Sprite.__init__(self)
self.image = pg.Surface((50, 50))
self.image.fill(GREEN)
self.rect = self.image.get_rect()
self.rect.center = ((WIDTH / 2, HEIGHT / 2))
self.x = x
self.y = y
player = Player()
pg.init()
screen = pg.display.set_mode((WIDTH, HEIGHT))
pg.display.set_caption('The Moon Smiles Back')
running = True
while running:
for event in pg.event.get():
if event.type == pg.QUIT:
running = False
if event.type == pg.KEYDOWN:
if event.key == pg.K_ESCAPE:
running = False
all_sprites = pg.sprite.Group()
all_sprites.add(player)
all_sprites.update()
screen.fill(BGCOLOR)
all_sprites.draw(screen)
pg.display.flip()
CLOCK.tick(FPS)
pg.quit()
Add two attributes to the Player class to store the current velocity of the player. In the update method, add the velocities to the x and y attributes and then set the rect to the new position.
class Player(pg.sprite.Sprite):
def __init__(self, x, y):
pg.sprite.Sprite.__init__(self)
self.image = pg.Surface((50, 50))
self.image.fill(GREEN)
self.rect = self.image.get_rect()
self.rect.center = (x, y)
self.x = x
self.y = y
self.velocity_x = 0
self.velocity_y = 0
def update(self):
self.x += self.velocity_x
self.y += self.velocity_y
self.rect.center = (self.x, self.y)
To move the player to the right, set the player.velocity_x to the desired speed if the 'd' key is pressed (in this example), and back to 0 if the key is released. Do the same for the other directions.
if event.type == pg.KEYDOWN:
if event.key == pg.K_ESCAPE:
running = False
elif event.key == pg.K_d:
player.velocity_x = 3
elif event.type == pg.KEYUP:
if event.key == pg.K_d:
player.velocity_x = 0
Related
I am trying to build a simple "flappy bird" like game. I am trying to sort all the code into classes and methods. How do I fix this problem? Is it the code not working because of calling some method too early or is it because there's something missing? I would really love it if someone would try to explain to me.
sprites.py:
import pygame
class Player(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface((50, 50))
self.image.fill((255, 255, 0))
self.rect = self.image.get_rect()
self.rect.x = 0
self.rect.y = (700 / 2)
self.movex = 0
self.movey = 0
def control(self, x, y):
self.movex += x
self.movey += y
def update(self):
self.rect.x += self.movex
self.rect.y += self.movey
def animate(self):
pass
class Obstacle(pygame.sprite.Sprite):
def __init__(self, x, y, width, height):
pygame.sprite.Sprite.__init__(self)
self.x = x
self.y = y
self.width = width
self.height = height
main.py:
from sprites import *
import pygame
WIDTH = 700
HEIGHT = 700
class Game:
def __init__(self):
pygame.init()
self.screen = pygame.display.set_mode((WIDTH, HEIGHT))
self.clock = pygame.time.Clock()
self.score = 0
self.running = True
def new(self):
pass
def events(self):
self.game_on = True
for event in pygame.event.get():
if event.type == pygame.QUIT:
self.game_on = False
self.running = False
if event.type == pygame.KEYDOWN:
if event.type == pygame.K_UP:
self.croc.control(0, -20)
def update(self):
self.croc = Player()
self.all_sprites = pygame.sprite.Group()
self.all_sprites.add(self.croc)
self.all_sprites.update()
def draw(self):
self.screen.fill((0, 0, 0))
self.all_sprites.draw(self.screen)
pygame.display.flip()
game = Game()
while game.running:
game.clock.tick(60)
game.new()
game.events()
game.update()
game.draw()
Thank you
There are 2 mistakes. The Player object is recreated in every frame. Create the player in the constructor of Game rather than in the method update:
class Game:
def __init__(self):
# [...]
self.croc = Player() # <--- ADD
self.all_sprites = pygame.sprite.Group() # <--- ADD
self.all_sprites.add(self.croc) # <--- ADD
def update(self):
# self.croc = Player() # <--- DELETE
# self.all_sprites = pygame.sprite.Group() # <--- DELETE
# self.all_sprites.add(self.croc) # <--- DELETE
self.all_sprites.update()
There is a type in the event loop. You've to get the key from the .key attribute rather than the .type attriburte:
if event.type == pygame.K_UP:
if event.key == pygame.K_UP:
Complete code:
import pygame
class Player(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface((50, 50))
self.image.fill((255, 255, 0))
self.rect = self.image.get_rect()
self.rect.x = 0
self.rect.y = (700 / 2)
self.movex = 0
self.movey = 0
def control(self, x, y):
self.movex += x
self.movey += y
def update(self):
self.rect.x += self.movex
self.rect.y += self.movey
def animate(self):
pass
class Obstacle(pygame.sprite.Sprite):
def __init__(self, x, y, width, height):
pygame.sprite.Sprite.__init__(self)
self.x = x
self.y = y
self.width = width
self.height = height
WIDTH = 700
HEIGHT = 700
class Game:
def __init__(self):
pygame.init()
self.screen = pygame.display.set_mode((WIDTH, HEIGHT))
self.clock = pygame.time.Clock()
self.score = 0
self.running = True
self.croc = Player()
self.all_sprites = pygame.sprite.Group()
self.all_sprites.add(self.croc)
def new(self):
pass
def events(self):
self.game_on = True
for event in pygame.event.get():
if event.type == pygame.QUIT:
self.game_on = False
self.running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
self.croc.control(0, -20)
def update(self):
self.all_sprites.update()
def draw(self):
self.screen.fill((0, 0, 0))
self.all_sprites.draw(self.screen)
pygame.display.flip()
game = Game()
while game.running:
game.clock.tick(60)
game.new()
game.events()
game.update()
game.draw()
I am new to pygame and trying to develop a game in which the player moves with arrow keys and rotates around with the position of mouse (like mini miltia). But I am able to rotate the player but not able to move it around. It is only showing the player with rotation but it is not moving.
def rot_center(image, rect, angle):
rot_image = pygame.transform.rotate(image, angle)
rot_rect = rot_image.get_rect(center=rect.center)
return rot_image, rot_rect
class Player(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image_orig = load_image('player.png')
self.image = self.image_orig
self.rect = self.image.get_rect()
self.rect_orig = self.rect
self.mask = pygame.mask.from_surface(self.image)
self.x, self.y = int(pygame.display.Info().current_w / 2), int(pygame.display.Info().current_h / 2)
self.rect.topleft = self.x, self.y
self.health = 100
self.damage_done = 0
self.chspeed_x = 10
self.chspeed_y = 10
self.dir = 0
def rot_aim(self, tx, ty):
self.dir = (math.atan2(self.y - ty, self.x - tx) * 180 / PI)
self.image, self.rect = rot_center(self.image_orig, self.rect_orig, self.dir)
def move(self, dx, dy):
self.chspeed_x = dx
self.chspeed_y = dy
self.x = self.x + self.chspeed_x * math.cos(math.radians(270 - self.dir))
self.y = self.y + self.chspeed_y * math.cos(math.radians(270 - self.dir))
def main():
pygame.init()
screen = pygame.display.set_mode((800, 600))
clock = pygame.time.Clock()
FPS = 30
paused = False
player = Player()
player_s = pygame.sprite.Group()
player_s.add(player)
while not paused:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
if event.type == pygame.MOUSEMOTION:
mousepos = pygame.mouse.get_pos()
mouseX = mousepos[0]
mouseY = mousepos[1]
player.rot_aim(mousepos[1], mousepos[0])
if event.type == pygame.KEYDOWN:
if event.type == pygame.K_UP:
player.move(0, 10)
if event.type == pygame.K_DOWN:
player.move(0, -10)
if event.type == pygame.K_RIGHT:
player.move(10, 0)
if event.type == pygame.K_LEFT:
player.move(-10, 0)
player_s.draw(screen)
clock.tick(FPS)
pygame.display.flip()
You missed to update self.rect after rotating or moving the player. Actually the position of the player (self.x, self.y) is changed. But since self.rect is used to draw the player, this attribute has to be updated by the position. The position has to be round, because a pygame.Rect object stores integral values:
class Player(pygame.sprite.Sprite):
# [...]
def rot_aim(self, tx, ty):
self.dir = (math.atan2(self.y - ty, self.x - tx) * 180 / PI)
self.image, self.rect = rot_center(self.image_orig, self.rect_orig, self.dir)
self.rect.center = round(self.x), round(self.y) # <--- this is missing
def move(self, dx, dy):
self.chspeed_x = dx
self.chspeed_y = dy
self.x = self.x + self.chspeed_x * math.cos(math.radians(270 - self.dir))
self.y = self.y + self.chspeed_y * math.cos(math.radians(270 - self.dir))
self.rect.center= round(self.x), round(self.y) # <--- this is missing
Further more there is a typo. You have to compare event.key to the button rather than event.type
For instance:
if event.type == pygame.K_UP:
if event.key == pygame.K_UP:
# [...]
Anyway I recommend to use pygame.key.get_pressed() rather than the button events, to achieve a continuously and smooth movement.
Finally clear the background by screen.fill(0) before drawing the scene:
def main():
# [...]
while not paused:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
if event.type == pygame.MOUSEMOTION:
mousepos = pygame.mouse.get_pos()
mouseX = mousepos[0]
mouseY = mousepos[1]
player.rot_aim(mousepos[1], mousepos[0])
keys = pygame.key.get_pressed()
if keys[pygame.K_UP]:
player.move(0, -10)
if keys[pygame.K_DOWN]:
player.move(0, 10)
if keys[pygame.K_RIGHT]:
player.move(10, 0)
if keys[pygame.K_LEFT]:
player.move(-10, 0)
screen.fill(0)
player_s.draw(screen)
clock.tick(FPS)
pygame.display.flip()
I am currently making a game in Pygame, and would like to generate several platforms randomly throughout my screen. However, I can't seem to figure out how to create a group so that I can draw several sprites at once. I have tried using super.__init__(self) and also replacing self with (*Group) , yet it isn't working. I also have just tried to add it to a group. How should I make my group and how do I correctly add my sprite to it?
Here is the code (the sprite I want to add in is created here but not drawn):
######## basic setup
import pygame, sys, time, random, threading, tkinter, ctypes
from threading import Timer
from pygame.locals import *
from tkinter import *
pygame.init()
WINDOWHEIGHT = 720
WINDOWWIDTH = 1280
windowSurface = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT), 0, 32)
pygame.display.set_caption('Hitman Grandma | vB1.0 (prealpha)')
white = (255,255,255)
red = (255,0,0)
black = (0,0,0)
green = (0,255,0)
blue = (0,0,255)
cyan = (0,255,255)
lightgrey = (198,198,198)
windowSurface.fill(lightgrey)
pygame.display.update()
mainClock = pygame.time.Clock()
########## variables
level = 0
touching = False
global x_speed
x_speed = 0
y_speed = 0
leftallowed = True
rightallowed = True
hgturnright = True
hgjumpallowed = True
########### the grandma d'awesome murder sorts
hgimage = pygame.image.load('hgfinal.png')
hgimage.convert_alpha()
class HG(object):
def __init__(self,x,y,image):
self.image = image
self.rect = self.image.get_rect()
self.x = x
self.y = y
def draw(self):
windowSurface.blit(self.image,(self.x,self.y))
def move(self):
self.x += x_speed
self.y += y_speed
def topcollide(self,box):
if not self.rect.colliderect(box.rect):
global y_speed
if y_speed < 20:
y_speed += 1
elif y_speed == 20:
y_speed = 20
print('shhoooo')
elif self.rect.colliderect(box.rect):
y_speed = 0
print('flop')
hg = HG(0,0,hgimage)
########### land and boundary
lands = pygame.image.load('hgland1.png')
floorland = pygame.transform.scale(lands,(1280,50))
sideedge = pygame.Rect(0,0,1,720),pygame.Rect(1279,0,1,720)
topedge = pygame.Rect(0,0,1280,1)
class Floor(object):
def __init__(self,x,y,image):
self.image = image
self.x = x
self.y = y
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
def draw(self):
windowSurface.blit(self.image,(self.x,self.y))
class Ground(object):
def __init__(self,x,y,image):
self.image = image
self.x = x
self.y = y
self.rect = self.image.get_rect()
def draw(self):
windowSurface.blit(self.image,(self.x,self.y))
class Ground(object):
def __init__(self,x,y,image):
super.__init__(self)
self.image = image
self.x = x
self.y = y
self.rect = self.image.get_rect(topleft = (x,y))
def draw(self):
windowSurface.blit(self.image,(self.x,self.y))
floor = Floor(0,670,floorland)
platform1 = Ground((random.randint(0,800)),(random.randint(50,620)),lands)
########### WHILE
while True:
########### background
windowSurface.fill(lightgrey)
########### hg movement
for event in pygame.event.get():
if event.type == KEYDOWN:
if event.key == K_LEFT and hg.x > 0 and leftallowed:
x_speed = -4
hgturnright = False
if event.key == K_RIGHT and (hg.x + 36) < WINDOWWIDTH and rightallowed:
x_speed = 4
hgturnright = True
if event.key == K_UP and hgjumpallowed:
y_speed = -17
if event.type == KEYUP:
if event.key == K_RIGHT:
x_speed = 0
if event.key == K_LEFT:
x_speed = 0
if event.type == KEYDOWN:
########### ctrl+q
if event.key == K_q and pygame.key.get_mods() & pygame.KMOD_CTRL:
pygame.quit()
sys.exit()
exit
########### [x]
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
exit
########### drawing and .move()
floor.draw()
hg.draw()
hg.move()
hg.topcollide(floor)
########### technicals
pygame.display.update()
mainClock.tick(40)
and here is the class I want to use:
class Ground(object):
def __init__(self,x,y,image):
super.__init__(self)
self.image = image
self.x = x
self.y = y
self.rect = self.image.get_rect(topleft = (x,y))
def draw(self):
windowSurface.blit(self.image,(self.x,self.y))
platform1 = Ground((random.randint(0,800)),(random.randint(50,620)),lands)
Also, here are the two images to use:
Your classes should inherit from pygame.sprite.Sprite, so that they can be put into sprite groups, e.g. class Platform(pg.sprite.Sprite):. Don't forget to call the __init__ method of the parent class super().__init__(). Then create the sprite groups (all_sprites = pg.sprite.Group()) and the sprite instances and call the add method of the groups to add the sprite.
Then you just have to call all_sprites.update() and all_sprites.draw(screen) in the main loop.
from random import randrange
import pygame as pg
class Platform(pg.sprite.Sprite):
def __init__(self, x, y, width, height):
super().__init__()
self.image = pg.Surface((width, height))
self.image.fill(pg.Color('dodgerblue1'))
self.rect = self.image.get_rect(topleft=(x, y))
def main():
screen = pg.display.set_mode((640, 480))
clock = pg.time.Clock()
all_sprites = pg.sprite.Group() # This group that will contain all sprites.
# You probably want to add the platforms to a separate
# group as well, so that you can use it for collision detection.
platforms = pg.sprite.Group()
for _ in range(6): # Create six platforms at random coords.
platform = Platform(randrange(600), randrange(440), 170, 20)
platforms.add(platform)
all_sprites.add(platform)
done = False
while not done:
for event in pg.event.get():
if event.type == pg.QUIT:
done = True
all_sprites.update()
screen.fill((30, 30, 30))
all_sprites.draw(screen)
pg.display.flip()
clock.tick(30)
if __name__ == '__main__':
pg.init()
main()
pg.quit()
new to pygame and game programming in general, just wondered how I could get a camera to follow a car (nothing fancy) in a top down car game - think Micro Machines! I'm using Python 3.6, and have got a bike rotating, and moving around. I've kept the code here shorter but I do have a static image for reference if the camera worked!
Here's what I have:
import pygame, math, sys, random
from pygame.locals import *
display_width = 1280
display_height = 800
# Sets size of screen
screen = pygame.display.set_mode((display_width, display_height))
# Initialises clock
clock = pygame.time.Clock()
# Colours
white = (255,255,255)
black = (0,0,0)
class Entity(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
class VehicleSprite(Entity):
# Creates a vehicle class
MAX_FORWARD_SPEED = 10
MAX_REVERSE_SPEED = 2
ACCELERATION = 0.05
TURN_SPEED = 0.000000000001
def __init__(self, image, position):
Entity.__init__(self)
# Creates object instance off
pygame.sprite.Sprite.__init__(self)
self.src_image = pygame.image.load(image)
self.position = position
self.speed = self.direction = 0
self.k_left = self.k_right = self.k_down = self.k_up = 0
def update(self, time):
# SIMULATION
self.speed += (self.k_up +self.k_down)
if self.speed > self.MAX_FORWARD_SPEED:
self.speed = self.MAX_FORWARD_SPEED
if self.speed < -self.MAX_REVERSE_SPEED:
self.speed = -self.MAX_REVERSE_SPEED
# Degrees sprite is facing (direction)
self.direction += (self.k_right + self.k_left)
x, y = self.position
rad = self.direction * math.pi / 180
x += -self.speed*math.sin(rad)
y += -self.speed*math.cos(rad)
self.position = (x, y)
self.image = pygame.transform.rotate(self.src_image, self.direction)
self.rect = self.image.get_rect()
self.rect.center = self.position
class Background(pygame.sprite.Sprite):
def __init__(self, image_file, location):
pygame.sprite.Sprite.__init__(self) #call Sprite initializer
self.image = pygame.image.load(image_file)
self.rect = self.image.get_rect()
self.rect.left, self.rect.top = location
rect = screen.get_rect()
# Background
BackGround = Background('/home/pi/gametuts/images/backgrounds/bkg_img.png', [0, 0])
# Bike image load
bike = VehicleSprite('/home/pi/gametuts/images/BikePixelBig.png', rect.center)
bike_group = pygame.sprite.RenderPlain(bike)
# Ball image load
ball = VehicleSprite('/home/pi/gametuts/images/ironball.png', rect.center)
ball_group = pygame.sprite.RenderPlain(ball)
# Main game loop
def game_loop():
while 1:
#USER INPUT
# Sets frame rate
time = clock.tick(60)
for event in pygame.event.get():
if not hasattr(event, 'key'): continue
down = event.type == KEYDOWN
# Bike Input (Player 1)
if event.key == K_d: bike.k_right = down * -5
elif event.key == K_a: bike.k_left = down * 5
elif event.key == K_w: bike.k_up = down * 2
elif event.key == K_s: bike.k_down = down * -2
# Quit
elif event.key == K_ESCAPE: sys.exit(0)
#RENDERING
# Game background
screen.fill(white)
screen.blit(BackGround.image, BackGround.rect)
# Bike render
bike_group.update(time)
bike_group.draw(screen)
ball_group.update(time)
ball_group.draw(screen)
pygame.display.flip()
game_loop()
pygame.quit()
quit()
Thanks in advance!
The simplest way to implement a camera is to use a pygame.math.Vector2 as the camera, subtract the player velocity from it each frame and add it to the position of all game elements during the blitting.
import pygame as pg
from pygame.math import Vector2
class Player(pg.sprite.Sprite):
def __init__(self, pos, walls, *groups):
super().__init__(*groups)
self.image = pg.Surface((30, 50))
self.image.fill(pg.Color('dodgerblue'))
self.rect = self.image.get_rect(center=pos)
self.vel = Vector2(0, 0)
self.pos = Vector2(pos)
self.walls = walls
self.camera = Vector2(0, 0)
def update(self):
self.camera -= self.vel # Change the camera pos if we're moving.
# Horizontal movement.
self.pos.x += self.vel.x
self.rect.centerx = self.pos.x
# Change the rect and self.pos coords if we touched a wall.
for wall in pg.sprite.spritecollide(self, self.walls, False):
if self.vel.x > 0:
self.rect.right = wall.rect.left
elif self.vel.x < 0:
self.rect.left = wall.rect.right
self.pos.x = self.rect.centerx
self.camera.x += self.vel.x # Also move the camera back.
# Vertical movement.
self.pos.y += self.vel.y
self.rect.centery = self.pos.y
for wall in pg.sprite.spritecollide(self, self.walls, False):
if self.vel.y > 0:
self.rect.bottom = wall.rect.top
elif self.vel.y < 0:
self.rect.top = wall.rect.bottom
self.pos.y = self.rect.centery
self.camera.y += self.vel.y
class Wall(pg.sprite.Sprite):
def __init__(self, x, y, w, h, *groups):
super().__init__(*groups)
self.image = pg.Surface((w, h))
self.image.fill(pg.Color('sienna2'))
self.rect = self.image.get_rect(topleft=(x, y))
def main():
screen = pg.display.set_mode((640, 480))
clock = pg.time.Clock()
all_sprites = pg.sprite.Group()
walls = pg.sprite.Group()
for rect in ((100, 170, 90, 20), (200, 100, 20, 140),
(400, 60, 150, 100), (300, 470, 150, 100)):
walls.add(Wall(*rect))
all_sprites.add(walls)
player = Player((320, 240), walls, all_sprites)
done = False
while not done:
for event in pg.event.get():
if event.type == pg.QUIT:
done = True
elif event.type == pg.KEYDOWN:
if event.key == pg.K_d:
player.vel.x = 5
elif event.key == pg.K_a:
player.vel.x = -5
elif event.key == pg.K_w:
player.vel.y = -5
elif event.key == pg.K_s:
player.vel.y = 5
elif event.type == pg.KEYUP:
if event.key == pg.K_d and player.vel.x > 0:
player.vel.x = 0
elif event.key == pg.K_a and player.vel.x < 0:
player.vel.x = 0
elif event.key == pg.K_w and player.vel.y < 0:
player.vel.y = 0
elif event.key == pg.K_s and player.vel.y > 0:
player.vel.y = 0
all_sprites.update()
screen.fill((30, 30, 30))
for sprite in all_sprites:
# Add the player's camera offset to the coords of all sprites.
screen.blit(sprite.image, sprite.rect.topleft+player.camera)
pg.display.flip()
clock.tick(30)
if __name__ == '__main__':
pg.init()
main()
pg.quit()
Edit: Here's your code example with a camera. I've also tried to improve a few more things, for example the max(min(...)) trick to clamp the speed value. I'm not sure if the movement works as you want, but you can of course adjust it yourself. (I'd probably make even more modifications to the update method.)
import math
import random
import pygame
pygame.init()
screen = pygame.display.set_mode((1280, 800))
rect = screen.get_rect()
clock = pygame.time.Clock()
WHITE = pygame.Color('white')
# Load images globally and reuse them in your program.
# Also use the `.convert()` or `.convert_alpha()` methods after
# loading the images to improve the performance.
VEHICLE1 = pygame.Surface((40, 70), pygame.SRCALPHA)
VEHICLE1.fill((130, 180, 20))
VEHICLE2 = pygame.Surface((40, 70), pygame.SRCALPHA)
VEHICLE2.fill((200, 120, 20))
BACKGROUND = pygame.Surface((1280, 800))
BACKGROUND.fill((30, 30, 30))
class Entity(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
class VehicleSprite(Entity):
MAX_FORWARD_SPEED = 10
MAX_REVERSE_SPEED = 2
ACCELERATION = 0.05
TURN_SPEED = 0.000000000001
def __init__(self, image, position):
Entity.__init__(self)
self.src_image = image
self.image = image
self.rect = self.image.get_rect(center=position)
self.position = pygame.math.Vector2(position)
self.velocity = pygame.math.Vector2(0, 0)
self.speed = self.direction = 0
self.k_left = self.k_right = self.k_down = self.k_up = 0
def update(self, time):
# SIMULATION
self.speed += self.k_up + self.k_down
# To clamp the speed.
self.speed = max(-self.MAX_REVERSE_SPEED,
min(self.speed, self.MAX_FORWARD_SPEED))
# Degrees sprite is facing (direction)
self.direction += (self.k_right + self.k_left)
rad = math.radians(self.direction)
self.velocity.x = -self.speed*math.sin(rad)
self.velocity.y = -self.speed*math.cos(rad)
self.position += self.velocity
self.image = pygame.transform.rotate(self.src_image, self.direction)
self.rect = self.image.get_rect(center=self.position)
class Background(pygame.sprite.Sprite):
def __init__(self, image, location):
pygame.sprite.Sprite.__init__(self)
self.image = image
self.rect = self.image.get_rect(topleft=location)
def game_loop():
background = Background(BACKGROUND, [0, 0])
bike = VehicleSprite(VEHICLE1, rect.center)
ball = VehicleSprite(VEHICLE2, rect.center)
bike_group = pygame.sprite.Group(bike)
ball_group = pygame.sprite.Group(ball)
all_sprites = pygame.sprite.Group(bike_group, ball_group)
camera = pygame.math.Vector2(0, 0)
done = False
while not done:
time = clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
elif event.type == pygame.KEYDOWN:
# Bike Input (Player 1)
if event.key == pygame.K_d:
bike.k_right = -5
elif event.key == pygame.K_a:
bike.k_left = 5
elif event.key == pygame.K_w:
bike.k_up = 2
elif event.key == pygame.K_s:
bike.k_down = -2
elif event.key == pygame.K_ESCAPE:
done = True
elif event.type == pygame.KEYUP:
if event.key == pygame.K_d:
bike.k_right = 0
elif event.key == pygame.K_a:
bike.k_left = 0
elif event.key == pygame.K_w:
bike.k_up = 0
elif event.key == pygame.K_s:
bike.k_down = 0
camera -= bike.velocity
all_sprites.update(time)
screen.fill(WHITE)
screen.blit(background.image, background.rect)
for sprite in all_sprites:
screen.blit(sprite.image, sprite.rect.topleft+camera)
pygame.display.flip()
game_loop()
pygame.quit()
import pygame, random
pygame.init()
screen = pygame.display.set_mode((640, 480))
class Ship(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.screen = screen
self.image = pygame.image.load("ship.jpg")
self.image = self.image.convert()
self.rect = self.image.get_rect()
self.rect.center = (320, 400)
self.dx = 0
self.dy = 0
self.x = self.rect.centerx
self.y = self.rect.centery
def update(self):
self.checkBounds()
def checkBounds(self):
screen = self.screen
if self.x > screen.get_width():
self.x = screen.get_width()
if self.x < 0:
self.x = 0
class Missile(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load("missile.jpg")
self.image = self.image.convert()
self.rect = self.image.get_rect()
self.reset()
def update(self):
self.rect.centery += self.dy
if self.rect.top > screen.get_height():
self.reset()
def reset(self):
self.rect.bottom = 0
self.rect.centerx = random.randrange(0, screen.get_width())
self.dy = random.randrange(5, 10)
def main():
background = pygame.Surface(screen.get_size())
background.fill((0, 0, 0))
screen.blit(background, (0, 0))
ship = Ship()
missile = Missile()
allSprites = pygame.sprite.Group(missile, ship)
clock = pygame.time.Clock()
keepGoing = True
while keepGoing:
clock.tick(30)
for event in pygame.event.get():
if event.type == pygame.QUIT:
keepGoing = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
ship.rect.centerx = ship.rect.centerx-10
elif event.key == pygame.K_RIGHT:
ship.rect.centerx = ship.rect.centerx + 10
elif event.type == pygame.KEYUP:
ship.rect.centerx = ship.rect.centerx + 0
elif event.key == pygame.K_DOWN:
ship.rect.centerx = ship.rect.centerx - 0
if pygame.sprite.collide_rect(ship,missile) == True:
self.image = pygame.image.load("explosion.jpg")
allSprites.clear(screen, background)
allSprites.update()
allSprites.draw(screen)
pygame.display.flip()
pygame.quit()
if __name__ == "__main__":
main()
self.image = pygame.image.load("explosion.jpg")
This line is not part of any class. There is no self here. I guess you mean
ship.image = pygame.image.load("explosion.jpg")
or something similar. Might as well be
missile.image = pygame.image.load("explosion.jpg")