How can I go back and forth between modules in pygame? - python

I'm trying to make a Home Screen for two games in pygame, I changed the first game's name to module1 in the code Im providing and the Home Screen to Mainscreen
module1 is already done and now I'm just trying to get the Main Menu script to import the maingame when I click on the play button that I already have on the screen display, then when I finish the game (health reaches 0) , if I want to go back to the Main Menu I should just click anywhere on the "game over" screen that should appear when health reaches 0 or press escape.
here is what I tried:
this is the whole game script, the game loop is at the end of the script and sorry for how messy it is:
# Pygame skeleton
import pygame
import math
import random
import sys
import os
pygame.init()
pygame.mixer.init()
vec = pygame.math.Vector2
# Constants
WIDTH = 1306
HEIGHT = 526
FPS_INGAME = 60
FPS_HOMESCREEN = 30
FULL_SCREEN = (0,0)
bullet_img = pygame.image.load('Bullet.png')
jump = False
bullet_timer = 0
score = 0
moving_left = False
moving_right = False
shoot = False
acceleration = 0.7
friction = -0.1
gravity = 9.8
platform_color = (150,59,230)
# Classes and Sprites
class Player(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.shoot_cooldown = 0
self.anime = []
self.frame_index = 0
self.update_time = pygame.time.get_ticks()
self.action = 0
animation_types = ["Shoot","Go"]
for animation in animation_types:
temp_list = []
num_of_frames = len(os.listdir(f'MySprite/{animation}'))
for i in range(1,num_of_frames):
img = pygame.image.load(f'MySprite/{animation}/{i}.png')
temp_list.append(img)
self.anime.append(temp_list)
self.direction = 1
self.flip = False
self.image = self.anime[self.action][self.frame_index]
self.rect = self.image.get_rect()
# vectors and sprite constants
self.health = 100
self.pos = vec(WIDTH/2, HEIGHT/2)
self.vel_vec = vec(0,0)
self.acc_vec = vec(0,0)
def jump(self):
self.rect.y += 1
hits = pygame.sprite.spritecollide(player_group.sprite, platform_group,False)
self.rect.y -= -1
if hits:
self.vel_vec.y = -15
def screen_edge(self):
if self.pos.x > WIDTH:
self.pos.x = 0
if self.pos.x < 0:
self.pos.x = WIDTH
def get_damage(self,damage_mag):
self.health -= damage_mag
def update(self):
animation_cooldown = 75
self.image = self.anime[self.action][self.frame_index]
if pygame.time.get_ticks() - self.update_time >= animation_cooldown:
self.update_time = pygame.time.get_ticks()
self.frame_index += 1
if self.frame_index >= len(self.anime[self.action]):
self.frame_index = 0
if self.shoot_cooldown > 0:
self.shoot_cooldown -= 1
def update_action(self,new_action):
if new_action != self.action:
self.action = new_action
self.frame_index = 0
self.update_time = pygame.time.get_ticks()
def move(self,moving_left,moving_right):
self.acc_vec = vec(0,acceleration)
if moving_left:
self.acc_vec.x = -(acceleration)
self.direction = 1
self.flip = False
if moving_right:
self.acc_vec.x = acceleration
self.direction = -1
self.flip = True
self.acc_vec.x += self.vel_vec.x * friction
self.vel_vec += self.acc_vec
self.pos += self.vel_vec + 0.5 * self.acc_vec
self.rect.midbottom = self.pos
hits = pygame.sprite.spritecollide(player_group.sprite, platform_group,False)
if hits:
self.pos.y = hits[0].rect.top
self.vel_vec.y = 0
def draw(self):
screen.blit(pygame.transform.flip(self.image,self.flip,False),self.rect)
class Platform(pygame.sprite.Sprite):
def __init__(self,x,y,w,h):
super().__init__()
self.image = pygame.Surface((w,h))
self.image.fill(platform_color)
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
class Hostiles(pygame.sprite.Sprite):
def __init__(self,x_pos,y_pos,speed):
super(Hostiles,self).__init__()
self.images = []
self.images.append(pygame.image.load('MySprite/images/go_1.png'))
self.images.append(pygame.image.load('MySprite/images/go_2.png'))
self.images.append(pygame.image.load('MySprite/images/go_3.png'))
self.images.append(pygame.image.load('MySprite/images/go_4.png'))
self.images.append(pygame.image.load('MySprite/images/go_5.png'))
self.images.append(pygame.image.load('MySprite/images/go_6.png'))
self.images.append(pygame.image.load('MySprite/images/go_7.png'))
self.images.append(pygame.image.load('MySprite/images/go_8.png'))
self.images.append(pygame.image.load('MySprite/images/go_9.png'))
self.images.append(pygame.image.load('MySprite/images/go_10.png'))
self.index = 0
self.image = self.images[self.index]
self.rect = self.image.get_rect(center = (x_pos,y_pos))
self.speed = speed
def update(self):
self.index += 1
if self.index >= len(self.images):
self.index = 0
self.image = self.images[self.index]
self.rect.centerx += self.speed
if self.rect.centerx >= 1350 or self.rect.centerx <= -50:
self.kill()
class Hostiles2(pygame.sprite.Sprite):
def __init__(self,x_pos,y_pos,speed):
super(Hostiles2,self).__init__()
self.images2 = []
self.images2.append(pygame.image.load('MySprite/images2/go_1.png'))
self.images2.append(pygame.image.load('MySprite/images2/go_2.png'))
self.images2.append(pygame.image.load('MySprite/images2/go_3.png'))
self.images2.append(pygame.image.load('MySprite/images2/go_4.png'))
self.images2.append(pygame.image.load('MySprite/images2/go_5.png'))
self.images2.append(pygame.image.load('MySprite/images2/go_6.png'))
self.images2.append(pygame.image.load('MySprite/images2/go_7.png'))
self.images2.append(pygame.image.load('MySprite/images2/go_8.png'))
self.images2.append(pygame.image.load('MySprite/images2/go_9.png'))
self.images2.append(pygame.image.load('MySprite/images2/go_10.png'))
self.index = 0
self.image = self.images2[self.index]
self.rect = self.image.get_rect(center = (x_pos,y_pos))
self.speed = speed
def update(self):
self.index += 1
if self.index >= len(self.images2):
self.index = 0
self.image = self.images2[self.index]
self.rect.centerx += self.speed
if self.rect.centerx >= 1350 or self.rect.centerx <= -50:
self.kill()
class Bullets(pygame.sprite.Sprite):
def __init__(self,x,y,direction):
super().__init__()
self.speed = 10
self.image = bullet_img
self.rect = self.image.get_rect(center = (x,y))
self.direction = direction
def update(self):
self.rect.x -= (self.direction * self.speed)
if self.rect.left >= WIDTH or self.rect.right <= 0:
self.kill()
screen.blit(self.image,self.rect)
# Functions
def make_text(font_type,font_size,text,color,position):
font = pygame.font.Font(font_type, font_size)
title = font.render(text,True,(color))
title_rect = title.get_rect(center = (position))
screen.blit(title,title_rect)
def main_game():
pygame.draw.rect(screen,(255,0,0),(22,20,200,10))
pygame.draw.rect(screen,platform_color,(22,20,2 * player_group.sprite.health,10))
screen.blit(heart,(0,2))
bullet_group.draw(screen)
player.draw()
hostiles_group.draw(screen)
platform_group.draw(screen)
bullet_group.update()
player_group.update()
hostiles_group.update()
player_group.update()
player.screen_edge()
if shoot:
if player.shoot_cooldown == 0:
bullet = Bullets(player.rect.centerx - (0.6 * player.direction * player.rect.size[0]),player.rect.centery,player.direction)
bullet_group.add(bullet)
player.shoot_cooldown = 40
if moving_left or moving_right:
player.update_action(1)
else:
player.update_action(0)
player.move(moving_left,moving_right)
if pygame.sprite.spritecollide(player_group.sprite,hostiles_group,True):
player_group.sprite.get_damage(10)
pygame.sprite.groupcollide(hostiles_group, bullet_group,True,True)
return 2
def game_over():
screen.fill((0,0,0))
text = gamefont.render("GAME OVER",True,(255,255,255))
text_rect = text.get_rect(center = (653,243))
screen.blit(text,text_rect)
scoresurface = gamefont.render(f"Score: {score}",True,(255,255,255))
score_rect = scoresurface.get_rect(center = (653,283))
screen.blit(scoresurface,score_rect)
# Creating window
screen = pygame.display.set_mode((WIDTH,HEIGHT))
pygame.display.set_caption("game name")
clock = pygame.time.Clock()
# Groups and objects
gamefont = pygame.font.Font('Chernobyl.ttf',40)
player = Player()
platform = Platform(0,HEIGHT-96,WIDTH,100)
platform_group = pygame.sprite.GroupSingle()
platform_group.add(platform)
player_group = pygame.sprite.GroupSingle()
player_group.add(player)
hostiles_group = pygame.sprite.Group()
hostile_event = pygame.USEREVENT
pygame.time.set_timer(hostile_event,300)
bullet_group = pygame.sprite.Group()
pygame.mouse.set_visible(True)
sky = pygame.image.load('SkyNight.png')
wallpaper = pygame.image.load('GamePlatform.png')
heart = pygame.image.load('Heart.png')
# Game loop
running = True
while running:
# Events (Inputs)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == hostile_event:
random_xpos = [-40,-20]
random_xpos2 = [1340,1360]
random_hs = [-2,2]
hostile_left = Hostiles2(random.choice(random_xpos),400,random.choice(random_hs))
hostile_right = Hostiles(random.choice(random_xpos2),400,random.choice(random_hs))
hostiles_group.add(hostile_left,hostile_right)
if event.type == pygame.MOUSEBUTTONDOWN and player_group.sprite.health <= 0:
player_group.sprite.health = 100
hostiles_group.empty()
score = 0
import MainMenu
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
moving_left = True
if event.key == pygame.K_RIGHT:
moving_right = True
if event.key == pygame.K_q:
shoot = True
if event.key == pygame.K_ESCAPE:
running = False
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT:
moving_left = False
if event.key == pygame.K_RIGHT:
moving_right = False
if event.key == pygame.K_q:
shoot = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
player_group.sprite.jump()
if player_group.sprite.health > 0:
score += main_game()
print (score)
else:
game_over()
pygame.display.update()
screen.blit(sky,FULL_SCREEN)
screen.blit(wallpaper,FULL_SCREEN)
programIcon = pygame.image.load('icon.png')
pygame.display.set_icon(programIcon)
clock.tick(FPS_INGAME)
and this is all the main screen / main menu .py file:
import pygame,sys
pygame.init()
screen = pygame.display.set_mode((1306,526))
clock = pygame.time.Clock()
pygame.mouse.set_visible(True)
screen_home = pygame.image.load('HomeScreen.png')
def make_text(font_type,font_size,text,color,position):
font = pygame.font.Font(font_type, font_size)
title = font.render(text,True,(color))
title_rect = title.get_rect(center = (position))
screen.blit(title,title_rect)
while True:
font1 = pygame.font.Font('Starjedi.ttf',60)
game1 = font1.render("Play",True,(255,255,255))
game1_rect = game1.get_rect(center = (640,300))
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.MOUSEBUTTONDOWN:
if game1_rect.collidepoint(event.pos):
import MainGame.py
screen.blit(screen_home,(0,0))
screen.blit(game1,game1_rect)
make_text('Chernobyl.ttf',70,"Title Here",(255,255,255),(315,80))
pygame.display.update()
clock.tick(45)
when I run the main menu I get the Home Screen I made, then I click on the on my display screen and it imports the game script and the game starts, when my health reaches 0 and I click on the screen to quit the game loop, it takes me back to the main menu which is exactly what I wanted,however, when I press play again to go back to the game it doesn't work it gives me an error:
ModuleNotFoundError: No module named 'MainGame.py'; 'MainGame' is not a package
I know the code is a mess I'm still new at this I'm sorry if my question wasn't clear enough, any help would be appreciated!

Ok, now that I see your code I can see you have a big problem using import:
You use it like this:
import MainGame.py
Assume the file you created is MainGame.py you supposed to import it this way:
import MainGame
Same goes to
import MainMenu.py
And that's might be the problem, though if you still have an issue, so instead of:
in the game, this is part of the main game loop:
Please copy all of the code, in both files, and write the name of each file next to the code.

Related

Enemy collision with pygame.sprite.spritecollide()

In my game, there is a sprite player which I can control. It can move right or left, it can jump, shoot fireballs(bullets) and a breathe fire. I have added an enemy which can move on itself from right to left on a limited distance that I set. What I would like to do now is make my player loose health if it collides with the enemy sprite using pygame.sprite.spritecollide(). However it isn't working out well I don't know how to fix my issue which is the following: if I run my code below it says NameError: name 'enemy_list' is not defined. The errored line is in Sprite1.py in the Player class under the update function. How do I fix my code? I created my Enemy class and Level class with the following website: https://opensource.com/article/18/5/pygame-enemy. I'm open to all suggestions. Thanks beforehand! I separated my code into three files: main.py, settings.py and Sprite1.py. Here's main.py:
import pygame
import os
import sys
import time
from pygame import mixer
from Sprite1 import *
from settings import *
'''
Setup
'''
pygame.init()
clock = pygame.time.Clock()
pygame.mixer.music.load('.\\sounds\\Fairy.mp3')
pygame.mixer.music.play(-1, 0.0)
all_sprites = pygame.sprite.Group()
player = Player(all_sprites)
player.rect.x = 500
player.rect.y = 500
eloc = []
eloc = [400,500]
enemy_list = Level.bad( 1, eloc )
showStartScreen(surface)
x = 0
'''
Main loop
'''
main = True
while main == True:
background = pygame.image.load(os.path.join('images', 'Bg.png')).convert()
surface.blit(background, (0, 0))
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
main = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
player.control(-steps,0)
if event.key == pygame.K_RIGHT:
player.control(steps,0)
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT:
player.control(steps,0)
if event.key == pygame.K_RIGHT:
player.control(-steps,0)
keys = pygame.key.get_pressed()
if not(isJump):
if keys[pygame.K_UP]:
isJump = True
else:
if jumpCount >= -10:
player.rect.y -= (jumpCount * abs(jumpCount)) * 1
jumpCount -= 2
else:
jumpCount = 10
isJump = False
# dt = time since last tick in milliseconds.
dt = clock.tick(60) / 1000
all_sprites.update(dt)
player.update(dt)
all_sprites.draw(surface) #refresh player position
enemy_list.draw(surface)
for e in enemy_list:
e.move()
pygame.display.flip()
Here's my settings.py:
import pygame
isJump = False
jumpCount = 10
width = 960
height = 720
fps = 40 # frame rate
pygame.display.set_caption('B.S.G.')
surface = pygame.display.set_mode((width, height))
PLAYER_ACC = 0.5
PLAYER_FRICTION = -0.12
PLAYER_GRAV = 0.8
PLAYER_JUMP = 20
PLAYER_LAYER = 2
PLATFORM_LAYER = 1
RED = (255, 0, 0)
steps = 10 # how fast to move
And here's my Sprite1.py:
import pygame
import sys
import os
import time
from pygame import mixer
from pygame.locals import *
from settings import *
vec = pygame.math.Vector2
def showStartScreen(surface):
show = True
while (show == True):
background = pygame.image.load(os.path.join('images', 'Starting_scr.png'))
# rect = surface.get_rect()
surface.blit(background, (0,0))
pygame.display.flip()
for event in pygame.event.get():
if event.type == pygame.MOUSEBUTTONDOWN:
show = False
class Player(pygame.sprite.Sprite):
def __init__(self, all_sprites):
pygame.sprite.Sprite.__init__(self)
self.movex = 0
self.movey = 0
self.frame = 0
self.health = 10
self.jumping = False
self.images = []
self.imagesleft = []
self.imagesright = []
self.direction = "right"
self.alpha = (0,0,0)
self.ani = 4 # animation cycles
self.all_sprites = all_sprites
self.add(self.all_sprites)
self.fire_timer = .1
self.bullet_timer = .1
self.pos = vec(40, height - 100)
self.vel = vec(0, 0)
for i in range(1,5):
img = pygame.image.load(os.path.join('images','hero' + str(i) + '.png')).convert()
img.convert_alpha()
img.set_colorkey(self.alpha)
self.imagesright.append(img)
self.image = self.imagesright[0]
self.rect = self.image.get_rect()
for i in range(1,5):
img = pygame.image.load(os.path.join('images','hero' + str(i) + '.png')).convert()
img = pygame.transform.flip(img, True, False)
img.convert_alpha()
img.set_colorkey(self.alpha)
self.imagesleft.append(img)
self.image = self.imagesleft[0]
self.rect = self.image.get_rect()
def control(self,x,y):
'''
control player movement
'''
self.movex += x
self.movey -= y
def update(self, dt):
'''
Update sprite position
'''
self.rect.x = self.rect.x + self.movex
self.rect.y = self.rect.y + self.movey
enemy_hit_list = pygame.sprite.spritecollide(self, enemy_list, False)
for enemy in ennemy_hit_list:
self.health -= 1
print(self.health)
# moving left
if self.movex < 0:
self.frame += 1
if self.frame > 3*self.ani:
self.frame = 0
self.image = self.imagesleft[self.frame//self.ani]
self.direction = "left"
# moving right
if self.movex > 0:
self.frame += 1
if self.frame > 3*self.ani:
self.frame = 0
self.image = self.imagesright[self.frame//self.ani]
self.direction = "right"
keys = pygame.key.get_pressed()
if keys[pygame.K_SPACE]:
self.bullet_timer -= dt # Subtract the time since the last tick.
if keys[pygame.K_x]:
self.fire_timer -= dt
if self.bullet_timer <= 0:
self.bullet_timer = 100 # Bullet ready.
if keys: # Left mouse button.
# Create a new bullet instance and add it to the groups.
if self.direction == "right":
Bullet([self.rect.x + self.image.get_width(), self.rect.y + self.image.get_height()/2], self.direction, self.all_sprites)
else:
Bullet([self.rect.x, self.rect.y + self.image.get_height()/2], self.direction, self.all_sprites)
self.bullet_timer = .5 # Reset the timer.
if self.fire_timer <= 0:
self.fire_timer = 100
if keys:
if self.direction == "right":
Fire([self.rect.x + 170, self.rect.y + self.image.get_height()/2], self.direction, self.all_sprites)
else:
Fire([self.rect.x - 90, self.rect.y + self.image.get_height()/2], self.direction, self.all_sprites)
self.fire_timer = .1
if self.health == 0:
self.kill()
class Enemy(pygame.sprite.Sprite):
'''
Spawn an enemy
'''
def __init__(self,x,y,img):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load(os.path.join('images',img))
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
self.counter = 0 # counter variable
def move(self):
'''
enemy movement
'''
distance = 20
speed = 15
if self.counter >= 0 and self.counter <= distance:
self.rect.x += speed
elif self.counter >= distance and self.counter <= distance*2:
self.rect.x -= speed
else:
self.counter = 0
self.counter += 1
class Bullet(pygame.sprite.Sprite):
IMAGE = None
FLIPPED_IMAGE = None
def __init__(self, pos, direction, *sprite_groups):
super().__init__(*sprite_groups)
# cache images
if not Bullet.IMAGE:
Bullet.IMAGE = pygame.image.load(os.path.join('images','fireball.png'))
Bullet.FLIPPED_IMAGE = pygame.transform.flip(Bullet.IMAGE, True, False)
if direction == "right":
self.vel = pygame.math.Vector2(750, 0)
self.image = Bullet.IMAGE
else:
self.vel = pygame.math.Vector2(-750, 0)
self.image = Bullet.FLIPPED_IMAGE
self.pos = pygame.math.Vector2(pos)
self.rect = self.image.get_rect(center=pos)
def update(self, dt):
# Add the velocity to the position vector to move the sprite
self.pos += self.vel * dt
self.rect.center = self.pos # Update the rect pos.
if not pygame.display.get_surface().get_rect().colliderect(self.rect):
self.kill()
class Fire(pygame.sprite.Sprite):
IMAGE = None
FLIPPED_IMAGE = None
def __init__(self, pos, direction, *sprite_groups):
super().__init__(*sprite_groups)
# cache images
if not Fire.IMAGE:
Fire.IMAGE = pygame.image.load(os.path.join('images','fire_drag.png'))
Fire.FLIPPED_IMAGE = pygame.transform.flip(Fire.IMAGE, True, False)
if direction == "right":
self.image = Fire.IMAGE
self.vel = pygame.math.Vector2(0, 0)
else:
self.image = Fire.FLIPPED_IMAGE
self.vel = pygame.math.Vector2(0, 0)
self.pos = pygame.math.Vector2(pos)
self.rect = self.image.get_rect(center=pos)
def update(self, dt):
self.too = True
self.pos += self.vel * dt
self.rect.center = self.pos # Update the rect pos.
if self.too == True:
self.kill()
class Level():
def bad(lvl,eloc):
if lvl == 1:
enemy = Enemy(eloc[0],eloc[1],'cookie1.png') # spawn enemy
enemy_list = pygame.sprite.Group() # create enemy group
enemy_list.add(enemy) # add enemy to group
if lvl == 2:
print("Level " + str(lvl) )
return enemy_list
def loot(lvl,lloc):
print(lvl)
enemy_list is defined in global namespace, in main.py, thus it is not accessible in the module Sprite.py.
Add an additional argument to the update method of the class Player:
class Player(pygame.sprite.Sprite):
# [...]
def update(self, dt, enemy_list):
# [...]
enemy_hit_list = pygame.sprite.spritecollide(self, enemy_list, False)
# [...]
Since player is a member of all_sprites, you have to add the argument to the update methods of the other sprites (Enemy, Bullet), too.
Pass enemy_list to the update method all_sprites in the main application loop. Note the update method of Player is invoked by all_sprites.update, thus player.update(dt, enemy_list) is superflous:
while main == True:
# [...]
all_sprites.update(dt, enemy_list)
# [...]

Adding second sprite doesn't work with pygame tutorial

I have been using this code from this tutorial https://opensource.com/article/18/5/pygame-enemy but I couldn't add more enemies simply by using
enemy = Enemy(40,100,'spr.png')# spawn enemy
enemy_list = pygame.sprite.Group() # create enemy group
enemy_list.add(enemy) # add enemy to group
The original images are from here https://opengameart.org/sites/default/files/opp2_sprites.zip
but I have separated in imgur for easy explanation:
content folder images:
yeti.png: https://imgur.com/GNNcU6z
stage.png: https://imgur.com/YyiEJ0q
and the image of the second enemy (sprit) that I wanted to put
spr.png: https://imgur.com/1fYXa7Y
I tried using the solution of this similar question How do I add enemies in pygame?, but just got errors or no results.
My code:
import pygame
import sys
import os
'''
Objects
'''
class Enemy(pygame.sprite.Sprite):
'''
Spawn an enemy
'''
def __init__(self, x, y, img):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load(os.path.join('images', img))
#self.image.convert_alpha()
#self.image.set_colorkey(ALPHA)
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
self.counter = 0
def move(self):
'''
enemy movement
'''
distance = 20
speed = 8
if self.counter >= 0 and self.counter <= distance:
self.rect.x += speed
elif self.counter >= distance and self.counter <= distance * 2:
self.rect.x -= speed
else:
self.counter = 0
self.counter += 1
class Level():
def bad(lvl,eloc):
if lvl == 1:
enemy = Enemy(eloc[0],eloc[1],'yeti.png') # spawn enemy
enemy_list = pygame.sprite.Group() # create enemy group
enemy_list.add(enemy) # add enemy to group
if lvl == 2:
print("Level " + str(lvl) )
return enemy_list
class Player(pygame.sprite.Sprite):
'''
Spawn a player
'''
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.movex = 0
self.movey = 0
self.frame = 0
self.health = 10
self.frame = 0
self.images = []
for i in range(1, 5):
img = pygame.image.load(
os.path.join('images', 'hero' + str(i) + '.png')).convert()
img.convert_alpha()
img.set_colorkey(ALPHA)
self.images.append(img)
self.image = self.images[0]
self.rect = self.image.get_rect()
def control(self, x, y):
'''
control player movement
'''
self.movex += x
self.movey += y
def update(self):
'''
Update sprite position
'''
self.rect.x = self.rect.x + self.movex
self.rect.y = self.rect.y + self.movey
# moving left
if self.movex < 0:
self.frame += 1
if self.frame > 3 * ani:
self.frame = 0
self.image = self.images[self.frame // ani]
# collisions
enemy_hit_list = pygame.sprite.spritecollide(self, enemy_list, False)
for enemy in enemy_hit_list:
self.health -= 1
print(self.health)
# moving right
if self.movex > 0:
self.frame += 1
if self.frame > 3 * ani:
self.frame = 0
self.image = self.images[(self.frame // ani)]
'''
Setup
'''
worldx = 560
worldy = 520
fps = 40 # frame rate
ani = 4 # animation cycles
clock = pygame.time.Clock()
pygame.init()
main = True
BLUE = (25, 25, 200)
BLACK = (23, 23, 23)
WHITE = (254, 254, 254)
ALPHA = (0, 255, 0)
world = pygame.display.set_mode([worldx, worldy])
backdrop = pygame.image.load(os.path.join('images', 'stage.png')).convert()
backdropbox = world.get_rect()
player = Player() # spawn player
player.rect.x = 0
player.rect.y = 0
player_list = pygame.sprite.Group()
player_list.add(player)
steps = 10 # how fast to move
eloc = []
eloc = [200,20]
enemy_list = Level.bad( 1, eloc )
'''
Main loop
'''
while main == True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
main = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT or event.key == ord('a'):
player.control(-steps, 0)
if event.key == pygame.K_RIGHT or event.key == ord('d'):
player.control(steps, 0)
if event.key == pygame.K_UP or event.key == ord('w'):
print('jump')
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == ord('a'):
player.control(steps, 0)
if event.key == pygame.K_RIGHT or event.key == ord('d'):
player.control(-steps, 0)
if event.key == ord('q'):
pygame.quit()
sys.exit()
main = False
# world.fill(BLACK)
world.blit(backdrop, backdropbox)
player.update()
player_list.draw(world) #refresh player position
enemy_list.draw(world)
for e in enemy_list:
e.move()
pygame.display.flip()
clock.tick(fps)
There are a number of issues to pay attention on your code.
Take a look to Level class. You need to use self in your class to refer to the class functions and variables. I have added a second function to add a second enemy (spr.png), therefore I put enemy_list outside the function, at class level, so it can be accessed by both functions.
class Level:
def __init__(self):
self.enemy_list = pygame.sprite.Group() # create enemy group
def bad_1(self, lvl, eloc):
if lvl == 1:
enemy = Enemy(eloc[0],eloc[1],'yeti.png') # spawn enemy
self.enemy_list.add(enemy) # add enemy to group
if lvl == 2:
print("Level " + str(lvl) )
return self.enemy_list
def bad_2(self, lvl, eloc):
if lvl == 1:
enemy = Enemy(eloc[0],eloc[1],'spr.png') # spawn enemy
self.enemy_list.add(enemy) # add enemy to group
if lvl == 2:
print("Level " + str(lvl) )
return self.enemy_list
I also changed this part. First, you need to instantiate the class (see l = Level()), then you can use its functions and variables. Note you were invoking Level.bad() just once, so there was just one enemy!
steps = 10 # how fast to move
l = Level()
eloc = [200,20]
enemy_list = l.bad_1(1, eloc)
eloc = [100,10]
enemy_list = l.bad_2(1, eloc)
My code is quite a "hack", something quick and easy-to-see, but it works now...

__init__() takes exactly 3 arguments (1 given)?

It is asking for 3 arguments and i have given it one. How do i give it 2 more and could you explain how to do that as well? Thanks
import pygame, random, collisionObjects
pygame.init()
screen = pygame.display.set_mode((640,480))
class Pirate(pygame.sprite.Sprite):
EAST = 0
def __init__(self, screen, dx):
self.screen = screen
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load("king_pirate/running e0000.bmp")
self.image = self.image.convert()
tranColor = self.image.get_at((1, 1))
self.image.set_colorkey(tranColor)
self.rect = self.image.get_rect()
self.rect.inflate_ip(-50, -30)
self.rect.center = (0, random.randrange(30,450))
self.img = []
self.loadPics()
self.frame = 0
self.delay = 4
self.pause = self.delay
self.dx = dx
def update(self):
#set delay
self.pause -= 1
if self.pause <= 0:
self.pause = self.delay
self.frame += 1
if self.frame > 7:
self.frame = 0
self.image = self.img[self.frame]
self.rect.centerx += self.dx
if self.rect.centerx > self.screen.get_width():
self.rect.centerx = 0
self.rect.centery = random.randrange(30,450)
#load pictures
def loadPics(self):
for i in range(8):
imgName = "king_pirate/running e000%d.bmp" % i
tmpImg = pygame.image.load(imgName)
tmpImg.convert()
tranColor = tmpImg.get_at((0, 0))
tmpImg.set_colorkey(tranColor)
self.img.append(tmpImg)
class Pirate2(pygame.sprite.Sprite):
WEST = 0
def __init__(self, screen, dx):
self.screen = screen
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load("pirate/running w0000.bmp")
self.image = self.image.convert()
tranColor = self.image.get_at((1, 1))
self.image.set_colorkey(tranColor)
self.rect = self.image.get_rect()
self.rect.inflate_ip(-50, -30)
self.rect.center = (640, random.randrange(20,460))
self.img = []
self.loadPics()
self.frame = 0
self.delay = 4
self.pause = self.delay
self.dx = dx
def update(self):
#set delay
self.pause -= 1
if self.pause <= 0:
self.pause = self.delay
self.frame += 1
if self.frame > 7:
self.frame = 0
self.image = self.img[self.frame]
self.rect.centerx -= self.dx
if self.rect.centerx < 0:
self.rect.centerx = self.screen.get_width()
self.rect.centery = random.randrange(20,460)
#load pictures
def loadPics(self):
for i in range(8):
imgName = "pirate/running w000%d.bmp" % i
tmpImg = pygame.image.load(imgName)
tmpImg.convert()
tranColor = tmpImg.get_at((0, 0))
tmpImg.set_colorkey(tranColor)
self.img.append(tmpImg)
#set up class for gold object,
class Gold(pygame.sprite.Sprite):
def __init__(self, screen, imageFile):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load(imageFile)
self.image = self.image.convert()
self.rect = self.image.get_rect()
self.rect.centerx = random.randrange(0, screen.get_width())
self.rect.centery = random.randrange(0, screen.get_height())
#main character class
class Thief(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load("thief2.gif")
self.image = self.image.convert()
tranColor = self.image.get_at((1, 1))
self.image.set_colorkey(tranColor)
self.rect = self.image.get_rect()
self.rect.inflate_ip(-15, -10)
self.rect.center = (30, (screen.get_height()-40))
self.dx = 30
self.dy = 30
if not pygame.mixer:
print("problem with sound")
else:
pygame.mixer.init()
self.collectcoin = pygame.mixer.Sound("collectcoin.wav")
self.hit = pygame.mixer.Sound("hit.ogg")
def update(self):
if self.rect.bottom > screen.get_height():
self.rect.centery = (screen.get_height()-40)
elif self.rect.top < 0:
self.rect.centery = 40
elif self.rect.right > screen.get_width():
self.rect.centerx = (screen.get_width()-30)
elif self.rect.left < 0:
self.rect.centerx = 30
#define movements
def moveUp(self):
self.rect.centery -= self.dy
def moveDown(self):
self.rect.centery += self.dy
def moveLeft(self):
self.rect.centerx -= self.dx
def moveRight(self):
self.rect.centerx += self.dx
def reset(self):
self.rect.center = (30, (screen.get_height()-40))
#set up a scoreboard
class Scoreboard(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.lives = 0
self.score = 0
self.font = pygame.font.SysFont("None", 40)
self.number = 0
#with a self updating label
def update(self):
self.text = "Damage: %d %% Gold Taken: %d" % (self.lives, self.score)
self.image = self.font.render(self.text, 1, (199,237,241))
self.rect = self.image.get_rect()
#define the game function
def game():
#set up background
background = pygame.Surface(screen.get_size())
background = pygame.image.load("sand.jpg")
background = pygame.transform.scale(background, screen.get_size())
screen.blit(background, (0, 0))
#initialize pirates & scoreboard sprites
pirate = Pirate()
scoreboard = Scoreboard()
#create two arrays for multiple gold object occurances
#two arrays are used for better distribution on screen
gold1 = []
numberofGold = 16
for i in range(numberofgolds):
oneGold = golds(screen,"gold1.png")
golds1.append(onegold)
for gold in golds1:
gold.rect.centerx = random.randrange(20,620)
gold.rect.centery = random.randrange(20,240)
gold.rect.inflate_ip(-5, -5)
gold2 = []
for i in range(numberofgolds):
onegold = golds(screen,"gold1.png")
golds2.append(onegold)
for gold in golds2:
gold.rect.centerx = random.randrange(20,620)
gold.rect.centery = random.randrange(250,460)
gold.rect.inflate_ip(-5, -5)
totalgolds = ((len(golds1)-1)+(len(golds2)-1))
#initialize gold sprites
goldSprites = pygame.sprite.Group(golds1,
#initialize pirate sprites & instances
pirate1 = pirate1(screen,13)
pirate2 = pirate2(screen,13)
pirate3 = pirate1(screen,11)
pirate4 = pirate2(screen,11)
pirate5 = pirate1(screen,13)
pirateSprites = pygame.sprite.Group(pirate1, pirate2, pirate3, pirate4, pirate5)
#use ordered updates to keep clean appearance
allSprites = pygame.sprite.OrderedUpdates(goldSprites, thief, pirateSprites, scoreboard)
#set up clock & loop
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_UP:
thief.moveUp()
elif event.key == pygame.K_DOWN:
thief.moveDown()
elif event.key == pygame.K_LEFT:
thief.moveLeft()
elif event.key == pygame.K_RIGHT:
thief.moveRight()
elif event.key == pygame.K_ESCAPE:
keepGoing = False
#check collisions here
hitpirates = pygame.sprite.spritecollide(thief, pirateSprites, False)
hitgold = pygame.sprite.spritecollide(thief, goldSprites, True)
if hitpirates:
thief.hit.play()
scoreboard.lives += 1
if scoreboard.lives >= 100:
keepGoing = False
number = 0
if hitgolds:
thief.collectcoin.play()
scoreboard.score += 1
totalgolds -= 1
if totalgolds <= 0:
keepGoing = False
number = 1
#draw sprites
allSprites.clear(screen, background)
allSprites.update()
allSprites.draw(screen)
pygame.display.flip()
return scoreboard.score
return scoreboard.number
def instructions(score, number):
pygame.display.set_caption("Hunt for Gold!")
background = pygame.Surface(screen.get_size())
background = pygame.image.load("sand.jpg")
background = pygame.transform.scale(background, screen.get_size())
screen.blit(background, (0, 0))
if number == 0:
message = "Sorry try again..."
elif number == 1:
message = "The theif escapes!"
else:
message = "Onto the hunt for gold!"
insFont = pygame.font.SysFont("Calibri", 25)
insLabels = []
instructions = (
"Last score: %d" % score ,
"%s" % message,
"",
"GOLD!",
"Get all the gold before you are "
"obliterated!",
"Use arrow keys to move the thief.",
"Space to start, Esc to quit."
)
for line in instructions:
tempLabel = insFont.render(line, 1 , (0,0,0))
insLabels.append(tempLabel)
#set up homescreen loop
keepGoing = True
clock = pygame.time.Clock()
while keepGoing:
clock.tick(30)
for event in pygame.event.get():
if event.type == pygame.QUIT:
keepGoing = False
donePlaying = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
keepGoing = False
donePlaying = False
if event.key == pygame.K_ESCAPE:
keepGoing = False
donePlaying = True
for i in range(len(insLabels)):
screen.blit(insLabels[i], (50, 30*i))
pygame.display.flip()
return donePlaying
#define main function
def main():
donePlaying = False
score = 0
message = ""
while not donePlaying:
donePlaying = instructions(score, message)
if not donePlaying:
score = game()
else:
pygame.quit()
if __name__ == "__main__":
main()
Glancing at your code, this line:
pirate = Pirate()
Your Pirate class expects self, screen, dx. You only implicitly provide self.
I can only guess at what you want, especially since I don't know off the bat what dx is supposed to mean in respect to your game, but this will probably at least avoid the error:
pirate = Pirate(pygame.display.get_surface(), 60)

My sprites checker doesn't work

I have created code to see whether my aliens are dead however it doesn't work, can anyone see the problem.
CODE:
enemies = pygame.sprite.Group(aliens)
if len(enemies) <= 0:
print("game over")
gameover()
Complete code:
#MathsVaders
import pygame, random, time
from pygame.locals import *
import Databaseconnector
import tkMessageBox
pygame.init()
# set up the graphics window
size = [800, 595]
screen = pygame.display.set_mode(size, 0)
screenrect = screen.get_rect()
pygame.display.set_caption("Mathsvaders")
# set some variables
done = False
life = 3
aliens = pygame.sprite.Group()
allsprites = pygame.sprite.Group()
bombs = pygame.sprite.Group()
green = [0, 255, 0]
white = [255, 255, 255]
# create a timer to control how often the screen updates
clock = pygame.time.Clock()
fps = 100
# loads images to use in the game which link in with my classes(further down)
cannon = pygame.image.load("spaceship.png").convert()
cannon.set_colorkey(white)
blast = pygame.image.load("blast.png").convert_alpha()
boom = pygame.image.load("expl.png").convert_alpha()
bomb = pygame.image.load("missile_player.png").convert_alpha()
back = pygame.image.load("rsz_space.png").convert()
enemy = pygame.image.load("sii.png").convert_alpha()
lives2 = pygame.image.load("alien2.png").convert()
lives2.set_colorkey(white)
lives3 = pygame.image.load("alien3.png").convert()
lives3.set_colorkey(white)
lives1 = pygame.image.load("alien1.png").convert()
lives1.set_colorkey(white)
# (Classes)
# the explosion class
class Explosion(pygame.sprite.Sprite):
def __init__(self, x, y):
pygame.sprite.Sprite.__init__(self)
self.image = boom
self.rect = self.image.get_rect()
self.rect.centerx = x
self.rect.centery = y
self.count = 6
def update(self):
self.count -= 1
if self.count < 1:
self.kill()
class scoreClass:
def __init__(self):
self.value = 0
# set a font, default font size 28
self.font = pygame.font.Font(None, 28)
def update(self):
text = self.font.render("Score: %s" % self.value, True, (green))
textRect = text.get_rect()
textRect.centerx = screenrect.centerx
screen.blit(text, textRect)
class Msg:
def __init__(self, words):
# set a font, default font size 28
self.font = pygame.font.Font(None, 28)
self.text = self.font.render(words, True, (green))
self.textRect = self.text.get_rect()
def update(self):
self.textRect.centerx = screenrect.centerx
self.textRect.centery = screenrect.centery
screen.blit(self.text, self.textRect)
# the invader class
class Pi(pygame.sprite.Sprite):
def __init__(self, x, y):
pygame.sprite.Sprite.__init__(self)
aliens.add(self)
self.image = enemy
self.rect = self.image.get_rect()
self.rect.left = x
self.rect.top = y
self.speed = 1
def update(self):
self.rect.right += self.speed
if self.rect.right >= (screenrect.right -5):
self.speed = -1
self.rect.top += self.rect.height
if self.rect.left <= (screenrect.left +5):
self.speed = 1
self.rect.top += self.rect.height
if self.rect.top > screenrect.bottom:
self.kill()
i = random.randrange(1000)
j = self.rect.centerx
if i == 1:
laser_bomb = Bomb(j, self.rect.bottom)
allsprites.add(laser_bomb)
aliens.add(laser_bomb)
class Gun(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = cannon
self.rect = self.image.get_rect()
self.rect.bottom = screenrect.bottom
self.rect.centerx = screenrect.centerx
self.speed=0
def update(self):
self.rect.centerx += self.speed
if self.rect.right >= screenrect.right:
self.rect.centerx = 0
if self.rect.right <= 0:
self.rect.right = screenrect.right
# bomb class
class Bomb(pygame.sprite.Sprite):
def __init__(self, x, y):
pygame.sprite.Sprite.__init__(self)
self.image = bomb
self.rect = self.image.get_rect()
self.rect.centerx = x
self.rect.centery = y
bombs.add(self)
def update(self):
self.rect.centery +=1
# the laser blast class
class Blast(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = blast
self.image.set_colorkey(white)
self.rect = self.image.get_rect()
self.rect.top = (player.rect.top + 5)
self.rect.centerx = player.rect.centerx
self.speed = 0
def update(self):
if self.speed == 0:
self.rect.centerx = player.rect.centerx
self.rect.top -= self.speed
# function to make a sheet of invaders
def invade():
for j in range(10, 200, 120):
for i in range(10):
aliens.add(Pi((i*70)+10, j))
def gameover():
message = Msg("Game Over")
message.update()
player.kill()
shot.kill()
SQL = 'INSERT INTO TblScore(Score, StudentID) VALUES (' + str(score.value) + ', ' + str(8) + ')'
Databaseconnector.INSERT(SQL)
#pygame.quit()
##def gameover():
## message = Msg("Game Over")
## message.update()
## player.kill()
## shot.kill()
## SQL = 'INSERT INTO TblScore(Score, StudentID) VALUES (' + str(score.value) + ', ' + str(8) + ')'
## Databaseconnector.INSERT(SQL)
##
## #pygame.quit()
def gamewon():
# sprites(aliens) == 0
#sprites.aliens == 0
message = Msg("YOU WON, YOUR SCORE WAS " + score + " WELL DONE")
message.update
aliens.kill()
shot.kill()
pygame.quit()
# pre-game window
invade()
message = Msg("Press a key to play.")
allsprites.add(aliens)
key = True
while key:
screen.blit(back, (0,0))
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
if event.type == pygame.KEYDOWN:
for item in (aliens):
item.kill()
key = False
allsprites.update()
allsprites.draw(screen)
message.update()
# set the loop to 40 cycles per second
clock.tick(fps)
# update the display
pygame.display.flip()
# Main Game Starts Here
score = scoreClass()
player = Gun()
shot = Blast()
invade()
allsprites.add(player, aliens, shot)
while done==False:
screen.blit(back, (0,0))
for event in pygame.event.get():
if event.type == pygame.QUIT:
done=True
if life <= 0:
gamewon()
## elif allsprites == 0:
## gamewon()
else:
# shoots laser missile
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
if shot.speed == 0:
shot.speed = 7
#laser.play()
if event.key == pygame.K_LEFT:
player.speed = -3
if event.key == pygame.K_RIGHT:
player.speed = 3
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT:
player.speed = 0
if event.key == pygame.K_RIGHT:
player.speed = 0
hit = pygame.sprite.spritecollide(shot, aliens, 1)
if len(hit) > 0:
explosion1 = Explosion(shot.rect.centerx, shot.rect.top)
score.value += 1500
shot.kill()
#explode.play()
shot = Blast()
allsprites.add(shot, explosion1)
hit2 = pygame.sprite.spritecollide(player, aliens, 1)
if len(hit2) > 0:
life -= 1
#explode.play()
explosion2 = Explosion(player.rect.centerx, player.rect.centery)
allsprites.add(explosion2)
player.kill()
shot.kill()
if life > 0:
ready = Msg("Push Harder !!.")
ready.update()
allsprites.update()
allsprites.draw(screen)
score.update()
pygame.display.flip()
for item in bombs:
item.kill()
while 1:
event = pygame.event.wait()
if event.type == pygame.KEYDOWN:
break
player = Gun()
shot = Blast()
allsprites.add(player, shot)
if shot.rect.top <= screenrect.top:
shot.kill()
shot = Blast()
allsprites.add(shot)
if life == 2:
men = lives2
if life == 1:
men = lives1
if life == 3:
men = lives3
if life > 0:
screen.blit(men, (0,0))
allsprites.update()
allsprites.draw(screen)
score.update()
# set the loop to "fps" cycles per second
clock.tick(fps)
# update the display
pygame.display.flip()
# close pygame
pygame.quit()
This is the "pythonic" way since an empty list is False:
if not enemies:
print("game over")
gameover()
Where is the part of code that kills your aliens?

Artificial inteligence in python and pygame for Pong clone

I'm making a program that clones pong based off a tutorial and I already have the program to where it is multiplayer with two separate people. I want to add an AI in the program instead of a player 2. I've been stuck on this for quite some time and would appreciate any help! Here is the code currently:
import sys, os, math, random, pygame
from pygame.locals import *
class paddle(pygame.sprite.Sprite):
def __init__(self, xy):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load(os.path.join('assets', 'pong_paddle.gif'))
self.rect = self.image.get_rect()
self.rect.centerx, self.rect.centery = xy
self.movementspeed = 5
self.velocity = 0
def up(self):
# increases vertical velocity
self.velocity -= self.movementspeed
def down(self):
# decreases vertical velocity
self.velocity += self.movementspeed
def move(self, dy):
# moves the paddle y, doesn't go out of top or bottom
if self.rect.bottom + dy > 400:
self.rect.bottom = 400
elif self.rect.top + dy < 0:
self.rect.top = 0
else:
self.rect.y += dy
def update(self):
# makes the paddle move every frame
self.move(self.velocity)
class aiplayer(object):
def __init__(self):
self.bias = random.random() - 0.5
self.hit_count = 0
def update(self, paddle, game,):
if (paddle.rect.centerx < game.bounds.centerx and game.ball.rect.centerx < game.bounds.centerx) or (paddle.rect.centerx > game.bounds.centerx and game.ball.rect.centerx > game.bounds.centerx):
delta = (paddle.rect.centery + self.bias * paddle.rect.height) - game.ball.rect.centery
if abs(delta) > paddle.velocity:
if delta > 0:
paddle.direction = -1
else:
paddle.direction = 1
else:
paddle.direction = 0
else:
paddle.direction = 0
def hit(self):
self.hit_count += 1
if self.hit_count > 6:
self.bias = random.random() - 0.5
self.hit_count = 0
def lost(self):
self.bias = random.random() - 0.5
def won(self):
pass
def render(self, surface):
x, y = self.location
w, h = self.image.get_size()
surface.blitz(self.image, (x-w/2, y-h/2))
class Ball(pygame.sprite.Sprite):
def __init__(self, xy):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load(os.path.join('assets', 'pong_ball.gif'))
self.rect = self.image.get_rect()
self.rect.centerx, self.rect.centery = xy
self.maxspeed = 10
self.servespeed = 5
self.velx = 0
self.vely = 0
def reset(self):
self.rect.centerx, self.rect.centery = 400, 200
self.velx = 0
self.vely = 0
def serve(self):
angle = random.randint(-45, 45)
if abs(angle) < 5 or abs(angle-180) < 5:
angle = random.randint(10, 20)
if random.random() > .5:
angle += 180
# this gets the velocity for the x and y coords
x = math.cos(math.radians(angle))
y = math.sin(math.radians(angle))
self.velx = self.servespeed * x
self.vely = self.servespeed * y
class Game(object):
def __init__(self):
pygame.init()
# creates the window
self.window = pygame.display.set_mode((800, 400))
# makes a clock
self.clock = pygame.time.Clock()
# window title
pygame.display.set_caption("Pong")
# tells pygame to watch for these certain events so we can close window
pygame.event.set_allowed([QUIT, KEYDOWN, KEYUP])
self.background = pygame.Surface((800, 400))
self.background.fill((55, 255, 85))
pygame.draw.line(self.background, (0,0,0), (400, 0), (400, 400), 2)
self.window.blit(self.background, (0,0))
#lets the background show up
pygame.display.flip()
#renders the sprites so that they actually show up
self.sprites = pygame.sprite.RenderUpdates()
# makes the paddles, adds to sprite group
self.leftpaddle = paddle((50, 200))
self.sprites.add(self.leftpaddle)
self.rightpaddle = paddle((750, 200))
self.sprites.add(self.rightpaddle)
# makes the ball
self.ball = Ball((400, 200))
self.sprites.add(self.ball)
def run(self):
# this lets the game run using a loop so its always active and never closes
running = True
while running:
self.clock.tick(60)
# pygame event, if user closes the game, then stop running
running = self.handleEvents()
pygame.display.set_caption("Pong %d fps" % self.clock.get_fps())
self.manageBall()
# updates the sprites(paddles, ball)
for sprite in self.sprites:
sprite.update()
# renders the sprites
self.sprites.clear(self.window, self.background)
dirty = self.sprites.draw(self.window)
pygame.display.update(dirty)
def handleEvents(self):
for event in pygame.event.get():
if event.type == QUIT:
return False
elif event.type == KEYDOWN:
if event.key == K_ESCAPE:
return False
# controls the right paddle
if event.key == K_w:
self.leftpaddle.up()
if event.key == K_s:
self.leftpaddle.down()
if event.key == K_UP:
self.rightpaddle.up()
if event.key == K_DOWN:
self.rightpaddle.down()
# serves the ball
if event.key == K_SPACE:
if self.ball.velx == 0 and self.ball.vely == 0:
self.ball.serve()
elif event.type == KEYUP:
if event.key == K_w:
self.leftpaddle.down()
if event.key == K_s:
self.leftpaddle.up()
if event.key == K_UP:
self.rightpaddle.down()
if event.key == K_DOWN:
self.rightpaddle.up()
elif event.type ==
return True
def manageBall(self):
# this moves the ball
self.ball.rect.x += self.ball.velx
self.ball.rect.y += self.ball.vely
if self.ball.rect.top < 0:
self.ball.rect.top = 1
# makes the ball bounce
self.ball.vely *= -1
elif self.ball.rect.bottom > 400:
self.ball.rect.bottom = 399
# makes ball bounce off bottom
self.ball.vely *= -1
# resets the ball if it hits the left or right screen
if self.ball.rect.left < 0:
self.ball.reset()
return
elif self.ball.rect.right > 800:
self.ball.reset()
return
collision = pygame.sprite.spritecollide(self.ball, [self.leftpaddle, self.rightpaddle], dokill = False)
if len(collision) > 0:
hitpaddle = collision[0]
# sends the ball back
self.ball.velx *= -1
# makes sure the ball doesn't get stuck in the paddle
self.ball.rect.x += self.ball.velx
# makes the game and runs it
if __name__ == '__main__':
game = Game()
game.run()
Make a function AI in the aiplayer and have it return up or down
int AI(self.position,ball.position):
if self.y>ball.y:
return -1
elif self.y<ball.y:
return 1
then, in the update() code for aiplayer, do something similar to this
self.y += movespeed*AI(self.position,ball.position)
Then, it either moves the paddle up or down depending on where the ball is ( you might need to switch if you add or subtract the movespeed to get the paddle to go the right direction). Also, it might be more effective to use the center of the paddle so that it won't put the top or bottom edge of the paddle at the ball.

Categories