0

I'd like to know if I could get some help implementing a bonus ship into a space invaders clone, based on the pyinvaders.py project. My idea is that after a certain amount of time, a sprite should appear that the player can shoot. After this the player sprite should change to a different one. However, I'm not sure how to go about implementing this, so I would appreciate some help with learning how to do it. The bonus ship is saved as "bonus.jpg".

The code so far is here:

import pygame, sys
import time
from pygame import *
import random

class Sprite:
def __init__(self,xpos,ypos,filename):
    self.x = xpos
    self.y = ypos
    self.bitmap = image.load(filename)
    self.bitmap.set_colorkey((0,0,0))
def set_position(self,xpos,ypos):
    self.x = xpos
    self.y = ypos
def render(self):
    screen.blit(self.bitmap,(self.x,self.y))

def Intersect(s1_x,s1_y,s2_x,s2_y):
"""Collision detection code for sprites of size 32x32"""
if(s1_x>s2_x-32) and (s1_x<s2_x+32) and (s1_y>s2_y-32) and (s1_y<s2_y+32):
    return 1
else:
    return 0

init()
black = (0, 0, 0)
screen = display.set_mode((640,480))
key.set_repeat(1,1) #rapid keyboard repeat
display.set_caption('PyInvaders')
backdrop = image.load('data/backdrop.bmp')
enemies = []
enemies_row2 = []
bgp = [0, 0]
x = 0
for count in range(10):
    enemies.append(Sprite(50*x+50,50,'data/baddie.bmp'))
    x+= 1
x = 0
for count in range(10):
    enemies_row2.append(Sprite(50*x+50,85,'data/baddie.bmp'))
    x+=1
hero = Sprite(20,400, 'data/hero.bmp')
ourmissile = Sprite(0,480,'data/heromissile.bmp')
enemymissile = Sprite(0,480,'data/baddiemissile.bmp')
enemymissile_row2 = Sprite(0,480,'data/baddiemissile.bmp')

clock = pygame.time.Clock()


done = False
score = 0

scorefont = font.Font(None,60)
enemyspeed = 3

while done == False:
    screen.blit(backdrop,(0,0))
    for count in range(len(enemies)):
        enemies[count].x += enemyspeed
        enemies[count].render()

    for count in range(len(enemies_row2)):
        enemies_row2[count].x += enemyspeed
        enemies_row2[count].render()

if len(enemies) != 0:
    if enemies[len(enemies)-1].x > 590:
        enemyspeed = -3
        for count in range(len(enemies)):
            enemies[count].y += 5

    if enemies[0].x < 10:
        enemyspeed = 3
        for count in range(len(enemies)):
            enemies[count].y += 5

if len(enemies_row2) != 0:
    if enemies_row2[len(enemies_row2)-1].x > 590:
        enemyspeed = -3
        for count in range(len(enemies_row2)):
            enemies_row2[count].y += 5

    if enemies_row2[0].x < 10:
        enemyspeed = 3
        for count in range(len(enemies_row2)):
            enemies_row2[count].y += 5

if ourmissile.y < 479 and ourmissile.y > 0:
    ourmissile.render()
    ourmissile.y -= 5

if enemymissile.y >= 480 and len(enemies) > 0:
    enemymissile.x = enemies[random.randint(0,len(enemies)-1)].x
    enemymissile.y = enemies[0].y

if enemymissile_row2.y >= 480 and len(enemies_row2) > 0:
    enemymissile_row2.x = enemies_row2[random.randint(0,len(enemies_row2)-1)].x
    enemymissile_row2.y = enemies_row2[0].y

if Intersect(hero.x,hero.y,enemymissile.x,enemymissile.y):
    done = True #you were hit by the baddie missile

if Intersect(hero.x,hero.y,enemymissile_row2.x,enemymissile_row2.y):
    done = True #you were hit by the baddie missile

if Intersect(ourmissile.x,ourmissile.y,enemymissile.x,enemymissile.y):
    (ourmissile.x,ourmissile.y) = (0,480)
    (enemymissile.x, enemymissile.y) = (0,480)

if Intersect(ourmissile.x,ourmissile.y,enemymissile_row2.x,enemymissile_row2.y):
    (ourmissile.x,ourmissile.y) = (0,480)
    (enemymissile_row2.x, enemymissile_row2.y) = (0,480)

for count in range(0,len(enemies)):
    if Intersect(ourmissile.x, ourmissile.y, enemies[count].x, enemies[count].y):
        del enemies[count]
        score += 50
        (ourmissile.x,ourmissile.y) = (0,480)
        break

for count in range(0,len(enemies_row2)):
    if Intersect(ourmissile.x, ourmissile.y, enemies_row2[count].x, enemies_row2[count].y):
        del enemies_row2[count]
        score += 50
        (ourmissile.x,ourmissile.y) = (0,480)
        break

if len(enemies) == 0 and len(enemies_row2) == 0:
    done = True

scoretext = scorefont.render('Score:' + str(score),True, (255,255,255),(0,0,0))
screen.blit(scoretext,(5,5))

for ourevent in event.get():
    if ourevent.type == QUIT:
        done = True #if someone closes out via the X in the titlebar
    if ourevent.type == KEYDOWN:
        if ourevent.key == K_RIGHT and hero.x < 590:
            hero.x += 5
        if ourevent.key == K_LEFT and hero.x > 10:
            hero.x -= 5
        if ourevent.key == K_SPACE:
            if (ourmissile.x,ourmissile.y) == (0,480) or ourmissile.y <=0:
                (ourmissile.x,ourmissile.y) = (hero.x, hero.y)

enemymissile.render()
enemymissile_row2.render()
enemymissile.y += 5
enemymissile_row2.y += 5
hero.render()
display.update()
time.delay(5)

 while done == True:
    screen.blit(backdrop, bgp)
    text = scorefont.render("You Scored: " + str(score), True, black)          
    screen.blit(text, (200, 200))
    pygame.display.flip()
    clock.tick(30)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
user136563
  • 13
  • 2
  • The main problem is that I'm not sure with how to go about starting this function unfortunately. I'm asking whether someone could help me in some way. I'll narrow down to the specific part I'm having trouble with. – user136563 Mar 21 '14 at 09:56
  • Just curious, were you able to get something out of my answer? – sshashank124 Mar 21 '14 at 11:50
  • Yes, it was quite helpful. A lot to take in, but I do get the general idea. – user136563 Mar 22 '14 at 12:41

1 Answers1

3

The way your code is currently set up, what you are trying to achieve can prove to be quite difficult.

You should try something as follows:

1) I would suggest that you create a separate class for the main character and a separate class for your enemies rather than have a common class called Sprite. Then, you can add individualized methods for each of the class such as __init__ and move and draw

2) You should create a variable in your main character class that contains the images of all the different types of ships that you can have. That way, later on in your code in your main loop you can easily change the ship type from say ships[0] to ships[1]. Here is a little sample snippet:

class Player:
    def __init__(self):
        self.ships = [image.load("weak_ship.png"), image.load("upgraded_ship.png"), image.load("best_ship.png")]
        self.current_ship = self.ships[0]
        self.fire_rate = 5

You can then initialize your player as:

player = Player()

Then later on in your main loop, you can easily change your ship type to a better ship by doing:

player.current_ship = player.ships[1]
player.fire_rate = 30 #this increases the rate of fire

and also things like:

player.draw() #in your Player class you will define a draw method that takes care of the drawing

to easily draw your ship in one clean and neat line of code

3) Similarly, for the enemies class you can have similar methods

4) I suggest inheriting pygame.sprite.Sprite in your classes as follows and then you can use some of its features such as the following:

You can create sprite groups in pygame as shown in the link here.

Then in your main code, you can easily draw all the sprites in the group by calling the sprite group's update method. This update method will then go through each of the instances' update methods that you can define to either move or draw. All this with just a few lines of code.

5) Finally, your "bonus" ship problem:

As I talked about the self.ships earlier, you can add another image to the list called the image.load("bonus.jpg")

Then you can easily in your main code change the player.current_ship to player.ships[4] as: player.current_ship = player.ships[4]

player.fire_rate = 100

I understand that I have just said a LOT of stuff but I really recommend that modifying your code as I described above will make it REALLY easy to add features as you keep developing:

Also, just quickly search on google for some examples of games made in pygame to get a good sense of how the code is neatly structured. Although you will initially have to put in a lot of effort, it will MORE that pay off in the long run. Happy Pygaming :)

I also highly suggest that you check out this link:

Community
  • 1
  • 1
sshashank124
  • 31,495
  • 9
  • 67
  • 76