Making multiple balls move in pygame - python-2.7

I need to make the balls in this code move around randomly. I am not sure what I am doing wrong. I am new to programming and this may be badly coded so any help would be appreciated. Right now the code makes a character in the middle of the screen that you can move up or down and it makes one ball in the top left corner of the screen that does not move. I want multiple balls on the screen and eventually I want the balls to be moving around randomly and if they collide with the character you lose this simple game.
from pygame import *
import random
class Ball(sprite.Sprite):
def __init__(self, numballs, balls = []):
sprite.Sprite.__init__(self)
self.image = image.load('ball.png')
self.rect = self.image.get_rect()
self.numballs = numballs
self.balls = balls
def multipleBalls(self):
for count in range(self.numballs):
self.balls.append(dict)
self.balls[count] = {'x': 0, 'y': 0, 'xmove': random.randint(1,2), 'ymove':random.randint(1,2)}
def ballMove(self):
for count in range(self.numballs):
self.balls[count]['x'] = self.balls[count]['x'] + self.balls[count]['xmove']
self.balls[count]['y'] = self.balls[count]['y'] + self.balls[count]['ymove']
def ballsOnScreen(self):
for count in range(self.numballs):
self.screen.blit(self.image, (self.balls[count]['x'], self.balls[count]['y']))
def ballBarrier(self):
for count in range(self.numballs):
if self.balls[count]['x'] > 620:
self.balls[count]['xmove'] = random.randint(-2, 0)
if self.balls[count]['x'] < -10:
self.balls[count]['xmove'] = random.randint(0, 2)
if self.balls[count]['y'] > 470:
self.balls[count]['ymove'] = random.randint(-2, 0)
if self.balls[count]['y'] < -10:
self.balls[count]['ymove'] = random.randint(0, 2)
def manageBall(self):
self.multipleBalls()
self.ballsOnScreen()
self.ballMove()
self.ballBarrier()
class Character(sprite.Sprite):
def __init__(self, xy):
sprite.Sprite.__init__(self)
self.image = image.load('character.png')
self.rect = self.image.get_rect()
self.rect.centerx, self.rect.centery = xy
self.movementspeed = 1
self.velocity = 0
def down(self):
self.velocity += self.movementspeed
def up(self):
self.velocity -= self.movementspeed
def characterMove(self, dy):
if self.rect.bottom + dy > 480:
self.rect.bottom = 480
elif self.rect.top + dy < 0:
self.rect.top = 0
else:
self.rect.y += dy
def update(self):
self.characterMove(self.velocity)
class Game(object):
def __init__(self):
init()
key.set_repeat(1, 30)
self.screen = display.set_mode((640, 480))
self.clock = time.Clock()
display.set_caption('Game')
event.set_allowed([QUIT, KEYDOWN, KEYUP])
self.background = Surface((640, 480))
self.background.fill((0,0,0))
self.screen.blit(self.background, (0,0))
display.flip()
self.sprites = sprite.RenderUpdates()
self.character = Character((320, 240))
self.sprites.add(self.character)
self.ball = Ball(5)
self.sprites.add(self.ball)
def run(self):
running = True
while running == True:
self.clock.tick(60)
running = self.handleEvents()
display.set_caption('game %d fps' % self.clock.get_fps())
for sprite in self.sprites:
sprite.update()
self.sprites.clear(self.screen, self.background)
dirty = self.sprites.draw(self.screen)
display.update(dirty)
self.ball.manageBall()
def handleEvents(self):
for e in event.get():
if e.type == QUIT:
return False
elif e.type == KEYDOWN:
if e.key == K_ESCAPE:
return False
if e.key == K_UP:
self.character.up()
if e.key == K_DOWN:
self.character.down()
return True
def main():
game = Game()
game.run()
main()

I've never used the Sprite class before so this was a good exercise. :)
I fixed your code, just change the image paths back to your icon locations and you should be good to go. The print statements might need reformatting if you're running an older version of Python.
I take out the forced call to the Sprite init method in the Ball and Character classes, it won't let me add them to the game.sprites render group. Not sure why.
I'm running Python 3.2.2 and Pygame 1.9.2pre so YMMV. :)
Controls:
UP / DOWN = Move your dude.
R = add a new, random ball.
from pygame import *
import random
SCREEN_WIDTH = 640
SCREEN_HEIGHT = 480
FPS = 60
class Ball(sprite.Sprite):
def __init__(self, xy = (0,0), xm = 0, ym = 0):
sprite.Sprite.__init__(self)
self.img_load('evil_balloon_32x32.png')
self.rect.centerx, self.rect.centery = xy
self.xmove = xm
self.ymove = ym
def update(self):
self.move()
self.ballBarrier()
def move(self):
self.rect.x += self.xmove
self.rect.y += self.ymove
def img_load(self, filename):
self.image = image.load(filename)
self.rect = self.image.get_rect()
def ballBarrier(self):
"""
Checks to make sure ball is within bounds, adjusts movement speed if it's not
"""
if self.rect.right > SCREEN_WIDTH:
self.xmove = random.randint(-2, 0)
if self.rect.left < 0:
self.xmove = random.randint(0, 2)
if self.rect.bottom > SCREEN_HEIGHT:
self.ymove = random.randint(-2, 0)
if self.rect.top < 0:
self.ymove = random.randint(0, 2)
class ball_manager():
def __init__(self, numballs = 5, balls = []):
self.blist = balls
if numballs > 0:
self.multipleBalls(numballs) # moved this here so balls get init'd only once
def update(self):
"""
Update position of all balls
"""
for ball in self.blist:
self.ballMove(ball)
def add_ball(self, xy = (0,0), xm = 0, ym = 0):
self.blist.append(Ball(xy, xm, ym)) # appends a random ball
def multipleBalls(self, numballs):
for i in range(numballs):
self.add_ball((random.randint(0, SCREEN_WIDTH),
random.randint(0, SCREEN_HEIGHT)),
random.randint(-2,2),
random.randint(-2,2))
class Character(sprite.Sprite):
def __init__(self, xy):
sprite.Sprite.__init__(self)
self.img_load()
self.rect.centerx, self.rect.centery = xy
self.movementspeed = 1
self.velocity = 0
def down(self):
self.velocity += self.movementspeed
def up(self):
self.velocity -= self.movementspeed
def characterMove(self, dy):
if self.rect.bottom + dy > SCREEN_HEIGHT:
self.rect.bottom = SCREEN_HEIGHT
self.velocity = 0
elif self.rect.top + dy < 0:
self.rect.top = 0
self.velocity = 0
else:
self.rect.y += dy
def update(self):
self.characterMove(self.velocity)
def img_load(self):
self.image = image.load("scary_clown_32x32.png")
self.rect = self.image.get_rect()
class Game(object):
def __init__(self):
init()
key.set_repeat(1, 30)
self.screen = display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
self.clock = time.Clock()
display.set_caption('Game')
event.set_allowed([QUIT, KEYDOWN, KEYUP])
self.background = Surface((SCREEN_WIDTH, SCREEN_HEIGHT))
self.background.fill((0,0,0))
self.screen.blit(self.background, (0,0))
display.flip()
self.sprites = sprite.RenderUpdates()
self.character = Character((SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2))
self.sprites.add(self.character)
self.balls = ball_manager(5)
for ball in self.balls.blist:
self.sprites.add(ball)
def run(self):
running = True
while running == True:
self.clock.tick(FPS)
running = self.handleEvents()
display.set_caption('game %d fps' % self.clock.get_fps())
self.sprites.clear(self.screen, self.background)
for sprite in self.sprites:
sprite.update()
dirty = self.sprites.draw(self.screen)
display.update(dirty)
def handleEvents(self):
for e in event.get():
if e.type == QUIT:
return False
elif e.type == KEYDOWN:
if e.key == K_ESCAPE:
return False
if e.key == K_UP:
self.character.up()
if e.key == K_DOWN:
self.character.down()
if e.key == K_r:
self.sprites.add(Ball((random.randint(0, SCREEN_WIDTH),
random.randint(0, SCREEN_HEIGHT)),
random.randint(-2,2),
random.randint(-2,2)))
return True
def main():
game = Game()
game.run()
quit()
main()
sys.exit()

Related

Pygame sprite file error

Disclaimer: I'm only 10 years old so please be patient with me please :D
So I'm working on this game in pygame where you play as a balloon and you have to avoid obstacles and collect points. The points add 10 to your score and the obstacles restart your game. You use the arrow keys to move. It's based off Ski-Free. But whenever I run it I don't get an error in my script, but an error in the sprite.py file that pygame comes with. For info, I use Mac OSX Sierra as my OS and IDLE 2.712 as my shell. I use python 2. So, here's my error:
Traceback (most recent call last):
File "/Users/------------/Desktop/Sky Balloon.py", line 75, in <module>
create_map()
File "/Users/------------/Desktop/Sky Balloon.py", line 58, in create_map
obstacles.add(obstacles)
File "/usr/local/lib/python2.7/site-packages/pygame/sprite.py", line 142, in add
self.add(*group)
TypeError: add() argument after * must be an iterable, not ObstacleClass
P.S. I did cover up my but the number of characters is still the same.
Now here's my actual game script. (Sky Balloon.py)
import pygame, sys, random
baloon_images = ["Baloon_gif.gif", "pop.gif"]
class BaloonClass(pygame.sprite.Sprite):
def __init__(self):f
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load("Baloon_gif.gif")
self.rect = self.image.get_rect()
self.rect.center = [320, 100]
self.angle = 0
def turn(self, direction):
self.angle = self.angle + direction
if self.angle < -2: self.angle = -2
if self.angle > 2: self.angle = 2
center = self.rect.center
self.image = pygame.image.load(baloon_images[self.angle])
self.rect = self.image.get_rect()
self.rect.center = center
speed = [self.angle, 6 - abs(self.angle) * 2]
return speed
def move(self, speed):
self.rect.centerx = self.rect.centerx + speed[0]
if self.rect.centerx < 20: self.rect.centerx = 20
if self.rect.centerx > 620: self.rect.centerx = 620
class ObstacleClass(pygame.sprite.Sprite):
def __init__(self, image_file, location, type):
pygame.sprite.Sprite.__init__(self)
self.image_file = image_file
self.image = pygame.image.load(image_file)
self.rect = self.image.get_rect()
self.rect.center = location
self.type = type
self.passed = False
def update(self):
global speed
self.rect.centery -= speed[1]
if self.rect.centery < -32:
self.kill()
def create_map():
global obstacles
locations = []
for i in range(10):
row = random.randint(0, 9)
col = random.randint(0, 9)
location = [col * 64 + 20, row * 64 + 20 + 640]
if not (location in locations):
locations.append(location)
type = random.choice(["cloud", "point"])
if type == "cloud": img = "cloud.png"
elif type == "point": img = "Points.png"
obstacles = ObstacleClass(img, location, type)
obstacles.add(obstacles)
def animate():
screen.fill([0, 255, 255])
obstacles.draw(screen)
screen.blit(baloon.image, baloon.rect)
screen.blit(score_text, [10, 10])
pygame.display.flip()
pygame.init()
screen = pygame.display.set_mode([640, 640])
clock = pygame.time.Clock()
baloon = BaloonClass()
speed = [0, 6]
obstacles = pygame.sprite.Group()
map_position = 0
points = 0
create_map()
font = pygame.font.Font(None, 50)
running = True
while running:
clock.tick(30)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
speed = baloon.turn(-1)
elif event.key == pygame.K_RIGHT:
speed = baloon.turn(1)
baloon.move(speed)
map_position += speed[1]
if map_position >=640:
create_map()
map_position = 0
hit = pygame.sprite.spritecollide(baloon, obstacles, False)
if hit:
if hit[0].type == "cloud" and not hit[0].passed:
points = points - 100
baloon.image = pygame.image.load("pop.gif")
animate()
pygame.time.delay(1000)
baloon.image = pygame.image.load("Baloon_gif.gif")
baloon.angle = 0
speed = [0, 6]
hit[0].passed = True
elif hit[0].type == "point" and not hit[0].passed:
points += 10
hit[0].kill()
obstacles.update()
score_text = font.render("Score: " +str(points), 1, (0, 0, 0))
animate()
pygame.quit
Thank You!
obstacles.add(obstacle) not obstacles.add(obstacles) (extra s)

Pygame : Controlling two sprites

import pygame, sys
pygame.init()
surf = pygame.display.set_mode((1280, 720))
black = (0, 0, 0)
surf.fill(black)
fps_clock = pygame.time.Clock()
pygame.display.flip()
class Player(pygame.sprite.Sprite):
def __init__(self, name, xx, yy):
self.name = name
self.image = pygame.Surface((22, 22))
self.image.fill((130, 100, 200))
self.rect = self.image.get_rect(x = xx, y = yy)
self.x_vel = 0
self.y_vel = 0
def speed(self, speed):
self.speed = speed
def update(self, keys):
if keys[pygame.K_DOWN]:
self.y_vel = 3
elif keys[pygame.K_UP]:
self.y_vel = -3
else:
self.y_vel = 0
if keys[pygame.K_LEFT]:
self.x_vel = -3
elif keys[pygame.K_RIGHT]:
self.x_vel = 3
else:
self.x_vel = 0
self.rect.x += self.x_vel
self.rect.y += self.y_vel
def update1(self, keys):
if keys[pygame.K_s]:
self.y_vel = 3
elif keys[pygame.K_w]:
self.y_vel = -3
else:
self.y_vel = 0
if keys[pygame.K_a]:
self.x_vel = -3
elif keys[pygame.K_d]:
self.x_vel = 3
else:
self.x_vel = 0
self.rect.x += self.x_vel
self.rect.y += self.y_vel
def draw(self, surface):
surf.fill(black)
surface.blit(self.image, self.rect)
player = Player('Tank', 100, 300)
player2 = Player('Tank2', 200, 500)
def main():
while True:
keys = pygame.key.get_pressed()
player.draw(surf)
player2.draw(surf)
player.update(keys)
player2.update1(keys)
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
pygame.display.update()
fps_clock.tick(60)
main()
Trying to create 2 sprites, one which can be controlled using the arrow keys, the other using the WASD keyset. It only blits one sprite on the image, which can be controlled using WASD. The other can be controlled by arrow keys if player2.update1(keys) is commented. Please don't beat down on me that much, still kind of a novice.
The problem is that you fill the whole screen with black before you draw each player. That means that when player two is drawn player one gets drawn over with black. Remove line 52 surf.fill(black) from def draw() and add it to the main game loop so that it is only called once.
def main():
while True:
surf.fill(black)

Check collision between two imported pictures

I'm trying to recreate a game, however all I need is to create a game-over feature that occurs when the player collides or fails to jump over the rock. I've tried to do the check collision yet the player is passing through. What should I do or change in order to display the game over screen when the player collides with the rock? Here is my sample code:
#--- Player Definition
class Player(pygame.sprite.Sprite):
#- Constructor
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.playing = False
self.image = pygame.image.load("bcquestchar.png")
self.rect = self.image.get_rect()
self.color = BLUE
self.rect.x = 50
self.rect.y = 210
self.goalY= 450
self.gameover = False
#- Allows Player to Jump
def jump(self):
self.goalY -= 25
#- Imports & Displays player_image
def draw(self, screen):
screen.blit(player_image, [self.rect.x, self.rect.y])
#--- Rock definition
class Rock(pygame.sprite.Sprite):
#- Constructor
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load("bcrocks.png")
self.rect = self.image.get_rect()
self.rect.x = random.randrange (0, 200)
self.rect.y = 335
#- Moves Rock
def move(self):
self.rect.x -= 3
#- Imports & Displays rock_image
def draw(self, screen):
screen.blit(self.image, [self.rect.x + 700, self.rect.y])
# Loop until user closes pygame
done = False
# How fast the screen updates
clock = pygame.time.Clock()
# Creates player
rock = Rock()
player = Player()
obstacles = pygame.sprite.Group()
obstacles.add(rock)
if pygame.sprite.spritecollide(player, obstacles, False):
player.gameover = True
#----- Main Program Loop -----#
while not done:
#movesound.play()
#- Calls in draw_background function
draw_background (screen, 0, 0)
#- Tracks Events
speed = 1
#--- Main Event Loop
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = False
#- User is playing when M1 is clicked
elif event.type == pygame.MOUSEBUTTONDOWN:
player.playing = True
#- User jumps when playing and has not lost
if(player.gameover == False and player.playing == True):
player.jump()
#- Is the player playing?
if(player.playing == True):
# Jump up when the up arrow is pressed
if event.type == pygame.MOUSEBUTTONDOWN:
currently_jumping = True
going_up = True
#hopsound.play()
if currently_jumping == True:
if player.rect.y < 188:
going_up = False
elif going_up == False and player.rect.y > 215:
currently_jumping = False
if going_up:
player.rect.y -= 2
elif going_up == False:
player.rect.y += 2
elif currently_jumping == False:
if(player.rect.y > 600 or player.rect.y < 0):
player.gameover = True
if(player.rect.y < 210):#player.goalY):
player_moving_up = False
elif(player.rect.y > 210):#player.goalY):
player_moving_up = True
if player_moving_up == True or player_moving_up == True:
player.rect.y += 1
player.rect.y -= 1
player.goalY += 3
if(timer3 > 120):
timer3 = 0
if(player.playing == True and player.gameover == False):
score += 30
#--- Draw and Move Rocks
for rock in obstacles:
rock.draw(screen)
if(player.gameover == False):
rock.move()
rock.draw(screen)
#rock.checkCollision(player.x, player.y)
if pygame.sprite.spritecollide(player, obstacles, False):
obstacles.remove(rock)
#----- Gameover
if(player.gameover == True):
player.goalY = 600
font = pygame.font.SysFont('Ariel', 50, True, False)
text = font.render("Game Over", True, WHITE)
screen.blit(text, [150, 100])
Code edited
Make Rock() also a pygame.sprite.Sprite class and if possible, put in a pygame.sprite.Group(). In that case, you can use if pygame.sprite.spritecollide() to check for detection:
rock = Rock()
player = Player()
obstacles = pygame.sprite.Group()
obsatcles.add(rock)
if pygame.sprite.spritecollide(player, obstacles, False):
pass #Do something
The good thing about using pygame.sprite.Group() is that you can use that to help detect collisions with the player and any other obstacle. Let's assume you have three items in obstacles, in which they are all rock's:
for rock in obstacles:
if pygame.sprite.spritecollide(player, obstacles, False):
obstacles.remove(rock) #Removes the obstacle
Put the group outside the sprite classes and before the while loop.
For the rock, use this in your init function:
self.rect = self.image.get_rect()
So it would be:
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load("filename.png")
self.rect = pygame.image.get_rect()
Then add this to your while loop:
for rock in obstacles:
rock.move()
rock.draw()
Your final class (excluding the last two functions) would be:
class Rock(pygames.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load("bcrocks.png")
self.rect = self.image.get_rect()
self.rect.x = random.randrange (0, 200)
self.rect.y = 335

Can not to draw all rectangles on the list

The problem is next, I have a list "enemy" and I am adding rectangles to it. After I am finished adding rectangles I need everything on the list to be drawn using the .draw() function that is part of the Enemy class.
# Colour
# Created by Niktia Kotter
#!/usr/bin/env python
import pygame, sys, random, time
from pygame.locals import*
# set up pygame
pygame.init()
FPS=60
fpsclock = pygame.time.Clock()
# R G B
WHITE = (255, 255, 255)
GREEN = (78, 255, 87)
YELLOW = (241, 255, 0)
BLUE = (80, 255, 239)
PURPLE = (203, 0, 255)
RED = (237, 28, 36)
SCREEN_W = 800
SCREEN_H = 480
SCREEN = pygame.display.set_mode((SCREEN_W,SCREEN_H),0,32)
snapMult = SCREEN_W / 5
pos0 = 0
pos1 = snapMult
pos2 = pos1 + snapMult
pos3 = pos2 + snapMult
pos4 = pos3 + snapMult
# set up calsses
class Actor:
def __init__ (self,sizeX,sizeY,colour,positionX,positionY):
self.sizeX = sizeX
self.sizeY = sizeY
self.colour = colour
self.positionX = positionX
self.positionY = positionY
def move(self, dx, i):
self.positionX += dx
self.location = i
def draw(self):
pygame.draw.rect(SCREEN, self.colour, (self.positionX, self.positionY, self.sizeX, self.sizeY))
return
class Enemy:
def __init__ (self,sizeX,sizeY,colour,positionX,positionY):
self.sizeX = sizeX
self.sizeY = sizeY
self.colour = colour
self.positionX = positionX
self.positionY = positionY
def move(self, dy, i):
self.positionY += dy
self.location = i
def draw(self):
pygame.draw.rect(SCREEN, self.colour, (self.positionX, self.positionY, self.sizeX, self.sizeY))
return
class Capture(object):
def __init__(self):
self.caption = pygame.display.set_caption('Space Invaders')
self.screen = SCREEN
self.startGame = True
self.gameOver = False
self.enemyCount = 0
def main(self):
clock = pygame.time.Clock()
actor =[]
enemy =[]
#enemy.append(Enemy(snapMult/20,snapMult/20,RED,pos1,SCREEN_H/2))
#print(enemy, sep='\n')
actor.append(Actor(snapMult,snapMult/2,RED,pos2,SCREEN_H-(snapMult/2)))
while True:
if self.startGame:
SCREEN.fill(WHITE)
actor[0].draw()
if self.enemyCount != 5 or self.enemyCount > 5:
num = random.randint(1, 5)
if num == 0:
print (0)
enemy.append(Enemy(snapMult/20,snapMult/20,RED,pos0,SCREEN_H/2))
if num == 1:
print (1)
enemy.append(Enemy(snapMult/20,snapMult/20,RED,pos1,SCREEN_H/2))
if num == 2:
print (2)
enemy.append(Enemy(snapMult/20,snapMult/20,RED,pos2,SCREEN_H/2))
if num == 3:
print (3)
enemy.append(Enemy(snapMult/20,snapMult/20,RED,pos3,SCREEN_H/2))
if num == 4:
print (4)
enemy.append(Enemy(snapMult/20,snapMult/20,RED,pos4,SCREEN_H/2))
print(enemy, sep='\n')
#for i in range(10):
# x = enemy[i]
# x.draw()
#for Enemy in enemy:
# Enemy.draw()
self.enemyCount += 1
for event in pygame.event.get():
if actor[0].positionX != pos4 and (event.type == KEYDOWN) and (event.key == K_d):
actor[0].move(snapMult,0)
if actor[0].positionX != pos0 and(event.type == KEYDOWN) and (event.key == K_a):
actor[0].move(-snapMult,0)
if event.type == QUIT:
pygame.quit()
sys.exit()
pygame.display.update()
fpsclock.tick(FPS)
if __name__ == '__main__':
game = Capture()
game.main()
Use a simple for loop:
for e in enemy:
e.draw()
Another way is to let your classes inherit from Sprite, and use a Group instead of an ordinay list, so you can use the draw() function of the Group.
Also, I don't think you want to call move on every event. You usually update the game state once per loop iteration, since e.g. moving the mouse generates a lot of events.

Pygame - AttributeError: 'int' object has no attribute 'y'

Hello I am currently working on a game in pygame and I am now trying to add a ground, gravity and jump. When I run the code I get an attribute error. Please help if you have a fix, here is the code:
import pygame, sys, time
from pygame.locals import *
pygame.init()
# A few variables
zx = 320
zy = 320
x = 25
y = 320
velX = 0
velY = 0
gravity = .50
ground = 720
clock = pygame.time.Clock()
# Screen
size = 1280, 720
screen = pygame.display.set_mode(size)
pygame.display.set_caption('Moon Survival!')
# Moon
moon = pygame.image.load('images/arena2.jpg')
pygame.display.update()
# Player
class Player(pygame.sprite.Sprite):
global gravity
def __init__(self, x, y):
# Player dimensions and position
self.x = x
self.y = y
self.width = 80
self.height = 80
# Player image and animation
self.i0 = pygame.image.load('images/soldier.png')
self.i1 = pygame.image.load('images/soldier2.png')
self.timeTarget = 10
self.timeNum = 0
self.currentImage = 0
# Jump and gravity
self.vSpeed = 1
self.jumpForce = 8
self.maxVspeed = 3
self.isJumping = False
# Jump inputs
def getInput(self):
keys = pygame.key.get_pressed()
if keys[pygame.K_SPACE]:
if not self.isJumping:
self.isJumping = True
# PLayer updates
def update(self):
# Jumping
self.getInput()
self.vSpeed += gravity
if self.vSpeed > self.maxVspeed:
self.vSpeed = self.maxVspeed
self.y += self.vSpeed
if self.y >= ground.y:
self.vSpeed = 0
self.y = ground.y
self.isJumping = False
if self.isJumping:
self.vSpeed += -self.jumpForce
# Animations
#self.timeNum += 1
if (self.timeNum == self.timeTarget):
if (self.currentImage == 0):
self.currentImage = 0
else:
self.currentImage = 0
self.timeNum = 0
self.render()
# Player rendering
def render(self):
if (self.currentImage == 0):
screen.blit(self.i0, (self.x, self.y))
#else:
#screen.blit(self.i1, (self.x, self.y))
# Zombies
zombie = pygame.image.load('images/zombie.png')
pygame.display.update()
# Sprite variables
player = Player(25, 320)
# Game loop
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
# Movement
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_a:
velX = -5
if event.key == pygame.K_d:
velX = +5
if event.type == pygame.KEYUP:
if event.key == pygame.K_a:
velX = 0
if event.key == pygame.K_d:
velX = 0
# Image blitting
screen.blit(moon, (0,0))
screen.blit(zombie, (zx, zy))
# Movement variables
player.x += velX
player.y += velY
player.update()
# Screen wrap
if player.x >= 1240:
player.x = 1
if player.x <= 0:
player.x = 1240
# Display updating
clock.tick(75)
pygame.display.update()
Any help will be greatly appreciated, thank you.
In some places you try to use int value as object:
ground = 720
self.y = ground.y # error !!!
ground is number int(integer) not object with .y
You could use pygame.Rect()
ground = pygame.Rect(0, 750, 0, 0) # (x, y, width, heigh)
and then you can use ground.x, ground.y, and others - see pygame.Rect().
.
btw: you should move #Movement code, # Movement variablescode, # Screen wrap code into Player class as functions and call that functions in main loop - to make main loop more readable.
# Movement variablescode, # Screen wrap code could be in player.update
# Movement code could be in Player class as event_handler(self, event)
def event_handler(self, event):
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_a:
velX = -5
elif event.key == pygame.K_d:
velX = +5
elif event.type == pygame.KEYUP:
if event.key in (pygame.K_a, pygame.K_d):
velX = 0
(you can use elif as above)
Now you can use this in main loop player.event_handler(event)
EDIT:
I made many modifications in your code - but I had no time to finish it.
Player still doesn't jump. But you have 10 moving zombies, pause (press P) and all in classes.
import pygame
import random
# Player
class Player(pygame.sprite.Sprite):
def __init__(self, x, y, gravity):
# Player dimensions and position
self.gravity = gravity
# Player image and animation
self.images = []
self.images.append(pygame.image.load('images/soldier.png'))
self.images.append(pygame.image.load('images/soldier2.png'))
#~ self.images.append(pygame.image.load('ball1.png'))
#~ self.images.append(pygame.image.load('ball2.png'))
self.maxImage = len(self.images)
self.currentImage = 0
#~ self.rect = pygame.Rect(x, y, 80, 80)
self.rect = self.images[0].get_rect()
self.rect.x = x
self.rect.y = y
self.timeTarget = 10
self.timeNum = 0
self.velX = 0
self.velY = 0
# Jump and gravity
self.vSpeed = 1
self.jumpForce = 8
self.maxVspeed = 3
self.isJumping = False
# Jump inputs
def handle_events(self, event):
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
if not self.isJumping:
self.isJumping = True
elif event.key == pygame.K_a:
self.velX = -5
elif event.key == pygame.K_d:
self.velX = +5
elif event.type == pygame.KEYUP:
if event.key in (pygame.K_a, pygame.K_d):
self.velX = 0
print "isJumping:", self.isJumping
# PLayer updates
def update(self, ground):
# Jumping
self.vSpeed -= self.gravity
if self.vSpeed > self.maxVspeed:
self.vSpeed = self.maxVspeed
self.rect.y -= self.vSpeed
if self.isJumping:
self.vSpeed -= self.jumpForce
if self.rect.bottom >= ground.y:
self.vSpeed = 0
self.rect.bottom = ground.y
self.isJumping = False
# Animations
if self.timeNum == self.timeTarget:
self.currentImage += 1
if self.currentImage >= self.maxImage:
self.currentImage = 0
self.timeNum = 0
self.rect.centerx += self.velX
self.rect.centery += self.velY
# Screen wrap
if self.rect.right > 1280:
self.rect.left = 0
elif self.rect.left < 0:
self.rect.right = 1280
# Player rendering
def render(self, surface):
surface.blit(self.images[self.currentImage], self.rect)
#----------------------------------------------------------------------
class Zombie():
def __init__(self, x, y):
self.image = pygame.image.load('images/zombie.png')
#~ self.image = pygame.image.load('ball2.png')
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
self.direction_left = True
def update(self, surface_rect):
if self.direction_left:
self.rect.x -= 1
if self.rect.left <= surface_rect.left:
self.direction_left = not self.direction_left
else:
self.rect.x += 1
if self.rect.right >= surface_rect.right:
self.direction_left = not self.direction_left
def render(self, surface):
surface.blit(self.image, self.rect)
#----------------------------------------------------------------------
class Background():
def __init__(self):
self.image = pygame.image.load('images/arena2.jpg')
#~ self.image = pygame.image.load('background.jpg')
self.rect = self.image.get_rect()
def render(self, surface):
surface.blit(self.image, self.rect)
#----------------------------------------------------------------------
class Game():
def __init__(self):
pygame.init()
# A few variables
self.gravity = .50
self.ground = pygame.Rect(0, 720, 0, 0)
# Screen
size = (1280, 720)
self.screen = pygame.display.set_mode(size)
pygame.display.set_caption('Moon Survival!')
# Moon / Background
self.moon = Background()
# Zombies
self.zombies = []
for i in range(10):
self.zombies.append( Zombie(random.randint(0,1280), random.randint(0,720)) )
# Player
self.player = Player(25, 320, self.gravity)
# Font for text
self.font = pygame.font.SysFont(None, 72)
# Pause - center on screen
self.pause_text = self.font.render("PAUSE", -1, (255,0,0))
self.pause_rect = self.pause_text.get_rect(center = self.screen.get_rect().center)
def run(self):
clock = pygame.time.Clock()
# "state machine"
RUNNING = True
PAUSED = False
GAME_OVER = False
# Game loop
while RUNNING:
# (all) Events
for event in pygame.event.get():
if event.type == pygame.QUIT:
RUNNING = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
RUNNING = False
elif event.key == pygame.K_p:
PAUSED = not PAUSED
# Player/Zomies events
if not PAUSED and not GAME_OVER:
self.player.handle_events(event)
# (all) Movements / Updates
if not PAUSED and not GAME_OVER:
self.player.update(self.ground)
for z in self.zombies:
z.update(self.screen.get_rect())
# (all) Display updating
self.moon.render(self.screen)
for z in self.zombies:
z.render(self.screen)
self.player.render(self.screen)
if PAUSED:
self.screen.blit(self.pause_text, self.pause_rect)
pygame.display.update()
# FTP
clock.tick(75)
# --- the end ---
pygame.quit()
#---------------------------------------------------------------------
Game().run()