Lazy dungeon
Jump to navigation
Jump to search
Lazy Dungeon žaidimas
Ši programa demonstruoja, kaip susikurti klasikinį Dungeon stiliaus žaidimą, kuriame veikėjas kovoja su priešais, keliasi lygį ir savo galią. Taip pradėdamas nuo silpniausių priešų - žurkių, pagrindinis kovotojas sustiprėja ir gali kautis su zombiais, o vėliau ir su pagrindinio lygio bosu.
Šioje programėlėje panaudoti keli skirtingi vaizdo failai ir garsai, kurie atsiranda priklausomai nuo atlikto veiksmo.
Žaisti Lazy Dungeon
Žaidimui reikalingi failai
Visus garsus ir vaizdus panaudotus šiame žaidime galima atsisiųsti čia.
Lazy Dungeon žaidimo kodas
import angis
import žaidimas
import random
# Buvau entity klases iškėlęs į atskirus modulius ir mėginau juos importuoti
# Bet tuomet tų klasių nepavykdavo užnaudoti main scripte
# Gali būti, kad tiesiog nemoku aprašyti python modulių, bet vistiek verta būtų pažiūrėti
# Jei importas veikia super būtų tabų palaikymas ir kad būtų galima kelis failus redaguoti projekte
# Arba bent, kad būtų galima atidaryti kitus failus redagavimui, kad ir tame pačiame lange
class Asset:
grassGraphics = 'pav/plyt/43.png'
dirtGraphics = 'pav/plyt/14.png'
stoneGraphics = 'pav/stat/akmuo3.png'
knightGraphics = 'pixil-frame-0.png'
ratGraphics = 'rat.png'
zombieGraphics = 'zombie.png'
necromancerGraphics = 'necromancer.png'
dungeonMusic = 'dungeon-music.mp3'
class MonsterType:
rat = 'rat'
zombie = 'zombie'
necromancer = 'necromancer'
class Entity:
entityRef = None
health = 0
xp = 0
attackStrength = 0
class WarriorEntity(Entity):
health = 10
xp = 0
attackStrength = 4
level = 1
currentXP = 0
lastPosition = None
stepLength = 50
movementSpeed = 10
healthStatsDisplay = None
levelDisplay = None
isAlive = True
isWin = False
gameRef = None
isDebugMode = False
def __init__(self, gameRef, x = 100, y = 100, debugMode = False):
self.isDebugMode = debugMode
self.gameRef = gameRef
self.entityRef = self.gameRef.Veikėjas(Asset.knightGraphics)
self.entityRef.nustatykKliūtį(x=1, y=1, plotis=48, aukštis=48)
self.lastPosition = [x, y]
self.entityRef.atsirask(x, y)
if self.isDebugMode:
self.entityRef.rodykZonas()
self.initPlayerStatsDisplay()
# Atrodo, kad nesuveikia destruktoriai
# def __del__(self):
# self.entityRef.atsirask(5000, 5000)
# self.entityRef.slėpkis()
def destroy(self):
self.entityRef.atsirask(5000, 5000)
self.entityRef.slėpkis()
def initPlayerStatsDisplay(self):
statsColor = "#FF0000"
self.healthStatsDisplay = self.gameRef.Tekstas()
self.healthStatsDisplay.atsirask(0, 600)
self.healthStatsDisplay.dydis(40)
self.healthStatsDisplay.spalva(statsColor)
self.levelDisplay = self.gameRef.Tekstas()
self.levelDisplay.atsirask(450, 600)
self.levelDisplay.dydis(40)
self.levelDisplay.spalva(statsColor)
self.redrawStats()
def back(self):
self.move(180)
def forward(self):
self.move(0)
def up(self):
self.move(90)
def down(self):
self.move(270)
def move(self, direction):
if self.isAlive and not self.isWin:
self.setLastPosition()
self.entityRef.judėk(self.stepLength, direction, self.movementSpeed)
def setLastPosition(self):
x, y = self.entityRef.duokKoordinates()
self.lastPosition = [x, y]
def teleportPlayerToLastPosition(self):
lastPosition = self.lastPosition
self.entityRef.atsirask(lastPosition[0], lastPosition[1])
def attack(self, enemy):
def enemyAttack(a, b, c):
# Nesuveikia trumpi garso įrašai
# TODO: Papildyti su pvz
# Nebeturėjau laiko įdėti pvz, bet kai garso įrašas trumpas (1-3 sec)
# Jis nesugroja
dmg, enemyXP, isWin = enemy.attack(self.getAttackDamage())
self.isWin = isWin
self.health = self.health - dmg
self.currentXP = self.currentXP + enemyXP
self.teleportPlayerToLastPosition()
self.checkState()
self.redrawStats()
return enemyAttack
def getAttackDamage(self):
return self.attackStrength + round(((self.level - 1) * self.attackStrength) * 0.5)
def onColisionAttach(self, enemy):
self.entityRef.susidūrus(enemy.entityRef, self.attack(enemy))
def drawHealth(self):
healthVisual = '|' * self.health
self.healthStatsDisplay.užrašas("HP: " + healthVisual)
def drawLevel(self):
self.levelDisplay.užrašas("LVL: " + str(self.level))
def checkState(self):
if self.health < 1:
self.isAlive = False
print('You died!')
print('To restart press R')
if self.currentXP >= self.level * 10 + (pow(2, self.level - 1) - 1 ) * 10:
self.health = 10 + self.level * 2
self.level = self.level + 1
if self.isWin:
print('Congratulations! You beat the evil necromancer!')
print('To restart press R')
def redrawStats(self):
self.drawHealth()
self.drawLevel()
class EnemyEntity(Entity):
isNecromancer = False
gameRef = None
number = 0
isDebugMode = False
def __init__(self, gameRef, x, y, z, debugMode = False, sprite = Asset.stoneGraphics):
self.isDebugMode = debugMode
self.gameRef = gameRef
self.entityRef = self.gameRef.Daiktas(sprite)
self.entityRef.nustatykKliūtį(x=25, y=25, plotis=1, aukštis=1)
self.entityRef.atsirask(x, y)
if self.isDebugMode:
self.entityRef.rodykZonas()
self.number = z
def destroy(self):
self.sendToGraveyard()
def attack(self, dmg):
self.life = self.life - dmg
if self.life < 1:
self.sendToGraveyard()
return 0, self.xp, self.isNecromancer
return self.attackStrength, 0, False
def sendToGraveyard(self):
self.entityRef.atsirask(1000 + (50 * self.number), 1000)
self.entityRef.slėpkis()
class Rat(EnemyEntity):
life = 5
attackStrength = 1
xp = 2
def __init__(self, gameRef, x, y, z, debugMode = False):
EnemyEntity.__init__(self, gameRef, x, y, z, debugMode, Asset.ratGraphics)
class Zombie(EnemyEntity):
life = 12
attackStrength = 2
xp = 4
def __init__(self, gameRef, x, y, z, debugMode = False):
EnemyEntity.__init__(self, gameRef, x, y, z, debugMode, Asset.zombieGraphics)
class Necromancer(EnemyEntity):
life = 20
attackStrength = 5
xp = 10
isNecromancer = True
def __init__(self, gameRef, x, y, z, debugMode = False):
EnemyEntity.__init__(self, gameRef, x, y, z, debugMode, Asset.necromancerGraphics)
class Organizer:
angisRef = None
gameRef = None
width = 600
tileWidth = 50
warriorEntity = None
enemyList = []
enemyCount = 0
occupiedLocations = [[1, 1]]
music = None
musicPlaying = False
isDebugMode = False
def __init__(self, angisRef, gameRef, width, debugMode = False):
self.isDebugMode = debugMode
self.angisRef = angisRef
self.gameRef = gameRef
self.width = width
self.angisRef.naudosiuFailus(
[
Asset.grassGraphics,
Asset.dirtGraphics,
Asset.stoneGraphics,
Asset.knightGraphics,
Asset.ratGraphics,
Asset.zombieGraphics,
Asset.necromancerGraphics,
Asset.dungeonMusic
])
self.initMusic()
self.initMap()
self.spawnPlayer()
self.spawnMapEnemies()
def destroy(self):
self.warriorEntity.destroy()
for enemy in self.enemyList:
enemy.destroy()
def initMusic(self):
self.music = angis.Garsas(Asset.dungeonMusic)
self.music.lygis(25)
self.music.grokFone()
self.musicPlaying = True
self.angisRef.paspaudus('m', self.toggleMusic)
def initMap(self):
self.gameRef.scena = self.gameRef.Scena(
plotis = self.width,
aukštis = self.width + 50,
plytelėsPlotis = self.tileWidth,
plytelėsAukštis = self.tileWidth
)
k1 = self.gameRef.Plytelė(Asset.grassGraphics)
k2 = self.gameRef.Plytelė(Asset.dirtGraphics)
maze = [
[k1, k1, k1, k1, k1, k1, k1, k1, k1, k1, k1, k1],
[k1, k2, k2, k2, k2, k2, k2, k2, k2, k2, k2, k1],
[k1, k2, k2, k2, k2, k2, k2, k2, k2, k2, k2, k1],
[k1, k2, k2, k2, k2, k2, k2, k2, k2, k2, k2, k1],
[k1, k2, k2, k2, k2, k2, k2, k2, k2, k2, k2, k1],
[k1, k2, k2, k2, k2, k2, k2, k2, k2, k2, k2, k1],
[k1, k2, k2, k2, k2, k2, k2, k2, k2, k2, k2, k1],
[k1, k2, k2, k2, k2, k2, k2, k2, k2, k2, k2, k1],
[k1, k2, k2, k2, k2, k2, k2, k2, k2, k2, k2, k1],
[k1, k2, k2, k2, k2, k2, k2, k2, k2, k2, k2, k1],
[k1, k2, k2, k2, k2, k2, k2, k2, k2, k2, k2, k1],
[k1, k1, k1, k1, k1, k1, k1, k1, k1, k1, k1, k1]
]
self.gameRef.scena.pridėkPlyteles(maze)
if self.isDebugMode:
self.gameRef.scena.showGrid()
for x in range(12):
self.addStoneBoundary(x * self.tileWidth, 0)
self.addStoneBoundary(x * self.tileWidth, self.width - self.tileWidth)
for x in range(1, 11):
self.addStoneBoundary(0, x * self.tileWidth)
self.addStoneBoundary(self.width - self.tileWidth, x * self.tileWidth)
def addStoneBoundary(self, x, y):
stone = self.gameRef.Daiktas(Asset.stoneGraphics)
stone.atsirask(x, y)
stone.nustatykKliūtį(x=1, y=1, plotis=48, aukštis=48)
if self.isDebugMode:
stone.rodykZonas()
def spawnPlayer(self):
self.warriorEntity = WarriorEntity(self.gameRef, 100, 100, self.isDebugMode)
self.angisRef.paspaudus('a', self.warriorEntity.back)
self.angisRef.paspaudus('w', self.warriorEntity.up)
self.angisRef.paspaudus('s', self.warriorEntity.down)
self.angisRef.paspaudus('d', self.warriorEntity.forward)
def spawnMapEnemies(self):
self.spawnEnemy(MonsterType.rat)
self.spawnEnemy(MonsterType.rat)
self.spawnEnemy(MonsterType.rat)
self.spawnEnemy(MonsterType.zombie)
self.spawnEnemy(MonsterType.zombie)
self.spawnEnemy(MonsterType.zombie)
self.spawnEnemy(MonsterType.zombie)
self.spawnEnemy(MonsterType.zombie)
self.spawnEnemy(MonsterType.zombie)
self.spawnEnemy(MonsterType.necromancer)
def spawnEnemy(self, monsterType):
while True:
x = random.randint(3, 10)
y = random.randint(3, 10)
if [x, y] in self.occupiedLocations:
continue
self.spawnEnemyInCoordinates(monsterType, x * 50, y * 50)
self.occupiedLocations.append([x, y])
break
def toggleMusic(self):
if self.musicPlaying:
self.music.stok()
self.musicPlaying = False
else:
self.music.grokFone()
self.musicPlaying = True
def spawnEnemyInCoordinates(self, monsterType, x, y):
self.enemyCount = self.enemyCount + 1
enemy = None
if monsterType == MonsterType.rat:
enemy = Rat(self.gameRef, x, y, self.enemyCount, self.isDebugMode)
elif monsterType == MonsterType.zombie:
enemy = Zombie(self.gameRef, x, y, self.enemyCount, self.isDebugMode)
elif monsterType == MonsterType.necromancer:
enemy = Necromancer(self.gameRef, x, y, self.enemyCount, self.isDebugMode)
else:
enemy = EnemyEntity(self.gameRef, x, y, self.enemyCount, self.isDebugMode)
self.warriorEntity.onColisionAttach(enemy)
self.enemyList.append(enemy)
debugMode = False
mapWidth = 600
organizer = Organizer(angis, žaidimas, mapWidth, debugMode)
def restartGame(organizerObj):
def restartGameFunction():
if(organizerObj.musicPlaying):
organizerObj.music.stok()
organizerObj.destroy()
organizer = Organizer(angis, žaidimas, mapWidth, debugMode)
return restartGameFunction
angis.paspaudus('r', restartGame(organizer))
Svarbu! Nepamiršk įsikelti žaidime naudojamus paveiksliukus ir garsus per failų tvarkyklę. Visi Lazy Dungeon žaidimui reikalingi failai yra čia.