def __init__(self, numero, pj, name): self.n = numero self.balas = [] self.maxHp = 100 self.name = name self.nameRender = pygame.font.Font("fonts/Pixeled.ttf", 13).render(name, 0, (0, 0, 0)) self.pj = pj self.currentHp = self.maxHp self.direction = [0, 0] self.lastDirection = [0, 0] self.lastPos = [0, 0] self.moving = False self.state = "normal" self.time = 0 #image stuff---------------------------------------------- #cargar imagenes y animaciones comunes a todos nImageStr = str(self.pj) self.fotogramaEnAnimacion = 0 self.currentAnimation = None self.nextAnimations = [] self.animationStillRight = Animation("StillRight", 2, 200, nImageStr) self.animationStillLeft = Animation("StillLeft", 2, 200, nImageStr, self.animationStillRight, 1, 0) #la left es igual que la right self.imageDead = load_image("graphics/pjs/dead.png", True) #cargar imagenes y animaciones especificas de cada uno if self.pj == 1: self.animationChargeAttackRight = Animation( "ChargeAttackRight", 8, 62.5, nImageStr) self.animationChargeAttackLeft = Animation( "ChargeAttackLeft", 8, 62.5, nImageStr, self.animationChargeAttackRight, 1, 0) if self.pj == 3: self.animationChargeAttackRight = Animation( "ChargeAttackRight", 5, 100, nImageStr) self.animationChargeAttackLeft = Animation( "ChargeAttackLeft", 5, 100, nImageStr, self.animationChargeAttackRight, 1, 0) if self.pj == 4 or self.pj == 2: self.animationUltiRight = Animation("UltiRight", 2, 200, nImageStr) self.animationUltiLeft = Animation("UltiLeft", 2, 200, nImageStr, self.animationUltiRight, 1, 0) #right quieto: 1 #left quieto: 2 #animacion right quieto: 3 #animacion left quieto:4 self.setAnimation(self.animationStillRight) self.image = self.animationStillRight[0] self.rect = self.image.get_rect()
def __init__(self, name, frames, delayBetweenFrames, nImagenStr, animationMirror = None, mirrorX = 0, mirrorY = 0): self.name = name self.frames = frames self.delayBetweenFrames = round(delayBetweenFrames) if animationMirror: #si la animacion es una copia de otra, la copia for frame in animationMirror: self.append(pygame.transform.flip(frame, mirrorX, mirrorY)) else: #si no, la carga g = locals() for i in range(1, self.frames+1): g["image" + name + str(i)] = load_image("graphics/pjs/" + nImagenStr + "/" + name + str(i) + ".png", True) self.append(eval("image" + name + str(i)))
def __init__(self, n, nCharacter, cd): self.n = n self.imageOriginal = load_image( "graphics/GUI/skills/" + str(nCharacter) + "_" + str(n) + ".png", False) #.convert_alpha() self.image = self.imageOriginal.copy() self.greySurfaceCd = pygame.Surface(self.imageOriginal.get_size(), pygame.SRCALPHA) self.greySurfaceCd.fill((0, 0, 0, 150)) self.font = pygame.font.Font("fonts/Pixeled.ttf", 12) #self.cd = cd self.actualCd = 0
def __init__(self, numero, numeroPlayer, numeroImagen, sizeModifier, angle, initialPos): self.n = numero self.nPlayer = numeroPlayer self.image = load_image("graphics/shots/" + str(numeroImagen) + ".png", True) if angle >= -90 and angle <= 90: self.image = pygame.transform.rotate(self.image, angle) #si el angulo es de la mitad derecha, lo rota los angulos necesarios elif angle > 90 or angle < -90: self.image = pygame.transform.rotate(self.image, 180-angle)#si es de la mitad izquierda, lo rota los angulos como si fuera de la mitad derechaa (180-angle) self.image = pygame.transform.flip(self.image, 1, 0)#y despues los voltea horizontalmente #esto es para que por ejemplo el puño no aparezca hacia abajo if sizeModifier != 1: self.image = pygame.transform.scale(self.image, (int(self.image.get_size()[0]*sizeModifier), int(self.image.get_size()[1]*sizeModifier))) self.rect = self.image.get_rect(center=initialPos) #la initialPos es necesaria, ya que a veces se dibuja un fotograma en el que el servidor
def __init__(self, fnt): self.image = pygame.Surface((settings.CLIENT_SCREEN_SIZE[0] * 0.70, settings.CLIENT_SCREEN_SIZE[1] * 0.70)) self.image.fill((120, 120, 120)) self.rect = self.image.get_rect() self.rect.x, self.rect.y = settings.CLIENT_SCREEN_SIZE[ 0] * 0.15, settings.CLIENT_SCREEN_SIZE[1] * 0.15 self.size = (self.rect.width, self.rect.height) #self.image.get_size() #textos--------- txtInstructions = [ "Move: w a s d.", "Normal shoot: left click.", "Charged attack: hold right click.", "Game by", "KleSoft, Kyntasia and CerviGamer" ] i = 0 g = locals() for txt in txtInstructions[0:-1]: g["txtInstructions" + str(i)] = fnt.render(txt, 0, (0, 0, 0)) #eval("txtInstructions" + str(i)).set_alpha(200) self.image.blit(eval("txtInstructions" + str(i)), (self.size[0] * 0.20, self.size[1] * (0.20 + (0.10 * i)))) i += 1 g["txtInstructions" + str(i)] = fnt.render( txtInstructions[-1], 0, (255, 0, 0)) #el ultimo lo hace aparte, ya que va con un color diferente self.image.blit(eval("txtInstructions" + str(i)), (self.size[0] * 0.20, self.size[1] * (0.20 + (0.10 * i)))) #fintextos------ #buttons-------- self.buttonSalir = load_image("graphics/GUI/exitButton.png", True) self.buttonSalirRect = self.buttonSalir.get_rect() self.buttonSalirRect.x, self.buttonSalirRect.y = self.size[ 0] * 0.85, self.size[ 1] * 0.85 #esta colision seria dentro del surface del menu self.buttonSalirRealRect = self.buttonSalir.get_rect() self.buttonSalirRealRect.x, self.buttonSalirRealRect.y = self.buttonSalirRect.x + self.rect.x, self.buttonSalirRect.y + self.rect.y #y esta colision seria en la pantalla entera self.image.blit(self.buttonSalir, self.buttonSalirRect) self.image.set_alpha(200)
def main(): print("Bienvenido al mejor juego de la historia") resFile = open("resolution", "r") res = resFile.read() resFile.close() g = locals() pygame.init() #MENU----------------------------------------------------------------------------- empezar = False pantalla = pygame.display.set_mode(settings.MENU_SCREEN_SIZE) pygame.display.set_caption(settings.CLIENT_SCREEN_TITLE) reloj = pygame.time.Clock() mFont = pygame.font.Font("fonts/Pixeled.ttf", 15) mNameTextBox = mTextBox([125, 190], [150, 20]) mButtonConectarRect = pygame.Rect(170, 231, 61, 29) mButtonCambiarPJRightRect = pygame.Rect(286, 135, 46, 28) mButtonCambiarPJLeftRect = pygame.Rect(71, 137, 46, 28) mOptionsSurface = pygame.Surface((settings.MENU_SCREEN_SIZE[0] * 0.80, settings.MENU_SCREEN_SIZE[1] * 0.80), pygame.SRCALPHA) mOptionsAbiertas = False mOptions = mRadioButton( (int(settings.MENU_SCREEN_SIZE[0] * 0.20), int(settings.MENU_SCREEN_SIZE[1] * 0.20)), ["2000x1125", "1600x900", "1350x760", "1200x675", "800x450"], mFont, int(res)) for i in range(settings.NUMERO_JUGADORES_ESCOGIBLES ): #cargo las imagenes de todos los personajes #g["mP" + str(i+1)] = [load_image("graphics/pjs/" + str(i+1) + ".png", True), load_image("graphics/pjs/" + str(i+1) + "_3.png", True)] g["mP" + str(i + 1)] = [ load_image("graphics/pjs/" + str(i + 1) + "/StillRight1.png", True), load_image("graphics/pjs/" + str(i + 1) + "/StillRight2.png", True) ] fotograma = 0 time = pygame.time.get_ticks() mMenuImage = load_image("graphics/GUI/menu.png", False) settings.mPEscogido = 1 #definir imagenes while empezar == False: reloj.tick(60) mouse = pygame.mouse.get_pressed() mousePos = pygame.mouse.get_pos() for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() if event.type == pygame.KEYDOWN: mNameTextBox.checkKeys(event.key) if event.key == pygame.K_LEFT: settings.mPEscogido = mCambiarPjElegido( settings.mPEscogido, -1) elif event.key == pygame.K_RIGHT: settings.mPEscogido = mCambiarPjElegido( settings.mPEscogido, 1) elif event.key == pygame.K_RETURN: if mNameTextBox.text: empezar = True elif event.key == pygame.K_ESCAPE: if mOptionsAbiertas == False: mOptionsAbiertas = True else: mOptionsAbiertas = False if mOptionsAbiertas == True: if event.key == pygame.K_DOWN: if mOptions.elementChosen != len( mOptions.elements) - 1: mOptions.elementChosen += 1 else: mOptions.elementChosen = 0 elif event.key == pygame.K_UP: if mOptions.elementChosen != 0: mOptions.elementChosen -= 1 else: mOptions.elementChosen = len(mOptions.elements) - 1 if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1: if mButtonConectarRect.collidepoint(mousePos): if mNameTextBox.text: empezar = True elif mButtonCambiarPJRightRect.collidepoint(mousePos): settings.mPEscogido = mCambiarPjElegido( settings.mPEscogido, 1) elif mButtonCambiarPJLeftRect.collidepoint(mousePos): settings.mPEscogido = mCambiarPjElegido( settings.mPEscogido, -1) if mOptionsAbiertas == True: mOptions.collide(mousePos) pantalla.blit(mMenuImage, (0, 0)) #for button in mButtons: # if button.rect.collidepoint(mousePos): # if mouse[0]: # empezar = True #button.draw(pantalla) if pygame.time.get_ticks() - time >= 200: if fotograma == 0: fotograma = 1 elif fotograma == 1: fotograma = 0 time = pygame.time.get_ticks() if settings.mPEscogido == 3: pantalla.blit( eval("mP" + str(settings.mPEscogido))[fotograma], (147, 80) ) #a saitama se le pone un poco a la izquierda por el tamaño de imagen else: pantalla.blit( eval("mP" + str(settings.mPEscogido))[fotograma], (163, 80)) #pygame.draw.rect(pantalla, (0,0,0), (100,20,200,20)) mNameTextBox.draw(pantalla) if mOptionsAbiertas: mOptionsSurface.fill((255, 255, 255, 200)) pantalla.blit(mOptionsSurface, (settings.MENU_SCREEN_SIZE[0] * 0.10, settings.MENU_SCREEN_SIZE[1] * 0.10)) mOptions.draw(pantalla) pygame.display.flip() #FINMENU------------------------------------------------------------------------- if mOptions.elementChosen == 0: RESOLUCION = (2000, 1125) elif mOptions.elementChosen == 1: RESOLUCION = (1600, 900) elif mOptions.elementChosen == 2: RESOLUCION = (1350, 760) elif mOptions.elementChosen == 3: RESOLUCION = (1200, 675) elif mOptions.elementChosen == 4: RESOLUCION = (800, 450) resFile = open("resolution", "w") resFile.write(str(mOptions.elementChosen)) resFile.close() #Creacion de objetos----------------------------- Globals.JugadoresEncontrados = [] PowerUps = [] Skills = [] Muros = [] PointsRanking = Ranking() Globals.s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) Globals.s.settimeout(5) MenuIngame = Menu(pygame.font.Font("fonts/Pixeled.ttf", 20)) Skill2 = Skill(2, settings.mPEscogido, 25) Skills.append(Skill2) #------------------------------------------------ #Proceso de conexión----------------------------- print("Intentando conectar...") sendDataToServer( packPacket(["newUser", mNameTextBox.text, settings.mPEscogido])) try: answer = recvSinglePacketFromServer( ) #compruebo si el servidor me acepta except ConnectionResetError: print("FATAL ERROR: CONNECTION RESET") sys.exit() if not int(answer[0]): print("Conexión rechazada") sys.exit() print("Let's go") pantalla = pygame.Surface( (settings.CLIENT_SCREEN_SIZE) ) #pantalla es la surface donde se dibuja todo, y que tiene el tamaño original de settings.CLIENT_SCREEN_SIZE truePantalla = pygame.display.set_mode( RESOLUCION ) #truePantalla es la pantalla verdadera, que tiene el tamaño de la resolucion escogida. la superficie anterior #se escala al tamaño de la resolucion despues de que se haya dibujado todo en ella, y se dibuja en truePantalla. todo esto ocurre en tDrawEverything pygame.display.set_caption(settings.CLIENT_SCREEN_TITLE) #NOTA: Ahora los datos de todos los jugadores, walls, powerups, etc los recibe el cliente dentro de tRecvData tEventExit = threading.Event() threadRecvData = threading.Thread(target=tRecvData, args=(tEventExit, PowerUps, Skills, Muros, PointsRanking), name="tRecvData", daemon=True) threadRecvData.start() threadDrawEverything = threading.Thread( target=tDrawEverything, args=(tEventExit, PowerUps, Skills, Muros, PointsRanking, MenuIngame, pantalla, truePantalla), name="tDrawEverything", daemon=True) threadDrawEverything.start() threadMusica = threading.Thread(target=tCheckAndSetMusic, args=(tEventExit, ), name="tCheckAndSetMusic", daemon=True) threadMusica.start() UPfirst, DOWNfirst, LEFTfirst, RIGHTfirst = False, False, False, False inputx, inputy, lastinputx, lastinputy = 0, 0, 0, 0 while tEventExit.is_set() == False: time = reloj.tick(60) #print(reloj.get_fps()) keys = pygame.key.get_pressed() mouse = pygame.mouse.get_pressed() screenMousePos = pygame.mouse.get_pos( ) #obtiene la posicion del raton en la pantalla del cliente, sin embargo esta posicion puede ser diferente a la real del servidor mousePos = [ 0, 0 ] #dependiendo de la resolucion. por ello, se multiplica por la relacion entre la resolucion real y la del cliente mousePos[0] = int( screenMousePos[0] * settings.CLIENT_SCREEN_SIZE[0] / RESOLUCION[0] ) #ej: si la resolucion del cliente es 1200x675 y la del servidor es de 1600x900, mousePos[1] = int( screenMousePos[1] * settings.CLIENT_SCREEN_SIZE[1] / RESOLUCION[1] ) #si clickas en la coordenada x 1200, la resolucion real seria 1600. for event in pygame.event.get(): if event.type == pygame.QUIT: #al intentar salir: tEventExit.set( ) #activa una flag para todos los threads terminen waitUntilAllSecondaryThreadsClosed( ) #espera a que terminen todos menos el main thread antes de cerrar el socket y enviar "bye" al server #esto es necesario ya que si no podriamos cerrar el socket mientras tRecvData lo usa o algo parecido. goodbye() #se cierra el socket, se envia bye y se sale break if event.type == pygame.MOUSEBUTTONDOWN: if event.button == 1: #LEFT CLICK if settings.MENU_ACTIVADO == True and MenuIngame.buttonSalirRealRect.collidepoint( mousePos): tEventExit.set( ) #todo es lo mismo que if event.type == pygame.QUIT: #la unica diferencia es que aqui no se cierra el socket, y despues vuelve a empezar el programa waitUntilAllSecondaryThreadsClosed() sendDataToServer(packPacket(["bye"])) settings.MENU_ACTIVADO = False main() if event.button == 3: #RIGHT CLICK if not checkIfMouseCollidesWithMenu( mousePos, MenuIngame.rect): sendDataToServer( packPacket(["skill", 1, mousePos[0], mousePos[1]])) #CHARGING #~ if event.type == pygame.MOUSEBUTTONDOWN and event.button == 3: #left click pulsar #~ sendDataToServer(packPacket(["startChargingAttack"])) #~ if event.type == pygame.MOUSEBUTTONUP and event.button == 3: #~ sendDataToServer(packPacket(["stopChargingAttack", mousePos[0], mousePos[1]])) if event.type == pygame.KEYDOWN: if event.key == K_ESCAPE: if settings.MENU_ACTIVADO == False: settings.MENU_ACTIVADO = True elif settings.MENU_ACTIVADO == True: settings.MENU_ACTIVADO = False if event.key == K_SPACE: if Skill2.actualCd <= 0: #esta comprobacion se hace en el servidor, pero tambien en el cliente. eso se debe a que hay 0.5 secs de diferencia entre #el cd del server y el del cliente, y si se enviara esta peticion en esos 0.5 secs, el cd del cliente se bugearia #a efectos practicos no tiene consecuencias ya que el que cuenta es el cd del server, pero queda feo sendDataToServer( packPacket(["skill", 2, mousePos[0], mousePos[1]])) if mouse[0]: #left click continuado: if not checkIfMouseCollidesWithMenu(mousePos, MenuIngame.rect): sendDataToServer( packPacket(["shoot", mousePos[0], mousePos[1]])) #print(mousePos) if keys[K_w]: if not keys[K_s]: inputy = -1 UPfirst = True DOWNfirst = False if keys[K_s]: if not keys[K_w]: inputy = 1 DOWNfirst = True UPfirst = False if keys[K_s] and keys[K_w]: if DOWNfirst == True: inputy = -1 elif UPfirst == True: inputy = 1 if not keys[K_w] and not keys[K_s]: inputy = 0 #EXPLICACION: si solo la tecla de arriba esta pulsada, va hacia arriba, y se establece que se pulsó primero la de arriba y no la de abajo. #Si solo la tecla de abajo esta pulsada, va hacia abajo, y se establece que se pulsó primero la de abajo y no la de arriba. #Si estan las dos pulsadas, y se pulsó primero la de abajo, va hacia arriba. Si se pulsó primero la de arriba, va hacia abajo. #Si no hay ninguna pulsada, no se mueve. Todo esto es aplicable también para el eje x. #Todo esto recoge la direccion a la que debe ir el jugador, y es enviado al servidor, quien se encarga de hacer los calculos y dar la posicion resultante. if keys[K_d]: if not keys[K_a]: inputx = 1 RIGHTfirst = True LEFTfirst = False if keys[K_a]: if not keys[K_d]: inputx = -1 LEFTfirst = True RIGHTfirst = False if keys[K_d] and keys[K_a]: if RIGHTfirst == True: inputx = -1 elif LEFTfirst == True: inputx = 1 if not keys[K_d] and not keys[K_a]: inputx = 0 if inputx != lastinputx or inputy != lastinputy: sendDataToServer(packPacket(["input", inputx, inputy])) lastinputx = inputx lastinputy = inputy
def __init__(self, n, currentState, currentPos): self.image = load_image("graphics/powerups/" + str(n) + ".png", True) self.rect = self.image.get_rect() self.rect.centerx, self.rect.centery = currentPos[0], currentPos[1] self.visible = currentState
def tDrawEverything(tEventExit, PowerUps, Skills, Muros, PointsRanking, MenuIngame, pantalla, pantallaVerdadera): reloj = pygame.time.Clock() #creacion de textos y surfaces fnt = pygame.font.Font("fonts/Pixeled.ttf", 20) barraInferior = load_image("graphics/GUI/skillbar.png", True) imageCharacter = load_image( "graphics/pjs/" + str(settings.mPEscogido) + "/c.png", True) barraInferior.blit(imageCharacter, (9, 14)) #fin creacion de textos y surfaces time = pygame.time.get_ticks() while tEventExit.is_set() == False: #print(Globals.JugadoresEncontrados) pantalla.fill((255, 255, 255)) #global settings.MENU_ACTIVADO for jugador in Globals.JugadoresEncontrados: #primero dibuja los jugadores y sus balas jugador.draw(pantalla) #pygame.draw.rect(pantalla, (255,0,0), jugador.rect, 2) for bala in jugador.balas: bala.draw(pantalla) #pygame.draw.rect(pantalla, (255,0,0), bala.rect, 2) for muro in Muros: muro.draw(pantalla) for powerup in PowerUps: #las powerups powerup.draw(pantalla) for jugador in Globals.JugadoresEncontrados: #las barras de vida y nombre, y la foto del pj jugador.drawHPBar(pantalla) if settings.MENU_ACTIVADO == True: MenuIngame.draw(pantalla) PointsRanking.draw(pantalla, fnt) for skill in Skills: skill.draw(barraInferior) #print(int((barraInferior.get_height()/2) - skill.image.get_height()), int(barraInferior.get_width()*0.20)) if checkIfAnyPlayerCollidesWithRect( barraInferior.get_rect(), (0, settings.CLIENT_SCREEN_SIZE[1] - barraInferior.get_height())): barraInferior.set_alpha(170) else: barraInferior.set_alpha(255) pantalla.blit( barraInferior, (0, settings.CLIENT_SCREEN_SIZE[1] - barraInferior.get_height())) #pygame.draw.rect(pantalla, (255,0,0), (200,200,20,100), 1) #todas las cosas se dibujan en la variable pantalla, que tiene de tamaño settings.CLIENT_SCREEN_SIZE (el tamaño original del servidor) #después, esta pantalla se escala al tamaño de la resolucion elegida para dibujarse en la pantallaVerdadera pantallaVerdadera.blit( pygame.transform.scale(pantalla, pantallaVerdadera.get_size()), (0, 0)) pygame.display.flip() #print(reloj.get_fps()) reloj.tick(60)