Merge pull request #8 from IRUSlan92I/gameclass

Version with new cool features
This commit is contained in:
2021-03-29 17:35:19 +03:00
committed by GitHub
7 changed files with 439 additions and 267 deletions
+33
View File
@@ -0,0 +1,33 @@
"""
Cloud entity class
"""
import pygame
import random
class Cloud(pygame.sprite.Sprite):
def __init__(self, mainGameClass):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface((random.randint(150, 350),
random.randint(50, 150)))
self.image.fill((random.randint(235, 255),
random.randint(235, 255),
random.randint(235, 255)))
self.rect = self.image.get_rect()
self.rect.center = (mainGameClass.getScreenWidth() + self.rect.width,
mainGameClass.getScreenHeight()/2 -
random.randint(100,
mainGameClass.getScreenHeight()/2-100))
self.speed = random.randint(1, 3)*mainGameClass.getGameSpeed() / 6
self.__doubleX = float(self.rect.x)
def update(self):
if (self.rect.x < -self.rect.width):
self.kill()
self.__doubleX -= self.speed
self.rect.x = self.__doubleX
+203 -252
View File
@@ -1,322 +1,273 @@
""" """
First test Pygame project Main game class
"""
Written in Python 3.X using Pygame library
"""
import pygame import pygame
import random import random
buttonsPause = (pygame.K_p,) from collections import deque
buttonsQuit = (pygame.K_F10,)
buttonsNewGame = (pygame.K_RETURN,)
buttonsJump = (pygame.K_UP, pygame.K_SPACE,)
buttonsCrouch = (pygame.K_DOWN,)
screenSize = (800, 600) from Player import Player
targetFps = 60 from StandingEnemy import StandingEnemy
from FlyingEnemy import FlyingEnemy
floorHeight = 50 from Cloud import Cloud
from Floor import Floor
gameSpeed = 0.0
score = 0
isGameOver = False
isPaused = False
isDownJump = False
isDownCrouch = False
enemyCD = 0
enemyChance = 0.0
floors = pygame.sprite.Group()
enemies = pygame.sprite.Group()
clouds = pygame.sprite.Group()
player = None
class Floor(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface((screenSize[0], floorHeight))
self.image.fill((255, 204, 102))
self.rect = self.image.get_rect()
self.rect.center = (screenSize[0]/2, screenSize[1]-floorHeight/2)
class Cloud(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface((random.randint(150, 350),
random.randint(50, 150)))
self.image.fill((random.randint(235, 255),
random.randint(235, 255),
random.randint(235, 255)))
self.rect = self.image.get_rect()
self.rect.center = (screenSize[0] + self.rect.width,
screenSize[1]/2 -
random.randint(100, screenSize[1]/2-100))
self.speed = random.randint(150, 300)/100
def update(self):
self.rect.x -= gameSpeed*self.speed
if (self.rect.x < -self.rect.width):
self.kill()
class Player(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface((50, 75))
self.image.fill((153, 151, 0))
self.rect = self.image.get_rect()
self.rect.center = (100, 400)
self.speed = 0.0
self.isJumping = False
self.isCrouching = False
self.hoverCount = 0
def crouch(self):
if not self.isCrouching:
self.isCrouching = True
self.rect = self.rect.inflate(0, -25)
def standup(self):
if self.isCrouching:
self.isCrouching = False
self.rect = self.rect.inflate(0, 25)
def update(self):
global isGameOver
if pygame.sprite.spritecollideany(player, enemies):
isGameOver = True
pass
if not self.speed: self.rect.y += 1
self.speed += 0.35
self.rect.y += self.speed
isOnFloor = False
while pygame.sprite.spritecollideany(player, floors):
isOnFloor = True
self.rect.y -= 1
if not isDownJump:
self.hoverCount = 0
if isOnFloor:
self.speed = 0
if isDownJump:
self.isJumping = True
if self.isCrouching:
self.standup()
elif isDownCrouch:
if not self.isCrouching:
self.crouch()
elif self.isCrouching:
self.standup()
if self.isJumping: class Drakora():
if isDownJump and self.hoverCount < 10: def getGameSpeed(self):
self.speed -= 1 - self.speed/(15+self.hoverCount*3) return self.__gameSpeed
self.hoverCount += 1
else:
self.isJumping = False
def getScore(self):
return self.__score
class Enemy(pygame.sprite.Sprite):
def setNextEnemyType(self):
if score < 10:
self.type = 1
elif score < 25: def getScreenWidth(self):
if random.randint(1, 100) < 95: self.type = 1 return self.screenSize[0]
else: self.type = 2
elif score < 50:
if random.randint(1, 100) < 85: self.type = 1
else: self.type = 2
else: def getScreenHeight(self):
if random.randint(1, 100) < 75: self.type = 1 return self.screenSize[1]
else: self.type = 2
def setNextEnemySubtype(self):
if self.type == 1:
self.subtype = random.randint(1, 5)
elif self.type == 2:
self.subtype = random.randint(1, 3)
def __init__(self): def getFloorHeight(self):
pygame.sprite.Sprite.__init__(self) return self.floorHeight
self.setNextEnemyType()
self.setNextEnemySubtype()
self.height = screenSize[1] - floorHeight def addScore(self, score):
self.__score += score
if self.type == 1: if self.__score%self.speedUpRate == 0:
if self.subtype == 1: self.image = pygame.Surface((25, 75)) self.__gameSpeed += self.__score/self.speedUpRate
elif self.subtype == 2: self.image = pygame.Surface((25, 25)) self.speedUpLabelCD = self.targetFps
elif self.subtype == 3: self.image = pygame.Surface((75, 25))
elif self.subtype == 4: self.image = pygame.Surface((50, 25))
elif self.subtype == 5: self.image = pygame.Surface((50, 50))
else: self.image = pygame.Surface((25, 50))
self.image.fill((0, 153, 0))
self.rect = self.image.get_rect()
self.height -= self.rect.height/2
elif self.type == 2: def newGame(self):
self.image = pygame.Surface((50, 25)) for enemy in self.enemies:
self.image.fill((51, 51, 0))
self.rect = self.image.get_rect()
self.height -= self.rect.height/2 + 10 + 25*self.subtype
self.rect.center = (screenSize[0] + self.rect.width, self.height)
def update(self):
global score, gameSpeed
self.rect.x -= gameSpeed
if (self.rect.x < -self.rect.width):
self.kill()
score += 1
gameSpeed += 0.025
def newGame():
global player, floor, enemies, sprites, score
global gameSpeed, isGameOver, enemyCD, enemyChance
for enemy in enemies:
enemy.kill() enemy.kill()
if player: player.kill() if self.player: self.player.kill()
player = Player() self.player = Player()
sprites.add(player) self.sprites.add(self.player)
gameSpeed = 3.0 self.__score = 0
score = 0 self.isGameOver = False
isGameOver = False self.isPaused = False
isPaused = False
enemyCD = 0 self.__gameSpeed = 2
enemyChance = 100.0
self.enemyCount = 0
self.enemyChance = 100.0
self.speedUpLabelCD = 0
self.nextEnemyMustBeFlying = False
self.enemyCD = self.getNextEnemyCD()
def init(): def __init__(self):
global player, floor, enemies, sprites, score self.buttonsPause = (pygame.K_p,)
self.buttonsQuit = (pygame.K_F10,)
self.buttonsNewGame = (pygame.K_RETURN,)
self.screenSize = (800, 600)
self.targetFps = 120
self.floorHeight = 50
self.floors = pygame.sprite.Group()
self.enemies = pygame.sprite.Group()
self.clouds = pygame.sprite.Group()
self.player = None
self.speedUpRate = 25
self.godmodeCount = 0
self.isGodmode = False
random.seed() random.seed()
pygame.init() pygame.init()
screen = pygame.display.set_mode(screenSize) self.screen = pygame.display.set_mode(self.screenSize)
pygame.display.set_caption('Drakora') pygame.display.set_caption('Drakora')
clock = pygame.time.Clock() self.clock = pygame.time.Clock()
sprites = pygame.sprite.Group() self.sprites = pygame.sprite.Group()
floors.add(Floor()) self.floors.add(Floor(self))
sprites.add(floors) self.sprites.add(self.floors)
newGame() 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)
return screen, clock, sprites self.charKeys = {
pygame.K_a:'a', pygame.K_b:'b', pygame.K_c:'c', pygame.K_d:'d',
pygame.K_e:'e', pygame.K_f:'f', pygame.K_g:'g', pygame.K_h:'h',
pygame.K_i:'i', pygame.K_j:'j', pygame.K_k:'k', pygame.K_l:'l',
pygame.K_m:'m', pygame.K_n:'n', pygame.K_o:'o', pygame.K_p:'p',
pygame.K_q:'q', pygame.K_r:'r', pygame.K_s:'s', pygame.K_t:'t',
pygame.K_u:'u', pygame.K_v:'v', pygame.K_w:'w', pygame.K_x:'x',
pygame.K_y:'y', pygame.K_z:'z',
}
self.pressedKeys = deque(maxlen=10)
self.isPressedKeysUpdated = True
def deinit(): self.newGame()
def __del__(self):
pygame.quit() pygame.quit()
def render(screen, sprites):
screen.fill((102, 153, 255))
sprites.draw(screen)
font = pygame.font.Font(pygame.font.match_font('liberation mono'), 32) def renderText(self, text, font, color, center):
text = font.render('%d'%(score), True, (255, 255, 255)) render = font.render(text, True, color)
rect = text.get_rect() rect = render.get_rect()
rect.midtop = (rect.width/2+10,10) rect.center = center
screen.blit(text, rect) self.screen.blit(render, rect)
if isGameOver:
font = pygame.font.Font(pygame.font.match_font('liberation mono'), 56)
text = font.render('GAME OVER', True, (255, 255, 255))
rect = text.get_rect()
rect.midtop = tuple(i/2 for i in screenSize)
screen.blit(text, rect)
elif isPaused:
font = pygame.font.Font(pygame.font.match_font('liberation mono'), 56)
text = font.render('PAUSED', True, (255, 255, 255))
rect = text.get_rect()
rect.midtop = tuple(i/2 for i in screenSize)
screen.blit(text, rect)
def render(self):
self.screen.fill((102, 153, 255))
self.sprites.draw(self.screen)
self.floors.draw(self.screen)
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))
if self.isGodmode:
self.renderText('godmode',
self.fontGodmode, (255, 255, 255),
(self.getScreenWidth()/2,40))
pygame.display.flip() pygame.display.flip()
def logic(clock, sprites): def getNextEnemyCD(self):
global enemyCD, enemyChance, isDownJump, isDownCrouch, isPaused if self.enemyCount == 0:
return 1000
elif self.enemyCount <= 5:
return 800 - 100*self.enemyCount
elif self.enemyCount%self.speedUpRate == 0:
return 1000
elif self.nextEnemyMustBeFlying:
return 600
else:
return 300
def collideCheck(self):
if pygame.sprite.spritecollideany(self.player, self.enemies):
if not self.isGodmode: self.isGameOver = True
self.player.isOnFloor = False
while pygame.sprite.spritecollideany(self.player, self.floors):
self.player.isOnFloor = True
self.player.rect.y -= 1
def doCheats(self):
if self.isPressedKeysUpdated:
pressedKeysStr = ''.join(self.pressedKeys)
if pressedKeysStr.endswith('godmode'):
self.isGodmode = not self.isGodmode
self.isPressedKeysUpdated = False
def logic(self):
self.player.updateSpeed(self.__gameSpeed)
for event in pygame.event.get(): for event in pygame.event.get():
self.player.control(event)
if event.type == pygame.QUIT: if event.type == pygame.QUIT:
return False return False
elif event.type == pygame.KEYDOWN: elif event.type == pygame.KEYDOWN:
if event.key in buttonsQuit: if event.key in self.buttonsQuit:
return False return False
if event.key in buttonsCrouch: elif event.key in self.buttonsNewGame:
isDownCrouch = True if self.isGameOver or self.isGodmode: self.newGame()
elif event.key in buttonsJump: elif event.key in self.buttonsPause:
isDownJump = True self.isPaused = not self.isPaused
elif event.key in buttonsNewGame:
if isGameOver: newGame()
elif event.key in buttonsPause:
isPaused = not isPaused
elif event.type == pygame.KEYUP: elif event.type == pygame.KEYUP:
if event.key in buttonsCrouch: if event.key in self.charKeys:
isDownCrouch = False self.pressedKeys.append(self.charKeys[event.key])
if event.key in buttonsJump: self.isPressedKeysUpdated = True
isDownJump = False
if not isGameOver and not isPaused: self.doCheats()
sprites.update()
enemyCD -= gameSpeed if not self.isGameOver and not self.isPaused:
self.sprites.update()
if random.randint(1, 100) == 1: self.enemyCD -= self.__gameSpeed
cloud = Cloud()
clouds.add(cloud)
sprites.add(cloud)
if enemyCD <= 0: if random.randint(1, 200) == 1:
enemyChance += (1/targetFps) * enemyChance/8 cloud = Cloud(self)
self.clouds.add(cloud)
self.sprites.add(cloud)
if random.randint(1, 100) < enemyChance: if self.enemyCD <= 0:
enemyCD = 200 self.enemyChance += (1/self.targetFps) * self.enemyChance/8
enemyChance = 1
enemy = Enemy()
enemies.add(enemy)
sprites.add(enemy)
if random.randint(1, 150) < self.enemyChance:
self.enemyCount += 1
self.enemyChance = 1
clock.tick(targetFps) if self.nextEnemyMustBeFlying:
enemy = FlyingEnemy(self)
else:
enemy = StandingEnemy(self)
if self.__score < 10:
self.nextEnemyMustBeFlying = False
elif self.__score < 20:
self.nextEnemyMustBeFlying = random.randint(1, 100) > 95
elif self.__score < 40:
self.nextEnemyMustBeFlying = random.randint(1, 100) > 85
else:
self.nextEnemyMustBeFlying = random.randint(1, 100) > 75
self.enemyCD = self.getNextEnemyCD()
self.enemies.add(enemy)
self.sprites.add(enemy)
self.collideCheck()
return True return True
def main_loop(screen, clock, sprites):
global isGameOver
def play(self):
isRunning = True isRunning = True
while isRunning: while isRunning:
isRunning = logic(clock, sprites) self.clock.tick(self.targetFps)
render(screen, sprites) self.render()
isRunning = self.logic()
if __name__ == '__main__': if __name__ == '__main__':
screen, clock, sprites = init() drakora = Drakora()
main_loop(screen, clock, sprites) drakora.play()
deinit() del Drakora
+25
View File
@@ -0,0 +1,25 @@
"""
Enemy entity class
"""
import pygame
import random
class Enemy(pygame.sprite.Sprite):
def __init__(self, mainGameClass):
pygame.sprite.Sprite.__init__(self)
self.thisGame = mainGameClass
self.height = (mainGameClass.getScreenHeight()
- mainGameClass.getFloorHeight())
def update(self):
if (self.rect.x < -self.rect.width):
self.kill()
self.thisGame.addScore(1)
self.rect.x -= self.speed
+18
View File
@@ -0,0 +1,18 @@
"""
Floor entity class
"""
import pygame
class Floor(pygame.sprite.Sprite):
def __init__(self, mainGameClass):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface((mainGameClass.getScreenWidth(),
mainGameClass.getFloorHeight()*101))
self.image.fill((255, 204, 102))
self.rect = self.image.get_rect()
self.rect.center = (mainGameClass.getScreenWidth()/2,
mainGameClass.getScreenHeight() +
mainGameClass.getFloorHeight()*49.5)
+25
View File
@@ -0,0 +1,25 @@
"""
Flying enemy entity class
"""
import pygame
import random
from Enemy import Enemy
class FlyingEnemy(Enemy):
def __init__(self, mainGameClass):
Enemy.__init__(self, mainGameClass)
self.subtype = random.randint(1, 7)
self.image = pygame.Surface((50, 25))
self.image.fill((51, 51, 0))
self.rect = self.image.get_rect()
self.height -= self.rect.height/2 + 10 + 10*self.subtype
self.rect.center = (mainGameClass.getScreenWidth() + self.rect.width,
self.height)
self.speed = self.thisGame.getGameSpeed()*2
+89
View File
@@ -0,0 +1,89 @@
"""
Player entity class
"""
import pygame
class Player(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface((50, 75))
self.image.fill((153, 151, 0))
self.rect = self.image.get_rect()
self.rect.center = (100, 400)
self.speed = 0.0
self.isJumping = False
self.isCrouching = False
self.hoverCount = 0
self.isOnFloor = False
self.isDownJump = False
self.isDownCrouch = False
self.buttonsJump = (pygame.K_UP, pygame.K_SPACE,)
self.buttonsCrouch = (pygame.K_DOWN,)
self.gameSpeed = 1
def crouch(self):
if not self.isCrouching:
self.isCrouching = True
self.rect = self.rect.inflate(0, -25)
# self.image.set_clip((50, 50))
def standup(self):
if self.isCrouching:
self.isCrouching = False
self.rect = self.rect.inflate(0, 25)
def updateSpeed(self, newGameSpeed):
self.gameSpeed = newGameSpeed
def control(self, event):
if event.type == pygame.KEYDOWN:
if event.key in self.buttonsCrouch:
self.isDownCrouch = True
elif event.key in self.buttonsJump:
self.isDownJump = True
elif event.type == pygame.KEYUP:
if event.key in self.buttonsCrouch:
self.isDownCrouch = False
elif event.key in self.buttonsJump:
self.isDownJump = False
def update(self):
if not self.speed: self.rect.y += 1
self.speed += 0.09 * self.gameSpeed
self.rect.y += self.speed
if not self.isDownJump:
self.hoverCount = 0
if self.isOnFloor:
self.speed = 0
if self.isDownJump:
self.isJumping = True
if self.isCrouching:
self.standup()
elif self.isDownCrouch:
if not self.isCrouching:
self.crouch()
elif self.isCrouching:
self.standup()
if self.isJumping:
if self.isDownJump and self.hoverCount < 8:
self.speed -= (1 - self.speed/(15+
self.hoverCount*3)) * self.gameSpeed/2
self.hoverCount += 1
else:
self.isJumping = False
+31
View File
@@ -0,0 +1,31 @@
"""
Standing enemy entity class
"""
import pygame
import random
from Enemy import Enemy
class StandingEnemy(Enemy):
def __init__(self, mainGameClass):
Enemy.__init__(self, mainGameClass)
self.subtype = random.randint(1, 5)
if self.subtype == 1: self.image = pygame.Surface((25, 75))
elif self.subtype == 2: self.image = pygame.Surface((25, 25))
elif self.subtype == 3: self.image = pygame.Surface((75, 25))
elif self.subtype == 4: self.image = pygame.Surface((50, 25))
elif self.subtype == 5: self.image = pygame.Surface((50, 50))
else: self.image = pygame.Surface((25, 50))
self.image.fill((0, 153, 0))
self.rect = self.image.get_rect()
self.height -= self.rect.height/2
self.rect.center = (mainGameClass.getScreenWidth() + self.rect.width,
self.height)
self.speed = self.thisGame.getGameSpeed()