matrices - Pygame sprite colisión movimiento aleatorio
pygame sprite collide circle (1)
Intento crear un juego (pygame) donde haya un sprite, que cuando, colisionado por el jugador se mueva aleatoriamente a otro lugar en la superficie, no estoy seguro de cómo lo haría, ya que tengo un conocimiento muy básico , supongo que tendría que asignar random.randint al sprite, pero ¿a dónde iría desde allí? Muchas gracias, agradecería la ayuda. El código está abajo :)
import pygame, sys
from pygame.locals import *
import random
pygame.init()
game=0
width=450
height=613
blue=(100,149,237)
white=(255,255,255)
purple =(128,0,128)
Level=pygame.image.load("level.jpg")
background=pygame.image.load("background.jpg")
startscreen=pygame.image.load("ocean.jpg")
gamescreen=pygame.image.load("screengame.jpg")
Display=pygame.display.set_mode((width,height))
pygame.display.set_caption("Ocean")
movex = 100
movey = 100
DirectX = 0
DirectY = 0
game = 0
MoveEnemy1X = 150
MoveEnemy1Y = 50
rectDirectX = 10
rectDirectY = 9
MoveEnemy2X = 300
MoveEnemy2Y = 100
rectDirect2X = 30
rectDirect2Y = 10
MoveEnemy3X = 400
MoveEnemy3Y = 200
rectDirect3X = 12
rectDirect3Y = 10
clock = pygame.time.Clock()
gameScore = 0
scorefont = pygame.font.SysFont("Arial",30)
score = scorefont.render("Score: " +str(gameScore),True,white)
##pygame.mixer.music.load(''ocean.mp3'')
##pygame.mixer.music.play(-1,0.0)
direc1 = 5
direc2 = 5
class Player(pygame.sprite.Sprite):
def __init__(self,x,y,width,height):
pygame.sprite.Sprite.__init__(self)
self.x = x
self.y = y
self.width = width
self.height = height
self.rect = pygame.Rect(x,y,width,height)
def RenderPlayer(self):
pygame.draw.rect(Display,blue,(self.x,self.y,self.width,self.height))
self.rect = pygame.Rect(self.x,self.y,self.width,self.height)
class EnemySprite(pygame.sprite.Sprite):
def __init__(self,x,y,width,height):
pygame.sprite.Sprite.__init__(self)
self.x = x
self.y = y
self.width = width
self.height = height
self.rect = pygame.Rect(x,y,width,height)
def RenderEnemy(self):
pygame.draw.rect(Display,white,(MoveEnemy1X,MoveEnemy1Y,30,30))
self.rect = pygame.Rect(MoveEnemy1X,MoveEnemy1Y,self.width,self.height)
class EnemySprite2(pygame.sprite.Sprite):
def __init__(self,x,y,width,height):
pygame.sprite.Sprite.__init__(self)
self.x = x
self.y = y
self.width = width
self.height = height
self.rect = pygame.Rect(x,y,width,height)
def RenderEnemy2(self):
pygame.draw.rect(Display,white,(MoveEnemy2X,MoveEnemy2Y,40,10))
self.rect = pygame.Rect(MoveEnemy2X,MoveEnemy2Y, self.width,self.height)
class EnemySprite3(pygame.sprite.Sprite):
def __init__(self,x,y,width,height):
pygame.sprite.Sprite.__init__(self)
self.x = x
self.y = y
self.width = width
self.height = height
self.rect = pygame.Rect(x,y,width,height)
def RenderEnemy3(self):
pygame.draw.rect(Display, white,(MoveEnemy3X,MoveEnemy3Y,10,10))
self.rect = pygame.Rect(MoveEnemy3X,MoveEnemy3Y, self.width,self.height)
class GoodSprite(pygame.sprite.Sprite):
def __init__(self,x,y,width,height):
pygame.sprite.Sprite.__init__(self)
self.x = x
self.y = y
self.width = width
self.height = height
self.rect = pygame.Rect(x,y,width,height)
def RenderGoodSprite(self):
pygame.draw.rect(Display,purple,(100,100,10,10))
self.rect = pygame.Rect(100,100,self.width,self.height)
Player1=Player(100,100,20,20)
Enemy1=EnemySprite(200,200,30,30)
Enemy2=EnemySprite2(300,200,40,10)
Enemy3=EnemySprite3(240,190,30,20)
Good=GoodSprite(150,400,10,10)
TheGameLoop = True
while TheGameLoop:
for event in pygame.event.get():
if (event.type==pygame.QUIT):
TheGameLoop=False
if (event.type==pygame.KEYDOWN):
if (event.key==pygame.K_LEFT):
direc1 = -4
gameScore+=1
score = scorefont.render("Score: " +str(gameScore),True,white)
if (event.key==pygame.K_RIGHT):
direc1 = 4
gameScore+=1
score = scorefont.render("Score: " +str(gameScore),True,white)
if (event.key==pygame.K_DOWN):
direc2 = 4
gameScore+=1
score = scorefont.render("Score: " +str(gameScore),True,white)
if (event.key==pygame.K_UP):
direc2 = -4
gameScore+=1
score = scorefont.render("Score: " +str(gameScore),True,white)
if (event.type==pygame.KEYUP):
if (event.key==pygame.K_LEFT):
direc1 = 0
if (event.key==pygame.K_RIGHT):
direc1 = 0
if (event.key==pygame.K_UP):
direc2 = 0
if (event.key==pygame.K_DOWN):
direc2 = 0
if MoveEnemy1X > 430:
MoveEnemy1X = 425
rectDirectX = -5
elif MoveEnemy1X < 0:
MoveEnemy1X = 10
rectDirectX = 5
elif MoveEnemy1Y > 613:
MoveEnemy1Y = 600
rectDirectY = -9
elif MoveEnemy1Y < 0:
MoveEnemy1Y = 0
rectDirectY = 11
if MoveEnemy2X > 430:
MoveEnemy2X = 425
rectDirect2X = -5
elif MoveEnemy2X < 0:
MoveEnemy2X = 11
rectDirect2X = 6
elif MoveEnemy2Y > 613:
MoveEnemy2Y = 600
rectDirect2Y = -12
elif MoveEnemy2Y < 0:
MoveEnemy2Y = 0
rectDirect2Y = 8
if MoveEnemy3X > 430:
MoveEnemy3X = 422
rectDirect3X = -7
elif MoveEnemy3X < 0:
MoveEnemy3X = 11
rectDirect3X = 8
elif MoveEnemy3Y > 613:
MoveEnemy3Y = 600
rectDirect3X = -12
elif MoveEnemy3Y < 0:
MoveEnemy3Y = 0
rectDirect3Y = 5
if direc1 > 430:
Display.blit(Level,(0,0))
pygame.display.update()
if game==0:
Display.blit(startscreen,(0,0))
if event.type==pygame.KEYDOWN:
if event.key==pygame.K_SPACE:
game=1
Display.blit(gamescreen,(0,0))
elif event.key==pygame.K_ESCAPE:
pygame.quit()
pygame.display.update()
if game==1:
Display.blit(gamescreen,(0,0))
Display.blit(score,(220,10))
Player1.RenderPlayer()
Enemy1.RenderEnemy()
Enemy2.RenderEnemy2()
Enemy3.RenderEnemy3()
Good.RenderGoodSprite()
Player1.x +=direc1
Player1.y +=direc2
MoveEnemy1X +=rectDirectX
MoveEnemy1Y +=rectDirectY
MoveEnemy2X +=rectDirect2X
MoveEnemy2Y +=rectDirect2Y
MoveEnemy3X + rectDirect3X
MoveEnemy3Y += rectDirectY
## pygame.mixer.music.load("ocean.mp3")
## pygame.mixer.music.play(-1,0.0)
pygame.display.update()
if pygame.sprite.collide_rect(Player1,Enemy1):
game=2
Display.blit(background,(0,0))
pygame.mixer.music.load("untitled.mp3")
pygame.mixer.music.play(1,0.0)
if pygame.sprite.collide_rect(Player1,Enemy2):
game=2
Display.blit(background,(0,0))
pygame.mixer.music.load("untitled.mp3")
pygame.mixer.music.play(1,0.0)
if pygame.sprite.collide_rect(Player1,Good):
gameScore+=1
Good.x=random.randint(0,500)
Good.y=random.randint(0,600)
pygame.display.update()
if game==2:
Display.blit(background,(0,0))
Display.blit(score,(200,20))
gameScore=0
pygame.display.update()
pygame.mixer.music.stop()
if event.type==pygame.KEYDOWN:
if event.key==pygame.K_SPACE:
game=1
pygame.display.update()
clock.tick(50)
Enfocando en esta sección de tu código:
if pygame.sprite.collide_rect(Player1,Enemy1):
game=2
Display.blit(background,(0,0))
pygame.mixer.music.load("untitled.mp3")
pygame.mixer.music.play(1,0.0)
Usualmente uso pygame.sprite.spritecollide ().
No estoy seguro si "collide_rect" puede hacer esto también, pero este es el truco:
pygame.sprite.spritecollide () devuelve una lista de colisiones. Esto es súper útil.
(Además, pondría todos tus sprites que quieras para que se comporten de esta manera en una lista).
- Así que si tuviera que usar todo esto en tu situación:
for each_enemy in enemy_list:
# see if player hit an enemy;
# the ''False'' flag means DON''T delete anything in the event of a collision
enemy_touched_list = pygame.sprite.spritecollide(each_enemy, Player1, False)
# good, now each enemy that was touching a player is in this list
# now we will iterate through this list and find a random place for the enemy.
for enemy_touched in enemy_touched_list:
enemy_touched.render(random.randint(0,width), random.randint(0,height))
Ok, entonces ese código atravesará a cada enemigo en tu lista de enemigos, verifica si está tocando a un jugador, y si es la posición del enemigo se reiniciará con tu método de clases Enemy .render ().
Para que la última línea funcione, tenemos que modificar un poco tu clase.
CLASES:
Parece que comprendes la sintaxis de configurar una clase, pero te estás perdiendo su poder.
¡No hay ninguna razón por la que deberías tener 4 clases enemigas! Todos son casi idénticos. ¡La única diferencia es unos pocos valores! ¡Eso suena como un objeto para mí!
Deberías tener UNA clase enemysprite y luego hacer tantos objetos de esa clase como tu corazón desee. Es por eso que las clases son las mejores. Cualquier ligera personalización que desee entre los sprites, configure su clase para que pueda pasarlos al crear un objeto.
--Dime si necesitas más ayuda para cambiar las cosas de la clase .--
--si eres nuevo en OOP y estas clases son de un tutorial, si ese es el caso, puedo darte más información--
y como dije antes, para que funcione mi versión de tu código, tenemos que cambiar tu método (pronto a ser único) de la clase enemiga .render ():
El original:
def RenderEnemy3(self):
pygame.draw.rect(Display, white,(MoveEnemy3X,MoveEnemy3Y,10,10))
self.rect = pygame.Rect(MoveEnemy3X,MoveEnemy3Y, self.width,self.height)
MODIFICADO:
def RenderEnemy3(self,xpos,ypos):
pygame.draw.rect(Display, white,(MoveEnemy3X,MoveEnemy3Y,xpos,ypos))
self.rect = pygame.Rect(MoveEnemy3X,MoveEnemy3Y, self.width,self.height)
Si quieres, puedo editar esta respuesta para incluir toda la clase "EnemySprite" modificada para que se comunique bien consigo misma y solo necesite UNA clase.
Espero que esto ayude. Simplemente comente si necesita aclaración sobre algo. Pygame es muy divertido.