def __init__(self, engine): self.engine = engine scenepath = os.path.join("scenes", "creation") BGMObj("creation.mp3") self.background = ImgObj(Texture(os.path.join(scenepath, "background.png"))) self.background.setScale(self.engine.w, self.engine.h, inPixels = True) self.background.setPosition(self.engine.w/2,self.engine.h/2) self.window = WinObj(Texture(os.path.join(scenepath, "window.png")), 0.0, 0.0) self.button = ImgObj(Texture("ok.png"), boundable = True, frameX = 2) self.button.setScale(75,75,inPixels = True) self.button.setPosition(self.engine.w*.25, self.engine.h*.5) self.font = FontObj("default.ttf") self.menu = MenuObj(self, commands = ["Easy", "Normal", "Hard"], position = (400, 330)) #family info self.name = [] #name of the family self.diffselected = 1 #the difficulty selected (match up number with position in difficulty array # (1 = default, Normal difficulty) self.fadeIn = True #are the windows transitioning in or out self.error = False #was an error thrown self.step = 0 #step 0 = naming, step 1 = choose difficulty self.exists = False
class Town(Scene): def __init__(self, engine): self.engine = engine self.townname = self.engine.town townpath = os.path.join("places", self.townname) self.townini = Configuration(os.path.join("..", "data", townpath, "town.ini")).town self.background = ImgObj(Texture(os.path.join(townpath, "background.png"))) self.background.setScale(self.engine.w, self.engine.h, inPixels = True) self.background.setPosition(self.engine.w/2, self.engine.h/2) self.font = FontObj("default.ttf", size = 32.0) self.audio = BGMObj(os.path.join(townpath, "bgm.mp3")) self.choices = [choice.strip() for choice in self.townini.choices.split(",")] self.choices.append("Return") self.menu = MenuObj(self, self.choices, buttonStyle = Texture(os.path.join(townpath, "button.png")), position = (100, 500)) self.enemies = [formation.strip() for formation in self.townini.enemylist.split(",")] def buttonClicked(self, image): self.menu.buttonClicked(image) def keyPressed(self, key, char): self.menu.keyPressed(key) #leave town if key == Input.BButton: self.engine.town = None self.engine.viewport.changeScene("Maplist") def select(self, index): if self.choices[index] == "Wilderness": self.engine.formation = Formation(random.choice(self.enemies)) self.engine.viewport.changeScene("BattleSystem") if index == len(self.choices)-1: self.engine.town = None self.engine.viewport.changeScene("Maplist") #else: # self.engine.subTown = self.choices[index] # self.engine.viewport.changeScene("Shop") def render(self, visibility): self.background.draw() self.menu.render() self.engine.drawText(self.font, self.townname, (430, 64))
def __init__(self, engine): self.engine = engine self.townname = self.engine.town townpath = os.path.join("places", self.townname) self.townini = Configuration(os.path.join("..", "data", townpath, "town.ini")).town self.background = ImgObj(Texture(os.path.join(townpath, "background.png"))) self.background.setScale(self.engine.w, self.engine.h, inPixels = True) self.background.setPosition(self.engine.w/2, self.engine.h/2) self.font = FontObj("default.ttf", size = 32.0) self.audio = BGMObj(os.path.join(townpath, "bgm.mp3")) self.choices = [choice.strip() for choice in self.townini.choices.split(",")] self.choices.append("Return") self.menu = MenuObj(self, self.choices, buttonStyle = Texture(os.path.join(townpath, "button.png")), position = (100, 500)) self.enemies = [formation.strip() for formation in self.townini.enemylist.split(",")]
def __init__(self, engine): self.engine = engine commands = ["New Game", "Exit"] self.continueEnabled = bool(len(self.engine.listPath(path = os.path.join("actors", "families"), value = "family.ini", flag = "folderDeepSearch")) > 0) if self.continueEnabled: commands.insert(1, "Continue") self.menu = MenuObj(self, commands, position = (150, 200)) self.background = ImgObj(Texture("mainbg.png")) self.background.setScale(self.engine.w, self.engine.h, inPixels = True) self.background.setPosition(self.engine.w/2, self.engine.h/2) self.music = BGMObj("test.mp3") self.selected = 0 self.helpButtons = [[Input.AButton, "Selects a command"], [Input.DnButton, "Scrolls down"], [Input.UpButton, "Scrolls up"]]
def __init__(self, engine): self.engine = engine self.family = self.engine.family scenepath = os.path.join("scenes", "menusystem") self.background = ImgObj(Texture(os.path.join(scenepath, "background.png"))) self.background.setScale(self.engine.w,self.engine.h, inPixels = True) self.background.setPosition(self.engine.w/2, self.engine.h/2) self.font = FontObj("default.ttf") #self.members = self.family.members #self.startIndex = 0 #self.endIndex = min(4, len(self.members)) self.choices = ["Family", "Character", "Settings", "Quit Game", "Exit Menu"] self.familyChoices = ["Inventory", "Bestiary", "Order"] self.charChoices = ["Spells", "Equipment", "Status"] #helps captions for each menu choice #explains the purpose of each menu before selecting self.help = ["Show what items you currently possess", "Plan your next battle by examining your arsenal of spells", "Equip your character with armor and weapons to give him/her the edge in battle", "Not sure about your character's stats? Want to know how to improve what with which item?", "Don't like the current feel of gameplay? Change it up a bit to your preference", "I guess you've had enough for today I suppose", "Return to your game"] self.menu = Menu(self, self.choices, position = (0, self.engine.h - 24.0)) self.familyMenu = Menu(self, self.familyChoices, position = (0,self.engine.h-72.0)) self.charMenu = Menu(self, self.charChoices, position = (0,self.engine.h-72.0)) self.quitPrompt = MenuObj(self, ["No", "Yes"], position = (self.engine.w/2, self.engine.h/2)) self.menuButton = ImgObj(Texture(os.path.join(scenepath, "button.png")), frameY = 2) self.playerWin = [PlayerStats(self, char, self.engine.h/4 + (self.engine.h/10 * i)) for i, char in enumerate(self.family.party.members)] self.dimension = 0 #this defines which sub-level of the menu you are on
class MainMenu(Scene): def __init__(self, engine): self.engine = engine commands = ["New Game", "Exit"] self.continueEnabled = bool(len(self.engine.listPath(path = os.path.join("actors", "families"), value = "family.ini", flag = "folderDeepSearch")) > 0) if self.continueEnabled: commands.insert(1, "Continue") self.menu = MenuObj(self, commands, position = (150, 200)) self.background = ImgObj(Texture("mainbg.png")) self.background.setScale(self.engine.w, self.engine.h, inPixels = True) self.background.setPosition(self.engine.w/2, self.engine.h/2) self.music = BGMObj("test.mp3") self.selected = 0 self.helpButtons = [[Input.AButton, "Selects a command"], [Input.DnButton, "Scrolls down"], [Input.UpButton, "Scrolls up"]] def buttonClicked(self, image): self.menu.buttonClicked(image) def keyPressed(self, key, char): self.menu.keyPressed(key) def select(self, index): if index == 0: self.engine.viewport.changeScene("CreateFamily") elif index == 1 and self.continueEnabled: #forcing for testing purposes #self.engine.family = Family("default") #self.engine.viewport.changeScene("MapList") self.engine.viewport.changeScene("FamilyList") else: self.engine.finished = True def run(self): pass def render(self, visibility): self.background.draw() self.menu.render(visibility)
def __init__(self, engine): self.engine = engine name = self.engine.dungeon #name of the dungeon path = os.path.join("places", name) #path to the dungeon self.dungeonini = Configuration(os.path.join("..", "data", path, "dungeon.ini")).dungeon #config file self.formations = [f.strip() for f in self.dungeonini.formations.split(",")] self.otherevents = [e.strip() for e in self.dungeonini.events.split(",")] self.field = Field(self, path) #the field data (grid) #ogg or mp3 support for background music self.music = BGMObj(os.path.join(path, "bgm.mp3"), fullpath = True) if not self.music: self.music = BGMObj(os.path.join(path, "bgm.ogg"), fullpath = True) w,h = self.engine.w, self.engine.h #background image self.background = ImgObj(os.path.join(path, "background.png")) self.background.setScale(self.engine.w, self.engine.h, inPixels = True) self.background.setPosition(w/2,h/2) #displays the current map direction self.compassbase = ImgObj(os.path.join("scenes", "dungeon", "compassbase.png")) self.compassbase.setPosition(w*.1, h*.1) self.compassbase.setScale(256, 256, True) self.compass = ImgObj(os.path.join("scenes", "dungeon", "compass.png")) self.compass.setPosition(w*.1, h*.1) self.compass.setScale(256, 256, True) #displays coordinates of the player self.font = FontObj("default.ttf", size = 32) self.font.setPosition(w*.5,h*.1) #displays player height self.bigFont = FontObj("default.ttf", size = 72) self.bigFont.setPosition(w*.8,h*.9) self.selectedPos = self.field.playerPos #selected position for movement self.distance = 0 #camera controls self.position = [w/2,h/2] self.panX = w/2 self.panY = h/2 self.cameraMotion = False self.angle = 135.0 if self.field.playerPos[0] > self.field.dimensions[0]/2: if self.field.playerPos[1] > self.field.dimensions[1]/2: self.angle = 225.0 else: self.angle = 135.0 else: if self.field.playerPos[1] > self.field.dimensions[1]/2: self.angle = 45.0 else: self.angle = 315.0 self.mode = 0 #0 = view, 1 = action menu, 2 = move self.actionMenu = MenuObj(self, ["Move", "Menu", "Escape"], (w*.8, h*.25), window = "window.png") self.moveKeys = {} #keys used for tile selection self.updateKeys()
class Dungeon(Scene): def __init__(self, engine): self.engine = engine name = self.engine.dungeon #name of the dungeon path = os.path.join("places", name) #path to the dungeon self.dungeonini = Configuration(os.path.join("..", "data", path, "dungeon.ini")).dungeon #config file self.formations = [f.strip() for f in self.dungeonini.formations.split(",")] self.otherevents = [e.strip() for e in self.dungeonini.events.split(",")] self.field = Field(self, path) #the field data (grid) #ogg or mp3 support for background music self.music = BGMObj(os.path.join(path, "bgm.mp3"), fullpath = True) if not self.music: self.music = BGMObj(os.path.join(path, "bgm.ogg"), fullpath = True) w,h = self.engine.w, self.engine.h #background image self.background = ImgObj(os.path.join(path, "background.png")) self.background.setScale(self.engine.w, self.engine.h, inPixels = True) self.background.setPosition(w/2,h/2) #displays the current map direction self.compassbase = ImgObj(os.path.join("scenes", "dungeon", "compassbase.png")) self.compassbase.setPosition(w*.1, h*.1) self.compassbase.setScale(256, 256, True) self.compass = ImgObj(os.path.join("scenes", "dungeon", "compass.png")) self.compass.setPosition(w*.1, h*.1) self.compass.setScale(256, 256, True) #displays coordinates of the player self.font = FontObj("default.ttf", size = 32) self.font.setPosition(w*.5,h*.1) #displays player height self.bigFont = FontObj("default.ttf", size = 72) self.bigFont.setPosition(w*.8,h*.9) self.selectedPos = self.field.playerPos #selected position for movement self.distance = 0 #camera controls self.position = [w/2,h/2] self.panX = w/2 self.panY = h/2 self.cameraMotion = False self.angle = 135.0 if self.field.playerPos[0] > self.field.dimensions[0]/2: if self.field.playerPos[1] > self.field.dimensions[1]/2: self.angle = 225.0 else: self.angle = 135.0 else: if self.field.playerPos[1] > self.field.dimensions[1]/2: self.angle = 45.0 else: self.angle = 315.0 self.mode = 0 #0 = view, 1 = action menu, 2 = move self.actionMenu = MenuObj(self, ["Move", "Menu", "Escape"], (w*.8, h*.25), window = "window.png") self.moveKeys = {} #keys used for tile selection self.updateKeys() #makes sure to flip input keys for selecting a tile when the map is rotated # so it makes sense # down is towards the camera, up is away def updateKeys(self): if self.angle == 45.0 or self.angle == 305.0: self.moveKeys[Input.DnButton] = [(self.selectedPos[0], self.selectedPos[1] + 1), 1] self.moveKeys[Input.UpButton] = [(self.selectedPos[0], self.selectedPos[1] - 1),-1] else: self.moveKeys[Input.UpButton] = [(self.selectedPos[0], self.selectedPos[1] + 1), 1] self.moveKeys[Input.DnButton] = [(self.selectedPos[0], self.selectedPos[1] - 1),-1] if self.angle == 45.0 or self.angle == 215.0: self.moveKeys[Input.RtButton] = [(self.selectedPos[0] + 1, self.selectedPos[1]), 1] self.moveKeys[Input.LtButton] = [(self.selectedPos[0] - 1, self.selectedPos[1]),-1] else: self.moveKeys[Input.LtButton] = [(self.selectedPos[0] + 1, self.selectedPos[1]), 1] self.moveKeys[Input.RtButton] = [(self.selectedPos[0] - 1, self.selectedPos[1]),-1] def keyPressed(self, key, char): #view mode # allows panning and rotating of the map if self.mode == 0: if key == Input.CButton: self.angle += 90.0 self.updateKeys() if key == Input.DButton: self.angle -= 90.0 self.updateKeys() if key == Input.RtButton: self.panX += _panRate if key == Input.LtButton: self.panX -= _panRate if key == Input.UpButton: self.panY += _panRate if key == Input.DnButton: self.panY -= _panRate #open action menu if key == Input.AButton: self.mode = 1 #resets pan position to center if key == Input.BButton: self.panX = w/2 self.panY = h/2 #selecting action elif self.mode == 1: self.actionMenu.keyPressed(key) if key == Input.BButton: self.mode = 0 #selecting tile to move to elif self.mode == 2: if key in self.moveKeys.keys(): try: heightdiff = self.field.grid[self.moveKeys[key][0]].height - self.field.grid[self.field.playerPos].height newDistance = self.distance + self.moveKeys[key][1] if not (abs(heightdiff) > 1 or abs(newDistance) > 1): self.selectedPos = self.moveKeys[key][0] self.distance = newDistance except: return self.field.setSelected(self.selectedPos) self.field.updateList() self.updateKeys() #move player to selected position if key == Input.AButton: self.distance = 0 self.field.playerPos = self.selectedPos self.field.grid[self.field.playerPos].show() self.field.deselect() self.field.updateList() self.mode = 0 #cancel movement if key == Input.BButton: self.selectedPos = self.field.playerPos self.field.deselect() self.field.updateList() self.mode = 1 #menu input def select(self, index): if index == 0: self.mode = 2 self.field.setSelected(self.selectedPos) self.field.updateList() #leave dungeon elif index == 2: self.engine.dungeon = None self.engine.viewport.changeScene("Maplist") def panTo(self, newPosition): #maker sure new position is a list, not tuple newPosition = list(newPosition) #force to new position when selecting tiles if self.mode == 2: self.position = newPosition self.cameraMotion = False if self.position[0] is not newPosition[0]: if abs(newPosition[0] - self.position[0]) > .5: self.position[0] += (newPosition[0]-self.position[0])*.05 else: self.position[0] = newPosition[0] self.cameraMotion = True if self.position[1] is not newPosition[1]: if abs(newPosition[1] - self.position[1]) > .5: self.position[1] += (newPosition[1]-self.position[1])*.05 else: self.position[1] = newPosition[1] self.cameraMotion = True def render(self, visibility): w,h = self.engine.w, self.engine.h self.panTo((self.panX, self.panY)) if not self.mode == 0: self.panX = w/2 self.panY = h/2 if self.mode == 2: self.field.setCenter(self.selectedPos) else: self.field.setCenter() glPushMatrix() glTranslatef(1,1,-1000) self.background.draw() glPopMatrix() glPushMatrix() glTranslatef(self.position[0],self.position[1],-32.0*(max(self.field.dimensions[0],self.field.dimensions[1])+max(self.field.playerPos[0], self.field.playerPos[1]))) if not self.field.rotateTo(self.angle): if self.angle > 360: self.angle %= 360 self.field.angle = self.angle if self.angle < 0: self.angle += 360 self.field.angle = self.angle else: self.cameraMotion = True self.field.render() glPopMatrix() self.bigFont.setText("%iH" % self.field.grid[self.selectedPos].height) self.bigFont.draw() '''Debug Position if self.mode == 2: location = "%s > %s" % (str(self.field.playerPos), str(self.selectedPos)) else: location = "%s" % str(self.field.playerPos) self.font.setText(location) self.font.draw() ''' self.compassbase.draw() self.compass.setAngle(self.field.angle) self.compass.draw() if self.mode == 1: self.actionMenu.render()
class CreateFamily(Scene): def __init__(self, engine): self.engine = engine scenepath = os.path.join("scenes", "creation") BGMObj("creation.mp3") self.background = ImgObj(Texture(os.path.join(scenepath, "background.png"))) self.background.setScale(self.engine.w, self.engine.h, inPixels = True) self.background.setPosition(self.engine.w/2,self.engine.h/2) self.window = WinObj(Texture(os.path.join(scenepath, "window.png")), 0.0, 0.0) self.button = ImgObj(Texture("ok.png"), boundable = True, frameX = 2) self.button.setScale(75,75,inPixels = True) self.button.setPosition(self.engine.w*.25, self.engine.h*.5) self.font = FontObj("default.ttf") self.menu = MenuObj(self, commands = ["Easy", "Normal", "Hard"], position = (400, 330)) #family info self.name = [] #name of the family self.diffselected = 1 #the difficulty selected (match up number with position in difficulty array # (1 = default, Normal difficulty) self.fadeIn = True #are the windows transitioning in or out self.error = False #was an error thrown self.step = 0 #step 0 = naming, step 1 = choose difficulty self.exists = False def buttonClicked(self, image): if self.step == 0: if image == self.button: if not self.exists: self.step += 1 else: self.menu.buttonClicked(image) def keyPressed(self, key, char): if self.step == 0: #name is a maximum of 13 letters if len(self.name) < 13: if (char >= 'a' and char <= 'z') or (char >= 'A' and char <= 'Z'): self.name.append(char) if len(self.name) > 0: #can not have the first character be a blank if key == K_SPACE: self.name.append(" ") if len(self.name) > 0: #can only delete letters if there are some to delete if key == K_BACKSPACE: self.name.pop(-1) if key == K_RETURN and not self.exists: self.next() elif self.step == 1: self.menu.keyPressed(key) def select(self, index): self.diffselected = index self.create() def run(self): self.exists = os.path.exists(os.path.join("..", "data", "actors", "families", string.join(self.name,''))) def next(self): if self.step == 0 and not self.name: self.error = True else: self.step += 1 def renderNaming(self): w, h = self.engine.w, self.engine.h self.window.setPosition(w/2, h/2) self.window.setDimensions(w*.4, h*.15) self.window.draw() if self.window.scale[0] == w*.4 and self.window.scale[1] == h*.15: self.engine.drawText(self.font, "Enter a name", (w*.5, h*.6)) name = string.join(self.name, '') self.engine.drawText(self.font, name, (w*.5, h*.5)) if name: if self.exists: frame = 2 else: frame = 1 self.button.setFrame(x = frame) self.button.draw() def renderDifficulty(self): w, h = self.engine.w, self.engine.h self.window.setPosition(w/2,h/2) self.window.setDimensions(w*.65, h*.25) self.window.draw() if self.window.scale[0] >= w*.65 and self.window.scale[1] >= h*.20: self.engine.drawText(self.font, "Select the difficulty", (w*.5, h*.65)) self.menu.render() def create(self): name = string.join(self.name, '') family = Family(None) family.create(name, self.diffselected) self.engine.family = Family(name) self.engine.viewport.changeScene("CreateCharacter") def render(self, visibility): w, h = self.engine.w, self.engine.h self.engine.drawImage(self.background) if self.step == 0: self.renderNaming() elif self.step == 1: self.renderDifficulty() else: self.create()
def __init__(self, engine): self.engine = engine self.camera = self.engine.viewport.camera #for simplicity's sake w, h = self.engine.w, self.engine.h musicpath = os.path.join("audio", "music", "battle") battleSongs = self.engine.listPath(musicpath, "ogg|mp3") musicpath = os.path.join("audio", "music", "victory") victorySongs = self.engine.listPath(musicpath, "ogg|mp3") if len(battleSongs) > 0: self.battleSong = os.path.join("battle", random.choice(battleSongs)) if len(victorySongs) > 0: self.victorySong = os.path.join("victory", random.choice(victorySongs)) if not pygame.mixer.music.get_busy(): self.music = BGMObj(self.battleSong) battlepath = os.path.join("scenes", "battlesystem") self.activeHighlight = ImgObj(Texture(os.path.join(battlepath, "active_highlight.png"))) self.diffStar = ImgObj(Texture(os.path.join(battlepath, "star.png"))) self.header = ImgObj(os.path.join(battlepath, "header.png")) self.footer = ImgObj(os.path.join(battlepath, "footer.png")) self.infohud = ImgObj(os.path.join(battlepath, "infohud.png")) self.vs = ImgObj(os.path.join(battlepath, "vs.png")) self.boost = ImgObj(os.path.join(battlepath, "boost.png")) self.defend = ImgObj(os.path.join(battlepath, "defend.png")) self.flee = ImgObj(os.path.join(battlepath, "flee.png")) fontStyle = self.engine.data.defaultFont self.text = FontObj(fontStyle, size = 32) self.hudtext = FontObj(fontStyle, size = 32) self.smtext = FontObj(fontStyle, size = 14) self.bigText = FontObj(fontStyle, size = 64) self.party = [m for m in self.engine.family.party.members] self.formation = [e for e in self.engine.formation.enemies] self.terrain = Terrain(self, self.engine.formation.terrain) self.incapParty = 0 #keeps track of how many in the party are incapacitated #when all members are then the battle is over #self.start = ImgObj(Texture("start.png")) #self.start.setPosition(self.engine.w / 2, self.engine.h / 2) self.huds = [BattleHUDCharacter(character, scale = .5) for character in self.party] #player huds self.eHuds = [BattleHUDEnemy(enemy) for enemy in self.formation] #enemy hud self.engageHud = None #battle engage hud self.commandMenu = BattleMenu(self, self.party[0]) #player's commands self.inMenu = False self.active = 0 #which character is currently selecting commands self.activeActor = None #which character/enemy is currently performing an action self.battling = False #are commands being selected or is fighting occuring? #turn order lists self.turn = 0 #whose turn is it self.totalTurns = 0 #keeps track of how many player turns it has taken to defeat the enemy group self.turns = {} for character in self.party: character.initForBattle() self.turns[character] = 0 for enemy in self.formation: enemy.initForBattle() self.turns[enemy] = 0 self.order = [] #target selection self.targetMenu = None self.targeting = False self.pointer = ImgObj(Texture(os.path.join(battlepath, "pointer.png")), frameX = 2) self.displayDelay = 0 #little delay ticker for displaying damage dealt upon a target self.introDelay = 100 #little intro rendering self.fade = ImgObj(Texture(surface = pygame.Surface((self.engine.w, self.engine.h)))) #battle lost self.lose = False self.loseMenu = MenuObj(self, ["Retry", "Give Up"], position = (self.engine.w/2, self.engine.h/2)) #victory! self.victoryPanel = None self.additionHUD = None self.numbers = ImgObj(Texture(os.path.join(battlepath, "numbers.png")), frameX = 10) self.hitImg = ImgObj(Texture(os.path.join(battlepath, "hit.png"))) self.hitImg.setAlignment("right") self.hitImg.setPosition(self.engine.w*.9, self.engine.h*.8) self.fade = 0
class BattleSystem(Scene): def __init__(self, engine): self.engine = engine self.camera = self.engine.viewport.camera #for simplicity's sake w, h = self.engine.w, self.engine.h musicpath = os.path.join("audio", "music", "battle") battleSongs = self.engine.listPath(musicpath, "ogg|mp3") musicpath = os.path.join("audio", "music", "victory") victorySongs = self.engine.listPath(musicpath, "ogg|mp3") if len(battleSongs) > 0: self.battleSong = os.path.join("battle", random.choice(battleSongs)) if len(victorySongs) > 0: self.victorySong = os.path.join("victory", random.choice(victorySongs)) if not pygame.mixer.music.get_busy(): self.music = BGMObj(self.battleSong) battlepath = os.path.join("scenes", "battlesystem") self.activeHighlight = ImgObj(Texture(os.path.join(battlepath, "active_highlight.png"))) self.diffStar = ImgObj(Texture(os.path.join(battlepath, "star.png"))) self.header = ImgObj(os.path.join(battlepath, "header.png")) self.footer = ImgObj(os.path.join(battlepath, "footer.png")) self.infohud = ImgObj(os.path.join(battlepath, "infohud.png")) self.vs = ImgObj(os.path.join(battlepath, "vs.png")) self.boost = ImgObj(os.path.join(battlepath, "boost.png")) self.defend = ImgObj(os.path.join(battlepath, "defend.png")) self.flee = ImgObj(os.path.join(battlepath, "flee.png")) fontStyle = self.engine.data.defaultFont self.text = FontObj(fontStyle, size = 32) self.hudtext = FontObj(fontStyle, size = 32) self.smtext = FontObj(fontStyle, size = 14) self.bigText = FontObj(fontStyle, size = 64) self.party = [m for m in self.engine.family.party.members] self.formation = [e for e in self.engine.formation.enemies] self.terrain = Terrain(self, self.engine.formation.terrain) self.incapParty = 0 #keeps track of how many in the party are incapacitated #when all members are then the battle is over #self.start = ImgObj(Texture("start.png")) #self.start.setPosition(self.engine.w / 2, self.engine.h / 2) self.huds = [BattleHUDCharacter(character, scale = .5) for character in self.party] #player huds self.eHuds = [BattleHUDEnemy(enemy) for enemy in self.formation] #enemy hud self.engageHud = None #battle engage hud self.commandMenu = BattleMenu(self, self.party[0]) #player's commands self.inMenu = False self.active = 0 #which character is currently selecting commands self.activeActor = None #which character/enemy is currently performing an action self.battling = False #are commands being selected or is fighting occuring? #turn order lists self.turn = 0 #whose turn is it self.totalTurns = 0 #keeps track of how many player turns it has taken to defeat the enemy group self.turns = {} for character in self.party: character.initForBattle() self.turns[character] = 0 for enemy in self.formation: enemy.initForBattle() self.turns[enemy] = 0 self.order = [] #target selection self.targetMenu = None self.targeting = False self.pointer = ImgObj(Texture(os.path.join(battlepath, "pointer.png")), frameX = 2) self.displayDelay = 0 #little delay ticker for displaying damage dealt upon a target self.introDelay = 100 #little intro rendering self.fade = ImgObj(Texture(surface = pygame.Surface((self.engine.w, self.engine.h)))) #battle lost self.lose = False self.loseMenu = MenuObj(self, ["Retry", "Give Up"], position = (self.engine.w/2, self.engine.h/2)) #victory! self.victoryPanel = None self.additionHUD = None self.numbers = ImgObj(Texture(os.path.join(battlepath, "numbers.png")), frameX = 10) self.hitImg = ImgObj(Texture(os.path.join(battlepath, "hit.png"))) self.hitImg.setAlignment("right") self.hitImg.setPosition(self.engine.w*.9, self.engine.h*.8) self.fade = 0 #make the additionHUD if the active actor has selected to perform an addition def makeAdditionHUD(self): if isinstance(self.activeActor, Character): if isinstance(self.activeActor.command, ComboAttack): self.additionHUD = BattleHUDAddition(self.engine, self.activeActor) #process key input for the scene def keyPressed(self, key, char): if self.introDelay > 0: #disable input during the intro return if self.lose: self.loseMenu.keyPressed(key) elif self.victoryPanel: self.victoryPanel.keyPressed(key) elif self.battling: if self.additionHUD: if not self.additionHUD.end: self.additionHUD.keyPressed(key) else: if key == Input.BButton: if self.commandMenu.step == 0: self.active -= 1 if self.active < 0: self.active = 0 self.commandMenu = BattleMenu(self, self.party[self.active]) if self.targeting: self.targeting = False self.commandMenu.keyPressed(key) def select(self, index): if self.lose: if index == 0: self.engine.changeScene("BattleSystem") else: self.flee() elif self.targeting: self.party[self.active].target = self.formation[index] self.next() def run(self): for hud in self.huds: hud.update() #win battle if len(self.formation) == 0 and not self.victoryPanel: self.victory() #lose battle elif self.incapParty == len(self.party): self.lose = True if self.battling: if self.additionHUD is not None: if not self.additionHUD.end: self.additionHUD.run() else: self.additionHUD = None else: self.execute() #organizes all the turns for order of execution def battleStart(self): self.turn = 0 #this needs to be called in case an enemy or actor has died self.turns = {} for character in self.party: if not character.incap: self.turns[character] = 0 for enemy in self.formation: self.turns[enemy] = 0 for character in self.party: self.turns[character] = random.randint(0, 50) + character.spd for enemy in self.formation: self.turns[enemy] = random.randint(0, 50) + enemy.spd enemy.getCommand(self.generateEnemyTargets(enemy)) #gets enemy's command and target #automatically puts actors who are defending or boosting first in order for actor in self.turns.keys(): if isinstance(actor, Defend) or isinstance(actor, Boost): self.turns[actor] = 1000 self.order = sorted(self.turns.items(), key=itemgetter(1)) self.activeActor = self.order[self.turn][0] self.battling = True self.makeAdditionHUD() #executes all of the commands def execute(self): actor = self.activeActor if actor.incap: self.next() ''' if self.displayDelay >= 100: actor.turnStart() anim = actor.command.animation if anim: self.displayDelay = 100 else: self.displayDelay = 110 ''' if self.displayDelay <= 110: return if self.displayDelay >= 360: if actor.target != None: if not actor.damage == "Miss": actor.target.currentHP -= actor.damage if actor.target.currentHP <= 0: if isinstance(actor.target, Character): self.incapParty += 1 if isinstance(actor.target, Enemy): self.formation.remove(actor.target) actor.target.incap = True #makes sure to remove the target from the order so they #don't attack if they die before their turn for i, target in enumerate(self.order): if target[0] == actor.target: self.order.pop(i) if i < self.turn: self.turn -= 1 break self.next() else: if isinstance(actor.command, Flee): if actor.command.success: self.end() self.next() #generates the target list for enemies and auto-targetting def generateEnemyTargets(self, actor): targets = [] if isinstance(actor, Character): targetGroup = self.formation else: targetGroup = self.party for t in targetGroup: if not t.incap: targets.append(t) return targets #generates the target list for allies def generateTargets(self, actor): if isinstance(actor, Character): targets = [enemy.name for enemy in self.formation] else: targets= [member.name for member in self.party] position = (self.engine.w - 150, self.engine.h/2 + 30*len(targets)/2) return targets #creates the menu for target selection and activates targeting def selectTarget(self): self.targetMenu = self.generateTargets(self.party[self.active]) self.targeting = True #advances the character for command selection def next(self): if self.battling: self.additionHUD = None #if a character in the user's party just acted, then increment the number of total turns if isinstance(self.activeActor, Character): self.totalTurns += 1 self.displayDelay = 0 self.turn += 1 if self.turn >= len(self.order) or len(self.formation) == 0: self.battling = False self.active = -1 for actor in self.party: actor.turnEnd() for actor in self.formation: actor.turnEnd() self.activeActor = None self.engageHud = None self.next() return self.activeActor = self.order[self.turn][0] #should be performed before the turn officially executes if self.activeActor.target != None: #if the actor's target was knocked out during this phase then a new target # is automatically selected and damage is recalculated if self.activeActor.target.incap: targets = self.generateEnemyTargets(self.activeActor) if len(targets) < 1: self.next() return self.activeActor.target = random.choice(targets) self.makeAdditionHUD() else: self.active += 1 if self.active < len(self.party): self.commandMenu = BattleMenu(self, self.party[self.active]) else: self.commandMenu = None self.battleStart() self.targeting = False def renderBase(self, visibility): self.header.setPosition(self.engine.w/2, self.engine.h-self.header.height/2) self.header.draw() if self.battling: self.text.setText("Fight it out") elif self.targeting: self.text.setText("Select your target") else: self.text.setText("Choose a command") self.text.setAlignment("left") self.text.setPosition(32.0, self.engine.h-self.header.height/2) self.text.draw() self.footer.setPosition(self.engine.w/2, self.footer.height/2) self.footer.draw() def renderBattleInterface(self, visibility): actor = self.activeActor target = actor.target y = self.footer.height/2 f = self.hudtext f.setColor((1,1,1,self.activeActor.getSprite().color[3])) f.setAlignment("center") f.setText(actor.name) f.setPosition(self.engine.w/8, y+16) f.draw() f.setText("HP: %s" % actor.hp) f.setPosition(self.engine.w/8+16, y-24) f.draw() if target is not actor and target is not None: f.setText(target.name) f.setPosition(self.engine.w/8*7, y+16) f.draw() f.setText("HP: %s" % target.hp) f.setPosition(self.engine.w/8*7-16, y-24) f.draw() self.vs.setColor((1,1,1,self.activeActor.getSprite().color[3])) self.vs.setPosition(self.engine.w/2, self.footer.height/2) self.vs.draw() else: if isinstance(actor.command, Boost): drawing = self.boost elif isinstance(actor.command, Defend): drawing = self.defend elif isinstance(actor.command, Flee): drawing = self.flee drawing.setColor((1,1,1,self.activeActor.getSprite().color[3])) drawing.setPosition(self.engine.w/8*5, y) drawing.draw() def renderCommandInterface(self, visibility): actor = self.party[self.active] sprite = actor.getSprite() if self.targeting: actor = self.formation[self.commandMenu.index] sprite = actor.getSprite() align = "right" x = self.engine.w y = self.footer.height+self.infohud.height/2 self.infohud.setAlignment(align) self.infohud.setPosition(x, y) self.infohud.setScale(1,1) self.infohud.draw() self.smtext.setText(actor.name) self.smtext.setAlignment(align) self.smtext.setPosition(x, y+16) self.smtext.draw() self.smtext.setText("HP: %s" % actor.hp) self.smtext.setAlignment(align) self.smtext.setPosition(x, y) self.smtext.draw() for i, hud in enumerate(self.huds): hud.setPosition(20, self.engine.h - self.header.height - 50 - 110*i) hud.draw() self.commandMenu.render(visibility) #renders the spiffy intro animation def renderIntro(self, visibility): for i, member in enumerate(self.party): sprite = member.getSprite() sprite.setPosition(self.engine.w*.8 + 15*i, self.engine.h*.6 - 45*i) self.engine.drawAnimation(sprite, loop = True, reverse = False, delay = 20) for enemy in self.formation: sprite = enemy.getSprite() sprite.draw() self.bigText.setText(self.engine.formation.name) self.bigText.setPosition(self.engine.w/2, self.engine.h/2 + 30) if self.introDelay < 20: self.bigText.fade((1,1,1,0), 20) else: self.bigText.fade((1,1,1,1), 60) self.bigText.draw() difficulty = self.engine.formation.getSelfDifficulty(self.party) if difficulty > 0: for i in range(int(difficulty)): pos = (self.engine.w/2 - (self.diffStar.width/2 + 10)*(difficulty-1) + (self.diffStar.width + 10) * i, self.engine.h/2 - 30) self.engine.drawImage(self.diffStar, position = pos) self.introDelay -= 2 def renderBattle(self, visibility): actor = self.activeActor target = actor.target spriteA = actor.getSprite() spriteA.setPosition(self.engine.w*.25+20*min(self.displayDelay/100.0,1), self.engine.h*.5) spriteA.setScale(-1,1) spriteA.setColor((1,1,1,self.displayDelay/100.0)) self.engine.drawAnimation(spriteA) if target is not actor and target is not None: spriteB = target.getSprite() spriteB.setPosition(self.engine.w*.75-20*min(self.displayDelay/100.0,1), self.engine.h*.5) spriteB.setScale(1,1) spriteB.setColor((1,1,1,self.displayDelay/100.0)) self.engine.drawAnimation(spriteB) else: spriteB = spriteA self.displayDelay += 5 ''' if self.displayDelay >= 100 and self.displayDelay < 110: if actor.command.draw(): self.displayDelay = 100 return else: self.displayDelay = 110 ''' if target != None and self.displayDelay >= 110: #draws the damage on screen if self.displayDelay > 300: a = (360 - self.displayDelay)/60.0 else: a = 1 d = str(actor.damage) if d is not "Miss": x = self.hitImg.position[0] y = self.hitImg.position[1] for i, n in enumerate(d[::-1]): self.engine.drawImage(self.numbers, position = (x - self.hitImg.width - 3 + (self.numbers.width-25)*i+2, y-2), frameX = int(n), color = (0,0,0,a)) self.engine.drawImage(self.numbers, position = (x - self.hitImg.width - 3 + (self.numbers.width-25)*i, y), frameX = int(n), color = (1,1,1,a)) self.engine.drawImage(self.hitImg, position = (x+2, y-2), color = (0,0,0,a)) self.engine.drawImage(self.hitImg, position = (x, y), color = (1,1,1,a)) def render(self, visibility): self.terrain.drawBackground() #if the battle is lost nothing else needs to be drawn or processed if self.lose: self.loseMenu.render(visibility) return #if the battle is won nothing else needs to be drawn if self.victoryPanel: self.victoryPanel.render() return if self.introDelay <= 0: self.renderBase(visibility) if self.battling: self.renderBattle(visibility) self.renderBattleInterface(visibility) else: self.renderCommandInterface(visibility) else: self.renderIntro(visibility) #show the victory screen def victory(self): self.victoryPanel = VictoryPanel(self, self.totalTurns) self.music = BGMObj(self.victorySong) def end(self): self.music.fadeToStop() self.engine.viewport.pop(self)
class MenuSystem(Scene): def __init__(self, engine): self.engine = engine self.family = self.engine.family scenepath = os.path.join("scenes", "menusystem") self.background = ImgObj(Texture(os.path.join(scenepath, "background.png"))) self.background.setScale(self.engine.w,self.engine.h, inPixels = True) self.background.setPosition(self.engine.w/2, self.engine.h/2) self.font = FontObj("default.ttf") #self.members = self.family.members #self.startIndex = 0 #self.endIndex = min(4, len(self.members)) self.choices = ["Family", "Character", "Settings", "Quit Game", "Exit Menu"] self.familyChoices = ["Inventory", "Bestiary", "Order"] self.charChoices = ["Spells", "Equipment", "Status"] #helps captions for each menu choice #explains the purpose of each menu before selecting self.help = ["Show what items you currently possess", "Plan your next battle by examining your arsenal of spells", "Equip your character with armor and weapons to give him/her the edge in battle", "Not sure about your character's stats? Want to know how to improve what with which item?", "Don't like the current feel of gameplay? Change it up a bit to your preference", "I guess you've had enough for today I suppose", "Return to your game"] self.menu = Menu(self, self.choices, position = (0, self.engine.h - 24.0)) self.familyMenu = Menu(self, self.familyChoices, position = (0,self.engine.h-72.0)) self.charMenu = Menu(self, self.charChoices, position = (0,self.engine.h-72.0)) self.quitPrompt = MenuObj(self, ["No", "Yes"], position = (self.engine.w/2, self.engine.h/2)) self.menuButton = ImgObj(Texture(os.path.join(scenepath, "button.png")), frameY = 2) self.playerWin = [PlayerStats(self, char, self.engine.h/4 + (self.engine.h/10 * i)) for i, char in enumerate(self.family.party.members)] self.dimension = 0 #this defines which sub-level of the menu you are on #self.statusbox = self.engine.loadImage(os.path.join("Data", "statusbox.png")) def buttonClicked(self, image): pass def keyPressed(self, key, char): if self.dimension == 1: self.familyMenu.keyPressed(key) #close the character submenu if key == Input.BButton: self.dimension = 0 elif self.dimension == 2: self.charMenu.keyPressed(key) #close the character submenu if key == Input.BButton: self.dimension = 0 elif self.dimension == 3: self.quitPrompt.keyPressed(key) if key == Input.BButton: self.dimension = 0 else: self.menu.keyPressed(key) #close the menu scene if key == Input.BButton: self.engine.viewport.changeScene("Maplist") def select(self, index): if self.dimension == 0: if index == 0: #family self.dimension = 1 elif index == 1: #character self.dimension = 2 elif index == 2: #settings self.engine.viewport.changeScene("SettingsScene") elif index == 3: #quit game self.dimension = 3 elif index == 4: #exit menu self.engine.viewport.changeScene("Maplist") elif self.dimension == 1: if index == 0: #inventory self.engine.viewport.changeScene("InventoryScene") elif index == 1: #bestiary self.engine.viewport.changeScene("BestiaryScene") elif index == 2: #order self.engine.viewport.changeScene("OrderScene") elif self.dimension == 2: if index == 0: #spells/techniques self.engine.viewport.changeScene("SpellScene") elif index == 1: #equipment self.engine.viewport.changeScene("EquipmentScene") elif index == 2: #status self.engine.viewport.changeScene("Status") elif self.dimension == 3: if index == 0: #no self.dimension = 0 elif index == 1: #yes self.engine.finished = True def run(self): pass def render(self, visibility): w, h = self.engine.w, self.engine.h self.background.draw() if self.dimension == 1: self.familyMenu.render() elif self.dimension == 2: self.charMenu.render() self.menu.render() for win in self.playerWin: win.render() self.engine.drawText(self.font, "%i Available Characters" % (len(self.family.members)), (w*.5, 24.0)) if self.dimension == 3: self.font.setText("Are you sure you wish to quit the game?") self.font.setPosition(self.engine.w/2, self.engine.h/2 + 40) self.font.draw() self.quitPrompt.render()