This is the code:
import pygame,sys
from pygame.locals import *
from random import randint
ancho = 1280
alto = 720
class Snake(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.ImageS = pygame.image.load("sprites/disparo1.png")
self.ImageSnake = pygame.image.load("sprites/cazador1 der.png")
self.rect = self.ImageSnake.get_rect()
self.rectS = self.ImageS.get_rect()
self.rect.centerx = 80
self.rect.centery = 80
self.ShotList= []
self.vel = 1
self.velS = 5
self.vidas = 3
self.viviendo = True
self.AS = False
def draw(self, ventana):
ventana.blit(self.ImageSnake, self.rect)
def move(self):
keys = pygame.key.get_pressed()
if keys[K_DOWN]:
self.rect.y += self.vel
if self.rect.bottom > 720:
self.rect.bottom = 720
if keys[K_UP]:
self.rect.y -= self.vel
if self.rect.top < 0:
self.rect.top = 0
if keys[K_RIGHT]:
self.rect.x += self.vel
if self.rect.right > 1280:
self.rect.right = 1280
if keys[K_LEFT]:
self.rect.x -= self.vel
if self.rect.left < 0:
self.rect.left = 0
def shoot(self, ventana):
keys = pygame.key.get_pressed()
if keys[K_SPACE] and not self.AS:
self.AS = True
self.rectS.right = self.rect.right + 10
self.rectS.top = self.rect.centery
if self.AS:
self.rectS.left = self.rectS.left + self.velS
if self.rectS.right > 1280:
self.AS = False
def drawShoot(self, ventana):
if self.AS:
ventana.blit(self.ImageS, self.rectS)
ventana.blit(self.ImageSnake, self.rect)
pygame.display.flip()
class zombieN1(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.ImageEnemy1 = pygame.image.load("sprites/zombie1 izq.png")
self.rect = self.ImageEnemy1.get_rect()
self.s = Snake()
self.y = self.s.rect.top
self.x = randint(1016,1280)
self.rect.top = self.y
self.rect.right = self.x
self.vel = 1
self.viviendo = True
self.vidas = 1
def movement(self):
self.rect.left = self.rect.left - self.vel
def destroy(self):
pass
def draw(self, ventana):
ventana.blit(self.ImageEnemy1, self.rect)
def Game():
pygame.init()
pygame.key.set_repeat(1,25)
ventana = pygame.display.set_mode((ancho, alto))
pygame.display.set_caption("Game")
Player = Snake()
Enemy1 = zombieN1()
BG = pygame.image.load("sprites/fondo.png")
InGame = True
ronda1 = True
while True:
Enemy1.destroy()
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
if InGame == True:
Player.move()
Player.shoot(ventana)
ventana.fill((205,69,159))
if ronda1 == True:
Enemy1.draw(ventana)
Enemy1.movement()
Enemy1.follow()
Player.draw(ventana)
Player.drawShoot(ventana)
pygame.display.update()
Game()
zombieN1
it constantly moves all the way to the left as seen in your def movement()
. I want that when it zombieN1
collides with the one disparo(rectS)
of Snake
, zombieN1
it is destroyed. Could any of you help me? If you need more information or a better explanation, tell me. I use Python 3.6.3.
There are methods of the class
pygame.sprite
intended to do just that, detect collisions and destroy the sprites that do so. As muchpygame.sprite.spritecollide
aspygame.sprite.groupcollide
they allow to do this. The first allows to detect the collision of a sprite with a group of sprites, the second detects collisions between two groups.I would personally make two changes to your code, especially if you want to be able to have multiple "bullets" and multiple "zombies" on the screen at once:
Your "shot" sprite should have its own class. Video games are one of the compelling reasons why OOP exists. Having your own class will allow you (in addition to encapsulating the code much better) to handle different numbers of shots and of different types very easily if you require it, as well as handling collisions and other events much more easily.
Use sprite groups (
pygame.sprite.Group()
). If you create groups to store all the sprites that have the same characteristics (enemies, shots, etc.), the task of detecting collisions is much easier thanks to the aforementioned methods.I've ended up changing quite a few things, but an example of what you could do is the following:
I have used
groupcollide
it since as a general rule you have several enemies and several shots at the same time:The first two arguments are the two groups of sprites to watch for collisions, the next two arguments indicate whether when one of each group collides it should destroy them.
Note that it
groupcollide
returns a dictionary with the collisions it detects, which you can use to handle them:The dictionary
colisiones
will be of the form:pygame.sprite.collide_rect(sprite1, sprite2)
If you are only going to have one enemy and one shot and you are not going to use groups you can use something like:
The same idea can be applied with your character and enemies to detect collisions.
With the above code and some sprites worthy of a Blender XD master we have the following:
Edition:
If you want an enemy to have several lives, you just have to create that attribute in its class, then iterate over the dictionary that returns
groupcollide
and subtract a life from each zombie, calling its methodkill
when its life attribute is less than or equal to 0.A very flexible option is for you to define an attribute
health
on the enemy's class and make it an integer. As you cause damage, you subtract a certain amount of life, causing it to be destroyed when it reaches zero. The beauty of this is that you can use different "weapons" that deal different damage.I leave you an example using this idea, in this case the health will be 300 and for each bullet you lose 100. The damage of the bullet is defined in the attribute
damage
of its class. You could have another type of "bullet" that deals 50 damage, another 10, etc. I use aproperty
next to asetter
so that it is the object itself that is destroyed when its life reaches zero, object-oriented programming is very nice for these things :)In your class
Bullet
add in__init__
the attributeself.damage = 100
In class
ZombieN1
add the attributeself._health = 300
in its__init__
and then we define the propertyhealth
and the setter :And finally, in the
while True
change the line with thegroupcollide
by:Everything would be like this: