From d986804c64ef57fea99d708683748f4cccffee92 Mon Sep 17 00:00:00 2001 From: Nikolya Andreychik Date: Sun, 4 Apr 2021 10:20:21 -0700 Subject: [PATCH 1/4] Init leaderboard menu --- Drakora.pyw | 57 ++++++++++++------- EndSceen.py | 158 ++++++++++++++++++++++++++++++++++++++++++++++++++++ leaders.txt | 5 ++ 3 files changed, 199 insertions(+), 21 deletions(-) create mode 100644 EndSceen.py create mode 100644 leaders.txt diff --git a/Drakora.pyw b/Drakora.pyw index 16e9a65..8c44d97 100644 --- a/Drakora.pyw +++ b/Drakora.pyw @@ -13,6 +13,7 @@ from StandingEnemy import StandingEnemy from FlyingEnemy import FlyingEnemy from Cloud import Cloud from Floor import Floor +from EndSceen import EndSceen class Drakora(): @@ -55,6 +56,13 @@ class Drakora(): self.speedUp() self.speedUpLabelCD = self.targetFps + def getFont(self): + return self.font + + + def getTime(self): + return self.time + def newGame(self): for enemy in self.enemies: @@ -87,6 +95,9 @@ class Drakora(): self.speedDownCheatLabelCD = 0 self.speedResetCheatLabelCD = 0 + self.time = 0 + self.endSceen.newEndScreen() + def __init__(self): random.seed() @@ -121,10 +132,10 @@ class Drakora(): self.drawBoxes = False - font = pygame.font.match_font('liberation mono') - self.fontScore = pygame.font.Font(font, 32) - self.fontMessage = pygame.font.Font(font, 56) - self.fontGodmode = pygame.font.Font(font, 12) + self.font = pygame.font.match_font('liberation mono') + self.fontScore = pygame.font.Font(self.font, 32) + self.fontMessage = pygame.font.Font(self.font, 56) + self.fontGodmode = pygame.font.Font(self.font, 12) self.charKeys = { pygame.K_a:'a', pygame.K_b:'b', pygame.K_c:'c', pygame.K_d:'d', @@ -138,6 +149,8 @@ class Drakora(): self.pressedKeys = deque(maxlen=10) self.isPressedKeysUpdated = True + self.endSceen = EndSceen(self) + self.newGame() @@ -167,23 +180,22 @@ class Drakora(): for floor in self.floors: pygame.draw.rect(self.screen, (255, 0, 0), floor.rect, 1) - self.renderText('%d'%(self.__score), - self.fontScore, (255, 255, 255), - (self.getScreenWidth()/2,20)) - if self.isGameOver: - self.renderText('GAME OVER', - self.fontMessage, (255, 255, 255), - tuple(i/2 for i in self.screenSize)) - elif self.isPaused: - self.renderText('PAUSED', - self.fontMessage, (255, 255, 255), - tuple(i/2 for i in self.screenSize)) - elif self.speedUpLabelCD > 0: - self.speedUpLabelCD -= 1 - self.renderText('SPEED UP', - self.fontMessage, (255, 255, 255), - tuple(i/2 for i in self.screenSize)) + self.endSceen.render(); + else: + self.renderText('%d'%(self.__score), + self.fontScore, (255, 255, 255), + (self.getScreenWidth()/2,20)) + + if self.isPaused: + self.renderText('PAUSED', + self.fontMessage, (255, 255, 255), + tuple(i/2 for i in self.screenSize)) + elif self.speedUpLabelCD > 0: + self.speedUpLabelCD -= 1 + self.renderText('SPEED UP', + self.fontMessage, (255, 255, 255), + tuple(i/2 for i in self.screenSize)) if self.isGodmode: self.renderText('godmode', @@ -267,6 +279,7 @@ class Drakora(): for event in pygame.event.get(): self.player.control(event) + self.endSceen.control(event) if event.type == pygame.QUIT: return False @@ -275,7 +288,7 @@ class Drakora(): if event.key in self.buttonsQuit: return False elif event.key in self.buttonsNewGame: - if self.isGameOver or self.isGodmode: self.newGame() + if self.isGodmode: self.newGame() elif event.key in self.buttonsPause: self.isPaused = not self.isPaused @@ -287,6 +300,8 @@ class Drakora(): self.doCheats() if not self.isGameOver and not self.isPaused: + self.time += 1/self.targetFps + for cloudGroup in self.cloudGroups: cloudGroup.update() self.enemies.update() self.players.update() diff --git a/EndSceen.py b/EndSceen.py new file mode 100644 index 0000000..27d3e9b --- /dev/null +++ b/EndSceen.py @@ -0,0 +1,158 @@ +""" +Enemy entity class +""" + + +import pygame + + +class EndSceen(): + def __init__(self, mainGameClass): + self.fontGameOver = pygame.font.Font(mainGameClass.getFont(), 56) + self.fontLeaderBoard = pygame.font.Font(mainGameClass.getFont(), 30) + self.fontLeaderBoardActive = pygame.font.Font(mainGameClass.getFont(), 30) + self.fontLeaderBoardActive.underline = True + self.game = mainGameClass + + def newEndScreen(self): + self.playerName = 'Player' + + self.scoresFromFile = [] + self.data = [] + + self.isBackButton = True + + fileWithData = open('leaders.txt') + + for line in fileWithData: + oneStr = line.split() + + if (len(oneStr) == 3): + self.data.append([oneStr[0][:10], int(oneStr[1]), float(oneStr[2])]) + + fileWithData.close() + + self.sortedDataByScores = sorted(enumerate(self.data), key=lambda i: i[1][1], reverse=True) + + + def renderText(self, text, font, color, center): + render = font.render(text, True, color) + rect = render.get_rect() + rect.center = center + self.game.screen.blit(render, rect) + + def drawTableLB(self, number): + j = 1 + placeFlag = False + + for i in [i[0] for i in self.sortedDataByScores[:number]]: + # print(self.data[i]) + + if (self.game.getScore() > self.data[i][1] and not placeFlag): + self.renderText('>{0:3} {1:^10} {2:6d} {3:8.2f}'.format(j, self.playerName[:10], self.game.getScore(), self.game.getTime()), + self.fontLeaderBoard, (255, 255, 255), + (self.game.getScreenWidth()/2,100 + j*50)) + j += 1 + placeFlag = True + + if (j > number): + break + + formatDataForOnePlayer = ' {0:3} {1:^10} {2:6d} {3:8.2f}'.format(j, *self.data[i]) + + self.renderText(formatDataForOnePlayer, + self.fontLeaderBoard, (255, 255, 255), + (self.game.getScreenWidth()/2,100 + j*50)) + + j += 1 + + if (j > number): + break + + if not placeFlag and j <= number: + self.renderText('>{0:3} {1:^10} {2:6d} {3:8.2f}'.format(j, self.playerName[:10], self.game.getScore(), self.game.getTime()), + self.fontLeaderBoard, (255, 255, 255), + (self.game.getScreenWidth()/2,100 + j*50)) + + + self.renderText(' {0:^10} {1:>6} {2:>8}'.format('.....', '..', '.....'), + self.fontLeaderBoard, (255, 255, 255), + (self.game.getScreenWidth()/2,100 + (number + 1)*50)) + + # for i in rows: + + def getScorePosition(self, score): + counter = 1 + for i in self.sortedDataByScores: + if i[1][1] < score: + return counter + else: + counter += 1 + return counter + + + def render(self): + self.renderText('GAME OVER', + self.fontGameOver, (255, 255, 255), + (self.game.getScreenWidth()/2,50)) + + self.renderText('Leaderboard', + self.fontLeaderBoard, (255, 255, 255), + (self.game.getScreenWidth()/2,100)) + + self.drawTableLB(5) + + self.renderText(' {0:3d} {1:^10} {2:6d} {3:8.2f}'.format(self.getScorePosition(self.game.getScore()), self.playerName[:10], self.game.getScore(), self.game.getTime()), + self.fontLeaderBoard, (255, 255, 255), + (self.game.getScreenWidth()/2,100 + 5*50 + 50 + 50)) + + self.renderText('Back', + self.fontLeaderBoard if not self.isBackButton else self.fontLeaderBoardActive, (255, 255, 255), + (self.game.getScreenWidth()/2 - 100, self.game.getScreenHeight() - 80)) + + self.renderText('Continue', + self.fontLeaderBoard if self.isBackButton else self.fontLeaderBoardActive, (255, 255, 255), + (self.game.getScreenWidth()/2 + 100, self.game.getScreenHeight() - 80)) + + def control(self, event): + if event.type == pygame.KEYDOWN and self.game.isGameOver: + if event.key == pygame.K_RIGHT: + self.isBackButton = False + + elif event.key == pygame.K_LEFT: + self.isBackButton = True + + elif event.key == pygame.K_RETURN: + self.saveResults() + + if self.isBackButton: + self.game.newGame() + else: + self.game.newGame() + + elif event.key == pygame.K_BACKSPACE: + self.playerName = self.playerName[:len(self.playerName) - 1] + + elif len(pygame.key.name(event.key)) == 1 and len(self.playerName) < 10: + if pygame.key.get_mods() & pygame.KMOD_LSHIFT: + self.playerName += pygame.key.name(event.key).upper() + else: + self.playerName += pygame.key.name(event.key).lower() + # self.playerName += self.game.charKeys[event.key] + + def saveResults(self): + with open ('leaders.txt', 'r') as fileWithData: + tmpData = fileWithData.readlines() + fileWithData.close() + + newData = [] + for line in tmpData: + if len(line.split()) == 3: + if not (line.split()[0].rstrip() == self.playerName.rstrip()): + newData.append(line) + + newData.append('{0} {1} {2:.2f}\n'.format(self.playerName, self.game.getScore(), self.game.getTime())) + + with open ('leaders.txt', 'w') as fileWithData: + fileWithData.writelines(newData) + fileWithData.close() diff --git a/leaders.txt b/leaders.txt new file mode 100644 index 0000000..9e0f24f --- /dev/null +++ b/leaders.txt @@ -0,0 +1,5 @@ +Kolya 1 11.37 +Coolguy 1 10.75 +Wow 74 185.72 +Player 0 7.16 +Cheater 1000 0.01 From 843df27d16f29885a3f4a1bcd51b92a84fc47ae2 Mon Sep 17 00:00:00 2001 From: Nikolya Andreychik Date: Mon, 5 Apr 2021 12:18:31 -0700 Subject: [PATCH 2/4] Modified leaderboard --- EndSceen.py | 52 +++++++++++++++++++++++++++++++++++++++------------- leaders.txt | 2 +- 2 files changed, 40 insertions(+), 14 deletions(-) diff --git a/EndSceen.py b/EndSceen.py index 27d3e9b..a2aa7d2 100644 --- a/EndSceen.py +++ b/EndSceen.py @@ -12,9 +12,12 @@ class EndSceen(): self.fontLeaderBoard = pygame.font.Font(mainGameClass.getFont(), 30) self.fontLeaderBoardActive = pygame.font.Font(mainGameClass.getFont(), 30) self.fontLeaderBoardActive.underline = True + self.fontError = pygame.font.Font(mainGameClass.getFont(), 15) + self.game = mainGameClass def newEndScreen(self): + self.endScreenTimer = 0; self.playerName = 'Player' self.scoresFromFile = [] @@ -35,8 +38,8 @@ class EndSceen(): self.sortedDataByScores = sorted(enumerate(self.data), key=lambda i: i[1][1], reverse=True) - def renderText(self, text, font, color, center): - render = font.render(text, True, color) + def renderText(self, text, font, color, center, backColor=None): + render = font.render(text, True, color, backColor) rect = render.get_rect() rect.center = center self.game.screen.blit(render, rect) @@ -49,7 +52,7 @@ class EndSceen(): # print(self.data[i]) if (self.game.getScore() > self.data[i][1] and not placeFlag): - self.renderText('>{0:3} {1:^10} {2:6d} {3:8.2f}'.format(j, self.playerName[:10], self.game.getScore(), self.game.getTime()), + self.renderText('>{0:3} {1:^10} {2:6d} {3:8.2f} '.format(j, self.playerName[:10], self.game.getScore(), self.game.getTime()), self.fontLeaderBoard, (255, 255, 255), (self.game.getScreenWidth()/2,100 + j*50)) j += 1 @@ -58,7 +61,7 @@ class EndSceen(): if (j > number): break - formatDataForOnePlayer = ' {0:3} {1:^10} {2:6d} {3:8.2f}'.format(j, *self.data[i]) + formatDataForOnePlayer = ' {0:3} {1:^10} {2:6d} {3:8.2f} '.format(j, *self.data[i]) self.renderText(formatDataForOnePlayer, self.fontLeaderBoard, (255, 255, 255), @@ -70,12 +73,12 @@ class EndSceen(): break if not placeFlag and j <= number: - self.renderText('>{0:3} {1:^10} {2:6d} {3:8.2f}'.format(j, self.playerName[:10], self.game.getScore(), self.game.getTime()), + self.renderText('>{0:3} {1:^10} {2:6d} {3:8.2f} '.format(j, self.playerName[:10], self.game.getScore(), self.game.getTime()), self.fontLeaderBoard, (255, 255, 255), (self.game.getScreenWidth()/2,100 + j*50)) - self.renderText(' {0:^10} {1:>6} {2:>8}'.format('.....', '..', '.....'), + self.renderText(' {0:>3} {1:^10} {2:>6} {3:>8} '.format('..','.....', '..', '.....'), self.fontLeaderBoard, (255, 255, 255), (self.game.getScreenWidth()/2,100 + (number + 1)*50)) @@ -92,6 +95,10 @@ class EndSceen(): def render(self): + backGround = pygame.Surface(self.game.screenSize, pygame.SRCALPHA) + backGround.fill((0,0,0,200)) + self.game.screen.blit(backGround, (0,0)) + self.renderText('GAME OVER', self.fontGameOver, (255, 255, 255), (self.game.getScreenWidth()/2,50)) @@ -102,9 +109,27 @@ class EndSceen(): self.drawTableLB(5) - self.renderText(' {0:3d} {1:^10} {2:6d} {3:8.2f}'.format(self.getScorePosition(self.game.getScore()), self.playerName[:10], self.game.getScore(), self.game.getTime()), + cursorChar = ' ' + if self.endScreenTimer > self.game.targetFps / 3: + cursorChar = '_' + + if self.endScreenTimer > 2 * self.game.targetFps / 3: + self.endScreenTimer = 0 + + self.endScreenTimer += 1 + + if len(self.playerName) > 0: + self.renderText(' {0:3d} {1:^10} {2:6d} {3:8.2f} '.format(self.getScorePosition(self.game.getScore()), self.playerName[:10] + (cursorChar if len(self.playerName) < 10 else ''), self.game.getScore(), self.game.getTime()), self.fontLeaderBoard, (255, 255, 255), - (self.game.getScreenWidth()/2,100 + 5*50 + 50 + 50)) + (self.game.getScreenWidth()/2,100 + (5 + 2)*50)) + else: + self.renderText(' {0:3d} {1:^10} {2:6d} {3:8.2f} '.format(self.getScorePosition(self.game.getScore()), self.playerName[:10] + (cursorChar if len(self.playerName) < 10 else ''), self.game.getScore(), self.game.getTime()), + self.fontLeaderBoard, (255, 255, 255), + (self.game.getScreenWidth()/2,100 + (5 + 2)*50), (200, 20, 20)) + + self.renderText(' {0:^30} '.format('Missing player name'), + self.fontError, (255, 255, 255), + (self.game.getScreenWidth()/2,100 + (5 + 2)*50 + 25)) self.renderText('Back', self.fontLeaderBoard if not self.isBackButton else self.fontLeaderBoardActive, (255, 255, 255), @@ -123,12 +148,13 @@ class EndSceen(): self.isBackButton = True elif event.key == pygame.K_RETURN: - self.saveResults() + if len(self.playerName) > 0: + self.saveResults() - if self.isBackButton: - self.game.newGame() - else: - self.game.newGame() + if self.isBackButton: + self.game.newGame() + else: + self.game.newGame() elif event.key == pygame.K_BACKSPACE: self.playerName = self.playerName[:len(self.playerName) - 1] diff --git a/leaders.txt b/leaders.txt index 9e0f24f..3b5b210 100644 --- a/leaders.txt +++ b/leaders.txt @@ -1,5 +1,5 @@ Kolya 1 11.37 Coolguy 1 10.75 Wow 74 185.72 -Player 0 7.16 Cheater 1000 0.01 +New-Kolya 2 15.20 From bbf81505e2a8cb7963aae710040ab97c83ea17b5 Mon Sep 17 00:00:00 2001 From: Nikolya Andreychik Date: Mon, 5 Apr 2021 14:01:42 -0700 Subject: [PATCH 3/4] Modified collision boxes --- CollisionBox.py | 21 +++++++++++++++++++++ Drakora.pyw | 7 +++++-- Player.py | 27 +++++++++++++++++++++++++++ leaders.txt | 1 + 4 files changed, 54 insertions(+), 2 deletions(-) create mode 100644 CollisionBox.py diff --git a/CollisionBox.py b/CollisionBox.py new file mode 100644 index 0000000..77ce5fc --- /dev/null +++ b/CollisionBox.py @@ -0,0 +1,21 @@ +""" +CollisionBox entity class +""" + +import pygame + + +class CollisionBox(pygame.sprite.Sprite): + def __init__(self, offsetX, offsetY, width, height, center): + pygame.sprite.Sprite.__init__(self) + + self.offset = (offsetX, offsetY) + self.size = (width, height) + self.rect = pygame.Rect(0, 0, width, height) + self.rect.center = center + + self.rect.x += self.offset[0] + self.rect.y += self.offset[1] + + def setY(self, y): + self.rect.y = y + self.offset[1] diff --git a/Drakora.pyw b/Drakora.pyw index 8c44d97..ec31570 100644 --- a/Drakora.pyw +++ b/Drakora.pyw @@ -174,7 +174,9 @@ class Drakora(): if self.drawBoxes: for player in self.players: - pygame.draw.rect(self.screen, (255, 0, 0), player.rect, 1) + for collision in self.player.getCollisionBoxes(): + pygame.draw.rect(self.screen, (255, 0, 0), collision.rect, 1) + # pygame.draw.rect(self.screen, (255, 0, 0), player.rect, 1) for enemy in self.enemies: pygame.draw.rect(self.screen, (255, 0, 0), enemy.rect, 1) for floor in self.floors: @@ -237,7 +239,7 @@ class Drakora(): def collideCheck(self): - if pygame.sprite.spritecollideany(self.player, self.enemies): + if sum([1 if pygame.sprite.spritecollideany(i, self.enemies) else 0 for i in self.player.getCollisionBoxes()]): if not self.isGodmode: self.isGameOver = True if self.player.isOnFloor: @@ -254,6 +256,7 @@ class Drakora(): def doCheats(self): + # self.drawBoxes = True if self.isPressedKeysUpdated: pressedKeysStr = ''.join(self.pressedKeys) diff --git a/Player.py b/Player.py index ee06e49..33f7958 100644 --- a/Player.py +++ b/Player.py @@ -6,6 +6,7 @@ Player entity class import pygame import math import os +from CollisionBox import CollisionBox class Player(pygame.sprite.Sprite): @@ -40,6 +41,9 @@ class Player(pygame.sprite.Sprite): for image in array: image.set_colorkey((255,0,255)) + def getCollisionBoxes(self): + return self.collisionBoxes + def __init__(self): pygame.sprite.Sprite.__init__(self) @@ -64,18 +68,38 @@ class Player(pygame.sprite.Sprite): self.gameSpeed = 1 self.updateCount = 0 + self.collisionBoxes = [] + + collision = CollisionBox(0, 20, 60, 20, self.rect.center) + self.collisionBoxes.append(collision) + collision = CollisionBox(-10, 5, 30, 20, self.rect.center) + self.collisionBoxes.append(collision) + collision = CollisionBox(0, 35, 25, 40, self.rect.center) + self.collisionBoxes.append(collision) + # self.collisionBoxes.append(self) + # collision = pygame.sprite.Sprite() + # collision.rect = pygame.Rect(0, 0, 25, 80) + # collision.rect.center = self.rect.center + # self.collisionBoxes.append(collision) + def crouch(self): if not self.isCrouching: self.isCrouching = True self.rect = self.rect.inflate(0, -32) + for i in self.collisionBoxes: + i.rect = i.inflate(0, -32) + def standup(self): if self.isCrouching: self.isCrouching = False self.rect = self.rect.inflate(0, 32) + for i in self.collisionBoxes: + i.rect = i.inflate(0, 32) + def updateSpeed(self, newGameSpeed): self.gameSpeed = newGameSpeed @@ -134,6 +158,9 @@ class Player(pygame.sprite.Sprite): self.rect.y += self.speed + for i in self.collisionBoxes: + i.setY(self.rect.y) + if self.updateCount >= 22 - math.log2(self.gameSpeed) * 2: if self.isOnFloor: if self.isCrouching: diff --git a/leaders.txt b/leaders.txt index 3b5b210..d1a8b6c 100644 --- a/leaders.txt +++ b/leaders.txt @@ -3,3 +3,4 @@ Coolguy 1 10.75 Wow 74 185.72 Cheater 1000 0.01 New-Kolya 2 15.20 +1 1 10.02 From b5c3dc32c7a6de1bf7c82f8ed9e1bab657f556e3 Mon Sep 17 00:00:00 2001 From: Nikolya Andreychik Date: Mon, 5 Apr 2021 14:06:34 -0700 Subject: [PATCH 4/4] Hotfix collision --- Drakora.pyw | 2 +- Player.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Drakora.pyw b/Drakora.pyw index ec31570..b72b900 100644 --- a/Drakora.pyw +++ b/Drakora.pyw @@ -256,7 +256,7 @@ class Drakora(): def doCheats(self): - # self.drawBoxes = True + self.drawBoxes = True if self.isPressedKeysUpdated: pressedKeysStr = ''.join(self.pressedKeys) diff --git a/Player.py b/Player.py index 33f7958..ad5bf2c 100644 --- a/Player.py +++ b/Player.py @@ -89,7 +89,7 @@ class Player(pygame.sprite.Sprite): self.rect = self.rect.inflate(0, -32) for i in self.collisionBoxes: - i.rect = i.inflate(0, -32) + i.rect.y -= 32 def standup(self): @@ -98,7 +98,7 @@ class Player(pygame.sprite.Sprite): self.rect = self.rect.inflate(0, 32) for i in self.collisionBoxes: - i.rect = i.inflate(0, 32) + i.rect.y += 32 def updateSpeed(self, newGameSpeed): self.gameSpeed = newGameSpeed